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.core.compiler.CharOperation;
013: import org.eclipse.jdt.internal.compiler.ASTVisitor;
014: import org.eclipse.jdt.internal.compiler.lookup.*;
015:
016: /**
017: * Node to represent Wildcard
018: */
019: public class Wildcard extends SingleTypeReference {
020:
021: public static final int UNBOUND = 0;
022: public static final int EXTENDS = 1;
023: public static final int SUPER = 2;
024:
025: public TypeReference bound;
026: public int kind;
027:
028: public Wildcard(int kind) {
029: super (WILDCARD_NAME, 0);
030: this .kind = kind;
031: }
032:
033: public char[][] getParameterizedTypeName() {
034: switch (this .kind) {
035: case Wildcard.UNBOUND:
036: return new char[][] { WILDCARD_NAME };
037: case Wildcard.EXTENDS:
038: return new char[][] { CharOperation
039: .concat(WILDCARD_NAME, WILDCARD_EXTENDS,
040: CharOperation.concatWith(this .bound
041: .getParameterizedTypeName(), '.')) };
042: default: // SUPER
043: return new char[][] { CharOperation.concat(WILDCARD_NAME,
044: WILDCARD_SUPER, CharOperation.concatWith(this .bound
045: .getParameterizedTypeName(), '.')) };
046: }
047: }
048:
049: public char[][] getTypeName() {
050: switch (this .kind) {
051: case Wildcard.UNBOUND:
052: return new char[][] { WILDCARD_NAME };
053: case Wildcard.EXTENDS:
054: return new char[][] { CharOperation.concat(WILDCARD_NAME,
055: WILDCARD_EXTENDS, CharOperation.concatWith(
056: this .bound.getTypeName(), '.')) };
057: default: // SUPER
058: return new char[][] { CharOperation.concat(WILDCARD_NAME,
059: WILDCARD_SUPER, CharOperation.concatWith(this .bound
060: .getTypeName(), '.')) };
061: }
062: }
063:
064: private TypeBinding internalResolveType(Scope scope,
065: ReferenceBinding genericType, int rank) {
066: TypeBinding boundType = null;
067: if (this .bound != null) {
068: boundType = scope.kind == Scope.CLASS_SCOPE ? this .bound
069: .resolveType((ClassScope) scope)
070: : this .bound
071: .resolveType((BlockScope) scope, true /* check bounds*/);
072:
073: if (boundType == null) {
074: return null;
075: }
076: }
077: WildcardBinding wildcard = scope.environment().createWildcard(
078: genericType, rank, boundType, null /*no extra bound*/,
079: this .kind);
080: return this .resolvedType = wildcard;
081: }
082:
083: public StringBuffer printExpression(int indent, StringBuffer output) {
084: switch (this .kind) {
085: case Wildcard.UNBOUND:
086: output.append(WILDCARD_NAME);
087: break;
088: case Wildcard.EXTENDS:
089: output.append(WILDCARD_NAME).append(WILDCARD_EXTENDS);
090: this .bound.printExpression(0, output);
091: break;
092: default: // SUPER
093: output.append(WILDCARD_NAME).append(WILDCARD_SUPER);
094: this .bound.printExpression(0, output);
095: break;
096: }
097: return output;
098: }
099:
100: // only invoked for improving resilience when unable to bind generic type from parameterized reference
101: public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
102: if (this .bound != null) {
103: this .bound.resolveType(scope, checkBounds);
104: }
105: return null;
106: }
107:
108: // only invoked for improving resilience when unable to bind generic type from parameterized reference
109: public TypeBinding resolveType(ClassScope scope) {
110: if (this .bound != null) {
111: this .bound.resolveType(scope);
112: }
113: return null;
114: }
115:
116: public TypeBinding resolveTypeArgument(BlockScope blockScope,
117: ReferenceBinding genericType, int rank) {
118: return internalResolveType(blockScope, genericType, rank);
119: }
120:
121: public TypeBinding resolveTypeArgument(ClassScope classScope,
122: ReferenceBinding genericType, int rank) {
123: return internalResolveType(classScope, genericType, rank);
124: }
125:
126: public void traverse(ASTVisitor visitor, BlockScope scope) {
127: if (visitor.visit(this , scope)) {
128: if (this .bound != null) {
129: this .bound.traverse(visitor, scope);
130: }
131: }
132: visitor.endVisit(this , scope);
133: }
134:
135: public void traverse(ASTVisitor visitor, ClassScope scope) {
136: if (visitor.visit(this, scope)) {
137: if (this.bound != null) {
138: this.bound.traverse(visitor, scope);
139: }
140: }
141: visitor.endVisit(this, scope);
142: }
143: }
|