📄 symbol.java
字号:
/**
* A total ordering between class symbols that refines the class
* inheritance graph.
*/
public boolean precedes(TypeSymbol that) {
return that.rank() < this.rank() || that.rank() == this.rank() &&
isLess(that.fullName(), this.fullname);
}
private boolean isLess(Name n1, Name n2) {
if (n1 == n2)
return false;
int i = n1.index + n1.len - 1;
int j = n2.index + n2.len - 1;
while (i != n1.index && j != n2.index &&
n1.table.names[i] == n2.table.names[j]) {
i--;
j--;
}
if (j == n2.index)
return false;
else if (i == n1.index)
return true;
else
return n1.table.names[i] < n2.table.names[j];
}
/**
* Complete the elaboration of this symbol's definition.
*/
public void complete() throws CompletionFailure {
try {
super.complete();
} catch (CompletionFailure ex) {
flags_field |= (PUBLIC | STATIC);
this.type = new ErrorType(this);
throw ex;
}
}
}
/**
* A class for variable symbols
*/
public static class VarSymbol extends Symbol {
/**
* The variable's declaration position.
*/
public int pos = Position.NOPOS;
/**
* The variable's address. Used for different purposes during
* flow analysis, translation and code generation.
* Flow analysis:
* If this is a blank final or local variable, its sequence number.
* Translation:
* If this is a private field, its access number.
* Code generation:
* If this is a local variable, its logical slot number.
*/
public int adr = -1;
/**
* The variable's constant value, if this is a constant.
* Before the constant value is evaluated, it points to
* an initalizer environment.
*/
public Object constValue;
/**
* 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 Symbol clone(Symbol newOwner) {
VarSymbol v = new VarSymbol(flags_field, name, type, newOwner);
v.pos = pos;
v.adr = adr;
v.constValue = constValue;
return v;
}
public static final List emptyList = new List();
public String toString() {
return "variable " + name;
}
public Symbol asMemberOf(Type site) {
return new VarSymbol(flags_field, name, site.memberType(this), owner);
}
}
/**
* A class for method symbols.
*/
public static class MethodSymbol extends Symbol {
public Code code = 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);
}
public static final List emptyList = new List();
/**
* Clone this symbol with new owner.
*/
public Symbol clone(Symbol newOwner) {
MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner);
m.code = code;
return m;
}
public String toString() {
if ((flags() & BLOCK) != 0) {
return "body of " + owner;
} else {
String s;
if (name == name.table.init)
s = "constructor " + owner.name;
else
s = "method " + name;
if (type != null) {
s += "(" + type.argtypes().toString() + ")";
}
return s;
}
}
/**
* 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() {
String s;
if ((flags() & BLOCK) != 0) {
s = owner.name.toString();
} else {
if (name == name.table.init)
s = owner.name.toString();
else
s = name.toString();
if (type != null) {
s += "(" + type.argtypes().toString() + ")";
}
}
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) {
Symbol impl = null;
for (List is = c.type.interfaces(); impl == null && is.nonEmpty();
is = is.tail) {
TypeSymbol i = ((Type) 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) &&
type.restype().isSameType(
owner.type.memberType(e.sym).restype())) {
impl = e.sym;
}
if (impl == null)
impl = implemented(i);
}
}
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) {
if (isConstructor() || _other.kind != MTH)
return false;
if (this == _other)
return true;
MethodSymbol other = (MethodSymbol)_other;
if (other.isOverridableIn((TypeSymbol) owner) &&
owner.type.asSuper(other.owner) != null &&
erasure().isSameType(other.type.erasure()))
return true;
return (flags() & ABSTRACT) == 0 && other.isOverridableIn(origin) &&
this.isMemberOf(origin) &&
erasure().isSameType(other.type.erasure());
}
/**
* 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) {
for (TypeSymbol c = origin; c != null; c = c.type.supertype().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))
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 both symbols have the same name.
* See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
*/
public boolean overrides(Symbol _other, TypeSymbol origin) {
if (isConstructor() || _other.kind != MTH)
return false;
MethodSymbol other = (MethodSymbol)_other;
if (other.isOverridableIn((TypeSymbol) owner) &&
owner.type.asSuper(other.owner) != null &&
owner.type.memberType(this).hasSameArgs(
owner.type.memberType(other)))
return true;
return (flags() & ABSTRACT) == 0 && other.isOverridableIn(origin) &&
this.isMemberOf(origin) &&
origin.type.memberType(this).hasSameArgs(
origin.type.memberType(other));
}
private boolean isOverridableIn(TypeSymbol origin) {
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:
return this.packge() == origin.packge() &&
(origin.flags() & INTERFACE) == 0;
default:
throw new AssertionError();
}
}
/**
* 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) {
for (Type t = origin.type; t.tag == CLASS; t = t.supertype()) {
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) && (m.flags() & SYNTHETIC) == 0)
return m;
}
}
}
if (Type.isDerivedRaw(origin.type))
return implementation(origin.type.supertype().tsym);
else
return null;
}
public Symbol asMemberOf(Type site) {
return new MethodSymbol(flags_field, name, site.memberType(this), owner);
}
}
/**
* 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 {
public Symbol sym;
/**
* A localized string describing the failure.
*/
public String errmsg;
public CompletionFailure(Symbol sym, String errmsg) {
super();
this.sym = sym;
this.errmsg = errmsg;
}
public String getMessage() {
return errmsg;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -