< prev index next >

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

Print this page
@@ -323,10 +323,20 @@
              if ((v.flags() & HASINIT) != 0) {
                  log.error(pos, Errors.CantAssignInitializedBeforeCtorCalled(v));
                  return;
              }
          }
+ 
+         if (!env.info.ctorPrologue &&
+                 v.owner.isValueClass() &&
+                 v.owner.kind == TYP &&
+                 v.owner == env.enclClass.sym &&
+                 (v.flags() & STATIC) == 0 &&
+                 (base == null ||
+                         TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))) {
+             log.error(pos, Errors.CantRefAfterCtorCalled(v));
+         }
      }
  
      /** Does tree represent a static reference to an identifier?
       *  It is assumed that tree is either a SELECT or an IDENT.
       *  We have to weed out selects from non-type names here.

@@ -1200,11 +1210,15 @@
                  // or we are compiling class java.lang.Object.
                  if (isConstructor && owner.type != syms.objectType) {
                      if (!TreeInfo.hasAnyConstructorCall(tree)) {
                          JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
                                  make.Ident(names._super), make.Idents(List.nil())));
-                         tree.body.stats = tree.body.stats.prepend(supCall);
+                         if (owner.isValueClass()) {
+                             tree.body.stats = tree.body.stats.append(supCall);
+                         } else {
+                             tree.body.stats = tree.body.stats.prepend(supCall);
+                         }
                      } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
                              (tree.mods.flags & GENERATEDCONSTR) == 0 &&
                              TreeInfo.hasConstructorCall(tree, names._super)) {
                          // enum constructors are not allowed to call super
                          // directly, so make sure there aren't any super calls

@@ -1314,14 +1328,23 @@
                      initEnv.info.lint = lint;
                      // In order to catch self-references, we set the variable's
                      // declaration position to maximal possible value, effectively
                      // marking the variable as undefined.
                      initEnv.info.enclVar = v;
-                     attribExpr(tree.init, initEnv, v.type);
-                     if (tree.isImplicitlyTyped()) {
-                         //fixup local variable type
-                         v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
+                     boolean previousCtorPrologue = initEnv.info.ctorPrologue;
+                     try {
+                         if (v.owner.kind == TYP && v.owner.isValueClass() && !v.isStatic()) {
+                             // strict instance initializer in a value class
+                             initEnv.info.ctorPrologue = true;
+                         }
+                         attribExpr(tree.init, initEnv, v.type);
+                         if (tree.isImplicitlyTyped()) {
+                             //fixup local variable type
+                             v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
+                         }
+                     } finally {
+                         initEnv.info.ctorPrologue = previousCtorPrologue;
                      }
                  }
                  if (tree.isImplicitlyTyped()) {
                      setSyntheticVariableType(tree, v.type);
                  }

@@ -1426,11 +1449,15 @@
                      env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
                      env.info.scope.owner);
              final Env<AttrContext> localEnv =
                  env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
  
-             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
+             if ((tree.flags & STATIC) != 0) {
+                 localEnv.info.staticLevel++;
+             } else {
+                 localEnv.info.instanceInitializerBlock = true;
+             }
              // Attribute all type annotations in the block
              annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
              annotate.flush();
              attribStats(tree.stats, localEnv);
  

@@ -1935,23 +1962,24 @@
          }
          return null;
      }
  
      public void visitSynchronized(JCSynchronized tree) {
-         chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
-         if (env.info.lint.isEnabled(LintCategory.SYNCHRONIZATION) && isValueBased(tree.lock.type)) {
+         boolean identityType = chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
+         if (env.info.lint.isEnabled(LintCategory.SYNCHRONIZATION) &&
+                 identityType &&
+                 isValueBased(tree.lock.type)) {
              log.warning(LintCategory.SYNCHRONIZATION, tree.pos(), Warnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
          }
          attribStat(tree.body, env);
          result = null;
      }
          // where
          private boolean isValueBased(Type t) {
              return t != null && t.tsym != null && (t.tsym.flags() & VALUE_BASED) != 0;
          }
  
- 
      public void visitTry(JCTry tree) {
          // Create a new local environment with a local
          Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
          try {
              boolean isTryWithResource = tree.resources.nonEmpty();

@@ -4367,10 +4395,11 @@
                  skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
          }
  
          // Attribute the qualifier expression, and determine its symbol (if any).
          Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
+         Assert.check(site == tree.selected.type);
          if (!pkind().contains(KindSelector.TYP_PCK))
              site = capture(site); // Capture field access
  
          // don't allow T.class T[].class, etc
          if (skind == KindSelector.TYP) {

@@ -5462,11 +5491,11 @@
  
                          if (!hasErrorSuper) {
                              log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
                          }
                      }
-                 } else {
+                 } else if ((c.flags_field & Flags.COMPOUND) == 0) {
                      if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
                          log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
                      }
  
                      if (!c.type.isCompound()) {

@@ -5500,10 +5529,15 @@
  
                  if (rs.isSerializable(c.type)) {
                      env.info.isSerializable = true;
                  }
  
+                 if (c.isValueClass()) {
+                     Assert.check(env.tree.hasTag(CLASSDEF));
+                     chk.checkConstraintsOfValueClass((JCClassDecl) env.tree, c);
+                 }
+ 
                  attribClassBody(env, c);
  
                  chk.checkDeprecatedAnnotation(env.tree.pos(), c);
                  chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
                  chk.checkFunctionalInterface((JCClassDecl) env.tree, c);

@@ -5642,11 +5676,11 @@
          // Check for proper use of serialVersionUID and other
          // serialization-related fields and methods
          if (env.info.lint.isEnabled(LintCategory.SERIAL)
                  && rs.isSerializable(c.type)
                  && !c.isAnonymous()) {
-             chk.checkSerialStructure(tree, c);
+             chk.checkSerialStructure(env, tree, c);
          }
          // Correctly organize the positions of the type annotations
          typeAnnotations.organizeTypeAnnotationsBodies(tree);
  
          // Check type annotations applicability rules
< prev index next >