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 + -
显示快捷键?