1 /*******************************************************************************
2  * Copyright (c) 2000, 2014 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *     Stephan Herrmann - Contribution for
11  *								Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
12  *******************************************************************************/
13 package org.eclipse.jdt.internal.compiler.ast;
14 
15 import org.eclipse.jdt.core.compiler.CharOperation;
16 import org.eclipse.jdt.internal.compiler.ASTVisitor;
17 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
18 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
19 import org.eclipse.jdt.internal.compiler.lookup.Scope;
20 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
21 
22 public class ArrayTypeReference extends SingleTypeReference {
23 	public int dimensions;
24 	private Annotation[][] annotationsOnDimensions; // jsr308 style type annotations on dimensions.
25 	public int originalSourceEnd;
26 	public int extendedDimensions;
27 
28 	/**
29 	 * ArrayTypeReference constructor comment.
30 	 * @param source char[]
31 	 * @param dimensions int
32 	 * @param pos int
33 	 */
ArrayTypeReference(char[] source, int dimensions, long pos)34 	public ArrayTypeReference(char[] source, int dimensions, long pos) {
35 
36 		super(source, pos);
37 		this.originalSourceEnd = this.sourceEnd;
38 		this.dimensions = dimensions ;
39 		this.annotationsOnDimensions = null;
40 	}
41 
ArrayTypeReference(char[] source, int dimensions, Annotation[][] annotationsOnDimensions, long pos)42 	public ArrayTypeReference(char[] source, int dimensions, Annotation[][] annotationsOnDimensions, long pos) {
43 		this(source, dimensions, pos);
44 		if (annotationsOnDimensions != null) {
45 			this.bits |= ASTNode.HasTypeAnnotations;
46 		}
47 		this.annotationsOnDimensions = annotationsOnDimensions;
48 	}
49 
dimensions()50 	public int dimensions() {
51 
52 		return this.dimensions;
53 	}
54 
extraDimensions()55 	public int extraDimensions() {
56 		return this.extendedDimensions;
57 	}
58 
59 	/**
60 	 @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getAnnotationsOnDimensions(boolean)
61 	*/
getAnnotationsOnDimensions(boolean useSourceOrder)62 	public Annotation[][] getAnnotationsOnDimensions(boolean useSourceOrder) {
63 		if (useSourceOrder || this.annotationsOnDimensions == null || this.annotationsOnDimensions.length == 0 || this.extendedDimensions == 0 || this.extendedDimensions == this.dimensions)
64 			return this.annotationsOnDimensions;
65 		Annotation [][] externalAnnotations = new Annotation[this.dimensions][];
66 		final int baseDimensions = this.dimensions - this.extendedDimensions;
67 		System.arraycopy(this.annotationsOnDimensions, baseDimensions, externalAnnotations, 0, this.extendedDimensions);
68 		System.arraycopy(this.annotationsOnDimensions, 0, externalAnnotations, this.extendedDimensions, baseDimensions);
69 		return externalAnnotations;
70 	}
71 
setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions)72 	public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) {
73 		this.annotationsOnDimensions = annotationsOnDimensions;
74 	}
75 	/**
76 	 * @return char[][]
77 	 */
getParameterizedTypeName()78 	public char [][] getParameterizedTypeName(){
79 		int dim = this.dimensions;
80 		char[] dimChars = new char[dim*2];
81 		for (int i = 0; i < dim; i++) {
82 			int index = i*2;
83 			dimChars[index] = '[';
84 			dimChars[index+1] = ']';
85 		}
86 		return new char[][]{ CharOperation.concat(this.token, dimChars) };
87 	}
getTypeBinding(Scope scope)88 	protected TypeBinding getTypeBinding(Scope scope) {
89 
90 		if (this.resolvedType != null) {
91 			return this.resolvedType;
92 		}
93 		if (this.dimensions > 255) {
94 			scope.problemReporter().tooManyDimensions(this);
95 		}
96 		TypeBinding leafComponentType = scope.getType(this.token);
97 		return scope.createArrayType(leafComponentType, this.dimensions);
98 
99 	}
100 
printExpression(int indent, StringBuffer output)101 	public StringBuffer printExpression(int indent, StringBuffer output){
102 
103 		super.printExpression(indent, output);
104 		if ((this.bits & IsVarArgs) != 0) {
105 			for (int i= 0 ; i < this.dimensions - 1; i++) {
106 				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
107 					output.append(' ');
108 					printAnnotations(this.annotationsOnDimensions[i], output);
109 					output.append(' ');
110 				}
111 				output.append("[]"); //$NON-NLS-1$
112 			}
113 			if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[this.dimensions - 1] != null) {
114 				output.append(' ');
115 				printAnnotations(this.annotationsOnDimensions[this.dimensions - 1], output);
116 				output.append(' ');
117 			}
118 			output.append("..."); //$NON-NLS-1$
119 		} else {
120 			for (int i= 0 ; i < this.dimensions; i++) {
121 				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
122 					output.append(" "); //$NON-NLS-1$
123 					printAnnotations(this.annotationsOnDimensions[i], output);
124 					output.append(" "); //$NON-NLS-1$
125 				}
126 				output.append("[]"); //$NON-NLS-1$
127 			}
128 		}
129 		return output;
130 	}
131 
traverse(ASTVisitor visitor, BlockScope scope)132 	public void traverse(ASTVisitor visitor, BlockScope scope) {
133 		if (visitor.visit(this, scope)) {
134 			if (this.annotations != null) {
135 				Annotation [] typeAnnotations = this.annotations[0];
136 				for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++) {
137 					typeAnnotations[i].traverse(visitor, scope);
138 				}
139 			}
140 			if (this.annotationsOnDimensions != null) {
141 				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
142 					Annotation[] annotations2 = this.annotationsOnDimensions[i];
143 					if (annotations2 != null) {
144 						for (int j = 0, max2 = annotations2.length; j < max2; j++) {
145 							Annotation annotation = annotations2[j];
146 							annotation.traverse(visitor, scope);
147 						}
148 					}
149 				}
150 			}
151 		}
152 		visitor.endVisit(this, scope);
153 	}
154 
traverse(ASTVisitor visitor, ClassScope scope)155 	public void traverse(ASTVisitor visitor, ClassScope scope) {
156 		if (visitor.visit(this, scope)) {
157 			if (this.annotations != null) {
158 				Annotation [] typeAnnotations = this.annotations[0];
159 				for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++) {
160 					typeAnnotations[i].traverse(visitor, scope);
161 				}
162 			}
163 			if (this.annotationsOnDimensions != null) {
164 				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
165 					Annotation[] annotations2 = this.annotationsOnDimensions[i];
166 					if (annotations2 != null) {
167 						for (int j = 0, max2 = annotations2.length; j < max2; j++) {
168 							Annotation annotation = annotations2[j];
169 							annotation.traverse(visitor, scope);
170 						}
171 					}
172 				}
173 			}
174 		}
175 		visitor.endVisit(this, scope);
176 	}
177 
internalResolveType(Scope scope, int location)178 	protected TypeBinding internalResolveType(Scope scope, int location) {
179 		TypeBinding internalResolveType = super.internalResolveType(scope, location);
180 		return internalResolveType;
181 	}
182 }
183