KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > ast > ParameterizedSingleTypeReference


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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  *******************************************************************************/

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 /**
19  * Syntactic representation of a reference to a generic type.
20  * Note that it might also have a dimension.
21  */

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) { // may be null in error cases
40
parameterizedType.boundCheck(scope, this.typeArguments);
41             }
42         }
43     }
44     /**
45      * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#copyDims(int)
46      */

47     public TypeReference copyDims(int dim) {
48         return new ParameterizedSingleTypeReference(token, typeArguments, dim, (((long)sourceStart)<<32)+sourceEnd);
49     }
50
51     /**
52      * @return char[][]
53      */

54     public char [][] getParameterizedTypeName(){
55         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(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     /**
78      * @see org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
79      */

80     protected TypeBinding getTypeBinding(Scope scope) {
81         return null; // not supported here - combined with resolveType(...)
82
}
83
84     /*
85      * No need to check for reference to raw type per construction
86      */

87     private TypeBinding internalResolveType(Scope scope, ReferenceBinding enclosingType, boolean checkBounds) {
88
89         // handle the error here
90
this.constant = Constant.NotAConstant;
91         if ((this.bits & ASTNode.DidResolve) != 0) { // is a shared type reference which was already resolved
92
if (this.resolvedType != null && !this.resolvedType.isValidBinding())
93                 return null; // already reported error
94
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                 // be resilient, still attempt resolving arguments
102
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 member type
115
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 { // resolving member type (relatively to enclosingType)
122
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         // check generic and arity
132
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) { // check generic
162
scope.problemReporter().nonGenericTypeCannotBeParameterized(this, currentType, argTypes);
163             return null;
164         } else if (argLength != typeVariables.length) { // check arity
165
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         // check argument type compatibility
178
if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
179
parameterizedType.boundCheck(scope, this.typeArguments);
180
181         this.resolvedType = parameterizedType;
182         if (isTypeUseDeprecated(this.resolvedType, scope))
183             reportDeprecatedType(this.resolvedType, scope);
184
185         // array type ?
186
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 JavaDoc printExpression(int indent, StringBuffer JavaDoc output){
195         output.append(token);
196         output.append("<"); //$NON-NLS-1$
197
int max = typeArguments.length - 1;
198         for (int i= 0; i < max; i++) {
199             typeArguments[i].print(0, output);
200             output.append(", ");//$NON-NLS-1$
201
}
202         typeArguments[max].print(0, output);
203         output.append(">"); //$NON-NLS-1$
204
if ((this.bits & IsVarArgs) != 0) {
205             for (int i= 0 ; i < dimensions - 1; i++) {
206                 output.append("[]"); //$NON-NLS-1$
207
}
208             output.append("..."); //$NON-NLS-1$
209
} else {
210             for (int i= 0 ; i < dimensions; i++) {
211                 output.append("[]"); //$NON-NLS-1$
212
}
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 /*no bounds check in classScope*/);
223     }
224     
225     public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) {
226         return internalResolveType(scope, enclosingType, true/*check bounds*/);
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