symbol.java

来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,297 行 · 第 1/3 页

JAVA
1,297
字号
/* * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.code;import java.util.ArrayList;import java.util.Collections;import java.util.Set;import java.util.concurrent.Callable;import javax.lang.model.element.*;import javax.lang.model.type.ReferenceType;import javax.lang.model.type.TypeMirror;import javax.tools.JavaFileObject;import com.sun.tools.javac.util.*;import com.sun.tools.javac.util.Name;import com.sun.tools.javac.code.Type.*;import com.sun.tools.javac.comp.Attr;import com.sun.tools.javac.comp.AttrContext;import com.sun.tools.javac.comp.Env;import com.sun.tools.javac.jvm.*;import com.sun.tools.javac.model.*;import com.sun.tools.javac.tree.JCTree;import static com.sun.tools.javac.code.Flags.*;import static com.sun.tools.javac.code.Kinds.*;import static com.sun.tools.javac.code.TypeTags.*;/** 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. * *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If *  you write code that depends on this, you do so at your own risk. *  This code and its internal interfaces are subject to change or *  deletion without notice.</b> */public abstract class Symbol implements Element {    // public Throwable debug = new Throwable();    /** 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 attributes of this symbol.     */    public List<Attribute.Compound> attributes_field;    /** An accessor method for the attributes of this symbol.     *  Attributes of class symbols should be accessed through the accessor     *  method to make sure that the class symbol is loaded.     */    public List<Attribute.Compound> getAnnotationMirrors() {        assert attributes_field != null;        return attributes_field;    }    /** Fetch a particular annotation from a symbol. */    public Attribute.Compound attribute(Symbol anno) {        for (Attribute.Compound a : getAnnotationMirrors())            if (a.type.tsym == anno) return a;        return null;    }    /** 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) {        this.kind = kind;        this.flags_field = flags;        this.type = type;        this.owner = owner;        this.completer = null;        this.erasure_field = null;        this.attributes_field = List.nil();        this.name = name;    }    /** Clone this symbol with new owner.     *  Legal only for fields and methods.     */    public Symbol clone(Symbol newOwner) {        throw new AssertionError();    }    /** The Java source which this symbol represents.     *  A description of this symbol; overrides Object.     */    public String toString() {        return name.toString();    }    /** 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 location() {        if (owner.name == null || (owner.name.len == 0 && owner.kind != PCK)) {	    return "";	}	return owner.toString();    }    public String location(Type site, Types types) {        if (owner.name == null || owner.name.len == 0) {            return location();        }        if (owner.type.tag == CLASS) {            Type ownertype = types.asOuterSuper(site, owner);            if (ownertype != null) return ownertype.toString();        }        return owner.toString();    }    /** The symbol's erased type.     */    public Type erasure(Types types) {        if (erasure_field == null)            erasure_field = types.erasure(type);        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(Types types) {        Type t = erasure(types);        if (name == name.table.init && owner.hasOuterInstance()) {            Type outerThisType = types.erasure(owner.type.getEnclosingType());            return new MethodType(t.getParameterTypes().prepend(outerThisType),                                  t.getReturnType(),                                  t.getThrownTypes(),                                  t.tsym);        } else {            return t;        }    }    public boolean isStatic() {        return            (flags() & STATIC) != 0 ||            (owner.flags() & INTERFACE) != 0 && kind != MTH;    }    public boolean isInterface() {        return (flags() & INTERFACE) != 0;    }    /** 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 getQualifiedName() {        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 getQualifiedName();    }    /** 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.getEnclosingType().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.getEnclosingType().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.type.tag != CLASS)) {            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, Types types) {        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, Types types) {        return            owner == clazz ||            clazz.isSubClass(owner, types) &&            isInheritedIn(clazz, types) &&            !hiddenIn((ClassSymbol)clazz, types);    }    /** 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, Types types) {        if (kind == MTH && (flags() & STATIC) == 0) return false;        while (true) {            if (owner == clazz) return false;            Scope.Entry e = clazz.members().lookup(name);            while (e.scope != null) {                if (e.sym == this) return false;                if (e.sym.kind == kind &&                    (kind != MTH ||                     (e.sym.flags() & STATIC) != 0 &&                     types.isSubSignature(e.sym.type, type)))                    return true;                e = e.next();            }            Type superType = types.supertype(clazz.type);            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, Types types) {        switch ((int)(flags_field & Flags.AccessFlags)) {        default: // error recovery        case PUBLIC:            return true;        case PRIVATE:            return this.owner == clazz;        case PROTECTED:            // we model interfaces as extending Object            return (clazz.flags() & INTERFACE) == 0;        case 0:            PackageSymbol thisPackage = this.packge();            for (Symbol sup = clazz;                 sup != null && sup != this.owner;                 sup = types.supertype(sup.type).tsym) {                if (sup.type.isErroneous())                    return true; // error recovery                if ((sup.flags() & COMPOUND) != 0)                    continue;                if (sup.packge() != thisPackage)                    return false;            }            return (clazz.flags() & INTERFACE) == 0;        }    }    /** The (variable or method) symbol seen as a member of given     *  class type`site' (this might change the symbol's type).     *  This is used exclusively for producing diagnostics.     */    public Symbol asMemberOf(Type site, Types types) {        throw new AssertionError();    }    /** Does this method symbol override `other' symbol, when both are seen as     *  members of class `origin'?  It is assumed that _other is a member     *  of origin.     *     *  It is assumed that both symbols have the same name.  The static     *  modifier is ignored for this test.     *     *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4     */    public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {        return false;    }    /** Complete the elaboration of this symbol's definition.     */    public void complete() throws CompletionFailure {        if (completer != null) {            Completer c = completer;            completer = null;            c.complete(this);        }    }    /** True if the symbol represents an entity that exists.     */    public boolean exists() {        return true;    }    public Type asType() {        return type;    }    public Symbol getEnclosingElement() {        return owner;    }    public ElementKind getKind() {        return ElementKind.OTHER;       // most unkind    }    public Set<Modifier> getModifiers() {        return Flags.asModifierSet(flags());    }    public Name getSimpleName() {        return name;    }    /**     * @deprecated this method should never be used by javac internally.     */    @Deprecated

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?