symbol.java

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

JAVA
1,297
字号
         */        public int adr = -1;        /** Construct a variable symbol, given its flags, name, type and owner.         */        public VarSymbol(long flags, Name name, Type type, Symbol owner) {            super(VAR, flags, name, type, owner);        }        /** Clone this symbol with new owner.         */        public VarSymbol clone(Symbol newOwner) {            VarSymbol v = new VarSymbol(flags_field, name, type, newOwner);            v.pos = pos;            v.adr = adr;            v.data = data;//          System.out.println("clone " + v + " in " + newOwner);//DEBUG            return v;        }        public String toString() {            return name.toString();        }        public Symbol asMemberOf(Type site, Types types) {            return new VarSymbol(flags_field, name, types.memberType(site, this), owner);        }        public ElementKind getKind() {            long flags = flags();            if ((flags & PARAMETER) != 0) {                if (isExceptionParameter())                    return ElementKind.EXCEPTION_PARAMETER;                else                    return ElementKind.PARAMETER;            } else if ((flags & ENUM) != 0) {                return ElementKind.ENUM_CONSTANT;            } else if (owner.kind == TYP || owner.kind == ERR) {                return ElementKind.FIELD;            } else {                return ElementKind.LOCAL_VARIABLE;            }        }        public <R, P> R accept(ElementVisitor<R, P> v, P p) {            return v.visitVariable(this, p);        }        public Object getConstantValue() { // Mirror API            return Constants.decode(getConstValue(), type);        }        public void setLazyConstValue(final Env<AttrContext> env,                                      final Log log,                                      final Attr attr,                                      final JCTree.JCExpression initializer)        {            setData(new Callable<Object>() {                public Object call() {                    JavaFileObject source = log.useSource(env.toplevel.sourcefile);                    try {                        // In order to catch self-references, we set                        // the variable's declaration position to                        // maximal possible value, effectively marking                        // the variable as undefined.                        int pos = VarSymbol.this.pos;                        VarSymbol.this.pos = Position.MAXPOS;                        Type itype = attr.attribExpr(initializer, env, type);                        VarSymbol.this.pos = pos;                        if (itype.constValue() != null)                            return attr.coerce(itype, type).constValue();                        else                            return null;                    } finally {                        log.useSource(source);                    }                }            });        }        /**         * The variable's constant value, if this is a constant.         * Before the constant value is evaluated, it points to an         * initalizer environment.  If this is not a constant, it can         * be used for other stuff.         */        private Object data;        public boolean isExceptionParameter() {            return data == ElementKind.EXCEPTION_PARAMETER;        }        public Object getConstValue() {            // TODO: Consider if getConstValue and getConstantValue can be collapsed            if (data == ElementKind.EXCEPTION_PARAMETER) {                return null;            } else if (data instanceof Callable<?>) {                // In this case, this is final a variable, with an as                // yet unevaluated initializer.                Callable<?> eval = (Callable<?>)data;                data = null; // to make sure we don't evaluate this twice.                try {                    data = eval.call();                } catch (Exception ex) {                    throw new AssertionError(ex);                }            }            return data;        }        public void setData(Object data) {            assert !(data instanceof Env<?>) : this;            this.data = data;        }    }    /** A class for method symbols.     */    public static class MethodSymbol extends Symbol implements ExecutableElement {        /** The code of the method. */        public Code code = null;        /** The parameters of the method. */        public List<VarSymbol> params = null;        /** The names of the parameters */        public List<Name> savedParameterNames;        /** For an attribute field accessor, its default value if any.         *  The value is null if none appeared in the method         *  declaration.         */        public Attribute defaultValue = null;        /** Construct a method symbol, given its flags, name, type and owner.         */        public MethodSymbol(long flags, Name name, Type type, Symbol owner) {            super(MTH, flags, name, type, owner);            assert owner.type.tag != TYPEVAR : owner + "." + name;        }        /** Clone this symbol with new owner.         */        public MethodSymbol clone(Symbol newOwner) {            MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner);            m.code = code;            return m;        }        /** The Java source which this symbol represents.         */        public String toString() {            if ((flags() & BLOCK) != 0) {                return owner.name.toString();            } else {                String s = (name == name.table.init)                    ? owner.name.toString()                    : name.toString();                if (type != null) {                    if (type.tag == FORALL)                        s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;                    s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";                }                return s;            }        }        /** find a symbol that this (proxy method) symbol implements.         *  @param    c       The class whose members are searched for         *                    implementations         */        public Symbol implemented(TypeSymbol c, Types types) {            Symbol impl = null;            for (List<Type> is = types.interfaces(c.type);                 impl == null && is.nonEmpty();                 is = is.tail) {                TypeSymbol i = is.head.tsym;                for (Scope.Entry e = i.members().lookup(name);                     impl == null && e.scope != null;                     e = e.next()) {                    if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&                        // FIXME: I suspect the following requires a                        // subst() for a parametric return type.                        types.isSameType(type.getReturnType(),                                         types.memberType(owner.type, e.sym).getReturnType())) {                        impl = e.sym;                    }                    if (impl == null)                        impl = implemented(i, types);                }            }            return impl;        }        /** Will the erasure of this method be considered by the VM to         *  override the erasure of the other when seen from class `origin'?         */        public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {            if (isConstructor() || _other.kind != MTH) return false;            if (this == _other) return true;            MethodSymbol other = (MethodSymbol)_other;            // check for a direct implementation            if (other.isOverridableIn((TypeSymbol)owner) &&                types.asSuper(owner.type, other.owner) != null &&                types.isSameType(erasure(types), other.erasure(types)))                return true;            // check for an inherited implementation            return                (flags() & ABSTRACT) == 0 &&                other.isOverridableIn(origin) &&                this.isMemberOf(origin, types) &&                types.isSameType(erasure(types), other.erasure(types));        }        /** The implementation of this (abstract) symbol in class origin,         *  from the VM's point of view, null if method does not have an         *  implementation in class.         *  @param origin   The class of which the implementation is a member.         */        public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {            for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {                for (Scope.Entry e = c.members().lookup(name);                     e.scope != null;                     e = e.next()) {                    if (e.sym.kind == MTH &&                        ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))                        return (MethodSymbol)e.sym;                }            }            return null;        }        /** Does this 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) {            if (isConstructor() || _other.kind != MTH) return false;            if (this == _other) return true;            MethodSymbol other = (MethodSymbol)_other;            // check for a direct implementation            if (other.isOverridableIn((TypeSymbol)owner) &&                types.asSuper(owner.type, other.owner) != null) {                Type mt = types.memberType(owner.type, this);                Type ot = types.memberType(owner.type, other);                if (types.isSubSignature(mt, ot)) {                    if (!checkResult)                        return true;                    if (types.returnTypeSubstitutable(mt, ot))                        return true;                }            }            // check for an inherited implementation            if ((flags() & ABSTRACT) != 0 ||                (other.flags() & ABSTRACT) == 0 ||                !other.isOverridableIn(origin) ||                !this.isMemberOf(origin, types))                return false;            // assert types.asSuper(origin.type, other.owner) != null;            Type mt = types.memberType(origin.type, this);            Type ot = types.memberType(origin.type, other);            return                types.isSubSignature(mt, ot) &&                (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings));        }        private boolean isOverridableIn(TypeSymbol origin) {            // JLS3 8.4.6.1            switch ((int)(flags_field & Flags.AccessFlags)) {            case Flags.PRIVATE:                return false;            case Flags.PUBLIC:                return true;            case Flags.PROTECTED:                return (origin.flags() & INTERFACE) == 0;            case 0:                // for package private: can only override in the same                // package                return                    this.packge() == origin.packge() &&                    (origin.flags() & INTERFACE) == 0;            default:                return false;            }        }        /** The implementation of this (abstract) symbol in class origin;         *  null if none exists. Synthetic methods are not considered         *  as possible implementations.         */        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {            for (Type t = origin.type; t.tag == CLASS; t = types.supertype(t)) {                TypeSymbol c = t.tsym;                for (Scope.Entry e = c.members().lookup(name);                     e.scope != null;                     e = e.next()) {                    if (e.sym.kind == MTH) {                        MethodSymbol m = (MethodSymbol) e.sym;                        if (m.overrides(this, origin, types, checkResult) &&                            (m.flags() & SYNTHETIC) == 0)                            return m;                    }                }            }            // if origin is derived from a raw type, we might have missed            // an implementation because we do not know enough about instantiations.            // in this case continue with the supertype as origin.            if (types.isDerivedRaw(origin.type))                return implementation(types.supertype(origin.type).tsym, types, checkResult);            else                return null;        }        public List<VarSymbol> params() {            owner.complete();            if (params == null) {                List<Name> names = savedParameterNames;                savedParameterNames = null;                if (names == null) {                    names = List.nil();                    int i = 0;                    for (Type t : type.getParameterTypes())                        names = names.prepend(name.table.fromString("arg" + i++));                    names = names.reverse();                }                ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();                for (Type t : type.getParameterTypes()) {                    buf.append(new VarSymbol(PARAMETER, names.head, t, this));                    names = names.tail;                }                params = buf.toList();            }            return params;        }        public Symbol asMemberOf(Type site, Types types) {            return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);        }        public ElementKind getKind() {            if (name == name.table.init)                return ElementKind.CONSTRUCTOR;            else if (name == name.table.clinit)                return ElementKind.STATIC_INIT;            else                return ElementKind.METHOD;        }        public Attribute getDefaultValue() {            return defaultValue;        }        public List<VarSymbol> getParameters() {            return params();        }        public boolean isVarArgs() {            return (flags() & VARARGS) != 0;        }        public <R, P> R accept(ElementVisitor<R, P> v, P p) {            return v.visitExecutable(this, p);        }        public Type getReturnType() {            return asType().getReturnType();        }        public List<Type> getThrownTypes() {            return asType().getThrownTypes();        }    }    /** A class for predefined operators.     */    public static class OperatorSymbol extends MethodSymbol {        public int opcode;        public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {            super(PUBLIC | STATIC, name, type, owner);            this.opcode = opcode;        }    }    /** Symbol completer interface.     */    public static interface Completer {        void complete(Symbol sym) throws CompletionFailure;    }    public static class CompletionFailure extends RuntimeException {        private static final long serialVersionUID = 0;        public Symbol sym;        /** A localized string describing the failure.         */        public String errmsg;        public CompletionFailure(Symbol sym, String errmsg) {            this.sym = sym;            this.errmsg = errmsg;//          this.printStackTrace();//DEBUG        }        public String getMessage() {            return errmsg;        }        @Override        public CompletionFailure initCause(Throwable cause) {            super.initCause(cause);            return this;        }    }}

⌨️ 快捷键说明

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