< prev index next >

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

Print this page
*** 479,12 ***
                  brk.target = swtch;
                  scan(brk);
              }
          }
  
!         // Do something with all static or non-static field initializers and initialization blocks.
          protected void forEachInitializer(JCClassDecl classDef, boolean isStatic, Consumer<? super JCTree> handler) {
              if (classDef == initScanClass)          // avoid infinite loops
                  return;
              JCClassDecl initScanClassPrev = initScanClass;
              initScanClass = classDef;
              try {
--- 479,22 ---
                  brk.target = swtch;
                  scan(brk);
              }
          }
  
!         // Do something with static or non-static field initializers and initialization blocks.
          protected void forEachInitializer(JCClassDecl classDef, boolean isStatic, Consumer<? super JCTree> handler) {
+             forEachInitializer(classDef, isStatic, false, handler);
+         }
+ 
+         /* Do something with static or non-static field initializers and initialization blocks.
+          * the `earlyOnly` argument will determine if we will deal or not with early variable instance
+          * initializers we want to process only those before a super() invocation and ignore them after
+          * it.
+          */
+         protected void forEachInitializer(JCClassDecl classDef, boolean isStatic, boolean earlyOnly,
+                                           Consumer<? super JCTree> handler) {
              if (classDef == initScanClass)          // avoid infinite loops
                  return;
              JCClassDecl initScanClassPrev = initScanClass;
              initScanClass = classDef;
              try {

*** 498,12 ***
                      /* we need to check for flags in the symbol too as there could be cases for which implicit flags are
                       * represented in the symbol but not in the tree modifiers as they were not originally in the source
                       * code
                       */
                      boolean isDefStatic = ((TreeInfo.flags(def) | (TreeInfo.symbolFor(def) == null ? 0 : TreeInfo.symbolFor(def).flags_field)) & STATIC) != 0;
!                     if (!def.hasTag(METHODDEF) && (isDefStatic == isStatic))
!                         handler.accept(def);
                  }
              } finally {
                  initScanClass = initScanClassPrev;
              }
          }
--- 508,22 ---
                      /* we need to check for flags in the symbol too as there could be cases for which implicit flags are
                       * represented in the symbol but not in the tree modifiers as they were not originally in the source
                       * code
                       */
                      boolean isDefStatic = ((TreeInfo.flags(def) | (TreeInfo.symbolFor(def) == null ? 0 : TreeInfo.symbolFor(def).flags_field)) & STATIC) != 0;
!                     if (!def.hasTag(METHODDEF) && (isDefStatic == isStatic)) {
!                         if (def instanceof JCVariableDecl varDecl) {
+                             boolean isEarly = varDecl.init != null &&
+                                     varDecl.sym.owner.isValueClass() &&
+                                     !varDecl.sym.isStatic();
+                             if (isEarly == earlyOnly) {
+                                 handler.accept(def);
+                             }
+                         } else if (!earlyOnly) {
+                             handler.accept(def);
+                         }
+                     }
                  }
              } finally {
                  initScanClass = initScanClassPrev;
              }
          }

*** 2296,11 ***
          void checkInit(DiagnosticPosition pos, VarSymbol sym, Error errkey) {
              if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
                  trackable(sym) &&
                  !inits.isMember(sym.adr) &&
                  (sym.flags_field & CLASH) == 0) {
!                     log.error(pos, errkey);
                  inits.incl(sym.adr);
              }
          }
  
          /** Utility method to reset several Bits instances.
--- 2316,11 ---
          void checkInit(DiagnosticPosition pos, VarSymbol sym, Error errkey) {
              if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
                  trackable(sym) &&
                  !inits.isMember(sym.adr) &&
                  (sym.flags_field & CLASH) == 0) {
!                 log.error(pos, errkey);
                  inits.incl(sym.adr);
              }
          }
  
          /** Utility method to reset several Bits instances.

*** 3030,18 ***
              scanExpr(tree.expr);
              markDead();
          }
  
          public void visitApply(JCMethodInvocation tree) {
              scanExpr(tree.meth);
              scanExprs(tree.args);
  
              // Handle superclass constructor invocations
              if (isConstructor) {
  
                  // If super(): at this point all initialization blocks will execute
!                 Name name = TreeInfo.name(tree.meth);
                  if (name == names._super) {
                      forEachInitializer(classDef, false, def -> {
                          scan(def);
                          clearPendingExits(false);
                      });
--- 3050,26 ---
              scanExpr(tree.expr);
              markDead();
          }
  
          public void visitApply(JCMethodInvocation tree) {
+             Name name = TreeInfo.name(tree.meth);
+             // let's process early initializers
+             if (name == names._super) {
+                 forEachInitializer(classDef, false, true, def -> {
+                     scan(def);
+                     clearPendingExits(false);
+                 });
+             }
              scanExpr(tree.meth);
              scanExprs(tree.args);
  
              // Handle superclass constructor invocations
              if (isConstructor) {
  
                  // If super(): at this point all initialization blocks will execute
! 
                  if (name == names._super) {
                      forEachInitializer(classDef, false, def -> {
                          scan(def);
                          clearPendingExits(false);
                      });
< prev index next >