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.*;
18 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
19 
20 public class ArrayQualifiedTypeReference extends QualifiedTypeReference {
21 	int dimensions;
22 	private Annotation[][] annotationsOnDimensions;  // jsr308 style type annotations on dimensions
23 	public int extendedDimensions;
24 
ArrayQualifiedTypeReference(char[][] sources , int dim, long[] poss)25 	public ArrayQualifiedTypeReference(char[][] sources , int dim, long[] poss) {
26 
27 		super( sources , poss);
28 		this.dimensions = dim ;
29 		this.annotationsOnDimensions = null;
30 	}
31 
ArrayQualifiedTypeReference(char[][] sources, int dim, Annotation[][] annotationsOnDimensions, long[] poss)32 	public ArrayQualifiedTypeReference(char[][] sources, int dim, Annotation[][] annotationsOnDimensions, long[] poss) {
33 		this(sources, dim, poss);
34 		this.annotationsOnDimensions = annotationsOnDimensions;
35 		if (annotationsOnDimensions != null)
36 			this.bits |= ASTNode.HasTypeAnnotations;
37 	}
38 
dimensions()39 	public int dimensions() {
40 
41 		return this.dimensions;
42 	}
43 
extraDimensions()44 	public int extraDimensions() {
45 		return this.extendedDimensions;
46 	}
47 
48 	/**
49 	 @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getAnnotationsOnDimensions(boolean)
50 	*/
getAnnotationsOnDimensions(boolean useSourceOrder)51 	public Annotation[][] getAnnotationsOnDimensions(boolean useSourceOrder) {
52 		if (useSourceOrder || this.annotationsOnDimensions == null || this.annotationsOnDimensions.length == 0 || this.extendedDimensions == 0 || this.extendedDimensions == this.dimensions)
53 			return this.annotationsOnDimensions;
54 		Annotation [][] externalAnnotations = new Annotation[this.dimensions][];
55 		final int baseDimensions = this.dimensions - this.extendedDimensions;
56 		System.arraycopy(this.annotationsOnDimensions, baseDimensions, externalAnnotations, 0, this.extendedDimensions);
57 		System.arraycopy(this.annotationsOnDimensions, 0, externalAnnotations, this.extendedDimensions, baseDimensions);
58 		return externalAnnotations;
59 	}
60 
setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions)61 	public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) {
62 		this.annotationsOnDimensions = annotationsOnDimensions;
63 	}
64 
65 	/**
66 	 * @return char[][]
67 	 */
getParameterizedTypeName()68 	public char [][] getParameterizedTypeName(){
69 		int dim = this.dimensions;
70 		char[] dimChars = new char[dim*2];
71 		for (int i = 0; i < dim; i++) {
72 			int index = i*2;
73 			dimChars[index] = '[';
74 			dimChars[index+1] = ']';
75 		}
76 		int length = this.tokens.length;
77 		char[][] qParamName = new char[length][];
78 		System.arraycopy(this.tokens, 0, qParamName, 0, length-1);
79 		qParamName[length-1] = CharOperation.concat(this.tokens[length-1], dimChars);
80 		return qParamName;
81 	}
82 
getTypeBinding(Scope scope)83 	protected TypeBinding getTypeBinding(Scope scope) {
84 
85 		if (this.resolvedType != null)
86 			return this.resolvedType;
87 		if (this.dimensions > 255) {
88 			scope.problemReporter().tooManyDimensions(this);
89 		}
90 		LookupEnvironment env = scope.environment();
91 		try {
92 			env.missingClassFileLocation = this;
93 			TypeBinding leafComponentType = super.getTypeBinding(scope);
94 			if (leafComponentType != null) {
95 				return this.resolvedType = scope.createArrayType(leafComponentType, this.dimensions);
96 			}
97 			return null;
98 		} catch (AbortCompilation e) {
99 			e.updateContext(this, scope.referenceCompilationUnit().compilationResult);
100 			throw e;
101 		} finally {
102 			env.missingClassFileLocation = null;
103 		}
104 	}
105 
internalResolveType(Scope scope, int location)106 	protected TypeBinding internalResolveType(Scope scope, int location) {
107 		TypeBinding internalResolveType = super.internalResolveType(scope, location);
108 		return internalResolveType;
109 	}
110 
printExpression(int indent, StringBuffer output)111 	public StringBuffer printExpression(int indent, StringBuffer output){
112 
113 		super.printExpression(indent, output);
114 		if ((this.bits & IsVarArgs) != 0) {
115 			for (int i= 0 ; i < this.dimensions - 1; i++) {
116 				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
117 					output.append(' ');
118 					printAnnotations(this.annotationsOnDimensions[i], output);
119 					output.append(' ');
120 				}
121 				output.append("[]"); //$NON-NLS-1$
122 			}
123 			if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[this.dimensions - 1] != null) {
124 				output.append(' ');
125 				printAnnotations(this.annotationsOnDimensions[this.dimensions - 1], output);
126 				output.append(' ');
127 			}
128 			output.append("..."); //$NON-NLS-1$
129 		} else {
130 			for (int i= 0 ; i < this.dimensions; i++) {
131 				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
132 					output.append(" "); //$NON-NLS-1$
133 					printAnnotations(this.annotationsOnDimensions[i], output);
134 					output.append(" "); //$NON-NLS-1$
135 				}
136 				output.append("[]"); //$NON-NLS-1$
137 			}
138 		}
139 		return output;
140 	}
141 
traverse(ASTVisitor visitor, BlockScope scope)142 	public void traverse(ASTVisitor visitor, BlockScope scope) {
143 		if (visitor.visit(this, scope)) {
144 			if (this.annotations != null) {
145 				int annotationsLevels = this.annotations.length;
146 				for (int i = 0; i < annotationsLevels; i++) {
147 					int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length;
148 					for (int j = 0; j < annotationsLength; j++)
149 						this.annotations[i][j].traverse(visitor, scope);
150 				}
151 			}
152 			if (this.annotationsOnDimensions != null) {
153 				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
154 					Annotation[] annotations2 = this.annotationsOnDimensions[i];
155 					for (int j = 0, max2 = annotations2 == null ? 0 : annotations2.length; j < max2; j++) {
156 						Annotation annotation = annotations2[j];
157 						annotation.traverse(visitor, scope);
158 					}
159 				}
160 			}
161 		}
162 		visitor.endVisit(this, scope);
163 	}
164 
traverse(ASTVisitor visitor, ClassScope scope)165 	public void traverse(ASTVisitor visitor, ClassScope scope) {
166 		if (visitor.visit(this, scope)) {
167 			if (this.annotations != null) {
168 				int annotationsLevels = this.annotations.length;
169 				for (int i = 0; i < annotationsLevels; i++) {
170 					int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length;
171 					for (int j = 0; j < annotationsLength; j++)
172 						this.annotations[i][j].traverse(visitor, scope);
173 				}
174 			}
175 			if (this.annotationsOnDimensions != null) {
176 				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
177 					Annotation[] annotations2 = this.annotationsOnDimensions[i];
178 					for (int j = 0, max2 = annotations2 == null ? 0 : annotations2.length; j < max2; j++) {
179 						Annotation annotation = annotations2[j];
180 						annotation.traverse(visitor, scope);
181 					}
182 				}
183 			}
184 		}
185 		visitor.endVisit(this, scope);
186 	}
187 }
188