< prev index next > src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
Print this page
* @param defs The list of class member declarations.
* @param c The enclosing class.
*/
List<JCTree> normalizeDefs(List<JCTree> defs, ClassSymbol c) {
ListBuffer<JCStatement> initCode = new ListBuffer<>();
+ // only used for value classes
+ ListBuffer<JCStatement> initBlocks = new ListBuffer<>();
ListBuffer<Attribute.TypeCompound> initTAs = new ListBuffer<>();
ListBuffer<JCStatement> clinitCode = new ListBuffer<>();
ListBuffer<Attribute.TypeCompound> clinitTAs = new ListBuffer<>();
ListBuffer<JCTree> methodDefs = new ListBuffer<>();
// Sort definitions into three listbuffers:
switch (def.getTag()) {
case BLOCK:
JCBlock block = (JCBlock)def;
if ((block.flags & STATIC) != 0)
clinitCode.append(block);
! else if ((block.flags & SYNTHETIC) == 0)
! initCode.append(block);
break;
case METHODDEF:
methodDefs.append(def);
break;
case VARDEF:
switch (def.getTag()) {
case BLOCK:
JCBlock block = (JCBlock)def;
if ((block.flags & STATIC) != 0)
clinitCode.append(block);
! else if ((block.flags & SYNTHETIC) == 0) {
! if (c.isValueClass()) {
+ initBlocks.append(block);
+ } else {
+ initCode.append(block);
+ }
+ }
break;
case METHODDEF:
methodDefs.append(def);
break;
case VARDEF:
default:
Assert.error();
}
}
// Insert any instance initializers into all constructors.
! if (initCode.length() != 0) {
- List<JCStatement> inits = initCode.toList();
initTAs.addAll(c.getInitTypeAttributes());
List<Attribute.TypeCompound> initTAlist = initTAs.toList();
for (JCTree t : methodDefs) {
! normalizeMethod((JCMethodDecl)t, inits, initTAlist);
}
}
// If there are class initializers, create a <clinit> method
// that contains them as its body.
if (clinitCode.length() != 0) {
default:
Assert.error();
}
}
// Insert any instance initializers into all constructors.
! if (initCode.length() != 0 || initBlocks.length() != 0) {
initTAs.addAll(c.getInitTypeAttributes());
List<Attribute.TypeCompound> initTAlist = initTAs.toList();
for (JCTree t : methodDefs) {
! normalizeMethod((JCMethodDecl)t, initCode.toList(), initBlocks.toList(), initTAlist);
}
}
// If there are class initializers, create a <clinit> method
// that contains them as its body.
if (clinitCode.length() != 0) {
* @param md The tree potentially representing a
* constructor's definition.
* @param initCode The list of instance initializer statements.
* @param initTAs Type annotations from the initializer expression.
*/
! void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<TypeCompound> initTAs) {
if (TreeInfo.isConstructor(md) && TreeInfo.hasConstructorCall(md, names._super)) {
// We are seeing a constructor that has a super() call.
// Find the super() invocation and append the given initializer code.
! TreeInfo.mapSuperCalls(md.body, supercall -> make.Block(0, initCode.prepend(supercall)));
if (md.body.endpos == Position.NOPOS)
md.body.endpos = TreeInfo.endPos(md.body.stats.last());
md.sym.appendUniqueTypeAttributes(initTAs);
}
}
/* ************************************************************************
* Traversal methods
*************************************************************************/
/** Visitor argument: The current environment.
* @param md The tree potentially representing a
* constructor's definition.
* @param initCode The list of instance initializer statements.
* @param initTAs Type annotations from the initializer expression.
*/
! void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<JCStatement> initBlocks, List<TypeCompound> initTAs) {
if (TreeInfo.isConstructor(md) && TreeInfo.hasConstructorCall(md, names._super)) {
// We are seeing a constructor that has a super() call.
// Find the super() invocation and append the given initializer code.
! if (md.sym.owner.isValueClass()) {
+ rewriteInitializersIfNeeded(md, initCode);
+ TreeInfo.mapSuperCalls(md.body, supercall -> make.Block(0, initCode.append(supercall).appendList(initBlocks)));
+ } else {
+ TreeInfo.mapSuperCalls(md.body, supercall -> make.Block(0, initCode.prepend(supercall)));
+ }
if (md.body.endpos == Position.NOPOS)
md.body.endpos = TreeInfo.endPos(md.body.stats.last());
md.sym.appendUniqueTypeAttributes(initTAs);
}
}
+ void rewriteInitializersIfNeeded(JCMethodDecl md, List<JCStatement> initCode) {
+ if (lower.initializerOuterThis.containsKey(md.sym.owner)) {
+ InitializerVisitor initializerVisitor = new InitializerVisitor(md, lower.initializerOuterThis.get(md.sym.owner));
+ for (JCStatement init : initCode) {
+ initializerVisitor.scan(init);
+ }
+ }
+ }
+
+ class InitializerVisitor extends TreeScanner {
+ JCMethodDecl md;
+ Set<JCExpression> exprSet;
+
+ InitializerVisitor(JCMethodDecl md, Set<JCExpression> exprSet) {
+ this.md = md;
+ this.exprSet = exprSet;
+ }
+
+ @Override
+ public void visitTree(JCTree tree) {}
+
+ @Override
+ public void visitIdent(JCIdent tree) {
+ if (exprSet.contains(tree)) {
+ for (JCVariableDecl param: md.params) {
+ if (param.name == tree.name &&
+ ((param.sym.flags_field & (MANDATED | NOOUTERTHIS)) == (MANDATED | NOOUTERTHIS))) {
+ tree.sym = param.sym;
+ }
+ }
+ }
+ }
+ }
+
/* ************************************************************************
* Traversal methods
*************************************************************************/
/** Visitor argument: The current environment.
if (tree.name == names._class) {
code.emitLdc((LoadableConstant)checkDimension(tree.pos(), tree.selected.type));
result = items.makeStackItem(pt);
return;
! }
Symbol ssym = TreeInfo.symbol(tree.selected);
// Are we selecting via super?
boolean selectSuper =
if (tree.name == names._class) {
code.emitLdc((LoadableConstant)checkDimension(tree.pos(), tree.selected.type));
result = items.makeStackItem(pt);
return;
! }
Symbol ssym = TreeInfo.symbol(tree.selected);
// Are we selecting via super?
boolean selectSuper =
< prev index next >