1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.ASTVisitor; 15 import org.eclipse.jdt.internal.compiler.impl.Constant; 16 import org.eclipse.jdt.internal.compiler.lookup.*; 17 18 22 public class ParameterizedQualifiedTypeReference extends ArrayQualifiedTypeReference { 23 24 public TypeReference[][] typeArguments; 25 26 31 public ParameterizedQualifiedTypeReference(char[][] tokens, TypeReference[][] typeArguments, int dim, long[] positions) { 32 33 super(tokens, dim, positions); 34 this.typeArguments = typeArguments; 35 } 36 public void checkBounds(Scope scope) { 37 if (this.resolvedType == null) return; 38 39 checkBounds( 40 (ReferenceBinding) this.resolvedType.leafComponentType(), 41 scope, 42 this.typeArguments.length - 1); 43 } 44 public void checkBounds(ReferenceBinding type, Scope scope, int index) { 45 if (index > 0 && type.enclosingType() != null) { 47 checkBounds(type.enclosingType(), scope, index - 1); 48 } 49 if (type.isParameterizedType()) { 50 ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type; 51 ReferenceBinding currentType = parameterizedType.genericType(); 52 TypeVariableBinding[] typeVariables = currentType.typeVariables(); 53 TypeBinding[] argTypes = parameterizedType.arguments; 54 if (argTypes != null && typeVariables != null) { parameterizedType.boundCheck(scope, this.typeArguments[index]); 56 } 57 } 58 } 59 public TypeReference copyDims(int dim){ 60 return new ParameterizedQualifiedTypeReference(this.tokens, this.typeArguments, dim, this.sourcePositions); 61 } 62 63 66 public char [][] getParameterizedTypeName(){ 67 int length = this.tokens.length; 68 char[][] qParamName = new char[length][]; 69 for (int i = 0; i < length; i++) { 70 TypeReference[] arguments = this.typeArguments[i]; 71 if (arguments == null) { 72 qParamName[i] = this.tokens[i]; 73 } else { 74 StringBuffer buffer = new StringBuffer (5); 75 buffer.append(this.tokens[i]); 76 buffer.append('<'); 77 for (int j = 0, argLength =arguments.length; j < argLength; j++) { 78 if (j > 0) buffer.append(','); 79 buffer.append(CharOperation.concatWith(arguments[j].getParameterizedTypeName(), '.')); 80 } 81 buffer.append('>'); 82 int nameLength = buffer.length(); 83 qParamName[i] = new char[nameLength]; 84 buffer.getChars(0, nameLength, qParamName[i], 0); 85 } 86 } 87 int dim = this.dimensions; 88 if (dim > 0) { 89 char[] dimChars = new char[dim*2]; 90 for (int i = 0; i < dim; i++) { 91 int index = i*2; 92 dimChars[index] = '['; 93 dimChars[index+1] = ']'; 94 } 95 qParamName[length-1] = CharOperation.concat(qParamName[length-1], dimChars); 96 } 97 return qParamName; 98 } 99 100 103 protected TypeBinding getTypeBinding(Scope scope) { 104 return null; } 106 107 110 private TypeBinding internalResolveType(Scope scope, boolean checkBounds) { 111 112 this.constant = Constant.NotAConstant; 114 if ((this.bits & ASTNode.DidResolve) != 0) { if (this.resolvedType != null && !this.resolvedType.isValidBinding()) 116 return null; return this.resolvedType; 118 } 119 this.bits |= ASTNode.DidResolve; 120 boolean isClassScope = scope.kind == Scope.CLASS_SCOPE; 121 Binding binding = scope.getPackage(this.tokens); 122 if (binding != null && !binding.isValidBinding()) { 123 this.resolvedType = (ReferenceBinding) binding; 124 reportInvalidType(scope); 125 for (int i = 0, max = this.tokens.length; i < max; i++) { 127 TypeReference[] args = this.typeArguments[i]; 128 if (args != null) { 129 int argLength = args.length; 130 for (int j = 0; j < argLength; j++) { 131 TypeReference typeArgument = args[j]; 132 if (isClassScope) { 133 typeArgument.resolveType((ClassScope) scope); 134 } else { 135 typeArgument.resolveType((BlockScope) scope, checkBounds); 136 } 137 } 138 } 139 } 140 return null; 141 } 142 143 PackageBinding packageBinding = binding == null ? null : (PackageBinding) binding; 144 boolean typeIsConsistent = true; 145 ReferenceBinding qualifiedType = null; 146 for (int i = packageBinding == null ? 0 : packageBinding.compoundName.length, max = this.tokens.length; i < max; i++) { 147 findNextTypeBinding(i, scope, packageBinding); 148 if (!(this.resolvedType.isValidBinding())) { 149 reportInvalidType(scope); 150 for (int j = i; j < max; j++) { 152 TypeReference[] args = this.typeArguments[j]; 153 if (args != null) { 154 int argLength = args.length; 155 for (int k = 0; k < argLength; k++) { 156 TypeReference typeArgument = args[k]; 157 if (isClassScope) { 158 typeArgument.resolveType((ClassScope) scope); 159 } else { 160 typeArgument.resolveType((BlockScope) scope); 161 } 162 } 163 } 164 } 165 return null; 166 } 167 ReferenceBinding currentType = (ReferenceBinding) this.resolvedType; 168 if (qualifiedType == null) { 169 qualifiedType = currentType.enclosingType(); if (qualifiedType != null && (qualifiedType.isGenericType() || qualifiedType.isParameterizedType())) { 171 qualifiedType = currentType.isStatic() 172 ? (ReferenceBinding) scope.environment().convertToRawType(qualifiedType) 173 : scope.environment().convertToParameterizedType(qualifiedType); 174 } 175 } 176 if (typeIsConsistent && currentType.isStatic() && qualifiedType != null && (qualifiedType.isParameterizedType() || qualifiedType.isGenericType())) { 177 scope.problemReporter().staticMemberOfParameterizedType(this, scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType)); 178 typeIsConsistent = false; 179 } 180 TypeReference[] args = this.typeArguments[i]; 182 if (args != null) { 183 TypeReference keep = null; 184 if (isClassScope) { 185 keep = ((ClassScope) scope).superTypeReference; 186 ((ClassScope) scope).superTypeReference = null; 187 } 188 int argLength = args.length; 189 TypeBinding[] argTypes = new TypeBinding[argLength]; 190 boolean argHasError = false; 191 for (int j = 0; j < argLength; j++) { 192 TypeReference arg = args[j]; 193 TypeBinding argType = isClassScope 194 ? arg.resolveTypeArgument((ClassScope) scope, currentType, j) 195 : arg.resolveTypeArgument((BlockScope) scope, currentType, j); 196 if (argType == null) { 197 argHasError = true; 198 } else { 199 argTypes[j] = argType; 200 } 201 } 202 if (argHasError) { 203 return null; 204 } 205 if (isClassScope) { 206 ((ClassScope) scope).superTypeReference = keep; 207 if (((ClassScope) scope).detectHierarchyCycle(currentType, this)) 208 return null; 209 } 210 211 TypeVariableBinding[] typeVariables = currentType.typeVariables(); 212 if (typeVariables == Binding.NO_TYPE_VARIABLES) { scope.problemReporter().nonGenericTypeCannotBeParameterized(i, this, currentType, argTypes); 214 return null; 215 } else if (argLength != typeVariables.length) { scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes); 217 return null; 218 } 219 if (typeIsConsistent && !currentType.isStatic()) { 221 ReferenceBinding actualEnclosing = currentType.enclosingType(); 222 if (actualEnclosing != null && actualEnclosing.isRawType()) { 223 scope.problemReporter().rawMemberTypeCannotBeParameterized( 224 this, scope.environment().createRawType((ReferenceBinding)currentType.erasure(), actualEnclosing), argTypes); 225 typeIsConsistent = false; 226 } 227 } 228 ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, qualifiedType); 229 if (checkBounds) parameterizedType.boundCheck(scope, args); 232 qualifiedType = parameterizedType; 233 } else { 234 if (isClassScope) 235 if (((ClassScope) scope).detectHierarchyCycle(currentType, this)) 236 return null; 237 ReferenceBinding currentErasure = (ReferenceBinding)currentType.erasure(); 238 if (currentErasure.isGenericType()) { 239 if (typeIsConsistent && qualifiedType != null && qualifiedType.isParameterizedType()) { 240 scope.problemReporter().parameterizedMemberTypeMissingArguments(this, scope.environment().createParameterizedType(currentErasure, null, qualifiedType)); 241 typeIsConsistent = false; 242 } 243 qualifiedType = scope.environment().createRawType(currentErasure, qualifiedType); } else { 245 qualifiedType = (qualifiedType != null && qualifiedType.isParameterizedType()) 246 ? scope.environment().createParameterizedType(currentErasure, null, qualifiedType) 247 : currentType; 248 } 249 } 250 if (isTypeUseDeprecated(qualifiedType, scope)) 251 reportDeprecatedType(qualifiedType, scope); 252 this.resolvedType = qualifiedType; 253 } 254 if (this.dimensions > 0) { 257 if (dimensions > 255) 258 scope.problemReporter().tooManyDimensions(this); 259 this.resolvedType = scope.createArrayType(this.resolvedType, dimensions); 260 } 261 return this.resolvedType; 262 } 263 264 public StringBuffer printExpression(int indent, StringBuffer output) { 265 int length = tokens.length; 266 for (int i = 0; i < length - 1; i++) { 267 output.append(tokens[i]); 268 TypeReference[] typeArgument = typeArguments[i]; 269 if (typeArgument != null) { 270 output.append('<'); 271 int max = typeArgument.length - 1; 272 for (int j = 0; j < max; j++) { 273 typeArgument[j].print(0, output); 274 output.append(", "); } 276 typeArgument[max].print(0, output); 277 output.append('>'); 278 } 279 output.append('.'); 280 } 281 output.append(tokens[length - 1]); 282 TypeReference[] typeArgument = typeArguments[length - 1]; 283 if (typeArgument != null) { 284 output.append('<'); 285 int max = typeArgument.length - 1; 286 for (int j = 0; j < max; j++) { 287 typeArgument[j].print(0, output); 288 output.append(", "); } 290 typeArgument[max].print(0, output); 291 output.append('>'); 292 } 293 if ((this.bits & IsVarArgs) != 0) { 294 for (int i= 0 ; i < dimensions - 1; i++) { 295 output.append("[]"); } 297 output.append("..."); } else { 299 for (int i= 0 ; i < dimensions; i++) { 300 output.append("[]"); } 302 } 303 return output; 304 } 305 306 public TypeBinding resolveType(BlockScope scope, boolean checkBounds) { 307 return internalResolveType(scope, checkBounds); 308 } 309 public TypeBinding resolveType(ClassScope scope) { 310 return internalResolveType(scope, false); 311 } 312 public void traverse(ASTVisitor visitor, BlockScope scope) { 313 if (visitor.visit(this, scope)) { 314 for (int i = 0, max = this.typeArguments.length; i < max; i++) { 315 if (this.typeArguments[i] != null) { 316 for (int j = 0, max2 = this.typeArguments[i].length; j < max2; j++) { 317 this.typeArguments[i][j].traverse(visitor, scope); 318 } 319 } 320 } 321 } 322 visitor.endVisit(this, scope); 323 } 324 325 public void traverse(ASTVisitor visitor, ClassScope scope) { 326 if (visitor.visit(this, scope)) { 327 for (int i = 0, max = this.typeArguments.length; i < max; i++) { 328 if (this.typeArguments[i] != null) { 329 for (int j = 0, max2 = this.typeArguments[i].length; j < max2; j++) { 330 this.typeArguments[i][j].traverse(visitor, scope); 331 } 332 } 333 } 334 } 335 visitor.endVisit(this, scope); 336 } 337 338 } 339 | Popular Tags |