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 ParameterizedSingleTypeReference extends ArrayTypeReference { 23 24 public TypeReference[] typeArguments; 25 26 public ParameterizedSingleTypeReference(char[] name, TypeReference[] typeArguments, int dim, long pos){ 27 super(name, dim, pos); 28 this.originalSourceEnd = this.sourceEnd; 29 this.typeArguments = typeArguments; 30 } 31 public void checkBounds(Scope scope) { 32 if (this.resolvedType == null) return; 33 34 if (this.resolvedType.leafComponentType() instanceof ParameterizedTypeBinding) { 35 ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) this.resolvedType.leafComponentType(); 36 ReferenceBinding currentType = parameterizedType.genericType(); 37 TypeVariableBinding[] typeVariables = currentType.typeVariables(); 38 TypeBinding[] argTypes = parameterizedType.arguments; 39 if (argTypes != null && typeVariables != null) { parameterizedType.boundCheck(scope, this.typeArguments); 41 } 42 } 43 } 44 47 public TypeReference copyDims(int dim) { 48 return new ParameterizedSingleTypeReference(token, typeArguments, dim, (((long)sourceStart)<<32)+sourceEnd); 49 } 50 51 54 public char [][] getParameterizedTypeName(){ 55 StringBuffer buffer = new StringBuffer (5); 56 buffer.append(this.token).append('<'); 57 for (int i = 0, length = this.typeArguments.length; i < length; i++) { 58 if (i > 0) buffer.append(','); 59 buffer.append(CharOperation.concatWith(this.typeArguments[i].getParameterizedTypeName(), '.')); 60 } 61 buffer.append('>'); 62 int nameLength = buffer.length(); 63 char[] name = new char[nameLength]; 64 buffer.getChars(0, nameLength, name, 0); 65 int dim = this.dimensions; 66 if (dim > 0) { 67 char[] dimChars = new char[dim*2]; 68 for (int i = 0; i < dim; i++) { 69 int index = i*2; 70 dimChars[index] = '['; 71 dimChars[index+1] = ']'; 72 } 73 name = CharOperation.concat(name, dimChars); 74 } 75 return new char[][]{ name }; 76 } 77 80 protected TypeBinding getTypeBinding(Scope scope) { 81 return null; } 83 84 87 private TypeBinding internalResolveType(Scope scope, ReferenceBinding enclosingType, boolean checkBounds) { 88 89 this.constant = Constant.NotAConstant; 91 if ((this.bits & ASTNode.DidResolve) != 0) { if (this.resolvedType != null && !this.resolvedType.isValidBinding()) 93 return null; return this.resolvedType; 95 } 96 this.bits |= ASTNode.DidResolve; 97 if (enclosingType == null) { 98 this.resolvedType = scope.getType(token); 99 if (!(this.resolvedType.isValidBinding())) { 100 reportInvalidType(scope); 101 boolean isClassScope = scope.kind == Scope.CLASS_SCOPE; 103 int argLength = this.typeArguments.length; 104 for (int i = 0; i < argLength; i++) { 105 TypeReference typeArgument = this.typeArguments[i]; 106 if (isClassScope) { 107 typeArgument.resolveType((ClassScope) scope); 108 } else { 109 typeArgument.resolveType((BlockScope) scope, checkBounds); 110 } 111 } 112 return null; 113 } 114 enclosingType = this.resolvedType.enclosingType(); if (enclosingType != null && (enclosingType.isGenericType() || enclosingType.isParameterizedType())) { 116 ReferenceBinding currentType = (ReferenceBinding) this.resolvedType; 117 enclosingType = currentType.isStatic() 118 ? (ReferenceBinding) scope.environment().convertToRawType(enclosingType) 119 : scope.environment().convertToParameterizedType(enclosingType); 120 } 121 } else { this.resolvedType = scope.getMemberType(token, enclosingType); 123 if (!this.resolvedType.isValidBinding()) { 124 scope.problemReporter().invalidEnclosingType(this, this.resolvedType, enclosingType); 125 return null; 126 } 127 if (isTypeUseDeprecated(this.resolvedType, scope)) 128 scope.problemReporter().deprecatedType(this.resolvedType, this); 129 } 130 131 boolean isClassScope = scope.kind == Scope.CLASS_SCOPE; 133 TypeReference keep = null; 134 if (isClassScope) { 135 keep = ((ClassScope) scope).superTypeReference; 136 ((ClassScope) scope).superTypeReference = null; 137 } 138 ReferenceBinding currentType = (ReferenceBinding) this.resolvedType; 139 int argLength = this.typeArguments.length; 140 TypeBinding[] argTypes = new TypeBinding[argLength]; 141 boolean argHasError = false; 142 for (int i = 0; i < argLength; i++) { 143 TypeReference typeArgument = this.typeArguments[i]; 144 TypeBinding argType = isClassScope 145 ? typeArgument.resolveTypeArgument((ClassScope) scope, currentType, i) 146 : typeArgument.resolveTypeArgument((BlockScope) scope, currentType, i); 147 if (argType == null) { 148 argHasError = true; 149 } else { 150 argTypes[i] = argType; 151 } 152 } 153 if (argHasError) return null; 154 if (isClassScope) { 155 ((ClassScope) scope).superTypeReference = keep; 156 if (((ClassScope) scope).detectHierarchyCycle(currentType, this)) 157 return null; 158 } 159 160 TypeVariableBinding[] typeVariables = currentType.typeVariables(); 161 if (typeVariables == Binding.NO_TYPE_VARIABLES) { scope.problemReporter().nonGenericTypeCannotBeParameterized(this, currentType, argTypes); 163 return null; 164 } else if (argLength != typeVariables.length) { scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes); 166 return null; 167 } else if (!currentType.isStatic()) { 168 ReferenceBinding actualEnclosing = currentType.enclosingType(); 169 if (actualEnclosing != null && actualEnclosing.isRawType()){ 170 scope.problemReporter().rawMemberTypeCannotBeParameterized( 171 this, scope.environment().createRawType((ReferenceBinding)currentType.erasure(), actualEnclosing), argTypes); 172 return null; 173 } 174 } 175 176 ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, enclosingType); 177 if (checkBounds) parameterizedType.boundCheck(scope, this.typeArguments); 180 181 this.resolvedType = parameterizedType; 182 if (isTypeUseDeprecated(this.resolvedType, scope)) 183 reportDeprecatedType(this.resolvedType, scope); 184 185 if (this.dimensions > 0) { 187 if (dimensions > 255) 188 scope.problemReporter().tooManyDimensions(this); 189 this.resolvedType = scope.createArrayType(this.resolvedType, dimensions); 190 } 191 return this.resolvedType; 192 } 193 194 public StringBuffer printExpression(int indent, StringBuffer output){ 195 output.append(token); 196 output.append("<"); int max = typeArguments.length - 1; 198 for (int i= 0; i < max; i++) { 199 typeArguments[i].print(0, output); 200 output.append(", "); } 202 typeArguments[max].print(0, output); 203 output.append(">"); if ((this.bits & IsVarArgs) != 0) { 205 for (int i= 0 ; i < dimensions - 1; i++) { 206 output.append("[]"); } 208 output.append("..."); } else { 210 for (int i= 0 ; i < dimensions; i++) { 211 output.append("[]"); } 213 } 214 return output; 215 } 216 217 public TypeBinding resolveType(BlockScope scope, boolean checkBounds) { 218 return internalResolveType(scope, null, checkBounds); 219 } 220 221 public TypeBinding resolveType(ClassScope scope) { 222 return internalResolveType(scope, null, false ); 223 } 224 225 public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) { 226 return internalResolveType(scope, enclosingType, true); 227 } 228 229 public void traverse(ASTVisitor visitor, BlockScope scope) { 230 if (visitor.visit(this, scope)) { 231 for (int i = 0, max = this.typeArguments.length; i < max; i++) { 232 this.typeArguments[i].traverse(visitor, scope); 233 } 234 } 235 visitor.endVisit(this, scope); 236 } 237 238 public void traverse(ASTVisitor visitor, ClassScope scope) { 239 if (visitor.visit(this, scope)) { 240 for (int i = 0, max = this.typeArguments.length; i < max; i++) { 241 this.typeArguments[i].traverse(visitor, scope); 242 } 243 } 244 visitor.endVisit(this, scope); 245 } 246 } 247 | Popular Tags |