📄 transinner.java
字号:
case PREINCcode:
case POSTINCcode:
case PREDECcode:
case POSTDECcode:
expr = makeUnary(((acode1 - PREINCcode)>> 1) + Tree.PREINC, ref);
break;
default:
expr = make.Assignop(treeTag(binaryAccessOperator(acode1)), ref,
(Tree) args.head);
((Assignop) expr).operator = binaryAccessOperator(acode1);
}
stat = make.Return(expr.setType(sym.type));
} else {
stat = make.Call(make.App(ref, args));
}
md.body = make.Block(0, List.make(stat));
for (List l = md.params; l.nonEmpty(); l = l.tail)
((Tree.VarDef) l.head).vartype = access(((Tree.VarDef) l.head).vartype);
md.restype = access(md.restype);
for (List l = md.thrown; l.nonEmpty(); l = l.tail)
l.head = access((Tree) l.head);
return md;
}
/**
* Construct definition of an access constructor.
* @param pos The source code position of the definition.
* @param constr The private constructor.
* @param accessor The access method for the constructor.
*/
Tree accessConstructorDef(int pos, Symbol constr, MethodSymbol accessor) {
make.at(pos);
MethodDef md = make.MethodDef(accessor, accessor.externalType(), null);
Ident callee = make.Ident(names._this);
callee.sym = constr;
callee.type = constr.type;
md.body = make.Block(0,
List.make( make.Call(
make.App(callee, make.Idents(md.params.reverse().tail.reverse())))));
return md;
}
/**
* A scope containing all free variable proxies for currently translated
* class, as well as its this$n symbol (if needed).
* Proxy scopes are nested in the same way classes are.
* Inside a constructor, proxies and any this$n symbol are duplicated
* in an additional innermost scope, where they represent the constructor
* parameters.
*/
Scope proxies;
/**
* A stack containing the this$n field of the currently translated
* classes (if needed) in innermost first order.
* Inside a constructor, proxies and any this$n symbol are duplicated
* in an additional innermost scope, where they represent the constructor
* parameters.
*/
List outerThisStack;
/**
* The name of a free variable proxy.
*/
Name proxyName(Name name) {
return names.fromString("val$" + name);
}
/**
* Proxy definitions for all free variables in given list, in reverse order.
* @param pos The source code position of the definition.
* @param freevars The free variables.
* @param owner The class in which the definitions go.
*/
List freevarDefs(int pos, List freevars, Symbol owner) {
long flags = FINAL | SYNTHETIC;
if (owner.kind == TYP && target.ordinal < Target.JDK1_4_2.ordinal)
flags |= PRIVATE;
List defs = VarDef.emptyList;
for (List l = freevars; l.nonEmpty(); l = l.tail) {
VarSymbol v = (Symbol.VarSymbol) l.head;
VarSymbol proxy =
new VarSymbol(flags, proxyName(v.name), v.erasure(), owner);
proxies.enter(proxy);
VarDef vd = make.at(pos).VarDef(proxy, null);
vd.vartype = access(vd.vartype);
defs = defs.prepend(vd);
}
return defs;
}
/**
* The name of a this$n field
* @param target The class referenced by the this$n field
*/
Name outerThisName(Type target) {
Type t = target.outer();
int nestingLevel = 0;
while (t.tag == CLASS) {
t = t.outer();
nestingLevel++;
}
return names.fromString("this$" + nestingLevel);
}
/**
* Definition for this$n field.
* @param pos The source code position of the definition.
* @param owner The class in which the definition goes.
*/
VarDef outerThisDef(int pos, Symbol owner) {
long flags = FINAL | SYNTHETIC;
if (owner.kind == TYP && target.ordinal < Target.JDK1_4_2.ordinal)
flags |= PRIVATE;
Type target = owner.enclClass().type.outer().erasure();
VarSymbol outerThis =
new VarSymbol(flags, outerThisName(target), target, owner);
outerThisStack = outerThisStack.prepend(outerThis);
VarDef vd = make.at(pos).VarDef(outerThis, null);
vd.vartype = access(vd.vartype);
return vd;
}
/**
* Return a list of trees that load the free variables in given list,
* in reverse order.
* @param pos The source code position to be used for the trees.
* @param freevars The list of free variables.
*/
List loadFreevars(int pos, List freevars) {
List args = Tree.emptyList;
for (List l = freevars; l.nonEmpty(); l = l.tail)
args = args.prepend(loadFreevar(pos, (Symbol.VarSymbol) l.head));
return args;
}
Tree loadFreevar(int pos, VarSymbol v) {
return access(v, make.at(pos).Ident(v), null, false);
}
/**
* Construct a tree simulating the expression <C.this>.
* @param pos The source code position to be used for the tree.
* @param c The qualifier class.
*/
Tree makeThis(int pos, TypeSymbol c) {
if (currentClass == c) {
return make.at(pos).This(c.erasure());
} else {
return makeOuterThis(pos, c);
}
}
/**
* Construct a tree that represents the outer instance
* <C.this>. Never pick the current `this'.
* @param pos The source code position to be used for the tree.
* @param c The qualifier class.
*/
Tree makeOuterThis(int pos, TypeSymbol c) {
List ots = outerThisStack;
if (ots.isEmpty()) {
log.error(pos, "no.encl.instance.of.type.in.scope", c.toJava());
assert false;
return make.Ident(syms.nullConst);
}
VarSymbol ot = (Symbol.VarSymbol) ots.head;
Tree tree = access(make.at(pos).Ident(ot));
TypeSymbol otc = ot.type.tsym;
while (otc != c) {
do {
ots = ots.tail;
if (ots.isEmpty()) {
log.error(pos, "no.encl.instance.of.type.in.scope", c.toJava());
assert false;
return tree;
}
ot = (Symbol.VarSymbol) ots.head;
} while (ot.owner != otc)
;
if (otc.owner.kind != PCK && !otc.hasOuterInstance()) {
chk.earlyRefError(pos, c);
assert false;
return make.Ident(syms.nullConst);
}
tree = access(make.at(pos).Select(tree, ot));
otc = ot.type.tsym;
}
return tree;
}
/**
* Construct a tree that represents the closest outer instance
* <C.this> such that the given symbol is a member of C.
* @param pos The source code position to be used for the tree.
* @param sym The accessed symbol.
* @param preciseMatch should we accept a type that is a subtype of
* sym's owner, even if it doesn't contain sym
* due to hiding, overriding, or non-inheritance
* due to protection?
*/
Tree makeOwnerThis(int pos, Symbol sym, boolean preciseMatch) {
Symbol c = sym.owner;
if (preciseMatch ? sym.isMemberOf(currentClass) :
currentClass.isSubClass(sym.owner)) {
return make.at(pos).This(c.erasure());
} else {
List ots = outerThisStack;
if (ots.isEmpty()) {
log.error(pos, "no.encl.instance.of.type.in.scope", c.toJava());
assert false;
return make.Ident(syms.nullConst);
}
VarSymbol ot = (Symbol.VarSymbol) ots.head;
Tree tree = access(make.at(pos).Ident(ot));
TypeSymbol otc = ot.type.tsym;
while (!(preciseMatch ? sym.isMemberOf(otc) :
otc.isSubClass(sym.owner))) {
do {
ots = ots.tail;
if (ots.isEmpty()) {
log.error(pos, "no.encl.instance.of.type.in.scope",
c.toJava());
assert false;
return tree;
}
ot = (Symbol.VarSymbol) ots.head;
} while (ot.owner != otc)
;
tree = access(make.at(pos).Select(tree, ot));
otc = ot.type.tsym;
}
return tree;
}
}
/**
* Return tree simulating the the assignment <this.name = name>, where
* name is the name of a free variable.
*/
Tree initField(int pos, Name name) {
Scope.Entry e = proxies.lookup(name);
Symbol rhs = e.sym;
assert rhs.owner.kind == MTH;
Symbol lhs = e.next().sym;
assert rhs.owner.owner == lhs.owner;
make.at(pos);
return make.Exec(
make.Assign(make.Select(make.This(lhs.owner.erasure()), lhs),
make.Ident(rhs)).setType(lhs.erasure()));
}
/**
* Return tree simulating the the assignment <this.this$n = this$n>.
*/
Tree initOuterThis(int pos) {
VarSymbol rhs = (Symbol.VarSymbol) outerThisStack.head;
assert rhs.owner.kind == MTH;
VarSymbol lhs = (Symbol.VarSymbol) outerThisStack.tail.head;
assert rhs.owner.owner == lhs.owner;
make.at(pos);
return make.Exec(
make.Assign(make.Select(make.This(lhs.owner.erasure()), lhs),
make.Ident(rhs)).setType(lhs.erasure()));
}
/**
* Return the symbol of a class to contain a cache of
* compiler-generated statics such as class$ and the
* $assertionsDisabled flag. We create an anonymous nested class
* unless one exists and return its symbol. However, for
* backward compatibility in 1.4 and earlier we use the
* top-level class.
*/
private ClassSymbol outerCacheClass() {
ClassSymbol clazz = outermostClassDef.sym;
if ((clazz.flags() & INTERFACE) == 0 &&
target.ordinal < Target.JDK1_4_2.ordinal)
return clazz;
Scope s = clazz.members();
for (Scope.Entry e = s.elems; e != null; e = e.sibling)
if (e.sym.kind == TYP && e.sym.name == names.empty &&
(e.sym.flags() & INTERFACE) == 0)
return (ClassSymbol) e.sym;
return makeEmptyClass(STATIC | SYNTHETIC, clazz);
}
/**
* Return symbol for "class$" method. If there is no method definition
* for class$, construct one as follows:
*
* class class$(String x0) {
* try {
* return Class.forName(x0);
* } catch (ClassNotFoundException x1) {
* throw new NoClassDefFoundError(x1.getMessage());
* }
* }
*/
private MethodSymbol classDollarSym(int pos) {
ClassSymbol outerCacheClass = outerCacheClass();
MethodSymbol classDollarSym =
(MethodSymbol) lookupSynthetic(names.classDollar,
outerCacheClass.members());
if (classDollarSym == null) {
classDollarSym = new MethodSymbol(STATIC | SYNTHETIC, names.classDollar,
new MethodType(Type.emptyList.prepend(syms.stringType),
syms.classType, Type.emptyList, syms.methodClass),
outerCacheClass);
enterSynthetic(pos, classDollarSym, outerCacheClass.members());
MethodDef md = make.MethodDef(classDollarSym, null);
try {
md.body = classDollarSymBody(pos, md);
} catch (CompletionFailure ex) {
md.body = make.Block(0, Tree.emptyList);
chk.completionError(pos, ex);
}
ClassDef outerCacheClassDef = classDef(outerCacheClass);
outerCacheClassDef.defs = outerCacheClassDef.defs.prepend(md);
}
return classDollarSym;
}
/**
* Generate code for class$(String name).
*/
Block classDollarSymBody(int pos, MethodDef md) {
MethodSymbol classDollarSym = md.sym;
ClassSymbol outerCacheClass = (ClassSymbol) classDollarSym.owner;
Tree returnResult;
if (target.ordinal >= Target.JDK1_4_2.ordinal) {
VarSymbol clsym =
new VarSymbol(STATIC | SYNTHETIC, names.fromString("cl$"),
syms.classLoaderType, outerCacheClass);
enterSynthetic(pos, clsym, outerCacheClass.members());
VarDef cldef = make.VarDef(clsym, null);
ClassDef outerCacheClassDef = classDef(outerCacheClass);
outerCacheClassDef.defs = outerCacheClassDef.defs.prepend(cldef);
Tree newcache = make.NewArray(make.Type(outerCacheClass.type),
Tree.emptyList.prepend(
make.Literal(Type.INT, new Integer(0)).setType(syms.intType))
, null);
newcache.type = new ArrayType(outerCacheClass.type, syms.arrayClass);
Symbol forNameSym =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -