< prev index next >

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

Print this page
@@ -303,10 +303,21 @@
                  log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
              } else {
                  log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
              }
          }
+ 
+         if (!env.info.ctorPrologue &&
+                 v.owner.isValueClass() &&
+                 !env.info.instanceInitializerBlock && // it is OK instance initializer blocks will go after super() anyways
+                 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.

@@ -1187,11 +1198,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

@@ -1329,11 +1344,12 @@
          for (Symbol s : syms.objectType.tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
              if (s.type.getParameterTypes().isEmpty()) {
                  return true;
              }
          }
-         return false;
+         // isValueObject is not included in Object yet so we need a work around
+         return name == names.isValueObject;
      }
  
      Fragment canInferLocalVarType(JCVariableDecl tree) {
          LocalInitScanner lis = new LocalInitScanner();
          lis.scan(tree.init);

@@ -1413,11 +1429,15 @@
                      env.info.scope.owner.flags() & STRICTFP, names.empty, null,
                      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);
  

@@ -1908,11 +1928,11 @@
          }
          return null;
      }
  
      public void visitSynchronized(JCSynchronized tree) {
-         chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
+         chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
          if (env.info.lint.isEnabled(LintCategory.SYNCHRONIZATION) && isValueBased(tree.lock.type)) {
              log.warning(LintCategory.SYNCHRONIZATION, tree.pos(), Warnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
          }
          attribStat(tree.body, env);
          result = null;

@@ -4361,10 +4381,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) {

@@ -5460,11 +5481,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()) {

@@ -5498,10 +5519,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);
< prev index next >