< prev index next >

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

Print this page
@@ -215,11 +215,11 @@
          if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0)
              m.flags_field |= Flags.VARARGS;
  
          localEnv.info.scope.leave();
          if (chk.checkUnique(tree.pos(), m, enclScope)) {
-         enclScope.enter(m);
+             enclScope.enter(m);
          }
  
          annotate.annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
          // Visit the signature of the method. Note that
          // TypeAnnotate doesn't descend into the body.

@@ -227,10 +227,25 @@
  
          if (tree.defaultValue != null) {
              m.defaultValue = annotate.unfinishedDefaultValue(); // set it to temporary sentinel for now
              annotate.annotateDefaultValueLater(tree.defaultValue, localEnv, m, tree.pos());
          }
+ 
+         if (m.isConstructor() && m.type.getParameterTypes().size() == 0) {
+             int statsSize = tree.body.stats.size();
+             if (statsSize == 0) {
+                 m.flags_field |= EMPTYNOARGCONSTR;
+             } else if (statsSize == 1 && TreeInfo.isSuperCall(tree.body.stats.head)) {
+                 JCExpressionStatement exec = (JCExpressionStatement) tree.body.stats.head;
+                 JCMethodInvocation meth = (JCMethodInvocation)exec.expr;
+                 if (meth.args.size() == 0) {
+                     // Deem a constructor "empty" even if it contains a 'super' call,
+                     // as long as it has no argument expressions (to respect common coding style).
+                     m.flags_field |= EMPTYNOARGCONSTR;
+                 }
+             }
+         }
      }
  
      /** Create a fresh environment for method bodies.
       *  @param tree     The method definition.
       *  @param env      The environment current outside of the method definition.

@@ -247,10 +262,16 @@
          if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++;
          localEnv.info.yieldResult = null;
          return localEnv;
      }
  
+     @Override
+     public void visitBlock(JCBlock tree) {
+         if ((tree.flags & STATIC) == 0 && tree.stats.size() > 0)
+             env.info.scope.owner.flags_field |= HASINITBLOCK;
+     }
+ 
      public void visitVarDef(JCVariableDecl tree) {
          Env<AttrContext> localEnv = env;
          if ((tree.mods.flags & STATIC) != 0 ||
              (env.info.scope.owner.flags() & INTERFACE) != 0) {
              localEnv = env.dup(tree, env.info.dup());

@@ -285,13 +306,16 @@
                  ? env.info.scope.owner.kind == MTH ? Type.noType : syms.errType
                  : tree.vartype.type;
          VarSymbol v = new VarSymbol(0, tree.name, vartype, enclScope.owner);
          v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
          tree.sym = v;
+         /* Don't want constant propagation/folding for instance fields of primitive classes,
+            as these can undergo updates via copy on write.
+         */
          if (tree.init != null) {
              v.flags_field |= HASINIT;
-             if ((v.flags_field & FINAL) != 0 &&
+             if ((v.flags_field & FINAL) != 0 && ((v.flags_field & STATIC) != 0 || !v.owner.isValueClass()) &&
                  needsLazyConstValue(tree.init)) {
                  Env<AttrContext> initEnv = getInitEnv(tree, env);
                  initEnv.info.enclVar = v;
                  v.setLazyConstValue(initEnv(tree, initEnv), attr, tree);
              }
< prev index next >