001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
011:
012: import org.eclipse.jdt.internal.compiler.ASTVisitor;
013: import org.eclipse.jdt.internal.compiler.flow.FlowContext;
014: import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
015: import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
016: import org.eclipse.jdt.internal.compiler.impl.Constant;
017: import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
018: import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
019: import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
020: import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
021: import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
022: import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
023: import org.eclipse.jdt.internal.compiler.lookup.Scope;
024: import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
025: import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
026: import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
027:
028: public abstract class TypeReference extends Expression {
029:
030: public FlowInfo analyseCode(BlockScope currentScope,
031: FlowContext flowContext, FlowInfo flowInfo) {
032: return flowInfo;
033: }
034:
035: // allows us to trap completion & selection nodes
036: public void aboutToResolve(Scope scope) {
037: // default implementation: do nothing
038: }
039:
040: /*
041: * Answer a base type reference (can be an array of base type).
042: */
043: public static final TypeReference baseTypeReference(int baseType,
044: int dim) {
045:
046: if (dim == 0) {
047: switch (baseType) {
048: case (TypeIds.T_void):
049: return new SingleTypeReference(
050: TypeBinding.VOID.simpleName, 0);
051: case (TypeIds.T_boolean):
052: return new SingleTypeReference(
053: TypeBinding.BOOLEAN.simpleName, 0);
054: case (TypeIds.T_char):
055: return new SingleTypeReference(
056: TypeBinding.CHAR.simpleName, 0);
057: case (TypeIds.T_float):
058: return new SingleTypeReference(
059: TypeBinding.FLOAT.simpleName, 0);
060: case (TypeIds.T_double):
061: return new SingleTypeReference(
062: TypeBinding.DOUBLE.simpleName, 0);
063: case (TypeIds.T_byte):
064: return new SingleTypeReference(
065: TypeBinding.BYTE.simpleName, 0);
066: case (TypeIds.T_short):
067: return new SingleTypeReference(
068: TypeBinding.SHORT.simpleName, 0);
069: case (TypeIds.T_int):
070: return new SingleTypeReference(
071: TypeBinding.INT.simpleName, 0);
072: default: //T_long
073: return new SingleTypeReference(
074: TypeBinding.LONG.simpleName, 0);
075: }
076: }
077: switch (baseType) {
078: case (TypeIds.T_void):
079: return new ArrayTypeReference(TypeBinding.VOID.simpleName,
080: dim, 0);
081: case (TypeIds.T_boolean):
082: return new ArrayTypeReference(
083: TypeBinding.BOOLEAN.simpleName, dim, 0);
084: case (TypeIds.T_char):
085: return new ArrayTypeReference(TypeBinding.CHAR.simpleName,
086: dim, 0);
087: case (TypeIds.T_float):
088: return new ArrayTypeReference(TypeBinding.FLOAT.simpleName,
089: dim, 0);
090: case (TypeIds.T_double):
091: return new ArrayTypeReference(
092: TypeBinding.DOUBLE.simpleName, dim, 0);
093: case (TypeIds.T_byte):
094: return new ArrayTypeReference(TypeBinding.BYTE.simpleName,
095: dim, 0);
096: case (TypeIds.T_short):
097: return new ArrayTypeReference(TypeBinding.SHORT.simpleName,
098: dim, 0);
099: case (TypeIds.T_int):
100: return new ArrayTypeReference(TypeBinding.INT.simpleName,
101: dim, 0);
102: default: //T_long
103: return new ArrayTypeReference(TypeBinding.LONG.simpleName,
104: dim, 0);
105: }
106: }
107:
108: public void checkBounds(Scope scope) {
109: // only parameterized type references have bounds
110: }
111:
112: public abstract TypeReference copyDims(int dim);
113:
114: public int dimensions() {
115: return 0;
116: }
117:
118: public abstract char[] getLastToken();
119:
120: /**
121: * @return char[][]
122: * TODO (jerome) should merge back into #getTypeName()
123: */
124: public char[][] getParameterizedTypeName() {
125: return getTypeName();
126: }
127:
128: protected abstract TypeBinding getTypeBinding(Scope scope);
129:
130: /**
131: * @return char[][]
132: */
133: public abstract char[][] getTypeName();
134:
135: public boolean isTypeReference() {
136: return true;
137: }
138:
139: public TypeBinding resolveSuperType(ClassScope scope) {
140: // assumes the implementation of resolveType(ClassScope) will call back to detect cycles
141: if (resolveType(scope) == null)
142: return null;
143:
144: if (this .resolvedType.isTypeVariable()) {
145: this .resolvedType = new ProblemReferenceBinding(
146: getTypeName(),
147: (ReferenceBinding) this .resolvedType,
148: ProblemReasons.IllegalSuperTypeVariable);
149: reportInvalidType(scope);
150: return null;
151: }
152: return this .resolvedType;
153: }
154:
155: public final TypeBinding resolveType(BlockScope blockScope) {
156: return resolveType(blockScope, true /* checkbounds if any */);
157: }
158:
159: public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
160: // handle the error here
161: this .constant = Constant.NotAConstant;
162: if (this .resolvedType != null) // is a shared type reference which was already resolved
163: return this .resolvedType.isValidBinding() ? this .resolvedType
164: : null; // already reported error
165:
166: TypeBinding type = this .resolvedType = getTypeBinding(scope);
167: if (type == null)
168: return null; // detected cycle while resolving hierarchy
169: if (!type.isValidBinding()) {
170: reportInvalidType(scope);
171: return null;
172: }
173: if (type.isArrayType()
174: && ((ArrayBinding) type).leafComponentType == TypeBinding.VOID) {
175: scope.problemReporter().cannotAllocateVoidArray(this );
176: return null;
177: }
178:
179: if (isTypeUseDeprecated(type, scope))
180: reportDeprecatedType(type, scope);
181:
182: type = scope.environment().convertToRawType(type);
183: if (type.leafComponentType().isRawType()
184: && (this .bits & ASTNode.IgnoreRawTypeCheck) == 0
185: && scope.compilerOptions().getSeverity(
186: CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
187: scope.problemReporter().rawTypeReference(this , type);
188: }
189: return this .resolvedType = type;
190: }
191:
192: public TypeBinding resolveType(ClassScope scope) {
193: // handle the error here
194: this .constant = Constant.NotAConstant;
195: if (this .resolvedType != null) // is a shared type reference which was already resolved
196: return this .resolvedType.isValidBinding() ? this .resolvedType
197: : null; // already reported error
198:
199: TypeBinding type = this .resolvedType = getTypeBinding(scope);
200: if (type == null)
201: return null; // detected cycle while resolving hierarchy
202: if (!type.isValidBinding()) {
203: reportInvalidType(scope);
204: return null;
205: }
206: if (type.isArrayType()
207: && ((ArrayBinding) type).leafComponentType == TypeBinding.VOID) {
208: scope.problemReporter().cannotAllocateVoidArray(this );
209: return null;
210: }
211: if (isTypeUseDeprecated(type, scope))
212: reportDeprecatedType(type, scope);
213:
214: type = scope.environment().convertToRawType(type);
215: if (type.leafComponentType().isRawType()
216: && (this .bits & ASTNode.IgnoreRawTypeCheck) == 0
217: && scope.compilerOptions().getSeverity(
218: CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
219: scope.problemReporter().rawTypeReference(this , type);
220: }
221: return this .resolvedType = type;
222: }
223:
224: public TypeBinding resolveTypeArgument(BlockScope blockScope,
225: ReferenceBinding genericType, int rank) {
226: return resolveType(blockScope, true /* check bounds*/);
227: }
228:
229: public TypeBinding resolveTypeArgument(ClassScope classScope,
230: ReferenceBinding genericType, int rank) {
231: return resolveType(classScope);
232: }
233:
234: protected void reportInvalidType(Scope scope) {
235: scope.problemReporter().invalidType(this , this .resolvedType);
236: }
237:
238: protected void reportDeprecatedType(TypeBinding type, Scope scope) {
239: scope.problemReporter().deprecatedType(type, this );
240: }
241:
242: public abstract void traverse(ASTVisitor visitor, BlockScope scope);
243:
244: public abstract void traverse(ASTVisitor visitor, ClassScope scope);
245: }
|