📄 symbol.java
字号:
/** * @(#)Symbol.java 1.45 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.tools.javac.v8.code;import com.sun.tools.javac.v8.util.*;import com.sun.tools.javac.v8.code.Type.*;/** * Root class for Java symbols. It contains subclasses * for specific sorts of symbols, such as variables, methods and operators, * types, packages. Each subclass is represented as a static inner class * inside Symbol. */public class Symbol implements Flags, Kinds, TypeTags { /** * The kind of this symbol. * @see Kinds. */ public int kind; /** * The flags of this symbol. */ public long flags_field; /** * An accessor method for the flags of this symbol. * Flags of class symbols should be accessed through the accessor * method to make sure that the class symbol is loaded. */ public long flags() { return flags_field; } /** * The name of this symbol in Utf8 representation. */ public Name name; /** * The type of this symbol. */ public Type type; /** * The owner of this symbol. */ public Symbol owner; /** * The completer of this symbol. */ public Completer completer; /** * A cache for the type erasure of this symbol. */ public Type erasure_field; /** * Construct a symbol with given kind, flags, name, type and owner. */ public Symbol(int kind, long flags, Name name, Type type, Symbol owner) { super(); this.kind = kind; this.flags_field = flags; this.type = type; this.owner = owner; this.completer = null; this.erasure_field = null; this.name = name; } /** * Clone this symbol with new owner. * Legal only for fields and methods. */ public Symbol clone(Symbol newOwner) { throw new AssertionError(); } /** * A description of this symbol; overrides Object. */ public String toString() { return name.toString(); } /** * The Java source which this symbol represents. Use of this method will * result in a loss of the plain-language description for the symbol. */ public String toJava() { return name.toString(); } /** * A description of the location of this symbol; used for * error reporting. * * XXX 06/09/99 iris * This method appears to be redundant and should probably be * unified with javaLocation(); */ public String location() { if (owner.name == null || owner.name.len == 0) return ""; else return " in " + owner; } public String location(Type site) { if (owner.name == null || owner.name.len == 0) { return ""; } if (owner.type.tag == CLASS) { Type ownertype = site.asOuterSuper(owner); if (ownertype != null) return " in class " + ownertype; } return " in " + owner; } /** * A Java source description of the location of this symbol; used for * error reporting. Use of this method may result in the loss of the * symbol's description. */ public String javaLocation() { if (owner.name == null || owner.name.len == 0) return ""; else return owner.toJava(); } public String javaLocation(Type site) { if (owner.name == null || owner.name.len == 0) { return ""; } if (owner.type.tag == CLASS) { Type ownertype = site.asOuterSuper(owner); if (ownertype != null) return ownertype.toJava(); } return owner.toJava(); } /** * The symbol's erased type. */ public Type erasure() { if (erasure_field == null) erasure_field = type.erasure(); return erasure_field; } /** * The external type of a symbol. This is the symbol's erased type * except for constructors of inner classes which get the enclosing * instance class added as first argument. */ public Type externalType() { Type t = erasure(); if (name == name.table.init && owner.hasOuterInstance()) { Type outerThisType = owner.type.outer().erasure(); return new MethodType(t.argtypes().prepend(outerThisType), t.restype(), t.thrown(), t.tsym); } else { return t; } } /** * Is this symbol declared (directly or indirectly) local * to a method or variable initializer? * Also includes fields of inner classes which are in * turn local to a method or variable initializer. */ public boolean isLocal() { return (owner.kind & (VAR | MTH)) != 0 || (owner.kind == TYP && owner.isLocal()); } /** * Is this symbol a constructor? */ public boolean isConstructor() { return name == name.table.init; } /** * The fully qualified name of this symbol. * This is the same as the symbol's name except for class symbols, * which are handled separately. */ public Name fullName() { return name; } /** * The fully qualified name of this symbol after converting to flat * representation. This is the same as the symbol's name except for * class symbols, which are handled separately. */ public Name flatName() { return fullName(); } /** * If this is a class or package, its members, otherwise null. */ public Scope members() { return null; } /** * A class is an inner class if it it has an enclosing instance class. */ public boolean isInner() { return type.outer().tag == CLASS; } /** * An inner class has an outer instance if it is not an interface * it has an enclosing instance class which might be referenced from the class. * Nested classes can see instance members of their enclosing class. * Their constructors carry an additional this$n parameter, inserted * implicitly by the compiler. * * @see isInner */ public boolean hasOuterInstance() { return type.outer().tag == CLASS && (flags() & (INTERFACE | NOOUTERTHIS)) == 0; } /** * The closest enclosing class of this symbol's declaration. */ public ClassSymbol enclClass() { Symbol c = this; while (c != null && (c.kind & TYP) == 0) c = c.owner; return (ClassSymbol) c; } /** * The outermost class which indirectly owns this symbol. */ public ClassSymbol outermostClass() { Symbol sym = this; Symbol prev = null; while (sym.kind != PCK) { prev = sym; sym = sym.owner; } return (ClassSymbol) prev; } /** * The package which indirectly owns this symbol. */ public PackageSymbol packge() { Symbol sym = this; while (sym.kind != PCK) { sym = sym.owner; } return (PackageSymbol) sym; } /** * Is this symbol a subclass of `base'? Only defined for ClassSymbols. */ public boolean isSubClass(Symbol base) { throw new AssertionError("isSubClass " + this); } /** * Fully check membership: hierarchy, protection, and hiding. * Does not exclude methods not inherited due to overriding. */ public boolean isMemberOf(TypeSymbol clazz) { return owner == clazz || clazz.isSubClass(owner) && isInheritedIn(clazz) && (kind == MTH || !hiddenIn((ClassSymbol) clazz)); } /** * Is this symbol the same as or enclosed by the given class? */ public boolean isEnclosedBy(ClassSymbol clazz) { for (Symbol sym = this; sym.kind != PCK; sym = sym.owner) if (sym == clazz) return true; return false; } /** * Check for hiding. Note that this doesn't handle multiple * (interface) inheritance. */ private boolean hiddenIn(ClassSymbol clazz) { while (true) { if (owner == clazz) return false; Scope.Entry e = clazz.members().lookup(name); while (e.scope != null) { if (e.sym.kind == kind) return e.sym != this; e = e.next(); } Type superType = clazz.type.supertype(); if (superType.tag != TypeTags.CLASS) return false; clazz = (ClassSymbol) superType.tsym; } } /** * Is this symbol inherited into a given class? * PRE: If symbol's owner is a interface, * it is already assumed that the interface is a superinterface * of given class. * @param clazz The class for which we want to establish membership. * This must be a subclass of the member's owner. */ public boolean isInheritedIn(Symbol clazz) { switch ((int)(flags_field & Flags.AccessFlags)) { case PUBLIC: return true; case PRIVATE: return this.owner == clazz; case PROTECTED: return (clazz.flags() & INTERFACE) == 0; case 0: PackageSymbol thisPackage = this.packge(); for (Symbol sup = clazz; sup != null && sup != this.owner; sup = sup.type.supertype().tsym) if (sup.packge() != thisPackage) return false; return (clazz.flags() & INTERFACE) == 0; default: throw new AssertionError(); } } /** * The (variable or method) symbol seen as a member of given * class type`site' (this might change the symbol's type). */ public Symbol asMemberOf(Type site) { throw new AssertionError(); } /** * Complete the elaboration of this symbol's definition. */ public void complete() throws CompletionFailure { if (completer != null) { Completer c = completer; completer = null; c.complete(this); } } /** * A class for type symbols. Type variables are represented by instances * of this class, classes and packages by instances of subclasses. */ public static class TypeSymbol extends Symbol { public TypeSymbol(long flags, Name name, Type type, Symbol owner) { super(TYP, flags, name, type, owner); } public String toString() { return "type variable " + name; } /** * form a fully qualified name from a name and an owner */ public static Name formFullName(Name name, Symbol owner) { if (owner == null) return name; if (((owner.kind != ERR)) && ((owner.kind & (VAR | MTH)) != 0)) return name; Name prefix = owner.fullName(); if (prefix == null || prefix == prefix.table.empty || prefix == prefix.table.emptyPackage) return name; else return prefix.append('.', name); } /** * form a fully qualified name from a name and an owner, after * converting to flat representation */ public static Name formFlatName(Name name, Symbol owner) { if (owner == null || (owner.kind & (VAR | MTH)) != 0) return name; char sep = owner.kind == TYP ? '$' : '.'; Name prefix = owner.flatName(); if (prefix == null || prefix == prefix.table.empty || prefix == prefix.table.emptyPackage) return name; else return prefix.append(sep, name); } /** * The rank of a class is the length of the longest path * between the class and java.lang.Object in the class inheritance * graph. Undefined for all other type symbols. */ public int rank() { throw new AssertionError(); } /** * A total ordering between type symbols that refines the class * inheritance graph. Typevariables always precede other type symbols. */ public boolean precedes(TypeSymbol that) { return this != that; } /** * If symbol is a package, does it exist? * Otherwise always true. */ public boolean exists() { return true; } } /** * A class for package symbols */ public static class PackageSymbol extends TypeSymbol { public Scope members_field; public Name fullname; public PackageSymbol(Name name, Type type, Symbol owner) { super(0, name, type, owner); this.kind = PCK; this.members_field = null; this.fullname = formFullName(name, owner); } public PackageSymbol(Name name, Symbol owner) { this(name, null, owner); this.type = new PackageType(this); } public String toString() { return "package " + fullname; } /** * The Java source which this symbol represents. Use of this method * will result in the loss of the plain-language description for * the symbol. */ public String toJava() { return fullname.toString(); } public Name fullName() { return fullname; } public Scope members() { if (completer != null) complete(); return members_field; } public long flags() { if (completer != null) complete(); return flags_field; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -