0001: /*
0002: * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: package com.sun.tools.javac.code;
0027:
0028: import java.util.ArrayList;
0029: import java.util.Collections;
0030: import java.util.Set;
0031: import java.util.concurrent.Callable;
0032: import javax.lang.model.element.*;
0033: import javax.lang.model.type.ReferenceType;
0034: import javax.lang.model.type.TypeMirror;
0035: import javax.tools.JavaFileObject;
0036:
0037: import com.sun.tools.javac.util.*;
0038: import com.sun.tools.javac.util.Name;
0039: import com.sun.tools.javac.code.Type.*;
0040: import com.sun.tools.javac.comp.Attr;
0041: import com.sun.tools.javac.comp.AttrContext;
0042: import com.sun.tools.javac.comp.Env;
0043: import com.sun.tools.javac.jvm.*;
0044: import com.sun.tools.javac.model.*;
0045: import com.sun.tools.javac.tree.JCTree;
0046:
0047: import static com.sun.tools.javac.code.Flags.*;
0048: import static com.sun.tools.javac.code.Kinds.*;
0049: import static com.sun.tools.javac.code.TypeTags.*;
0050:
0051: /** Root class for Java symbols. It contains subclasses
0052: * for specific sorts of symbols, such as variables, methods and operators,
0053: * types, packages. Each subclass is represented as a static inner class
0054: * inside Symbol.
0055: *
0056: * <p><b>This is NOT part of any API supported by Sun Microsystems. If
0057: * you write code that depends on this, you do so at your own risk.
0058: * This code and its internal interfaces are subject to change or
0059: * deletion without notice.</b>
0060: */
0061: @Version("@(#)Symbol.java 1.103 07/05/05")
0062: public abstract class Symbol implements Element {
0063: // public Throwable debug = new Throwable();
0064:
0065: /** The kind of this symbol.
0066: * @see Kinds
0067: */
0068: public int kind;
0069:
0070: /** The flags of this symbol.
0071: */
0072: public long flags_field;
0073:
0074: /** An accessor method for the flags of this symbol.
0075: * Flags of class symbols should be accessed through the accessor
0076: * method to make sure that the class symbol is loaded.
0077: */
0078: public long flags() {
0079: return flags_field;
0080: }
0081:
0082: /** The attributes of this symbol.
0083: */
0084: public List<Attribute.Compound> attributes_field;
0085:
0086: /** An accessor method for the attributes of this symbol.
0087: * Attributes of class symbols should be accessed through the accessor
0088: * method to make sure that the class symbol is loaded.
0089: */
0090: public List<Attribute.Compound> getAnnotationMirrors() {
0091: assert attributes_field != null;
0092: return attributes_field;
0093: }
0094:
0095: /** Fetch a particular annotation from a symbol. */
0096: public Attribute.Compound attribute(Symbol anno) {
0097: for (Attribute.Compound a : getAnnotationMirrors())
0098: if (a.type.tsym == anno)
0099: return a;
0100: return null;
0101: }
0102:
0103: /** The name of this symbol in Utf8 representation.
0104: */
0105: public Name name;
0106:
0107: /** The type of this symbol.
0108: */
0109: public Type type;
0110:
0111: /** The owner of this symbol.
0112: */
0113: public Symbol owner;
0114:
0115: /** The completer of this symbol.
0116: */
0117: public Completer completer;
0118:
0119: /** A cache for the type erasure of this symbol.
0120: */
0121: public Type erasure_field;
0122:
0123: /** Construct a symbol with given kind, flags, name, type and owner.
0124: */
0125: public Symbol(int kind, long flags, Name name, Type type,
0126: Symbol owner) {
0127: this .kind = kind;
0128: this .flags_field = flags;
0129: this .type = type;
0130: this .owner = owner;
0131: this .completer = null;
0132: this .erasure_field = null;
0133: this .attributes_field = List.nil();
0134: this .name = name;
0135: }
0136:
0137: /** Clone this symbol with new owner.
0138: * Legal only for fields and methods.
0139: */
0140: public Symbol clone(Symbol newOwner) {
0141: throw new AssertionError();
0142: }
0143:
0144: /** The Java source which this symbol represents.
0145: * A description of this symbol; overrides Object.
0146: */
0147: public String toString() {
0148: return name.toString();
0149: }
0150:
0151: /** A Java source description of the location of this symbol; used for
0152: * error reporting. Use of this method may result in the loss of the
0153: * symbol's description.
0154: */
0155: public String location() {
0156: if (owner.name == null
0157: || (owner.name.len == 0 && owner.kind != PCK)) {
0158: return "";
0159: }
0160: return owner.toString();
0161: }
0162:
0163: public String location(Type site, Types types) {
0164: if (owner.name == null || owner.name.len == 0) {
0165: return location();
0166: }
0167: if (owner.type.tag == CLASS) {
0168: Type ownertype = types.asOuterSuper(site, owner);
0169: if (ownertype != null)
0170: return ownertype.toString();
0171: }
0172: return owner.toString();
0173: }
0174:
0175: /** The symbol's erased type.
0176: */
0177: public Type erasure(Types types) {
0178: if (erasure_field == null)
0179: erasure_field = types.erasure(type);
0180: return erasure_field;
0181: }
0182:
0183: /** The external type of a symbol. This is the symbol's erased type
0184: * except for constructors of inner classes which get the enclosing
0185: * instance class added as first argument.
0186: */
0187: public Type externalType(Types types) {
0188: Type t = erasure(types);
0189: if (name == name.table.init && owner.hasOuterInstance()) {
0190: Type outerThisType = types.erasure(owner.type
0191: .getEnclosingType());
0192: return new MethodType(t.getParameterTypes().prepend(
0193: outerThisType), t.getReturnType(), t
0194: .getThrownTypes(), t.tsym);
0195: } else {
0196: return t;
0197: }
0198: }
0199:
0200: public boolean isStatic() {
0201: return (flags() & STATIC) != 0
0202: || (owner.flags() & INTERFACE) != 0 && kind != MTH;
0203: }
0204:
0205: public boolean isInterface() {
0206: return (flags() & INTERFACE) != 0;
0207: }
0208:
0209: /** Is this symbol declared (directly or indirectly) local
0210: * to a method or variable initializer?
0211: * Also includes fields of inner classes which are in
0212: * turn local to a method or variable initializer.
0213: */
0214: public boolean isLocal() {
0215: return (owner.kind & (VAR | MTH)) != 0
0216: || (owner.kind == TYP && owner.isLocal());
0217: }
0218:
0219: /** Is this symbol a constructor?
0220: */
0221: public boolean isConstructor() {
0222: return name == name.table.init;
0223: }
0224:
0225: /** The fully qualified name of this symbol.
0226: * This is the same as the symbol's name except for class symbols,
0227: * which are handled separately.
0228: */
0229: public Name getQualifiedName() {
0230: return name;
0231: }
0232:
0233: /** The fully qualified name of this symbol after converting to flat
0234: * representation. This is the same as the symbol's name except for
0235: * class symbols, which are handled separately.
0236: */
0237: public Name flatName() {
0238: return getQualifiedName();
0239: }
0240:
0241: /** If this is a class or package, its members, otherwise null.
0242: */
0243: public Scope members() {
0244: return null;
0245: }
0246:
0247: /** A class is an inner class if it it has an enclosing instance class.
0248: */
0249: public boolean isInner() {
0250: return type.getEnclosingType().tag == CLASS;
0251: }
0252:
0253: /** An inner class has an outer instance if it is not an interface
0254: * it has an enclosing instance class which might be referenced from the class.
0255: * Nested classes can see instance members of their enclosing class.
0256: * Their constructors carry an additional this$n parameter, inserted
0257: * implicitly by the compiler.
0258: *
0259: * @see #isInner
0260: */
0261: public boolean hasOuterInstance() {
0262: return type.getEnclosingType().tag == CLASS
0263: && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
0264: }
0265:
0266: /** The closest enclosing class of this symbol's declaration.
0267: */
0268: public ClassSymbol enclClass() {
0269: Symbol c = this ;
0270: while (c != null
0271: && ((c.kind & TYP) == 0 || c.type.tag != CLASS)) {
0272: c = c.owner;
0273: }
0274: return (ClassSymbol) c;
0275: }
0276:
0277: /** The outermost class which indirectly owns this symbol.
0278: */
0279: public ClassSymbol outermostClass() {
0280: Symbol sym = this ;
0281: Symbol prev = null;
0282: while (sym.kind != PCK) {
0283: prev = sym;
0284: sym = sym.owner;
0285: }
0286: return (ClassSymbol) prev;
0287: }
0288:
0289: /** The package which indirectly owns this symbol.
0290: */
0291: public PackageSymbol packge() {
0292: Symbol sym = this ;
0293: while (sym.kind != PCK) {
0294: sym = sym.owner;
0295: }
0296: return (PackageSymbol) sym;
0297: }
0298:
0299: /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
0300: */
0301: public boolean isSubClass(Symbol base, Types types) {
0302: throw new AssertionError("isSubClass " + this );
0303: }
0304:
0305: /** Fully check membership: hierarchy, protection, and hiding.
0306: * Does not exclude methods not inherited due to overriding.
0307: */
0308: public boolean isMemberOf(TypeSymbol clazz, Types types) {
0309: return owner == clazz || clazz.isSubClass(owner, types)
0310: && isInheritedIn(clazz, types)
0311: && !hiddenIn((ClassSymbol) clazz, types);
0312: }
0313:
0314: /** Is this symbol the same as or enclosed by the given class? */
0315: public boolean isEnclosedBy(ClassSymbol clazz) {
0316: for (Symbol sym = this ; sym.kind != PCK; sym = sym.owner)
0317: if (sym == clazz)
0318: return true;
0319: return false;
0320: }
0321:
0322: /** Check for hiding. Note that this doesn't handle multiple
0323: * (interface) inheritance. */
0324: private boolean hiddenIn(ClassSymbol clazz, Types types) {
0325: if (kind == MTH && (flags() & STATIC) == 0)
0326: return false;
0327: while (true) {
0328: if (owner == clazz)
0329: return false;
0330: Scope.Entry e = clazz.members().lookup(name);
0331: while (e.scope != null) {
0332: if (e.sym == this )
0333: return false;
0334: if (e.sym.kind == kind
0335: && (kind != MTH || (e.sym.flags() & STATIC) != 0
0336: && types.isSubSignature(e.sym.type,
0337: type)))
0338: return true;
0339: e = e.next();
0340: }
0341: Type super Type = types.super type(clazz.type);
0342: if (super Type.tag != TypeTags.CLASS)
0343: return false;
0344: clazz = (ClassSymbol) super Type.tsym;
0345: }
0346: }
0347:
0348: /** Is this symbol inherited into a given class?
0349: * PRE: If symbol's owner is a interface,
0350: * it is already assumed that the interface is a superinterface
0351: * of given class.
0352: * @param clazz The class for which we want to establish membership.
0353: * This must be a subclass of the member's owner.
0354: */
0355: public boolean isInheritedIn(Symbol clazz, Types types) {
0356: switch ((int) (flags_field & Flags.AccessFlags)) {
0357: default: // error recovery
0358: case PUBLIC:
0359: return true;
0360: case PRIVATE:
0361: return this .owner == clazz;
0362: case PROTECTED:
0363: // we model interfaces as extending Object
0364: return (clazz.flags() & INTERFACE) == 0;
0365: case 0:
0366: PackageSymbol this Package = this .packge();
0367: for (Symbol sup = clazz; sup != null && sup != this .owner; sup = types
0368: .super type(sup.type).tsym) {
0369: if (sup.type.isErroneous())
0370: return true; // error recovery
0371: if ((sup.flags() & COMPOUND) != 0)
0372: continue;
0373: if (sup.packge() != this Package)
0374: return false;
0375: }
0376: return (clazz.flags() & INTERFACE) == 0;
0377: }
0378: }
0379:
0380: /** The (variable or method) symbol seen as a member of given
0381: * class type`site' (this might change the symbol's type).
0382: * This is used exclusively for producing diagnostics.
0383: */
0384: public Symbol asMemberOf(Type site, Types types) {
0385: throw new AssertionError();
0386: }
0387:
0388: /** Does this method symbol override `other' symbol, when both are seen as
0389: * members of class `origin'? It is assumed that _other is a member
0390: * of origin.
0391: *
0392: * It is assumed that both symbols have the same name. The static
0393: * modifier is ignored for this test.
0394: *
0395: * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
0396: */
0397: public boolean overrides(Symbol _other, TypeSymbol origin,
0398: Types types, boolean checkResult) {
0399: return false;
0400: }
0401:
0402: /** Complete the elaboration of this symbol's definition.
0403: */
0404: public void complete() throws CompletionFailure {
0405: if (completer != null) {
0406: Completer c = completer;
0407: completer = null;
0408: c.complete(this );
0409: }
0410: }
0411:
0412: /** True if the symbol represents an entity that exists.
0413: */
0414: public boolean exists() {
0415: return true;
0416: }
0417:
0418: public Type asType() {
0419: return type;
0420: }
0421:
0422: public Symbol getEnclosingElement() {
0423: return owner;
0424: }
0425:
0426: public ElementKind getKind() {
0427: return ElementKind.OTHER; // most unkind
0428: }
0429:
0430: public Set<Modifier> getModifiers() {
0431: return Flags.asModifierSet(flags());
0432: }
0433:
0434: public Name getSimpleName() {
0435: return name;
0436: }
0437:
0438: /**
0439: * @deprecated this method should never be used by javac internally.
0440: */
0441: @Deprecated
0442: public <A extends java.lang.annotation.Annotation> A getAnnotation(
0443: Class<A> annoType) {
0444: return JavacElements.getAnnotation(this , annoType);
0445: }
0446:
0447: // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
0448: public java.util.List<Symbol> getEnclosedElements() {
0449: return List.nil();
0450: }
0451:
0452: public List<TypeSymbol> getTypeParameters() {
0453: ListBuffer<TypeSymbol> l = ListBuffer.lb();
0454: for (Type t : type.getTypeArguments()) {
0455: l.append(t.tsym);
0456: }
0457: return l.toList();
0458: }
0459:
0460: public static class DelegatedSymbol extends Symbol {
0461: protected Symbol other;
0462:
0463: public DelegatedSymbol(Symbol other) {
0464: super (other.kind, other.flags_field, other.name,
0465: other.type, other.owner);
0466: this .other = other;
0467: }
0468:
0469: public String toString() {
0470: return other.toString();
0471: }
0472:
0473: public String location() {
0474: return other.location();
0475: }
0476:
0477: public String location(Type site, Types types) {
0478: return other.location(site, types);
0479: }
0480:
0481: public Type erasure(Types types) {
0482: return other.erasure(types);
0483: }
0484:
0485: public Type externalType(Types types) {
0486: return other.externalType(types);
0487: }
0488:
0489: public boolean isLocal() {
0490: return other.isLocal();
0491: }
0492:
0493: public boolean isConstructor() {
0494: return other.isConstructor();
0495: }
0496:
0497: public Name getQualifiedName() {
0498: return other.getQualifiedName();
0499: }
0500:
0501: public Name flatName() {
0502: return other.flatName();
0503: }
0504:
0505: public Scope members() {
0506: return other.members();
0507: }
0508:
0509: public boolean isInner() {
0510: return other.isInner();
0511: }
0512:
0513: public boolean hasOuterInstance() {
0514: return other.hasOuterInstance();
0515: }
0516:
0517: public ClassSymbol enclClass() {
0518: return other.enclClass();
0519: }
0520:
0521: public ClassSymbol outermostClass() {
0522: return other.outermostClass();
0523: }
0524:
0525: public PackageSymbol packge() {
0526: return other.packge();
0527: }
0528:
0529: public boolean isSubClass(Symbol base, Types types) {
0530: return other.isSubClass(base, types);
0531: }
0532:
0533: public boolean isMemberOf(TypeSymbol clazz, Types types) {
0534: return other.isMemberOf(clazz, types);
0535: }
0536:
0537: public boolean isEnclosedBy(ClassSymbol clazz) {
0538: return other.isEnclosedBy(clazz);
0539: }
0540:
0541: public boolean isInheritedIn(Symbol clazz, Types types) {
0542: return other.isInheritedIn(clazz, types);
0543: }
0544:
0545: public Symbol asMemberOf(Type site, Types types) {
0546: return other.asMemberOf(site, types);
0547: }
0548:
0549: public void complete() throws CompletionFailure {
0550: other.complete();
0551: }
0552:
0553: public <R, P> R accept(ElementVisitor<R, P> v, P p) {
0554: return other.accept(v, p);
0555: }
0556: }
0557:
0558: /** A class for type symbols. Type variables are represented by instances
0559: * of this class, classes and packages by instances of subclasses.
0560: */
0561: public static class TypeSymbol extends Symbol implements
0562: TypeParameterElement {
0563: // Implements TypeParameterElement because type parameters don't
0564: // have their own TypeSymbol subclass.
0565: // TODO: type parameters should have their own TypeSymbol subclass
0566:
0567: public TypeSymbol(long flags, Name name, Type type, Symbol owner) {
0568: super (TYP, flags, name, type, owner);
0569: }
0570:
0571: /** form a fully qualified name from a name and an owner
0572: */
0573: static public Name formFullName(Name name, Symbol owner) {
0574: if (owner == null)
0575: return name;
0576: if (((owner.kind != ERR))
0577: && ((owner.kind & (VAR | MTH)) != 0 || (owner.kind == TYP && owner.type.tag == TYPEVAR)))
0578: return name;
0579: Name prefix = owner.getQualifiedName();
0580: if (prefix == null || prefix == prefix.table.empty)
0581: return name;
0582: else
0583: return prefix.append('.', name);
0584: }
0585:
0586: /** form a fully qualified name from a name and an owner, after
0587: * converting to flat representation
0588: */
0589: static public Name formFlatName(Name name, Symbol owner) {
0590: if (owner == null || (owner.kind & (VAR | MTH)) != 0
0591: || (owner.kind == TYP && owner.type.tag == TYPEVAR))
0592: return name;
0593: char sep = owner.kind == TYP ? '$' : '.';
0594: Name prefix = owner.flatName();
0595: if (prefix == null || prefix == prefix.table.empty)
0596: return name;
0597: else
0598: return prefix.append(sep, name);
0599: }
0600:
0601: /**
0602: * A total ordering between type symbols that refines the
0603: * class inheritance graph.
0604: *
0605: * Typevariables always precede other kinds of symbols.
0606: */
0607: public final boolean precedes(TypeSymbol that, Types types) {
0608: if (this == that)
0609: return false;
0610: if (this .type.tag == that.type.tag) {
0611: if (this .type.tag == CLASS) {
0612: return types.rank(that.type) < types
0613: .rank(this .type)
0614: || types.rank(that.type) == types
0615: .rank(this .type)
0616: && that.getQualifiedName().compareTo(
0617: this .getQualifiedName()) < 0;
0618: } else if (this .type.tag == TYPEVAR) {
0619: return types.isSubtype(this .type, that.type);
0620: }
0621: }
0622: return this .type.tag == TYPEVAR;
0623: }
0624:
0625: // For type params; overridden in subclasses.
0626: public ElementKind getKind() {
0627: return ElementKind.TYPE_PARAMETER;
0628: }
0629:
0630: public java.util.List<Symbol> getEnclosedElements() {
0631: List<Symbol> list = List.nil();
0632: for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
0633: if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0
0634: && e.sym.owner == this )
0635: list = list.prepend(e.sym);
0636: }
0637: return list;
0638: }
0639:
0640: // For type params.
0641: // Perhaps not needed if getEnclosingElement can be spec'ed
0642: // to do the same thing.
0643: // TODO: getGenericElement() might not be needed
0644: public Symbol getGenericElement() {
0645: return owner;
0646: }
0647:
0648: public <R, P> R accept(ElementVisitor<R, P> v, P p) {
0649: assert type.tag == TYPEVAR; // else override will be invoked
0650: return v.visitTypeParameter(this , p);
0651: }
0652:
0653: public List<Type> getBounds() {
0654: TypeVar t = (TypeVar) type;
0655: Type bound = t.getUpperBound();
0656: if (!bound.isCompound())
0657: return List.of(bound);
0658: ClassType ct = (ClassType) bound;
0659: if (!ct.tsym.erasure_field.isInterface()) {
0660: return ct.interfaces_field.prepend(ct.super type_field);
0661: } else {
0662: // No superclass was given in bounds.
0663: // In this case, supertype is Object, erasure is first interface.
0664: return ct.interfaces_field;
0665: }
0666: }
0667: }
0668:
0669: /** A class for package symbols
0670: */
0671: public static class PackageSymbol extends TypeSymbol implements
0672: PackageElement {
0673:
0674: public Scope members_field;
0675: public Name fullname;
0676: public ClassSymbol package_info; // see bug 6443073
0677:
0678: public PackageSymbol(Name name, Type type, Symbol owner) {
0679: super (0, name, type, owner);
0680: this .kind = PCK;
0681: this .members_field = null;
0682: this .fullname = formFullName(name, owner);
0683: }
0684:
0685: public PackageSymbol(Name name, Symbol owner) {
0686: this (name, null, owner);
0687: this .type = new PackageType(this );
0688: }
0689:
0690: public String toString() {
0691: return fullname.toString();
0692: }
0693:
0694: public Name getQualifiedName() {
0695: return fullname;
0696: }
0697:
0698: public boolean isUnnamed() {
0699: return name.isEmpty() && owner != null;
0700: }
0701:
0702: public Scope members() {
0703: if (completer != null)
0704: complete();
0705: return members_field;
0706: }
0707:
0708: public long flags() {
0709: if (completer != null)
0710: complete();
0711: return flags_field;
0712: }
0713:
0714: public List<Attribute.Compound> getAnnotationMirrors() {
0715: if (completer != null)
0716: complete();
0717: assert attributes_field != null;
0718: return attributes_field;
0719: }
0720:
0721: /** A package "exists" if a type or package that exists has
0722: * been seen within it.
0723: */
0724: public boolean exists() {
0725: return (flags_field & EXISTS) != 0;
0726: }
0727:
0728: public ElementKind getKind() {
0729: return ElementKind.PACKAGE;
0730: }
0731:
0732: public Symbol getEnclosingElement() {
0733: return null;
0734: }
0735:
0736: public <R, P> R accept(ElementVisitor<R, P> v, P p) {
0737: return v.visitPackage(this , p);
0738: }
0739: }
0740:
0741: /** A class for class symbols
0742: */
0743: public static class ClassSymbol extends TypeSymbol implements
0744: TypeElement {
0745:
0746: /** a scope for all class members; variables, methods and inner classes
0747: * type parameters are not part of this scope
0748: */
0749: public Scope members_field;
0750:
0751: /** the fully qualified name of the class, i.e. pck.outer.inner.
0752: * null for anonymous classes
0753: */
0754: public Name fullname;
0755:
0756: /** the fully qualified name of the class after converting to flat
0757: * representation, i.e. pck.outer$inner,
0758: * set externally for local and anonymous classes
0759: */
0760: public Name flatname;
0761:
0762: /** the sourcefile where the class came from
0763: */
0764: public JavaFileObject sourcefile;
0765:
0766: /** the classfile from where to load this class
0767: * this will have extension .class or .java
0768: */
0769: public JavaFileObject classfile;
0770:
0771: /** the constant pool of the class
0772: */
0773: public Pool pool;
0774:
0775: public ClassSymbol(long flags, Name name, Type type,
0776: Symbol owner) {
0777: super (flags, name, type, owner);
0778: this .members_field = null;
0779: this .fullname = formFullName(name, owner);
0780: this .flatname = formFlatName(name, owner);
0781: this .sourcefile = null;
0782: this .classfile = null;
0783: this .pool = null;
0784: }
0785:
0786: public ClassSymbol(long flags, Name name, Symbol owner) {
0787: this (flags, name, new ClassType(Type.noType, null, null),
0788: owner);
0789: this .type.tsym = this ;
0790: }
0791:
0792: /** The Java source which this symbol represents.
0793: */
0794: public String toString() {
0795: return className();
0796: }
0797:
0798: public long flags() {
0799: if (completer != null)
0800: complete();
0801: return flags_field;
0802: }
0803:
0804: public Scope members() {
0805: if (completer != null)
0806: complete();
0807: return members_field;
0808: }
0809:
0810: public List<Attribute.Compound> getAnnotationMirrors() {
0811: if (completer != null)
0812: complete();
0813: assert attributes_field != null;
0814: return attributes_field;
0815: }
0816:
0817: public Type erasure(Types types) {
0818: if (erasure_field == null)
0819: erasure_field = new ClassType(types.erasure(type
0820: .getEnclosingType()), List.<Type> nil(), this );
0821: return erasure_field;
0822: }
0823:
0824: public String className() {
0825: if (name.len == 0)
0826: return Log.getLocalizedString("anonymous.class",
0827: flatname);
0828: else
0829: return fullname.toString();
0830: }
0831:
0832: public Name getQualifiedName() {
0833: return fullname;
0834: }
0835:
0836: public Name flatName() {
0837: return flatname;
0838: }
0839:
0840: public boolean isSubClass(Symbol base, Types types) {
0841: if (this == base) {
0842: return true;
0843: } else if ((base.flags() & INTERFACE) != 0) {
0844: for (Type t = type; t.tag == CLASS; t = types
0845: .super type(t))
0846: for (List<Type> is = types.interfaces(t); is
0847: .nonEmpty(); is = is.tail)
0848: if (is.head.tsym.isSubClass(base, types))
0849: return true;
0850: } else {
0851: for (Type t = type; t.tag == CLASS; t = types
0852: .super type(t))
0853: if (t.tsym == base)
0854: return true;
0855: }
0856: return false;
0857: }
0858:
0859: /** Complete the elaboration of this symbol's definition.
0860: */
0861: public void complete() throws CompletionFailure {
0862: try {
0863: super .complete();
0864: } catch (CompletionFailure ex) {
0865: // quiet error recovery
0866: flags_field |= (PUBLIC | STATIC);
0867: this .type = new ErrorType(this );
0868: throw ex;
0869: }
0870: }
0871:
0872: public List<Type> getInterfaces() {
0873: complete();
0874: if (type instanceof ClassType) {
0875: ClassType t = (ClassType) type;
0876: if (t.interfaces_field == null) // FIXME: shouldn't be null
0877: t.interfaces_field = List.nil();
0878: return t.interfaces_field;
0879: } else {
0880: return List.nil();
0881: }
0882: }
0883:
0884: public Type getSuperclass() {
0885: complete();
0886: if (type instanceof ClassType) {
0887: ClassType t = (ClassType) type;
0888: if (t.super type_field == null) // FIXME: shouldn't be null
0889: t.super type_field = Type.noType;
0890: // An interface has no superclass; its supertype is Object.
0891: return t.isInterface() ? Type.noType
0892: : t.super type_field;
0893: } else {
0894: return Type.noType;
0895: }
0896: }
0897:
0898: public ElementKind getKind() {
0899: long flags = flags();
0900: if ((flags & ANNOTATION) != 0)
0901: return ElementKind.ANNOTATION_TYPE;
0902: else if ((flags & INTERFACE) != 0)
0903: return ElementKind.INTERFACE;
0904: else if ((flags & ENUM) != 0)
0905: return ElementKind.ENUM;
0906: else
0907: return ElementKind.CLASS;
0908: }
0909:
0910: public NestingKind getNestingKind() {
0911: complete();
0912: if (owner.kind == PCK)
0913: return NestingKind.TOP_LEVEL;
0914: else if (name.isEmpty())
0915: return NestingKind.ANONYMOUS;
0916: else if (owner.kind == MTH)
0917: return NestingKind.LOCAL;
0918: else
0919: return NestingKind.MEMBER;
0920: }
0921:
0922: /**
0923: * @deprecated this method should never be used by javac internally.
0924: */
0925: @Override
0926: @Deprecated
0927: public <A extends java.lang.annotation.Annotation> A getAnnotation(
0928: Class<A> annoType) {
0929: return JavacElements.getAnnotation(this , annoType);
0930: }
0931:
0932: public <R, P> R accept(ElementVisitor<R, P> v, P p) {
0933: return v.visitType(this , p);
0934: }
0935: }
0936:
0937: /** A class for variable symbols
0938: */
0939: public static class VarSymbol extends Symbol implements
0940: VariableElement {
0941:
0942: /** The variable's declaration position.
0943: */
0944: public int pos = Position.NOPOS;
0945:
0946: /** The variable's address. Used for different purposes during
0947: * flow analysis, translation and code generation.
0948: * Flow analysis:
0949: * If this is a blank final or local variable, its sequence number.
0950: * Translation:
0951: * If this is a private field, its access number.
0952: * Code generation:
0953: * If this is a local variable, its logical slot number.
0954: */
0955: public int adr = -1;
0956:
0957: /** Construct a variable symbol, given its flags, name, type and owner.
0958: */
0959: public VarSymbol(long flags, Name name, Type type, Symbol owner) {
0960: super (VAR, flags, name, type, owner);
0961: }
0962:
0963: /** Clone this symbol with new owner.
0964: */
0965: public VarSymbol clone(Symbol newOwner) {
0966: VarSymbol v = new VarSymbol(flags_field, name, type,
0967: newOwner);
0968: v.pos = pos;
0969: v.adr = adr;
0970: v.data = data;
0971: // System.out.println("clone " + v + " in " + newOwner);//DEBUG
0972: return v;
0973: }
0974:
0975: public String toString() {
0976: return name.toString();
0977: }
0978:
0979: public Symbol asMemberOf(Type site, Types types) {
0980: return new VarSymbol(flags_field, name, types.memberType(
0981: site, this ), owner);
0982: }
0983:
0984: public ElementKind getKind() {
0985: long flags = flags();
0986: if ((flags & PARAMETER) != 0) {
0987: if (isExceptionParameter())
0988: return ElementKind.EXCEPTION_PARAMETER;
0989: else
0990: return ElementKind.PARAMETER;
0991: } else if ((flags & ENUM) != 0) {
0992: return ElementKind.ENUM_CONSTANT;
0993: } else if (owner.kind == TYP || owner.kind == ERR) {
0994: return ElementKind.FIELD;
0995: } else {
0996: return ElementKind.LOCAL_VARIABLE;
0997: }
0998: }
0999:
1000: public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1001: return v.visitVariable(this , p);
1002: }
1003:
1004: public Object getConstantValue() { // Mirror API
1005: return Constants.decode(getConstValue(), type);
1006: }
1007:
1008: public void setLazyConstValue(final Env<AttrContext> env,
1009: final Log log, final Attr attr,
1010: final JCTree.JCExpression initializer) {
1011: setData(new Callable<Object>() {
1012: public Object call() {
1013: JavaFileObject source = log
1014: .useSource(env.toplevel.sourcefile);
1015: try {
1016: // In order to catch self-references, we set
1017: // the variable's declaration position to
1018: // maximal possible value, effectively marking
1019: // the variable as undefined.
1020: int pos = VarSymbol.this .pos;
1021: VarSymbol.this .pos = Position.MAXPOS;
1022: Type itype = attr.attribExpr(initializer, env,
1023: type);
1024: VarSymbol.this .pos = pos;
1025: if (itype.constValue() != null)
1026: return attr.coerce(itype, type)
1027: .constValue();
1028: else
1029: return null;
1030: } finally {
1031: log.useSource(source);
1032: }
1033: }
1034: });
1035: }
1036:
1037: /**
1038: * The variable's constant value, if this is a constant.
1039: * Before the constant value is evaluated, it points to an
1040: * initalizer environment. If this is not a constant, it can
1041: * be used for other stuff.
1042: */
1043: private Object data;
1044:
1045: public boolean isExceptionParameter() {
1046: return data == ElementKind.EXCEPTION_PARAMETER;
1047: }
1048:
1049: public Object getConstValue() {
1050: // TODO: Consider if getConstValue and getConstantValue can be collapsed
1051: if (data == ElementKind.EXCEPTION_PARAMETER) {
1052: return null;
1053: } else if (data instanceof Callable<?>) {
1054: // In this case, this is final a variable, with an as
1055: // yet unevaluated initializer.
1056: Callable<?> eval = (Callable<?>) data;
1057: data = null; // to make sure we don't evaluate this twice.
1058: try {
1059: data = eval.call();
1060: } catch (Exception ex) {
1061: throw new AssertionError(ex);
1062: }
1063: }
1064: return data;
1065: }
1066:
1067: public void setData(Object data) {
1068: assert !(data instanceof Env<?>) : this ;
1069: this .data = data;
1070: }
1071: }
1072:
1073: /** A class for method symbols.
1074: */
1075: public static class MethodSymbol extends Symbol implements
1076: ExecutableElement {
1077:
1078: /** The code of the method. */
1079: public Code code = null;
1080:
1081: /** The parameters of the method. */
1082: public List<VarSymbol> params = null;
1083:
1084: /** The names of the parameters */
1085: public List<Name> savedParameterNames;
1086:
1087: /** For an attribute field accessor, its default value if any.
1088: * The value is null if none appeared in the method
1089: * declaration.
1090: */
1091: public Attribute defaultValue = null;
1092:
1093: /** Construct a method symbol, given its flags, name, type and owner.
1094: */
1095: public MethodSymbol(long flags, Name name, Type type,
1096: Symbol owner) {
1097: super (MTH, flags, name, type, owner);
1098: assert owner.type.tag != TYPEVAR : owner + "." + name;
1099: }
1100:
1101: /** Clone this symbol with new owner.
1102: */
1103: public MethodSymbol clone(Symbol newOwner) {
1104: MethodSymbol m = new MethodSymbol(flags_field, name, type,
1105: newOwner);
1106: m.code = code;
1107: return m;
1108: }
1109:
1110: /** The Java source which this symbol represents.
1111: */
1112: public String toString() {
1113: if ((flags() & BLOCK) != 0) {
1114: return owner.name.toString();
1115: } else {
1116: String s = (name == name.table.init) ? owner.name
1117: .toString() : name.toString();
1118: if (type != null) {
1119: if (type.tag == FORALL)
1120: s = "<" + ((ForAll) type).getTypeArguments()
1121: + ">" + s;
1122: s += "(" + type.argtypes((flags() & VARARGS) != 0)
1123: + ")";
1124: }
1125: return s;
1126: }
1127: }
1128:
1129: /** find a symbol that this (proxy method) symbol implements.
1130: * @param c The class whose members are searched for
1131: * implementations
1132: */
1133: public Symbol implemented(TypeSymbol c, Types types) {
1134: Symbol impl = null;
1135: for (List<Type> is = types.interfaces(c.type); impl == null
1136: && is.nonEmpty(); is = is.tail) {
1137: TypeSymbol i = is.head.tsym;
1138: for (Scope.Entry e = i.members().lookup(name); impl == null
1139: && e.scope != null; e = e.next()) {
1140: if (this .overrides(e.sym, (TypeSymbol) owner,
1141: types, true)
1142: &&
1143: // FIXME: I suspect the following requires a
1144: // subst() for a parametric return type.
1145: types.isSameType(type.getReturnType(),
1146: types.memberType(owner.type, e.sym)
1147: .getReturnType())) {
1148: impl = e.sym;
1149: }
1150: if (impl == null)
1151: impl = implemented(i, types);
1152: }
1153: }
1154: return impl;
1155: }
1156:
1157: /** Will the erasure of this method be considered by the VM to
1158: * override the erasure of the other when seen from class `origin'?
1159: */
1160: public boolean binaryOverrides(Symbol _other,
1161: TypeSymbol origin, Types types) {
1162: if (isConstructor() || _other.kind != MTH)
1163: return false;
1164:
1165: if (this == _other)
1166: return true;
1167: MethodSymbol other = (MethodSymbol) _other;
1168:
1169: // check for a direct implementation
1170: if (other.isOverridableIn((TypeSymbol) owner)
1171: && types.asSuper(owner.type, other.owner) != null
1172: && types.isSameType(erasure(types), other
1173: .erasure(types)))
1174: return true;
1175:
1176: // check for an inherited implementation
1177: return (flags() & ABSTRACT) == 0
1178: && other.isOverridableIn(origin)
1179: && this .isMemberOf(origin, types)
1180: && types.isSameType(erasure(types), other
1181: .erasure(types));
1182: }
1183:
1184: /** The implementation of this (abstract) symbol in class origin,
1185: * from the VM's point of view, null if method does not have an
1186: * implementation in class.
1187: * @param origin The class of which the implementation is a member.
1188: */
1189: public MethodSymbol binaryImplementation(ClassSymbol origin,
1190: Types types) {
1191: for (TypeSymbol c = origin; c != null; c = types
1192: .super type(c.type).tsym) {
1193: for (Scope.Entry e = c.members().lookup(name); e.scope != null; e = e
1194: .next()) {
1195: if (e.sym.kind == MTH
1196: && ((MethodSymbol) e.sym).binaryOverrides(
1197: this , origin, types))
1198: return (MethodSymbol) e.sym;
1199: }
1200: }
1201: return null;
1202: }
1203:
1204: /** Does this symbol override `other' symbol, when both are seen as
1205: * members of class `origin'? It is assumed that _other is a member
1206: * of origin.
1207: *
1208: * It is assumed that both symbols have the same name. The static
1209: * modifier is ignored for this test.
1210: *
1211: * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1212: */
1213: public boolean overrides(Symbol _other, TypeSymbol origin,
1214: Types types, boolean checkResult) {
1215: if (isConstructor() || _other.kind != MTH)
1216: return false;
1217:
1218: if (this == _other)
1219: return true;
1220: MethodSymbol other = (MethodSymbol) _other;
1221:
1222: // check for a direct implementation
1223: if (other.isOverridableIn((TypeSymbol) owner)
1224: && types.asSuper(owner.type, other.owner) != null) {
1225: Type mt = types.memberType(owner.type, this );
1226: Type ot = types.memberType(owner.type, other);
1227: if (types.isSubSignature(mt, ot)) {
1228: if (!checkResult)
1229: return true;
1230: if (types.returnTypeSubstitutable(mt, ot))
1231: return true;
1232: }
1233: }
1234:
1235: // check for an inherited implementation
1236: if ((flags() & ABSTRACT) != 0
1237: || (other.flags() & ABSTRACT) == 0
1238: || !other.isOverridableIn(origin)
1239: || !this .isMemberOf(origin, types))
1240: return false;
1241:
1242: // assert types.asSuper(origin.type, other.owner) != null;
1243: Type mt = types.memberType(origin.type, this );
1244: Type ot = types.memberType(origin.type, other);
1245: return types.isSubSignature(mt, ot)
1246: && (!checkResult || types.resultSubtype(mt, ot,
1247: Warner.noWarnings));
1248: }
1249:
1250: private boolean isOverridableIn(TypeSymbol origin) {
1251: // JLS3 8.4.6.1
1252: switch ((int) (flags_field & Flags.AccessFlags)) {
1253: case Flags.PRIVATE:
1254: return false;
1255: case Flags.PUBLIC:
1256: return true;
1257: case Flags.PROTECTED:
1258: return (origin.flags() & INTERFACE) == 0;
1259: case 0:
1260: // for package private: can only override in the same
1261: // package
1262: return this .packge() == origin.packge()
1263: && (origin.flags() & INTERFACE) == 0;
1264: default:
1265: return false;
1266: }
1267: }
1268:
1269: /** The implementation of this (abstract) symbol in class origin;
1270: * null if none exists. Synthetic methods are not considered
1271: * as possible implementations.
1272: */
1273: public MethodSymbol implementation(TypeSymbol origin,
1274: Types types, boolean checkResult) {
1275: for (Type t = origin.type; t.tag == CLASS; t = types
1276: .super type(t)) {
1277: TypeSymbol c = t.tsym;
1278: for (Scope.Entry e = c.members().lookup(name); e.scope != null; e = e
1279: .next()) {
1280: if (e.sym.kind == MTH) {
1281: MethodSymbol m = (MethodSymbol) e.sym;
1282: if (m.overrides(this , origin, types,
1283: checkResult)
1284: && (m.flags() & SYNTHETIC) == 0)
1285: return m;
1286: }
1287: }
1288: }
1289: // if origin is derived from a raw type, we might have missed
1290: // an implementation because we do not know enough about instantiations.
1291: // in this case continue with the supertype as origin.
1292: if (types.isDerivedRaw(origin.type))
1293: return implementation(
1294: types.super type(origin.type).tsym, types,
1295: checkResult);
1296: else
1297: return null;
1298: }
1299:
1300: public List<VarSymbol> params() {
1301: owner.complete();
1302: if (params == null) {
1303: List<Name> names = savedParameterNames;
1304: savedParameterNames = null;
1305: if (names == null) {
1306: names = List.nil();
1307: int i = 0;
1308: for (Type t : type.getParameterTypes())
1309: names = names.prepend(name.table
1310: .fromString("arg" + i++));
1311: names = names.reverse();
1312: }
1313: ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1314: for (Type t : type.getParameterTypes()) {
1315: buf.append(new VarSymbol(PARAMETER, names.head, t,
1316: this ));
1317: names = names.tail;
1318: }
1319: params = buf.toList();
1320: }
1321: return params;
1322: }
1323:
1324: public Symbol asMemberOf(Type site, Types types) {
1325: return new MethodSymbol(flags_field, name, types
1326: .memberType(site, this ), owner);
1327: }
1328:
1329: public ElementKind getKind() {
1330: if (name == name.table.init)
1331: return ElementKind.CONSTRUCTOR;
1332: else if (name == name.table.clinit)
1333: return ElementKind.STATIC_INIT;
1334: else
1335: return ElementKind.METHOD;
1336: }
1337:
1338: public Attribute getDefaultValue() {
1339: return defaultValue;
1340: }
1341:
1342: public List<VarSymbol> getParameters() {
1343: return params();
1344: }
1345:
1346: public boolean isVarArgs() {
1347: return (flags() & VARARGS) != 0;
1348: }
1349:
1350: public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1351: return v.visitExecutable(this , p);
1352: }
1353:
1354: public Type getReturnType() {
1355: return asType().getReturnType();
1356: }
1357:
1358: public List<Type> getThrownTypes() {
1359: return asType().getThrownTypes();
1360: }
1361: }
1362:
1363: /** A class for predefined operators.
1364: */
1365: public static class OperatorSymbol extends MethodSymbol {
1366:
1367: public int opcode;
1368:
1369: public OperatorSymbol(Name name, Type type, int opcode,
1370: Symbol owner) {
1371: super (PUBLIC | STATIC, name, type, owner);
1372: this .opcode = opcode;
1373: }
1374: }
1375:
1376: /** Symbol completer interface.
1377: */
1378: public static interface Completer {
1379: void complete(Symbol sym) throws CompletionFailure;
1380: }
1381:
1382: public static class CompletionFailure extends RuntimeException {
1383: private static final long serialVersionUID = 0;
1384: public Symbol sym;
1385:
1386: /** A localized string describing the failure.
1387: */
1388: public String errmsg;
1389:
1390: public CompletionFailure(Symbol sym, String errmsg) {
1391: this .sym = sym;
1392: this .errmsg = errmsg;
1393: // this.printStackTrace();//DEBUG
1394: }
1395:
1396: public String getMessage() {
1397: return errmsg;
1398: }
1399:
1400: @Override
1401: public CompletionFailure initCause(Throwable cause) {
1402: super.initCause(cause);
1403: return this;
1404: }
1405:
1406: }
1407: }
|