8016613: javac should avoid source 8 only analysis when compiling for source 7
authorvromero
Thu, 20 Jun 2013 08:45:43 +0100
changeset 18643 fdd7572e0c18
parent 18414 ee1e93e83d2b
child 18644 02f65c63159c
8016613: javac should avoid source 8 only analysis when compiling for source 7 Reviewed-by: jjg Contributed-by: maurizio.cimadamore@oracle.com
langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java	Wed Jun 19 22:07:05 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java	Thu Jun 20 08:45:43 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,9 +73,13 @@
      */
     public final static int MTH = 1 << 4;
 
+    /** Poly kind, for deferred types.
+     */
+    public final static int POLY = 1 << 5;
+
     /** The error kind, which includes all other kinds.
      */
-    public final static int ERR = (1 << 5) - 1;
+    public final static int ERR = (1 << 6) - 1;
 
     /** The set of all kinds.
      */
@@ -83,7 +87,7 @@
 
     /** Kinds for erroneous symbols that complement the above
      */
-    public static final int ERRONEOUS = 1 << 6;
+    public static final int ERRONEOUS = 1 << 7;
     public static final int AMBIGUOUS    = ERRONEOUS+1; // ambiguous reference
     public static final int HIDDEN       = ERRONEOUS+2; // hidden method or field
     public static final int STATICERR    = ERRONEOUS+3; // nonstatic member from static context
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jun 19 22:07:05 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jun 20 08:45:43 2013 +0100
@@ -134,6 +134,7 @@
         allowAnonOuterThis = source.allowAnonOuterThis();
         allowStringsInSwitch = source.allowStringsInSwitch();
         allowPoly = source.allowPoly();
+        allowTypeAnnos = source.allowTypeAnnotations();
         allowLambda = source.allowLambda();
         allowDefaultMethods = source.allowDefaultMethods();
         sourceName = source.name;
@@ -147,6 +148,7 @@
         statInfo = new ResultInfo(NIL, Type.noType);
         varInfo = new ResultInfo(VAR, Type.noType);
         unknownExprInfo = new ResultInfo(VAL, Type.noType);
+        unknownAnyPolyInfo = new ResultInfo(VAL, Infer.anyPoly);
         unknownTypeInfo = new ResultInfo(TYP, Type.noType);
         unknownTypeExprInfo = new ResultInfo(Kinds.TYP | Kinds.VAL, Type.noType);
         recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
@@ -160,6 +162,10 @@
      */
     boolean allowPoly;
 
+    /** Switch: support type annotations.
+     */
+    boolean allowTypeAnnos;
+
     /** Switch: support generics?
      */
     boolean allowGenerics;
@@ -240,7 +246,7 @@
         InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
         Type owntype = found;
         if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
