< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java

Print this page
@@ -904,11 +904,11 @@
          for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
              ClassSymbol c = l.head;
              if (isTranslatedClassAvailable(c))
                  continue;
              // Create class definition tree.
-             JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC,
+             JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE,
                      c.outermostClass(), c.flatname, false);
              swapAccessConstructorTag(c, cdec.sym);
              translated.append(cdec);
          }
      }

@@ -1388,11 +1388,11 @@
              Name flatname = names.fromString("" + topClass.getQualifiedName() +
                                              target.syntheticNameChar() +
                                              i);
              ClassSymbol ctag = chk.getCompiled(topModle, flatname);
              if (ctag == null)
-                 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
+                 ctag = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, topClass).sym;
              else if (!ctag.isAnonymous())
                  continue;
              // keep a record of all tags, to verify that all are generated as required
              accessConstrTags = accessConstrTags.prepend(ctag);
              return ctag;

@@ -1857,11 +1857,11 @@
                      return tree;
                  }
                  ot = ots.head;
              } while (ot.owner != otc);
              if (otc.owner.kind != PCK && !otc.hasOuterInstance()) {
-                 chk.earlyRefError(pos, c);
+                 log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
                  Assert.error(); // should have been caught in Attr
                  return makeNull();
              }
              tree = access(make.at(pos).Select(tree, ot));
              ot.flags_field &= ~NOOUTERTHIS;

@@ -1897,11 +1897,10 @@
      JCExpression makeOwnerThisN(DiagnosticPosition pos, Symbol sym, boolean preciseMatch) {
          Symbol c = sym.owner;
          List<VarSymbol> ots = outerThisStack;
          if (ots.isEmpty()) {
              log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
-             Assert.error();
              return makeNull();
          }
          VarSymbol ot = ots.head;
          JCExpression tree = access(make.at(pos).Ident(ot));
          ot.flags_field &= ~NOOUTERTHIS;

@@ -1909,11 +1908,10 @@
          while (!(preciseMatch ? sym.isMemberOf(otc, types) : otc.isSubClass(sym.owner, types))) {
              do {
                  ots = ots.tail;
                  if (ots.isEmpty()) {
                      log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
-                     Assert.error();
                      return tree;
                  }
                  ot = ots.head;
              } while (ot.owner != otc);
              tree = access(make.at(pos).Select(tree, ot));

@@ -1967,11 +1965,11 @@
          Scope s = clazz.members();
          for (Symbol sym : s.getSymbols(NON_RECURSIVE))
              if (sym.kind == TYP &&
                  sym.name == names.empty &&
                  (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
-         return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
+         return makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, clazz).sym;
      }
  
      /** Create an attributed tree of the form left.name(). */
      private JCMethodInvocation makeCall(JCExpression left, Name name, List<JCExpression> args) {
          Assert.checkNonNull(left.type);

@@ -2019,11 +2017,11 @@
      /**Used to create an auxiliary class to hold $assertionsDisabled for interfaces.
       */
      private ClassSymbol assertionsDisabledClass() {
          if (assertionsDisabledClassCache != null) return assertionsDisabledClassCache;
  
-         assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC, outermostClassDef.sym).sym;
+         assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, outermostClassDef.sym).sym;
  
          return assertionsDisabledClassCache;
      }
  
      // This code is not particularly robust if the user has

@@ -2349,21 +2347,23 @@
  
          for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
              tree.defs = tree.defs.prepend(l.head);
              enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
          }
-         // If this$n was accessed, add the field definition and
-         // update initial constructors to initialize it
+         // If this$n was accessed, add the field definition and prepend
+         // initializer code to any super() invocation to initialize it
          if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
              tree.defs = tree.defs.prepend(otdef);
              enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
  
-            for (JCTree def : tree.defs) {
-                 if (TreeInfo.isInitialConstructor(def)) {
-                   JCMethodDecl mdef = (JCMethodDecl) def;
-                   mdef.body.stats = mdef.body.stats.prepend(
-                       initOuterThis(mdef.body.pos, mdef.params.head.sym));
+             for (JCTree def : tree.defs) {
+                 if (TreeInfo.isConstructor(def)) {
+                     JCMethodDecl mdef = (JCMethodDecl)def;
+                     if (TreeInfo.hasConstructorCall(mdef, names._super)) {
+                         List<JCStatement> initializer = List.of(initOuterThis(mdef.body.pos, mdef.params.head.sym));
+                         TreeInfo.mapSuperCalls(mdef.body, supercall -> make.Block(0, initializer.append(supercall)));
+                     }
                  }
              }
          }
  
          proxies = prevProxies;

@@ -2824,23 +2824,22 @@
              tree.params = tree.params.appendList(fvdefs);
              if (currentClass.hasOuterInstance()) {
                  tree.params = tree.params.prepend(otdef);
              }
  
-             // If this is an initial constructor, i.e., it does not start with
-             // this(...), insert initializers for this$n and proxies
-             // before (pre-1.4, after) the call to superclass constructor.
-             JCStatement selfCall = translate(tree.body.stats.head);
+             // Determine whether this constructor has a super() invocation
+             boolean invokesSuper = TreeInfo.hasConstructorCall(tree, names._super);
  
-             List<JCStatement> added = List.nil();
+             // Create initializers for this$n and proxies
+             ListBuffer<JCStatement> added = new ListBuffer<>();
              if (fvs.nonEmpty()) {
                  List<Type> addedargtypes = List.nil();
                  for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail) {
                      m.capturedLocals =
                          m.capturedLocals.prepend((VarSymbol)
                                                  (proxies.get(l.head)));
-                     if (TreeInfo.isInitialConstructor(tree)) {
+                     if (invokesSuper) {
                          added = added.prepend(
                            initField(tree.body.pos, proxies.get(l.head), prevProxies.get(l.head)));
                      }
                      addedargtypes = addedargtypes.prepend(l.head.erasure(types));
                  }

@@ -2850,17 +2849,22 @@
                      olderasure.getReturnType(),
                      olderasure.getThrownTypes(),
                      syms.methodClass);
              }
  
+             // Recursively translate existing local statements
+             tree.body.stats = translate(tree.body.stats);
+ 
+             // Prepend initializers in front of super() call
+             if (added.nonEmpty()) {
+                 List<JCStatement> initializers = added.toList();
+                 TreeInfo.mapSuperCalls(tree.body, supercall -> make.Block(0, initializers.append(supercall)));
+             }
+ 
              // pop local variables from proxy stack
              proxies = prevProxies;
  
-             // recursively translate following local statements and
-             // combine with this- or super-call
-             List<JCStatement> stats = translate(tree.body.stats.tail);
-             tree.body.stats = stats.prepend(selfCall).prependList(added);
              outerThisStack = prevOuterThisStack;
          } else {
              Map<Symbol, Symbol> prevLambdaTranslationMap =
                      lambdaTranslationMap;
              try {
< prev index next >