--- old/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java 2014-05-09 16:27:53.658276452 -0400 +++ new/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java 2014-05-09 16:27:53.560272294 -0400 @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Set; +import javax.lang.model.type.TypeKind; import javax.tools.JavaFileObject; import com.sun.tools.javac.code.*; @@ -41,6 +42,7 @@ import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.code.TypeAnnotationPosition.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.ANNOTATION; @@ -113,6 +115,7 @@ deferredLintHandler = DeferredLintHandler.instance(context); lint = Lint.instance(context); allowTypeAnnos = source.allowTypeAnnotations(); + speculative = false; } /** Switch: support type annotations. @@ -135,6 +138,11 @@ */ boolean completionEnabled = true; + /** The creator that will be used for any varDef's we visit. */ + Annotate.PositionCreator creator; + + boolean speculative; + /* ---------- Processing import clauses ---------------- */ @@ -361,32 +369,75 @@ * @param thrown The method's thrown exceptions. * @param env The method's (local) environment. */ - Type signature(MethodSymbol msym, - List typarams, - List params, - JCTree res, - JCVariableDecl recvparam, - List thrown, - Env env) { + Type signature(final MethodSymbol msym, + final List typarams, + final List params, + final JCTree res, + final JCVariableDecl recvparam, + final List thrown, + final Env env, + final List declAnnos, + final DiagnosticPosition deferPos) { + int i; // Enter and attribute type parameters. List tvars = enter.classEnter(typarams, env); - attr.attribTypeVariables(typarams, env); + attr.attribTypeVariables(typarams, env, currentLambda, speculative); + + // Handle type annotations on type parameters + i = 0; + for (List l = typarams; l.nonEmpty(); + l = l.tail, i++) { + final JCTypeParameter param = l.head; + annotate.annotateTypeLater(param, env, msym, deferPos, currentLambda, + annotate.methodTypeParamCreator(i), + speculative); + + int j = 0; + for (List bounds = param.bounds; + bounds.nonEmpty(); bounds = bounds.tail, j++) { + annotate.annotateTypeLater(bounds.head, env, msym, deferPos, currentLambda, + annotate.methodTypeParamBoundCreator(param, i, j), + speculative); + } + } // Enter and attribute value parameters. ListBuffer argbuf = new ListBuffer<>(); - for (List l = params; l.nonEmpty(); l = l.tail) { - memberEnter(l.head, env); + i = 0; + for (List l = params; l.nonEmpty(); l = l.tail, i++) { + memberEnter(l.head, env, annotate.paramCreator(i)); argbuf.append(l.head.vartype.type); } // Attribute result type, if one is given. - Type restype = res == null ? syms.voidType : attr.attribType(res, env); + Type restype; + + if (res != null) { + restype = attr.attribType(res, env, currentLambda, speculative); + annotate.annotateTypeLater(res, declAnnos, env, msym, deferPos, + currentLambda, annotate.returnCreator, + speculative); + } else { + // For constructors, synthesize a type annotation position + List typepath = List.nil(); + Type encl = msym.owner.type.getEnclosingType(); + while (encl != null && encl.getKind() != TypeKind.NONE && + encl.getKind() != TypeKind.ERROR) { + typepath = typepath.prepend(TypePathEntry.INNER_TYPE); + encl = encl.getEnclosingType(); + } + TypeAnnotationPosition tapos = + TypeAnnotationPosition.methodReturn(typepath, currentLambda, -1); + annotate.annotateLater(declAnnos, env, msym, deferPos, tapos); + restype = syms.voidType; + } + // Attribute receiver type, if one is given. Type recvtype; if (recvparam!=null) { - memberEnter(recvparam, env); + memberEnter(recvparam, env, annotate.receiverCreator); recvtype = recvparam.vartype.type; } else { recvtype = null; @@ -394,8 +445,13 @@ // Attribute thrown exceptions. ListBuffer thrownbuf = new ListBuffer<>(); - for (List l = thrown; l.nonEmpty(); l = l.tail) { - Type exc = attr.attribType(l.head, env); + i = 0; + for (List l = thrown; l.nonEmpty(); l = l.tail, i++) { + Type exc = attr.attribType(l.head, env, currentLambda, speculative); + annotate.annotateTypeLater(l.head, env, msym, deferPos, + currentLambda, + annotate.throwCreator(i), + speculative); if (!exc.hasTag(TYPEVAR)) { exc = chk.checkClassType(l.head.pos(), exc); } else if (exc.tsym.owner == msym) { @@ -421,36 +477,75 @@ */ protected Env env; + protected JCLambda currentLambda; + /** Enter field and method definitions and process import * clauses, catching any completion failure exceptions. */ - protected void memberEnter(JCTree tree, Env env) { + protected void memberEnter(JCTree tree, Env env, + Annotate.PositionCreator creator, + JCLambda lambda, + boolean speculative) { Env prevEnv = this.env; + Annotate.PositionCreator prevCreator = this.creator; + JCLambda prevLambda = this.currentLambda; + boolean prevSpeculative = this.speculative; try { this.env = env; + this.creator = creator; + this.currentLambda = lambda; + this.speculative = speculative; tree.accept(this); } catch (CompletionFailure ex) { chk.completionError(tree.pos(), ex); } finally { + this.creator = prevCreator; this.env = prevEnv; + this.currentLambda = prevLambda; + this.speculative = prevSpeculative; } } + protected void memberEnter(JCTree tree, + Env env, + Annotate.PositionCreator creator) { + memberEnter(tree, env, creator, currentLambda, speculative); + } + + protected void memberEnter(JCTree tree, Env env) { + memberEnter(tree, env, annotate.noCreator, currentLambda, speculative); + } + /** Enter members from a list of trees. */ - void memberEnter(List trees, Env env) { + void memberEnter(List trees, + Env env, + Annotate.PositionCreator creator, + JCLambda lambda, + boolean speculative) { for (List l = trees; l.nonEmpty(); l = l.tail) - memberEnter(l.head, env); + memberEnter(l.head, env, creator, lambda, speculative); + } + + void memberEnter(List trees, + Env env, + Annotate.PositionCreator creator) { + memberEnter(trees, env, creator, currentLambda, speculative); + } + + void memberEnter(List trees, + Env env) { + memberEnter(trees, env, annotate.noCreator, currentLambda, speculative); } /** Enter members for a class. */ - void finishClass(JCClassDecl tree, Env env) { + void finishClass(final JCClassDecl tree, final Env env) { if ((tree.mods.flags & Flags.ENUM) != 0 && (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) { addEnumMembers(tree, env); } - memberEnter(tree.defs, env); + memberEnter(tree.defs, env, annotate.fieldCreator); } /** Add the implicit members for an enum type @@ -525,7 +620,7 @@ } } // process package annotations - annotate.annotateLater(tree.annotations, env, env.toplevel.packge, null); + annotate.annotateLater(tree.annotations, env, env.toplevel.packge); } // process the non-static imports and the static imports of types. @@ -537,7 +632,8 @@ // effects of other imports in Resolve.findGlobalType Env localEnv = env.dup(tree); - TypeSymbol p = attr.attribImportQualifier(tree, localEnv).tsym; + TypeSymbol p = attr.attribImportQualifier(tree, localEnv, currentLambda, + speculative).tsym; if (name == names.asterisk) { // Import on demand. chk.checkCanonical(imp.selected); @@ -578,8 +674,8 @@ // Compute the method type m.type = signature(m, tree.typarams, tree.params, tree.restype, tree.recvparam, - tree.thrown, - localEnv); + tree.thrown, localEnv, + tree.mods.annotations, tree.pos()); } finally { deferredLintHandler.setPos(prevLintPos); } @@ -606,13 +702,9 @@ 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. - annotate.annotateTypeLater(tree, localEnv, m, tree.pos()); - if (tree.defaultValue != null) - annotateDefaultValueLater(tree.defaultValue, localEnv, m); + annotateDefaultValueLater(tree.defaultValue, localEnv, + m, annotate.noCreator); } finally { annotate.enterDone(); } @@ -649,7 +741,8 @@ if (TreeInfo.isEnumInit(tree)) { attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); } else { - attr.attribType(tree.vartype, localEnv); + attr.attribType(tree.vartype, localEnv, + currentLambda, speculative); if (tree.nameexpr != null) { attr.attribExpr(tree.nameexpr, localEnv); MethodSymbol m = localEnv.enclMethod.sym; @@ -692,15 +785,17 @@ needsLazyConstValue(tree.init)) { Env initEnv = getInitEnv(tree, env); initEnv.info.enclVar = v; - v.setLazyConstValue(initEnv(tree, initEnv), attr, tree); + v.setLazyConstValue(initEnv(tree, initEnv), attr, tree, + currentLambda, speculative); } } if (chk.checkUnique(tree.pos(), v, enclScope)) { chk.checkTransparentVar(tree.pos(), v, enclScope); enclScope.enter(v); } - annotate.annotateLater(tree.mods.annotations, localEnv, v, tree.pos()); - annotate.annotateTypeLater(tree.vartype, env, v, tree.pos()); + annotate.annotateTypeLater(tree.vartype, tree.mods.annotations, + localEnv, v, tree.pos(), + currentLambda, creator, speculative); v.pos = tree.pos; } finally { annotate.enterDone(); @@ -831,7 +926,7 @@ // To prevent deep recursion, suppress completion of some // types. completionEnabled = false; - return attr.attribType(tree, env); + return attr.attribType(tree, env, currentLambda, speculative); } finally { completionEnabled = true; } @@ -853,7 +948,8 @@ /** Queue processing of an attribute default value. */ void annotateDefaultValueLater(final JCExpression defaultValue, final Env localEnv, - final MethodSymbol m) { + final MethodSymbol m, + final Annotate.PositionCreator creator) { annotate.normal(new Annotate.Worker() { @Override public String toString() { @@ -864,8 +960,9 @@ @Override public void run() { JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); + final TypeAnnotationPosition position = creator.create(); try { - enterDefaultValue(defaultValue, localEnv, m); + enterDefaultValue(defaultValue, localEnv, m, position); } finally { log.useSource(prev); } @@ -889,10 +986,12 @@ /** Enter a default value for an attribute method. */ private void enterDefaultValue(final JCExpression defaultValue, final Env localEnv, - final MethodSymbol m) { + final MethodSymbol m, + final TypeAnnotationPosition position) { m.defaultValue = annotate.enterAttributeValue(m.type.getReturnType(), defaultValue, - localEnv); + localEnv, + position); } /* ******************************************************************** @@ -911,6 +1010,7 @@ return; } + int i; ClassSymbol c = (ClassSymbol)sym; ClassType ct = (ClassType)c.type; Env env = enter.typeEnvs.get(c); @@ -940,22 +1040,26 @@ // create an environment for evaluating the base clauses Env baseEnv = baseEnv(tree, env); - if (tree.extending != null) - annotate.annotateTypeLater(tree.extending, baseEnv, sym, tree.pos()); - for (JCExpression impl : tree.implementing) - annotate.annotateTypeLater(impl, baseEnv, sym, tree.pos()); - annotate.flush(); - // Determine supertype. - Type supertype = - (tree.extending != null) - ? attr.attribBase(tree.extending, baseEnv, true, false, true) - : ((tree.mods.flags & Flags.ENUM) != 0) + Type supertype; + + if (tree.extending != null) { + supertype = attr.attribBase(tree.extending, baseEnv, + true, false, true, currentLambda, + speculative); + annotate.annotateTypeLater(tree.extending, baseEnv, sym, + tree.pos(), currentLambda, + annotate.extendsCreator, + speculative); + } else { + supertype = ((tree.mods.flags & Flags.ENUM) != 0) ? attr.attribBase(enumBase(tree.pos, c), baseEnv, - true, false, false) + true, false, false, currentLambda, + speculative) : (c.fullname == names.java_lang_Object) ? Type.noType : syms.objectType; + } ct.supertype_field = modelMissingTypes(supertype, tree.extending, false); // Determine interfaces. @@ -963,18 +1067,26 @@ ListBuffer all_interfaces = null; // lazy init Set interfaceSet = new HashSet<>(); List interfaceTrees = tree.implementing; + i = 0; for (JCExpression iface : interfaceTrees) { - Type i = attr.attribBase(iface, baseEnv, false, true, true); - if (i.hasTag(CLASS)) { - interfaces.append(i); - if (all_interfaces != null) all_interfaces.append(i); - chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet); + Type it = attr.attribBase(iface, baseEnv, false, true, true, + currentLambda, speculative); + if (it.hasTag(CLASS)) { + interfaces.append(it); + if (all_interfaces != null) all_interfaces.append(it); + chk.checkNotRepeated(iface.pos(), types.erasure(it), interfaceSet); } else { if (all_interfaces == null) all_interfaces = new ListBuffer().appendList(interfaces); - all_interfaces.append(modelMissingTypes(i, iface, true)); + all_interfaces.append(modelMissingTypes(it, iface, true)); + } + annotate.annotateTypeLater(iface, baseEnv, sym, tree.pos(), + currentLambda, annotate.implementsCreator(i++), + speculative); } + annotate.flush(); + if ((c.flags_field & ANNOTATION) != 0) { ct.interfaces_field = List.of(syms.annotationType); ct.all_interfaces_field = ct.interfaces_field; @@ -1001,7 +1113,8 @@ // In general, we cannot fully process annotations yet, but we // can attribute the annotation types and then check to see if the // @Deprecated annotation is present. - attr.attribAnnotationTypes(tree.mods.annotations, baseEnv); + attr.attribAnnotationTypes(tree.mods.annotations, baseEnv, + currentLambda, speculative); if (hasDeprecatedAnnotation(tree.mods.annotations)) c.flags_field |= DEPRECATED; annotate.annotateLater(tree.mods.annotations, baseEnv, c, tree.pos()); @@ -1009,10 +1122,28 @@ chk.checkNonCyclicDecl(tree); - attr.attribTypeVariables(tree.typarams, baseEnv); + attr.attribTypeVariables(tree.typarams, baseEnv, + currentLambda, speculative); // Do this here, where we have the symbol. - for (JCTypeParameter tp : tree.typarams) - annotate.annotateTypeLater(tp, baseEnv, sym, tree.pos()); + i = 0; + for (List l = tree.typarams; l.nonEmpty(); + l = l.tail, i++) { + final JCTypeParameter typaram = l.head; + annotate.annotateTypeLater(typaram, baseEnv, sym, tree.pos(), + currentLambda, annotate.typeParamCreator(i), + speculative); + + int j = 0; + for(List b = typaram.bounds; b.nonEmpty(); + b = b.tail, j++) { + final JCExpression bound = b.head; + annotate.annotateTypeLater(bound, baseEnv, sym, + tree.pos(), currentLambda, + annotate.typeParamBoundCreator(typaram, i, j), + speculative); + } + + } // Add default constructor if needed. if ((c.flags() & INTERFACE) == 0 && @@ -1093,7 +1224,8 @@ Env toFinish = halfcompleted.next(); finish(toFinish); if (allowTypeAnnos) { - typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree); + // Note: This call is slated for removal in + // the next patch typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree); } }