-            if (inferenceContext.free(found)) {
+            if (allowPoly && inferenceContext.free(found)) {
                 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
                     @Override
                     public void typesInferred(InferenceContext inferenceContext) {
@@ -558,6 +564,7 @@
 
     final ResultInfo statInfo;
     final ResultInfo varInfo;
+    final ResultInfo unknownAnyPolyInfo;
     final ResultInfo unknownExprInfo;
     final ResultInfo unknownTypeInfo;
     final ResultInfo unknownTypeExprInfo;
@@ -664,17 +671,21 @@
             attribStat(l.head, env);
     }
 
-    /** Attribute the arguments in a method call, returning a list of types.
+    /** Attribute the arguments in a method call, returning the method kind.
      */
-    List<Type> attribArgs(List<JCExpression> trees, Env<AttrContext> env) {
-        ListBuffer<Type> argtypes = new ListBuffer<Type>();
+    int attribArgs(List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) {
+        int kind = VAL;
         for (JCExpression arg : trees) {
-            Type argtype = allowPoly && deferredAttr.isDeferred(env, arg) ?
-                    deferredAttr.new DeferredType(arg, env) :
-                    chk.checkNonVoid(arg, attribExpr(arg, env, Infer.anyPoly));
+            Type argtype;
+            if (allowPoly && deferredAttr.isDeferred(env, arg)) {
+                argtype = deferredAttr.new DeferredType(arg, env);
+                kind |= POLY;
+            } else {
+                argtype = chk.checkNonVoid(arg, attribTree(arg, env, unknownAnyPolyInfo));
+            }
             argtypes.append(argtype);
         }
-        return argtypes.toList();
+        return kind;
     }
 
     /** Attribute a type argument list, returning a list of types.
@@ -1739,6 +1750,7 @@
         boolean isConstructorCall =
             methName == names._this || methName == names._super;
 
+        ListBuffer<Type> argtypesBuf = ListBuffer.lb();
         if (isConstructorCall) {
             // We are seeing a ...this(...) or ...super(...) call.
             // Check that this is the first statement in a constructor.
@@ -1749,7 +1761,8 @@
                 localEnv.info.isSelfCall = true;
 
                 // Attribute arguments, yielding list of argument types.
-                argtypes = attribArgs(tree.args, localEnv);
+                attribArgs(tree.args, localEnv, argtypesBuf);
+                argtypes = argtypesBuf.toList();
                 typeargtypes = attribTypes(tree.typeargs, localEnv);
 
                 // Variable `site' points to the class in which the called
@@ -1821,7 +1834,8 @@
         } else {
             // Otherwise, we are seeing a regular method call.
             // Attribute the arguments, yielding list of argument types, ...
-            argtypes = attribArgs(tree.args, localEnv);
+            int kind = attribArgs(tree.args, localEnv, argtypesBuf);
+            argtypes = argtypesBuf.toList();
             typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
 
             // ... and attribute the method using as a prototype a methodtype
@@ -1829,7 +1843,7 @@
             // arguments (this will also set the method symbol).
             Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
             localEnv.info.pendingResolutionPhase = null;
-            Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(VAL, mpt, resultInfo.checkContext));
+            Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(kind, mpt, resultInfo.checkContext));
 
             // Compute the result type.
             Type restype = mtype.getReturnType();
@@ -1999,7 +2013,9 @@
         }
 
         // Attribute constructor arguments.
-        List<Type> argtypes = attribArgs(tree.args, localEnv);
+        ListBuffer<Type> argtypesBuf = ListBuffer.lb();
+        int pkind = attribArgs(tree.args, localEnv, argtypesBuf);
+        List<Type> argtypes = argtypesBuf.toList();
         List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
 
         // If we have made no mistakes in the class type...
@@ -2086,11 +2102,16 @@
                             clazztype,
                             tree.constructor,
                             rsEnv,
-                            new ResultInfo(MTH, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
+                            new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
                     if (rsEnv.info.lastResolveVarargs())
                         Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
                 }
-                findDiamondIfNeeded(localEnv, tree, clazztype);
+                if (cdef == null &&
+                        !clazztype.isErroneous() &&
+                        clazztype.getTypeArguments().nonEmpty() &&
+                        findDiamonds) {
+                    findDiamond(localEnv, tree, clazztype);
+                }
             }
 
             if (cdef != null) {
@@ -2157,7 +2178,7 @@
                     clazztype,
                     tree.constructor,
                     localEnv,
-                    new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
+                    new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
             } else {
                 if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
                     checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
@@ -2172,32 +2193,27 @@
         chk.validate(tree.typeargs, localEnv);
     }
     //where
-        void findDiamondIfNeeded(Env<AttrContext> env, JCNewClass tree, Type clazztype) {
-            if (tree.def == null &&
-                    !clazztype.isErroneous() &&
-                    clazztype.getTypeArguments().nonEmpty() &&
-                    findDiamonds) {
-                JCTypeApply ta = (JCTypeApply)tree.clazz;
-                List<JCExpression> prevTypeargs = ta.arguments;
-                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 polyPt = allowPoly ?
-                            syms.objectType :
-                            clazztype;
-                    if (!inferred.isErroneous() &&
-                        types.isAssignable(inferred, pt().hasTag(NONE) ? polyPt : pt(), types.noWarnings)) {
-                        String key = types.isSameType(clazztype, inferred) ?
-                            "diamond.redundant.args" :
-                            "diamond.redundant.args.1";
-                        log.warning(tree.clazz.pos(), key, clazztype, inferred);
-                    }
-                } finally {
-                    ta.arguments = prevTypeargs;
+        void findDiamond(Env<AttrContext> env, JCNewClass tree, Type clazztype) {
+            JCTypeApply ta = (JCTypeApply)tree.clazz;
+            List<JCExpression> prevTypeargs = ta.arguments;
+            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 polyPt = allowPoly ?
+                        syms.objectType :
+                        clazztype;
+                if (!inferred.isErroneous() &&
+                    types.isAssignable(inferred, pt().hasTag(NONE) ? polyPt : pt(), types.noWarnings)) {
+                    String key = types.isSameType(clazztype, inferred) ?
+                        "diamond.redundant.args" :
+                        "diamond.redundant.args.1";
+                    log.warning(tree.clazz.pos(), key, clazztype, inferred);
                 }
+            } finally {
+                ta.arguments = prevTypeargs;
             }
         }
 
@@ -3051,7 +3067,7 @@
         //should we propagate the target type?
         final ResultInfo castInfo;
         JCExpression expr = TreeInfo.skipParens(tree.expr);
-        boolean isPoly = expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE);
+        boolean isPoly = allowPoly && (expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE));
         if (isPoly) {
             //expression is a poly - we need to propagate target type info
             castInfo = new ResultInfo(VAL, clazztype, new Check.NestedCheckContext(resultInfo.checkContext) {
@@ -3440,10 +3456,14 @@
                      Symbol sym,
                      Env<AttrContext> env,
                      ResultInfo resultInfo) {
-            Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase));
-            Type owntype = checkIdInternal(tree, site, sym, pt, env, resultInfo);
-            resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
-            return owntype;
+            if ((resultInfo.pkind & POLY) != 0) {
+                Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase));
+                Type owntype = checkIdInternal(tree, site, sym, pt, env, resultInfo);
+                resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
+                return owntype;
+            } else {
+                return checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo);
+            }
         }
 
         Type checkIdInternal(JCTree tree,
@@ -3541,7 +3561,7 @@
                 break;
             case MTH: {
                 owntype = checkMethod(site, sym,
-                        new ResultInfo(VAL, resultInfo.pt.getReturnType(), resultInfo.checkContext),
+                        new ResultInfo(resultInfo.pkind, resultInfo.pt.getReturnType(), resultInfo.checkContext),
                         env, TreeInfo.args(env.tree), resultInfo.pt.getParameterTypes(),
                         resultInfo.pt.getTypeArguments());
                 break;
@@ -4289,12 +4309,13 @@
             (c.flags() & ABSTRACT) == 0) {
             checkSerialVersionUID(tree, c);
         }
-
-        // Correctly organize the postions of the type annotations
-        TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree);
-
-        // Check type annotations applicability rules
-        validateTypeAnnotations(tree);
+        if (allowTypeAnnos) {
+            // Correctly organize the postions of the type annotations
+            TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree);
+
+            // Check type annotations applicability rules
+            validateTypeAnnotations(tree);
+        }
     }
         // where
         /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Wed Jun 19 22:07:05 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Jun 20 08:45:43 2013 +0100
@@ -959,10 +959,8 @@
             if (sym.kind == Kinds.AMBIGUOUS) {
                 Resolve.AmbiguityError err = (Resolve.AmbiguityError)sym.baseSymbol();
                 result = ArgumentExpressionKind.PRIMITIVE;
-                for (List<Symbol> ambigousSyms = err.ambiguousSyms ;
-                        ambigousSyms.nonEmpty() && !result.isPoly() ;
-                        ambigousSyms = ambigousSyms.tail) {
-                    Symbol s = ambigousSyms.head;
+                for (Symbol s : err.ambiguousSyms) {
+                    if (result.isPoly()) break;
                     if (s.kind == Kinds.MTH) {
                         result = reduce(ArgumentExpressionKind.methodKind(s, types));
                     }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Wed Jun 19 22:07:05 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Jun 20 08:45:43 2013 +0100
@@ -109,15 +109,20 @@
         source = Source.instance(context);
         target = Target.instance(context);
         deferredLintHandler = DeferredLintHandler.instance(context);
+        allowTypeAnnos = source.allowTypeAnnotations();
     }
 
+    /** Switch: support type annotations.
+     */
+    boolean allowTypeAnnos;
+
     /** A queue for classes whose members still need to be entered into the
      *  symbol table.
      */
     ListBuffer<Env<AttrContext>> halfcompleted = new ListBuffer<Env<AttrContext>>();
 
     /** Set to true only when the first of a set of classes is
-     *  processed from the halfcompleted queue.
+     *  processed from the half completed queue.
      */
     boolean isFirst = true;
 
@@ -1072,7 +1077,9 @@
                 isFirst = true;
             }
         }
-        TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate);
+        if (allowTypeAnnos) {
+            TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate);
+        }
     }
 
     /*
@@ -1117,7 +1124,9 @@
     }
 
     public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym) {
-        tree.accept(new TypeAnnotate(env, sym));
+        if (allowTypeAnnos) {
+            tree.accept(new TypeAnnotate(env, sym));
+        }
     }
 
     /**