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.lookup.*;
014: import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
015:
016: public class QualifiedTypeReference extends TypeReference {
017:
018: public char[][] tokens;
019: public long[] sourcePositions;
020:
021: public QualifiedTypeReference(char[][] sources, long[] poss) {
022:
023: tokens = sources;
024: sourcePositions = poss;
025: sourceStart = (int) (sourcePositions[0] >>> 32);
026: sourceEnd = (int) (sourcePositions[sourcePositions.length - 1] & 0x00000000FFFFFFFFL);
027: }
028:
029: public TypeReference copyDims(int dim) {
030: //return a type reference copy of me with some dimensions
031: //warning : the new type ref has a null binding
032: return new ArrayQualifiedTypeReference(tokens, dim,
033: sourcePositions);
034: }
035:
036: protected TypeBinding findNextTypeBinding(int tokenIndex,
037: Scope scope, PackageBinding packageBinding) {
038: LookupEnvironment env = scope.environment();
039: try {
040: env.missingClassFileLocation = this ;
041: if (this .resolvedType == null) {
042: this .resolvedType = scope.getType(
043: this .tokens[tokenIndex], packageBinding);
044: } else {
045: this .resolvedType = scope.getMemberType(
046: this .tokens[tokenIndex],
047: (ReferenceBinding) this .resolvedType);
048: if (this .resolvedType instanceof ProblemReferenceBinding) {
049: ProblemReferenceBinding problemBinding = (ProblemReferenceBinding) this .resolvedType;
050: this .resolvedType = new ProblemReferenceBinding(
051: org.eclipse.jdt.core.compiler.CharOperation
052: .subarray(this .tokens, 0,
053: tokenIndex + 1),
054: problemBinding.closestMatch(),
055: this .resolvedType.problemId());
056: }
057: }
058: return this .resolvedType;
059: } catch (AbortCompilation e) {
060: e.updateContext(this ,
061: scope.referenceCompilationUnit().compilationResult);
062: throw e;
063: } finally {
064: env.missingClassFileLocation = null;
065: }
066: }
067:
068: public char[] getLastToken() {
069: return this .tokens[this .tokens.length - 1];
070: }
071:
072: protected TypeBinding getTypeBinding(Scope scope) {
073:
074: if (this .resolvedType != null)
075: return this .resolvedType;
076:
077: Binding binding = scope.getPackage(this .tokens);
078: if (binding != null && !binding.isValidBinding())
079: return (ReferenceBinding) binding; // not found
080:
081: PackageBinding packageBinding = binding == null ? null
082: : (PackageBinding) binding;
083: boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
084: ReferenceBinding qualifiedType = null;
085: for (int i = packageBinding == null ? 0
086: : packageBinding.compoundName.length, max = this .tokens.length, last = max - 1; i < max; i++) {
087: findNextTypeBinding(i, scope, packageBinding);
088: if (!this .resolvedType.isValidBinding())
089: return this .resolvedType;
090: if (i == 0
091: && this .resolvedType.isTypeVariable()
092: && ((TypeVariableBinding) this .resolvedType).firstBound == null) { // cannot select from a type variable
093: scope.problemReporter().illegalAccessFromTypeVariable(
094: (TypeVariableBinding) this .resolvedType, this );
095: return this .resolvedType = null;
096: }
097: if (i < last
098: && isTypeUseDeprecated(this .resolvedType, scope)) {
099: reportDeprecatedType(this .resolvedType, scope);
100: }
101: if (isClassScope)
102: if (((ClassScope) scope).detectHierarchyCycle(
103: this .resolvedType, this )) // must connect hierarchy to find inherited member types
104: return null;
105: ReferenceBinding currentType = (ReferenceBinding) this .resolvedType;
106: if (qualifiedType != null) {
107: boolean rawQualified;
108: if (currentType.isGenericType()) {
109: qualifiedType = scope.environment().createRawType(
110: currentType, qualifiedType);
111: } else if ((rawQualified = qualifiedType.isRawType())
112: && !currentType.isStatic()) {
113: qualifiedType = scope.environment().createRawType(
114: (ReferenceBinding) currentType.erasure(),
115: qualifiedType);
116: } else if ((rawQualified || qualifiedType
117: .isParameterizedType())
118: && qualifiedType.erasure() == currentType
119: .enclosingType().erasure()) {
120: qualifiedType = scope.environment()
121: .createParameterizedType(
122: (ReferenceBinding) currentType
123: .erasure(), null,
124: qualifiedType);
125: } else {
126: qualifiedType = currentType;
127: }
128: } else {
129: qualifiedType = currentType.isGenericType() ? (ReferenceBinding) scope
130: .environment().convertToRawType(currentType)
131: : currentType;
132: }
133: }
134: this .resolvedType = qualifiedType;
135: return this .resolvedType;
136: }
137:
138: public char[][] getTypeName() {
139:
140: return tokens;
141: }
142:
143: public StringBuffer printExpression(int indent, StringBuffer output) {
144:
145: for (int i = 0; i < tokens.length; i++) {
146: if (i > 0)
147: output.append('.');
148: output.append(tokens[i]);
149: }
150: return output;
151: }
152:
153: public void traverse(ASTVisitor visitor, BlockScope scope) {
154:
155: visitor.visit(this , scope);
156: visitor.endVisit(this , scope);
157: }
158:
159: public void traverse(ASTVisitor visitor, ClassScope scope) {
160:
161: visitor.visit(this, scope);
162: visitor.endVisit(this, scope);
163: }
164: }
|