📄 transinner.java
字号:
case ByteCodes.idiv:
case ByteCodes.ldiv:
case ByteCodes.fdiv:
case ByteCodes.ddiv:
return Tree.DIV_ASG;
case ByteCodes.imod:
case ByteCodes.lmod:
case ByteCodes.fmod:
case ByteCodes.dmod:
return Tree.MOD_ASG;
default:
throw new AssertionError();
}
}
/**
* The name of the access method with number `anum' and access code `acode'.
*/
Name accessName(int anum, int acode) {
return names.fromString("access$" + anum + acode / 10 + acode % 10);
}
/**
* Return access symbol for a private or protected symbol from an inner class.
* @param sym The accessed private symbol.
* @param tree The accessing tree.
* @param enclOp The closest enclosing operation node of tree,
* null if tree is not a subtree of an operation.
* @param protAccess Is access to a protected symbol in another
* package?
* @param refSuper Is access via a (qualified) C.super?
*/
MethodSymbol accessSymbol(Symbol sym, Tree tree, Tree enclOp,
boolean protAccess, boolean refSuper) {
ClassSymbol accOwner = refSuper && protAccess ?
(ClassSymbol)((Select) tree).selected.type.tsym :
accessClass(sym, protAccess);
Symbol vsym = sym;
if (sym.owner != accOwner) {
vsym = sym.clone(accOwner);
actualSymbols.put(vsym, sym);
}
Integer anum = (Integer) accessNums.get(vsym);
if (anum == null) {
anum = new Integer(accessed.length());
accessNums.put(vsym, anum);
accessSyms.put(vsym, new MethodSymbol[NCODES]);
accessed.append(vsym);
}
int acode;
List argtypes;
Type restype;
List thrown;
switch (vsym.kind) {
case VAR:
acode = accessCode(tree, enclOp);
if (acode >= FIRSTASGOPcode) {
OperatorSymbol operator = binaryAccessOperator(acode);
if (operator.opcode == string_add)
argtypes = List.make(syms.objectType);
else
argtypes = operator.type.argtypes().tail;
} else if (acode == ASSIGNcode)
argtypes = Type.emptyList.prepend(vsym.erasure());
else
argtypes = Type.emptyList;
restype = vsym.erasure();
thrown = Type.emptyList;
break;
case MTH:
acode = DEREFcode;
argtypes = vsym.erasure().argtypes();
restype = vsym.erasure().restype();
thrown = vsym.type.thrown();
break;
default:
throw new AssertionError();
}
if (protAccess && refSuper)
acode++;
if ((vsym.flags() & STATIC) == 0) {
argtypes = argtypes.prepend(vsym.owner.erasure());
}
MethodSymbol[] accessors = (Symbol.MethodSymbol[]) accessSyms.get(vsym);
MethodSymbol accessor = accessors[acode];
if (accessor == null) {
accessor = new MethodSymbol(STATIC | SYNTHETIC,
accessName(anum.intValue(), acode),
new MethodType(argtypes, restype, thrown, syms.methodClass),
accOwner);
enterSynthetic(tree.pos, accessor, accOwner.members());
accessors[acode] = accessor;
}
return accessor;
}
/**
* The qualifier to be used for accessing a symbol in an outer class.
* This is either C.sym or C.this.sym, depending on whether or not
* sym is static.
* @param sym The accessed symbol.
*/
Tree accessBase(int pos, Symbol sym) {
return (sym.flags() & STATIC) != 0 ?
access(make.at(pos).QualIdent(sym.owner)) :
makeOwnerThis(pos, sym, true);
}
/**
* Do we need an access method to reference private symbol?
*/
boolean needsPrivateAccess(Symbol sym) {
if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
return false;
} else if (sym.name == names.init &&
(sym.owner.owner.kind & (VAR | MTH)) != 0) {
sym.flags_field &= ~PRIVATE;
return false;
} else {
return true;
}
}
/**
* Do we need an access method to reference symbol in other package?
*/
boolean needsProtectedAccess(Symbol sym) {
return (sym.flags() & PROTECTED) != 0 &&
sym.owner.owner != currentClass.owner &&
sym.packge() != currentClass.packge() &&
!currentClass.isSubClass(sym.owner);
}
/**
* The class in which an access method for given symbol goes.
* @param sym The access symbol
* @param protAccess Is access to a protected symbol in another
* package?
*/
ClassSymbol accessClass(Symbol sym, boolean protAccess) {
if (protAccess) {
ClassSymbol c = currentClass;
while (!c.isSubClass(sym.owner)) {
c = c.owner.enclClass();
}
return c;
} else {
return sym.owner.enclClass();
}
}
/**
* Ensure that identifier is accessible, return tree accessing the identifier.
* @param sym The accessed symbol.
* @param tree The tree referring to the symbol.
* @param enclOp The closest enclosing operation node of tree,
* null if tree is not a subtree of an operation.
* @param refSuper Is access via a (qualified) C.super?
*/
Tree access(Symbol sym, Tree tree, Tree enclOp, boolean refSuper) {
while (sym.kind == VAR && sym.owner.kind == MTH &&
sym.owner.enclClass() != currentClass) {
Object cv = ((VarSymbol) sym).constValue;
if (cv != null) {
make.at(tree.pos);
return makeLit(sym.type, cv);
}
sym = proxies.lookup(proxyName(sym.name)).sym;
assert sym != null && (sym.flags_field & FINAL) != 0;
tree = make.at(tree.pos).Ident(sym);
}
Tree base = (tree.tag == Tree.SELECT) ? ((Select) tree).selected : null;
switch (sym.kind) {
case TYP:
if (sym.owner.kind != PCK) {
Name flatname = Convert.shortName(sym.flatName());
while (base != null && TreeInfo.symbol(base) != null &&
TreeInfo.symbol(base).kind != PCK) {
base = (base.tag == Tree.SELECT) ? ((Select) base).selected :
null;
}
if (tree.tag == Tree.IDENT) {
((Ident) tree).name = flatname;
} else if (base == null) {
tree = make.at(tree.pos).Ident(sym);
((Ident) tree).name = flatname;
} else {
((Select) tree).selected = base;
((Select) tree).name = flatname;
}
}
break;
case MTH:
case VAR:
if (sym.owner.kind == TYP) {
boolean protAccess = refSuper && !needsPrivateAccess(sym) ||
needsProtectedAccess(sym);
boolean accReq = protAccess || needsPrivateAccess(sym);
boolean baseReq = base == null && sym.owner != syms.predefClass &&
!sym.isMemberOf(currentClass);
if (accReq || baseReq) {
make.at(tree.pos);
if (sym.kind == VAR) {
Object cv = ((VarSymbol) sym).constValue;
if (cv != null)
return makeLit(sym.type, cv);
}
if (accReq) {
List args = Tree.emptyList;
if ((sym.flags() & STATIC) == 0) {
if (base == null)
base = makeOwnerThis(tree.pos, sym, true);
args = args.prepend(base);
base = null;
}
Symbol access = accessSymbol(sym, tree, enclOp, protAccess,
refSuper);
Tree receiver = make.Select(base != null ? base :
make.QualIdent(access.owner), access);
return make.App(receiver, args);
} else if (baseReq) {
return make.at(tree.pos).Select(
accessBase(tree.pos, sym), sym);
}
}
}
}
return tree;
}
/**
* Ensure that identifier is accessible, return tree accessing the identifier.
* @param tree The identifier tree.
*/
Tree access(Tree tree) {
Symbol sym = TreeInfo.symbol(tree);
return sym == null ? tree : access(sym, tree, null, false);
}
/**
* Return access constructor for a private constructor,
* or the constructor itself, if no access constructor is needed.
* @param pos The position to report diagnostics, if any.
* @param constr The private constructor.
*/
Symbol accessConstructor(int pos, Symbol constr) {
if (needsPrivateAccess(constr)) {
ClassSymbol accOwner = accessClass(constr, false);
MethodSymbol aconstr = (Symbol.MethodSymbol) accessConstrs.get(constr);
if (aconstr == null) {
aconstr = new MethodSymbol(SYNTHETIC, names.init,
new MethodType( constr.type.argtypes().append(
accessConstructorTag().type), constr.type.restype(),
constr.type.thrown(), syms.methodClass), accOwner);
enterSynthetic(pos, aconstr, accOwner.members());
accessConstrs.put(constr, aconstr);
accessed.append(constr);
}
return aconstr;
} else {
return constr;
}
}
/**
* Return an anonymous class nested in this toplevel class.
*/
ClassSymbol accessConstructorTag() {
ClassSymbol topClass = currentClass.outermostClass();
Name flatname = names.fromString(topClass.fullName() + "$1");
ClassSymbol ctag = (Symbol.ClassSymbol) chk.compiled.get(flatname);
if (ctag == null)
ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass);
return ctag;
}
/**
* Add all required access methods for a private symbol to enclosing class.
* @param sym The symbol.
*/
void makeAccessible(Symbol sym) {
ClassDef cdef = classDef(sym.owner.enclClass());
assert cdef != null :
"class def not found: " + sym + " in " + sym.owner;
if (sym.name == names.init) {
cdef.defs = cdef.defs.prepend( accessConstructorDef(cdef.pos, sym,
(Symbol.MethodSymbol) accessConstrs.get(sym)));
} else {
MethodSymbol[] accessors = (Symbol.MethodSymbol[]) accessSyms.get(sym);
for (int i = 0; i < NCODES; i++) {
if (accessors[i] != null)
cdef.defs = cdef.defs.prepend(
accessDef(cdef.pos, sym, accessors[i], i));
}
}
}
/**
* Construct definition of an access method.
* @param pos The source code position of the definition.
* @param sym The private or protected symbol.
* @param accessor The access method for the symbol.
* @param acode The access code.
*/
Tree accessDef(int pos, Symbol vsym, MethodSymbol accessor, int acode) {
currentClass = vsym.owner.enclClass();
make.at(pos);
MethodDef md = make.MethodDef(accessor, null);
Symbol sym = (Symbol) actualSymbols.get(vsym);
if (sym == null)
sym = vsym;
Tree ref;
List args;
if ((sym.flags() & STATIC) != 0) {
ref = make.Ident(sym);
args = make.Idents(md.params);
} else {
ref = make.Select(make.Ident((Tree.VarDef) md.params.head), sym);
args = make.Idents(md.params.tail);
}
Tree stat;
if (sym.kind == VAR) {
int acode1 = acode - (acode & 1);
Tree expr;
switch (acode1) {
case DEREFcode:
expr = ref;
break;
case ASSIGNcode:
expr = make.Assign(ref, (Tree) args.head);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -