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

Print this page

        

@@ -37,10 +37,11 @@
 import com.sun.source.util.SimpleTreeVisitor;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.TypeAnnotationPosition.*;
 import com.sun.tools.javac.comp.Check.CheckContext;
 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
 import com.sun.tools.javac.comp.Infer.InferenceContext;
 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.jvm.*;

@@ -92,10 +93,13 @@
     final JCDiagnostic.Factory diags;
     final Annotate annotate;
     final TypeAnnotations typeAnnotations;
     final DeferredLintHandler deferredLintHandler;
 
+    /** The creator that will be used for any varDef's we visit. */
+    Annotate.PositionCreator creator;
+
     public static Attr instance(Context context) {
         Attr instance = context.get(attrKey);
         if (instance == null)
             instance = new Attr(context);
         return instance;

@@ -120,10 +124,12 @@
         types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         annotate = Annotate.instance(context);
         typeAnnotations = TypeAnnotations.instance(context);
         deferredLintHandler = DeferredLintHandler.instance(context);
+        creator = null;
+        speculative = false;
 
         Options options = Options.instance(context);
 
         Source source = Source.instance(context);
         allowGenerics = source.allowGenerics();

@@ -229,10 +235,15 @@
     /**
      * Switch: name of source level; used for error reporting.
      */
     String sourceName;
 
+    /**
+     * Whether or not this is speculative attribution
+     */
+    boolean speculative;
+
     /** Check kind and type of given tree against protokind and prototype.
      *  If check succeeds, store type in tree and return it.
      *  If check fails, store errType in tree and return it.
      *  No checks are performed if the prototype is a method type.
      *  It is not necessary in this case since we know that kind and type

@@ -423,23 +434,29 @@
 
     public Type coerce(Type etype, Type ttype) {
         return cfolder.coerce(etype, ttype);
     }
 
-    public Type attribType(JCTree node, TypeSymbol sym) {
+    public Type attribType(JCTree node, TypeSymbol sym,
+                           JCLambda currentLambda, boolean speculative) {
         Env<AttrContext> env = enter.typeEnvs.get(sym);
         Env<AttrContext> localEnv = env.dup(node, env.info.dup());
-        return attribTree(node, localEnv, unknownTypeInfo);
+        return attribTree(node, localEnv, currentLambda,
+                          unknownTypeInfo, speculative);
     }
 
-    public Type attribImportQualifier(JCImport tree, Env<AttrContext> env) {
+    public Type attribType(JCTree node, TypeSymbol sym) {
+        return attribType(node, sym, currentLambda, speculative);
+    }
+
+    public Type attribImportQualifier(JCImport tree, Env<AttrContext> env,
+                                      JCLambda currLambda, boolean speculative) {
         // Attribute qualifying package or class.
         JCFieldAccess s = (JCFieldAccess)tree.qualid;
-        return attribTree(s.selected,
-                       env,
+        return attribTree(s.selected, env, currentLambda,
                        new ResultInfo(tree.staticImport ? TYP : (TYP | PCK),
-                       Type.noType));
+                                         Type.noType), speculative);
     }
 
     public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
         breakTree = tree;
         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);

@@ -569,10 +586,12 @@
 
     /** Visitor argument: the current environment.
      */
     Env<AttrContext> env;
 
+    JCLambda currentLambda;
+
     /** Visitor argument: the currently expected attribution result.
      */
     ResultInfo resultInfo;
 
     /** Visitor result: the computed type.

@@ -584,16 +603,22 @@
      *
      *  @param tree    The tree to be visited.
      *  @param env     The environment visitor argument.
      *  @param resultInfo   The result info visitor argument.
      */
-    Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
+    Type attribTree(JCTree tree, Env<AttrContext> env,
+                    JCLambda lambda, ResultInfo resultInfo,
+                    boolean speculative) {
         Env<AttrContext> prevEnv = this.env;
         ResultInfo prevResult = this.resultInfo;
+        JCLambda prevLambda = this.currentLambda;
+        boolean prevSpeculative = this.speculative;
         try {
             this.env = env;
             this.resultInfo = resultInfo;
+            this.currentLambda = lambda;
+            this.speculative = speculative;
             tree.accept(this);
             if (tree == breakTree &&
                     resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
                 throw new BreakAttr(copyEnv(env));
             }

@@ -602,11 +627,22 @@
             tree.type = syms.errType;
             return chk.completionError(tree.pos(), ex);
         } finally {
             this.env = prevEnv;
             this.resultInfo = prevResult;
+            this.currentLambda = prevLambda;
+            this.speculative = prevSpeculative;
+        }
         }
+
+    Type attribTree(JCTree tree, Env<AttrContext> env,
+                    JCLambda currentLambda, ResultInfo resultInfo) {
+        return attribTree(tree, env, currentLambda, resultInfo, speculative);
+    }
+
+    Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
+        return attribTree(tree, env, currentLambda, resultInfo, speculative);
     }
 
     Env<AttrContext> copyEnv(Env<AttrContext> env) {
         Env<AttrContext> newEnv =
                 env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));

@@ -631,52 +667,95 @@
         return newScope;
     }
 
     /** Derived visitor method: attribute an expression tree.
      */
+    public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt,
+                           JCLambda currentLambda, boolean speculative) {
+        return attribTree(tree, env, currentLambda,
+                          new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType),
+                          speculative);
+    }
+
     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
-        return attribTree(tree, env, new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType));
+        return attribExpr(tree, env, pt, currentLambda, speculative);
     }
 
     /** Derived visitor method: attribute an expression tree with
      *  no constraints on the computed type.
      */
     public Type attribExpr(JCTree tree, Env<AttrContext> env) {
-        return attribTree(tree, env, unknownExprInfo);
+        return attribTree(tree, env, currentLambda,
+                          unknownExprInfo, speculative);
     }
 
     /** Derived visitor method: attribute a type tree.
      */
+
     public Type attribType(JCTree tree, Env<AttrContext> env) {
-        Type result = attribType(tree, env, Type.noType);
+        Type result = attribType(tree, env, Type.noType,
+                                 currentLambda, speculative);
+        return result;
+    }
+
+    public Type attribType(JCTree tree, Env<AttrContext> env,
+                           JCLambda currentLambda, boolean speculative) {
+        Type result = attribType(tree, env, Type.noType,
+                                 currentLambda, speculative);
         return result;
     }
 
     /** Derived visitor method: attribute a type tree.
      */
-    Type attribType(JCTree tree, Env<AttrContext> env, Type pt) {
-        Type result = attribTree(tree, env, new ResultInfo(TYP, pt));
+    Type attribType(JCTree tree, Env<AttrContext> env, Type pt,
+                    JCLambda currentLambda, boolean speculative) {
+        Type result = attribTree(tree, env, currentLambda,
+                                 new ResultInfo(TYP, pt), speculative);
         return result;
     }
 
     /** Derived visitor method: attribute a statement or definition tree.
      */
+
     public Type attribStat(JCTree tree, Env<AttrContext> env) {
-        return attribTree(tree, env, statInfo);
+        return attribTree(tree, env, currentLambda, statInfo, speculative);
+    }
+
+    public Type attribStat(JCTree tree, JCLambda lambda,
+                           Env<AttrContext> env) {
+        return attribTree(tree, env, lambda, statInfo, speculative);
+    }
+
+    public Type attribStat(JCTree tree, JCLambda lambda,
+                           Env<AttrContext> env, boolean speculative) {
+        return attribTree(tree, env, lambda, statInfo, speculative);
     }
 
     /** Attribute a list of expressions, returning a list of types.
      */
     List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) {
         ListBuffer<Type> ts = new ListBuffer<>();
         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
-            ts.append(attribExpr(l.head, env, pt));
+            ts.append(attribExpr(l.head, env, pt, currentLambda, speculative));
         return ts.toList();
     }
 
     /** Attribute a list of statements, returning nothing.
      */
+    <T extends JCTree> void attribStats(List<T> trees, JCLambda lambda,
+                                        Env<AttrContext> env,
+                                        boolean speculative) {
+        for (List<T> l = trees; l.nonEmpty(); l = l.tail)
+            attribStat(l.head, lambda, env, speculative);
+    }
+
+    <T extends JCTree> void attribStats(List<T> trees, JCLambda lambda,
+                                        Env<AttrContext> env) {
+        for (List<T> l = trees; l.nonEmpty(); l = l.tail)
+            attribStat(l.head, lambda, env);
+    }
+
     <T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) {
         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
             attribStat(l.head, env);
     }
 

@@ -684,15 +763,16 @@
      */
     int attribArgs(List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) {
         int kind = VAL;
         for (JCExpression arg : trees) {
             Type argtype;
-            if (allowPoly && deferredAttr.isDeferred(env, arg)) {
-                argtype = deferredAttr.new DeferredType(arg, env);
+            if (allowPoly && deferredAttr.isDeferred(env, arg, currentLambda)) {
+                argtype = deferredAttr.new DeferredType(arg, env, currentLambda,
+                                                        annotate.noCreator);
                 kind |= POLY;
             } else {
-                argtype = chk.checkNonVoid(arg, attribTree(arg, env, unknownAnyPolyInfo));
+                argtype = chk.checkNonVoid(arg, attribTree(arg, env, currentLambda, unknownAnyPolyInfo, speculative));
             }
             argtypes.append(argtype);
         }
         return kind;
     }

@@ -719,19 +799,23 @@
      * Attribute type variables (of generic classes or methods).
      * Compound types are attributed later in attribBounds.
      * @param typarams the type variables to enter
      * @param env      the current environment
      */
-    void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env) {
+    void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env,
+                             JCLambda currentLambda, boolean speculative) {
         for (JCTypeParameter tvar : typarams) {
             TypeVar a = (TypeVar)tvar.type;
             a.tsym.flags_field |= UNATTRIBUTED;
             a.bound = Type.noType;
             if (!tvar.bounds.isEmpty()) {
-                List<Type> bounds = List.of(attribType(tvar.bounds.head, env));
+                List<Type> bounds =
+                    List.of(attribType(tvar.bounds.head, env,
+                                       currentLambda, speculative));
                 for (JCExpression bound : tvar.bounds.tail)
-                    bounds = bounds.prepend(attribType(bound, env));
+                    bounds = bounds.prepend(attribType(bound, env, currentLambda,
+                                                       speculative));
                 types.setBounds(a, bounds.reverse());
             } else {
                 // if no bounds are given, assume a single bound of
                 // java.lang.Object.
                 types.setBounds(a, List.of(syms.objectType));

@@ -745,33 +829,43 @@
 
     /**
      * Attribute the type references in a list of annotations.
      */
     void attribAnnotationTypes(List<JCAnnotation> annotations,
-                               Env<AttrContext> env) {
+                               Env<AttrContext> env,
+                               JCLambda currentLambda,
+                               boolean speculative) {
         for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
             JCAnnotation a = al.head;
-            attribType(a.annotationType, env);
+            attribType(a.annotationType, env, currentLambda, speculative);
+        }
         }
+
+    void attribAnnotationTypes(List<JCAnnotation> annotations,
+                               Env<AttrContext> env) {
+        attribAnnotationTypes(annotations, env, currentLambda, speculative);
     }
 
     /**
      * Attribute a "lazy constant value".
      *  @param env         The env for the const value
      *  @param initializer The initializer for the const value
      *  @param type        The expected type, or null
      *  @see VarSymbol#setLazyConstValue
      */
-    public Object attribLazyConstantValue(Env<AttrContext> env,
+    public Object attribLazyConstantValue(final Env<AttrContext> env,
                                       JCVariableDecl variable,
-                                      Type type) {
+                                          Type type,
+                                          JCLambda currentLambda,
+                                          boolean speculative) {
 
         DiagnosticPosition prevLintPos
                 = deferredLintHandler.setPos(variable.pos());
 
         try {
-            Type itype = attribExpr(variable.init, env, type);
+            Type itype = attribExpr(variable.init, env, type,
+                                    currentLambda, speculative);
             if (itype.constValue() != null) {
                 return coerce(itype, type).constValue();
             } else {
                 return null;
             }

@@ -790,14 +884,16 @@
      */
     Type attribBase(JCTree tree,
                     Env<AttrContext> env,
                     boolean classExpected,
                     boolean interfaceExpected,
-                    boolean checkExtensible) {
+                    boolean checkExtensible,
+                    JCLambda currentLambda,
+                    boolean speculative) {
         Type t = tree.type != null ?
             tree.type :
-            attribType(tree, env);
+            attribType(tree, env, currentLambda, speculative);
         return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
     }
     Type checkBase(Type t,
                    JCTree tree,
                    Env<AttrContext> env,

@@ -878,10 +974,11 @@
                 ((JCNewClass) env.tree).encl == null)
             {
                 c.flags_field |= NOOUTERTHIS;
             }
             attribClass(tree.pos(), c);
+
             result = tree.type = c.type;
         }
     }
 
     public void visitMethodDef(JCMethodDecl tree) {

@@ -1015,14 +1112,10 @@
                                   "call.to.super.not.allowed.in.enum.ctor",
                                   env.enclClass.sym);
                     }
                 }
 
-                // Attribute all type annotations in the body
-                annotate.annotateTypeLater(tree.body, localEnv, m, null);
-                annotate.flush();
-
                 // Attribute method body.
                 attribStat(tree.body, localEnv);
             }
 
             localEnv.info.scope.leave();

@@ -1032,25 +1125,29 @@
             chk.setLint(prevLint);
             chk.setMethod(prevMethod);
         }
     }
 
-    public void visitVarDef(JCVariableDecl tree) {
+    public void visitVarDef(final JCVariableDecl tree) {
         // Local variables have not been entered yet, so we need to do it now:
         if (env.info.scope.owner.kind == MTH) {
             if (tree.sym != null) {
                 // parameters have already been entered
                 env.info.scope.enter(tree.sym);
             } else {
-                memberEnter.memberEnter(tree, env);
-                annotate.flush();
+                Annotate.PositionCreator oldcreator = creator;
+
+                if (creator == null) {
+                    creator = annotate.localVarCreator(tree.pos);
             }
-        } else {
-            if (tree.init != null) {
-                // Field initializer expression need to be entered.
-                annotate.annotateTypeLater(tree.init, env, tree.sym, tree.pos());
+
+                annotate.enterStart();
+                memberEnter.memberEnter(tree, env, creator,
+                                        currentLambda, speculative);
+                annotate.enterDone();
                 annotate.flush();
+                creator = oldcreator;
             }
         }
 
         VarSymbol v = tree.sym;
         Lint lint = env.info.lint.augment(v);

@@ -1097,21 +1194,19 @@
     public void visitBlock(JCBlock tree) {
         if (env.info.scope.owner.kind == TYP) {
             // Block is a static or instance initializer;
             // let the owner of the environment be a freshly
             // created BLOCK-method.
-            Env<AttrContext> localEnv =
+            final Env<AttrContext> localEnv =
                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
             localEnv.info.scope.owner =
                 new MethodSymbol(tree.flags | BLOCK |
                     env.info.scope.owner.flags() & STRICTFP, names.empty, null,
                     env.info.scope.owner);
-            if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
 
-            // Attribute all type annotations in the block
-            annotate.annotateTypeLater(tree, localEnv, localEnv.info.scope.owner, null);
-            annotate.flush();
+            if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
+            attribStats(tree.stats, localEnv);
 
             {
                 // Store init and clinit type annotations with the ClassSymbol
                 // to allow output in Gen.normalizeDefs.
                 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;

@@ -1120,12 +1215,10 @@
                     cs.appendClassInitTypeAttributes(tas);
                 } else {
                     cs.appendInitTypeAttributes(tas);
                 }
             }
-
-            attribStats(tree.stats, localEnv);
         } else {
             // Create a new local environment with a local scope.
             Env<AttrContext> localEnv =
                 env.dup(tree, env.info.dup(env.info.scope.dup()));
             try {

@@ -1344,11 +1437,14 @@
                             chk.basicHandler.report(pos, diags.fragment("try.not.applicable.to.type", details));
                         }
                     };
                     ResultInfo twrResult = new ResultInfo(VAL, syms.autoCloseableType, twrContext);
                     if (resource.hasTag(VARDEF)) {
+                        Annotate.PositionCreator oldcreator = creator;
+                        creator = annotate.resourceVarCreator(tree.pos);
                         attribStat(resource, tryEnv);
+                        creator = oldcreator;
                         twrResult.check(resource, resource.type);
 
                         //check that resource type cannot throw InterruptedException
                         checkAutoCloseable(resource.pos(), localEnv, resource.type);
 

@@ -1369,11 +1465,14 @@
             for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
                 JCCatch c = l.head;
                 Env<AttrContext> catchEnv =
                     localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
                 try {
+                    Annotate.PositionCreator oldcreator = creator;
+                    creator = annotate.exceptionParamCreator(tree.pos);
                     Type ctype = attribStat(c.param, catchEnv);
+                    creator = oldcreator;
                     if (TreeInfo.isMultiCatch(c)) {
                         //multi-catch parameter is implicitly marked as final
                         c.param.sym.flags_field |= FINAL | UNION;
                     }
                     if (c.param.sym.kind == Kinds.VAR) {

@@ -1475,21 +1574,26 @@
                     JCConditional condTree = (JCConditional)tree;
                     return isBooleanOrNumeric(env, condTree.truepart) &&
                             isBooleanOrNumeric(env, condTree.falsepart);
                 case APPLY:
                     JCMethodInvocation speculativeMethodTree =
-                            (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
+                        (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo,
+                                                                           currentLambda, annotate.noCreator);
                     Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
                     return types.unboxedTypeOrType(owntype).isPrimitive();
                 case NEWCLASS:
                     JCExpression className =
                             removeClassParams.translate(((JCNewClass)tree).clazz);
                     JCExpression speculativeNewClassTree =
-                            (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
+                        (JCExpression)deferredAttr.attribSpeculative(className,
+                                                                     env,
+                                                                     unknownTypeInfo,
+                                                                     currentLambda,
+                                                                     annotate.newObjCreator(tree.pos));
                     return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
                 default:
-                    Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
+                    Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo, currentLambda, annotate.noCreator).type;
                     speculativeType = types.unboxedTypeOrType(speculativeType);
                     return speculativeType.isPrimitive();
             }
         }
         //where

@@ -1748,11 +1852,31 @@
                 localEnv.info.isSelfCall = true;
 
                 // Attribute arguments, yielding list of argument types.
                 attribArgs(tree.args, localEnv, argtypesBuf);
                 argtypes = argtypesBuf.toList();
-                typeargtypes = attribTypes(tree.typeargs, localEnv);
+
+                // Attribute and annotate the type arguments
+                ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
+                int i = 0;
+
+                for (List<JCExpression> l = tree.typeargs;
+                     l.nonEmpty(); l = l.tail, i++) {
+                    final JCExpression arg = l.head;
+                    annotate.enterStart();
+                    typeargtypesbuf.append(attribType(arg, localEnv));
+                    annotate.annotateTypeLater(arg, localEnv,
+                                               localEnv.info.scope.owner,
+                                               tree.pos(), currentLambda,
+                                               annotate.constructorInvokeTypeArgCreator(i, tree.pos),
+                                               speculative);
+                    annotate.enterDone();
+                    annotate.flush();
+                }
+
+                typeargtypes =
+                    chk.checkRefTypes(tree.typeargs, typeargtypesbuf.toList());
 
                 // Variable `site' points to the class in which the called
                 // constructor is defined.
                 Type site = env.enclClass.sym.type;
                 if (methName == names._super) {

@@ -1821,11 +1945,30 @@
         } else {
             // Otherwise, we are seeing a regular method call.
             // Attribute the arguments, yielding list of argument types, ...
             int kind = attribArgs(tree.args, localEnv, argtypesBuf);
             argtypes = argtypesBuf.toList();
-            typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
+
+            // Attribute and annotate the type arguments
+            ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
+            int i = 0;
+
+            for (List<JCExpression> l = tree.typeargs;
+                 l.nonEmpty(); l = l.tail, i++) {
+                final JCExpression arg = l.head;
+                annotate.enterStart();
+                typeargtypesbuf.append(attribType(arg, localEnv));
+                annotate.annotateTypeLater(arg, localEnv,
+                                           localEnv.info.scope.owner,
+                                           tree.pos(), currentLambda,
+                                           annotate.methodInvokeTypeArgCreator(i, tree.pos),
+                                           speculative);
+                annotate.flush();
+                annotate.enterDone();
+            }
+
+            typeargtypes = typeargtypesbuf.toList();
 
             // ... and attribute the method using as a prototype a methodtype
             // whose formal argument types is exactly the list of actual
             // arguments (this will also set the method symbol).
             Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);

@@ -1846,10 +1989,11 @@
 
             // Check that value of resulting type is admissible in the
             // current context.  Also, capture the return type
             result = check(tree, capture(restype), VAL, resultInfo);
         }
+
         chk.validate(tree.typeargs, localEnv);
     }
     //where
         Type adjustMethodReturnType(Type qualifierType, Name methodName, List<Type> argtypes, Type restype) {
             if (allowCovariantReturns &&

@@ -1921,18 +2065,16 @@
             clazzid = ((JCTypeApply) clazz).clazz;
             if (clazzid.hasTag(ANNOTATED_TYPE)) {
                 annoclazzid = (JCAnnotatedType) clazzid;
                 clazzid = annoclazzid.underlyingType;
             }
-        } else {
-            if (clazz.hasTag(ANNOTATED_TYPE)) {
+        } else if (clazz.hasTag(ANNOTATED_TYPE)) {
                 annoclazzid = (JCAnnotatedType) clazz;
                 clazzid = annoclazzid.underlyingType;
             } else {
                 clazzid = clazz;
             }
-        }
 
         JCExpression clazzid1 = clazzid; // The same in fully qualified form
 
         if (tree.encl != null) {
             // We are seeing a qualified new, of the form

@@ -1950,15 +2092,16 @@
             clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
                                                  ((JCIdent) clazzid).name);
 
             EndPosTable endPosTable = this.env.toplevel.endPositions;
             endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable));
-            if (clazz.hasTag(ANNOTATED_TYPE)) {
-                JCAnnotatedType annoType = (JCAnnotatedType) clazz;
-                List<JCAnnotation> annos = annoType.annotations;
+            if (annoclazzid != null) {
+                JCAnnotatedType annoType = annoclazzid;
+                List<JCAnnotation> annos = annoclazzid.annotations;
+
+                if (clazz.hasTag(TYPEAPPLY)) {
 
-                if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
                     clazzid1 = make.at(tree.pos).
                         TypeApply(clazzid1,
                                   ((JCTypeApply) clazz).arguments);
                 }
 

@@ -1971,16 +2114,23 @@
             }
 
             clazz = clazzid1;
         }
 
+        annotate.enterStart();
         // Attribute clazz expression and store
         // symbol + type back into the attributed tree.
         Type clazztype = TreeInfo.isEnumInit(env.tree) ?
             attribIdentAsEnumType(env, (JCIdent)clazz) :
             attribType(clazz, env);
 
+        annotate.annotateTypeLater(clazz, env, env.info.scope.owner,
+                                   tree.pos(), currentLambda,
+                                   annotate.newObjCreator(tree.pos),
+                                   speculative);
+        annotate.enterDone();
+        annotate.flush();
         clazztype = chk.checkDiamond(tree, clazztype);
         chk.validate(clazz, localEnv);
         if (tree.encl != null) {
             // We have to work in this case to store
             // symbol + type back into the attributed tree.

@@ -2005,11 +2155,31 @@
 
         // Attribute constructor arguments.
         ListBuffer<Type> argtypesBuf = new ListBuffer<>();
         int pkind = attribArgs(tree.args, localEnv, argtypesBuf);
         List<Type> argtypes = argtypesBuf.toList();
-        List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
+        List<Type> typeargtypes;
+
+        // Attribute and annotate the type arguments
+        ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
+        int i = 0;
+
+        for (List<JCExpression> l = tree.typeargs;
+             l.nonEmpty(); l = l.tail, i++) {
+            final JCExpression arg = l.head;
+            annotate.enterStart();
+            typeargtypesbuf.append(attribType(arg, localEnv));
+            annotate.annotateTypeLater(arg, localEnv,
+                                       localEnv.info.scope.owner,
+                                       tree.pos(), currentLambda,
+                                       annotate.constructorInvokeTypeArgCreator(i, tree.pos),
+                                       speculative);
+            annotate.flush();
+            annotate.enterDone();
+        }
+        typeargtypes =
+            chk.checkRefTypes(tree.typeargs, typeargtypesbuf.toList());
 
         // If we have made no mistakes in the class type...
         if (clazztype.hasTag(CLASS)) {
             // Enums may not be instantiated except implicitly
             if (allowEnums &&

@@ -2188,11 +2358,14 @@
             try {
                 //create a 'fake' diamond AST node by removing type-argument trees
                 ta.arguments = List.nil();
                 ResultInfo findDiamondResult = new ResultInfo(VAL,
                         resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
-                Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
+                Type inferred = deferredAttr.attribSpeculative(tree, env,
+                                                               findDiamondResult,
+                                                               currentLambda,
+                                                               annotate.newObjCreator(tree.pos)).type;
                 Type polyPt = allowPoly ?
                         syms.objectType :
                         clazztype;
                 if (!inferred.isErroneous() &&
                     (allowPoly && pt() == Infer.anyPoly ?

@@ -2250,12 +2423,23 @@
 
     public void visitNewArray(JCNewArray tree) {
         Type owntype = types.createErrorType(tree.type);
         Env<AttrContext> localEnv = env.dup(tree);
         Type elemtype;
+
+        for(List<JCAnnotation> dim : tree.dimAnnotations) {
+            this.attribAnnotationTypes(dim, localEnv);
+        }
+
         if (tree.elemtype != null) {
+            annotate.enterStart();
             elemtype = attribType(tree.elemtype, localEnv);
+            annotate.annotateTypeLater(tree, env, env.info.scope.owner, tree.pos(),
+                                       currentLambda, annotate.newObjCreator(tree.pos),
+                                       speculative);
+            annotate.enterDone();
+            annotate.flush();
             chk.validate(tree.elemtype, localEnv);
             owntype = elemtype;
             for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
                 attribExpr(l.head, localEnv, syms.intType);
                 owntype = new ArrayType(owntype, syms.arrayClass,

@@ -2272,10 +2456,11 @@
                               pt());
                 }
                 elemtype = types.createErrorType(pt());
             }
         }
+
         if (tree.elems != null) {
             attribExprs(tree.elems, localEnv, elemtype);
             owntype = new ArrayType(elemtype, syms.arrayClass,
                                     Type.noAnnotations);
         }

@@ -2310,11 +2495,18 @@
                 localEnv.info.isSerializable = true;
             }
             List<Type> explicitParamTypes = null;
             if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
                 //attribute lambda parameters
-                attribStats(that.params, localEnv);
+                int i = 0;
+                Annotate.PositionCreator oldcreator = creator;
+                for (List<JCVariableDecl> l = that.params;
+                     l.nonEmpty(); l = l.tail, i++) {
+                    creator = annotate.paramCreator(i);
+                    attribStat(l.head, that, localEnv);
+                }
+                creator = oldcreator;
                 explicitParamTypes = TreeInfo.types(that.params);
             }
 
             Type lambdaType;
             if (pt() != Type.recoveryType) {

@@ -2366,11 +2558,11 @@
                             actuals.tail;
                     params = params.tail;
                 }
 
                 //attribute lambda parameters
-                attribStats(that.params, localEnv);
+                attribStats(that.params, that, localEnv);
 
                 if (arityMismatch) {
                     resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
                         result = that.type = types.createErrorType(currentTarget);
                         return;

@@ -2391,14 +2583,14 @@
                 recoveryInfo :
                 new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
             localEnv.info.returnResult = bodyResultInfo;
 
             if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
-                attribTree(that.getBody(), localEnv, bodyResultInfo);
+                attribTree(that.getBody(), localEnv, that, bodyResultInfo);
             } else {
                 JCBlock body = (JCBlock)that.body;
-                attribStats(body.stats, localEnv);
+                attribStats(body.stats, that, localEnv);
             }
 
             result = check(that, currentTarget, VAL, resultInfo);
 
             boolean isSpeculativeRound =

@@ -2666,23 +2858,33 @@
             return lambdaEnv;
         }
 
     @Override
     public void visitReference(final JCMemberReference that) {
+        final boolean isConstructor = that.getName() == names.init;
+
         if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
             if (pt().hasTag(NONE)) {
                 //method reference only allowed in assignment or method invocation/cast context
                 log.error(that.pos(), "unexpected.mref");
             }
             result = that.type = types.createErrorType(pt());
             return;
         }
         final Env<AttrContext> localEnv = env.dup(that);
         try {
+            annotate.enterStart();
             //attribute member reference qualifier - if this is a constructor
             //reference, the expected kind must be a type
             Type exprType = attribTree(that.expr, env, memberReferenceQualifierResult(that));
+            final Annotate.PositionCreator creator =
+                isConstructor ? annotate.constructorRefCreator(that.pos) :
+                annotate.methodRefCreator(that.pos);
+            annotate.annotateTypeLater(that.expr, localEnv, env.info.scope.owner, that.pos(),
+                                       currentLambda, creator, speculative);
+            annotate.enterDone();
+            annotate.flush();
 
             if (that.getMode() == JCMemberReference.ReferenceMode.NEW) {
                 exprType = chk.checkConstructorRefType(that.expr, exprType);
                 if (!exprType.isErroneous() &&
                     exprType.isRaw() &&

@@ -2708,11 +2910,26 @@
             }
 
             //attrib type-arguments
             List<Type> typeargtypes = List.nil();
             if (that.typeargs != null) {
+                annotate.enterStart();
                 typeargtypes = attribTypes(that.typeargs, localEnv);
+
+                // Annotate type arguments
+                int i = 0;
+                for (List<JCExpression> l = that.typeargs;
+                     l.nonEmpty(); l = l.tail, i++) {
+                    final Annotate.PositionCreator typeArgCreator =
+                        isConstructor ? annotate.constructorRefTypeArgCreator(i, that.pos) :
+                        annotate.methodRefTypeArgCreator(i, that.pos);
+                    final JCExpression arg = l.head;
+                    annotate.annotateTypeLater(arg, env, env.info.scope.owner, that.pos(),
+                                               currentLambda, typeArgCreator, speculative);
+                }
+                annotate.flush();
+                annotate.enterDone();
             }
 
             Type desc;
             Type currentTarget = pt();
             boolean isTargetSerializable =

@@ -3081,11 +3298,18 @@
         }
         result = check(tree, owntype, VAL, resultInfo);
     }
 
     public void visitTypeCast(final JCTypeCast tree) {
+        annotate.enterStart();
         Type clazztype = attribType(tree.clazz, env);
+        annotate.annotateTypeLater(tree.clazz, env, env.info.scope.owner,
+                                   tree.pos(), currentLambda,
+                                   annotate.castCreator(tree.pos),
+                                   speculative);
+        annotate.flush();
+        annotate.enterDone();
         chk.validate(tree.clazz, env, false);
         //a fresh environment is required for 292 inference to work properly ---
         //see Infer.instantiatePolymorphicSignatureInstance()
         Env<AttrContext> localEnv = env.dup(tree);
         //should we propagate the target type?

@@ -3114,11 +3338,18 @@
     }
 
     public void visitTypeTest(JCInstanceOf tree) {
         Type exprtype = chk.checkNullOrRefType(
             tree.expr.pos(), attribExpr(tree.expr, env));
+        annotate.enterStart();
         Type clazztype = attribType(tree.clazz, env);
+        annotate.annotateTypeLater(tree.clazz, env, env.info.scope.owner, tree.pos(),
+                                   currentLambda, annotate.instanceOfCreator(tree.pos),
+                                   speculative);
+        annotate.flush();
+        annotate.enterDone();
+
         if (!clazztype.hasTag(TYPEVAR)) {
             clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype);
         }
         if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) {
             log.error(tree.clazz.pos(), "illegal.generic.type.for.instof");

@@ -4074,12 +4305,17 @@
 
     public void visitAnnotation(JCAnnotation tree) {
         Assert.error("should be handled in Annotate");
     }
 
+    /* This needs to be removed or otherwise changed, as it implicitly
+     * relies on the annotated types having previously been visited by
+     * Annotate.TypeAnnotate.
+     */
     public void visitAnnotatedType(JCAnnotatedType tree) {
-        Type underlyingType = attribType(tree.getUnderlyingType(), env);
+        Type underlyingType = attribTree(tree.getUnderlyingType(), env,
+                                         resultInfo);
         this.attribAnnotationTypes(tree.annotations, env);
         annotateType(tree, tree.annotations);
         result = tree.type = underlyingType;
     }
 

@@ -4094,12 +4330,14 @@
             }
             @Override
             public void run() {
                 List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
                 Assert.check(annotations.size() == compounds.size());
+                if (!tree.type.hasTag(TypeTag.PACKAGE)) {
                 tree.type = tree.type.annotatedType(compounds);
                 }
+            }
         });
     }
 
     private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
         if (annotations.isEmpty()) {

@@ -4346,17 +4584,10 @@
             isSerializable(c.type) &&
             (c.flags() & Flags.ENUM) == 0 &&
             checkForSerial(c)) {
             checkSerialVersionUID(tree, c);
         }
-        if (allowTypeAnnos) {
-            // Correctly organize the postions of the type annotations
-            typeAnnotations.organizeTypeAnnotationsBodies(tree);
-
-            // Check type annotations applicability rules
-            validateTypeAnnotations(tree, false);
-        }
     }
         // where
         boolean checkForSerial(ClassSymbol c) {
             if ((c.flags() & ABSTRACT) == 0) {
                 return true;

@@ -4426,10 +4657,15 @@
 
     private Type capture(Type type) {
         return types.capture(type);
     }
 
+    /**************************************
+     *                                    *
+     * This code is considered deprecated *
+     *                                    *
+     **************************************/
     public void validateTypeAnnotations(JCTree tree, boolean sigOnly) {
         tree.accept(new TypeAnnotationsValidator(sigOnly));
     }
     //where
     private final class TypeAnnotationsValidator extends TreeScanner {

@@ -4476,11 +4712,10 @@
                 scan(tree.defaultValue);
                 scan(tree.body);
             }
         }
         public void visitVarDef(final JCVariableDecl tree) {
-            //System.err.println("validateTypeAnnotations.visitVarDef " + tree);
             if (tree.sym != null && tree.sym.type != null)
                 validateAnnotatedType(tree.vartype, tree.sym.type);
             scan(tree.mods);
             scan(tree.vartype);
             if (!sigOnly) {

@@ -4519,11 +4754,10 @@
                 validateAnnotatedType(tree.elemtype, tree.elemtype.type);
             }
             super.visitNewArray(tree);
         }
         public void visitClassDef(JCClassDecl tree) {
-            //System.err.println("validateTypeAnnotations.visitClassDef " + tree);
             if (sigOnly) {
                 scan(tree.mods);
                 scan(tree.typarams);
                 scan(tree.extending);
                 scan(tree.implementing);

@@ -4548,11 +4782,10 @@
          * of the symbol.
          * Therefore, we need to override each individual location where a type
          * can occur.
          */
         private void validateAnnotatedType(final JCTree errtree, final Type type) {
-            //System.err.println("Attr.validateAnnotatedType: " + errtree + " type: " + type);
 
             if (type.isPrimitiveOrVoid()) {
                 return;
             }
 

@@ -4588,17 +4821,17 @@
                     }
                 } else if (enclTr.hasTag(ANNOTATED_TYPE)) {
                     JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr;
                     if (enclTy == null || enclTy.hasTag(NONE)) {
                         if (at.getAnnotations().size() == 1) {
-                            log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute);
+                            //log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute);
                         } else {
                             ListBuffer<Attribute.Compound> comps = new ListBuffer<>();
                             for (JCAnnotation an : at.getAnnotations()) {
                                 comps.add(an.attribute);
                             }
-                            log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList());
+                            //log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList());
                         }
                         repeat = false;
                     }
                     enclTr = at.underlyingType;
                     // enclTy doesn't need to be changed

@@ -4645,10 +4878,12 @@
             // Ensure that no declaration annotations are present.
             // Note that a tree type might be an AnnotatedType with
             // empty annotations, if only declaration annotations were given.
             // This method will raise an error for such a type.
             for (JCAnnotation ai : annotations) {
+                Assert.checkNonNull(ai.type);
+
                 if (!ai.type.isErroneous() &&
                         typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
                     log.error(ai.pos(), "annotation.type.not.applicable");
                 }
             }