# HG changeset patch # User emc # Date 1393355208 18000 # Node ID 1994a0d3b8de05802cbcef29886a8f1da644f940 # Parent 63050cb085833c1584911a883d42b38b0789a185 8035758: Move annotation codepaths from MemberEnter.java to Annotate.java Summary: Cosmetic code cleanup patch, moving code to the file where it ought to reside. Reviewed-by: vromero diff -r 63050cb08583 -r 1994a0d3b8de langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Sat Feb 22 17:42:10 2014 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Tue Feb 25 14:06:48 2014 -0500 @@ -25,8 +25,12 @@ package com.sun.tools.javac.comp; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; +import javax.tools.JavaFileObject; + import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.code.*; @@ -34,6 +38,7 @@ import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; +import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTag.ARRAY; import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.tree.JCTree.Tag.*; @@ -57,15 +62,21 @@ return instance; } - final Attr attr; - final TreeMaker make; - final Log log; - final Symtab syms; - final Names names; - final Resolve rs; - final Types types; - final ConstFold cfolder; - final Check chk; + private final Attr attr; + private final TreeMaker make; + private final Log log; + private final Symtab syms; + private final Names names; + private final Resolve rs; + private final Types types; + private final ConstFold cfolder; + private final Check chk; + private final Lint lint; + private final DeferredLintHandler deferredLintHandler; + private final Source source; + + private boolean allowTypeAnnos; + private boolean allowRepeatedAnnos; protected Annotate(Context context) { context.put(annotateKey, this); @@ -78,6 +89,11 @@ types = Types.instance(context); cfolder = ConstFold.instance(context); chk = Check.instance(context); + source = Source.instance(context); + lint = Lint.instance(context); + deferredLintHandler = DeferredLintHandler.instance(context); + allowRepeatedAnnos = source.allowRepeatedAnnotations(); + allowTypeAnnos = source.allowTypeAnnotations(); } /* ******************************************************************** @@ -669,4 +685,261 @@ return fatalError ? null : containerValueSymbol; } + +/* ******************************************************************** + * Annotation processing + *********************************************************************/ + + /** Queue annotations for later processing. */ + void annotateLater(final List annotations, + final Env localEnv, + final Symbol s, + final DiagnosticPosition deferPos) { + if (annotations.isEmpty()) { + return; + } + if (s.kind != PCK) { + s.resetAnnotations(); // mark Annotations as incomplete for now + } + normal(new Annotate.Worker() { + @Override + public String toString() { + return "annotate " + annotations + " onto " + s + " in " + s.owner; + } + + @Override + public void run() { + Assert.check(s.kind == PCK || s.annotationsPendingCompletion()); + JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); + DiagnosticPosition prevLintPos = + deferPos != null + ? deferredLintHandler.setPos(deferPos) + : deferredLintHandler.immediate(); + Lint prevLint = deferPos != null ? null : chk.setLint(lint); + try { + if (s.hasAnnotations() && + annotations.nonEmpty()) + log.error(annotations.head.pos, + "already.annotated", + kindName(s), s); + actualEnterAnnotations(annotations, localEnv, s); + } finally { + if (prevLint != null) + chk.setLint(prevLint); + deferredLintHandler.setPos(prevLintPos); + log.useSource(prev); + } + } + }); + + validate(new Annotate.Worker() { //validate annotations + @Override + public void run() { + JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); + try { + chk.validateAnnotations(annotations, s); + } finally { + log.useSource(prev); + } + } + }); + } + + /** Enter a set of annotations. */ + private void actualEnterAnnotations(List annotations, + Env env, + Symbol s) { + Map> annotated = new LinkedHashMap<>(); + Map pos = new HashMap<>(); + + for (List al = annotations; !al.isEmpty(); al = al.tail) { + JCAnnotation a = al.head; + Attribute.Compound c = enterAnnotation(a, syms.annotationType, env); + if (c == null) { + continue; + } + + if (annotated.containsKey(a.type.tsym)) { + if (!allowRepeatedAnnos) { + log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); + allowRepeatedAnnos = true; + } + ListBuffer l = annotated.get(a.type.tsym); + l = l.append(c); + annotated.put(a.type.tsym, l); + pos.put(c, a.pos()); + } else { + annotated.put(a.type.tsym, ListBuffer.of(c)); + pos.put(c, a.pos()); + } + + // Note: @Deprecated has no effect on local variables and parameters + if (!c.type.isErroneous() + && s.owner.kind != MTH + && types.isSameType(c.type, syms.deprecatedType)) { + s.flags_field |= Flags.DEPRECATED; + } + } + + s.setDeclarationAttributesWithCompletion( + new AnnotateRepeatedContext<>(env, annotated, pos, log, false)); + } + + /* + * If the symbol is non-null, attach the type annotation to it. + */ + private void actualEnterTypeAnnotations(final List annotations, + final Env env, + final Symbol s) { + Map> annotated = new LinkedHashMap<>(); + Map pos = new HashMap<>(); + + for (List al = annotations; !al.isEmpty(); al = al.tail) { + JCAnnotation a = al.head; + Attribute.TypeCompound tc = + enterTypeAnnotation(a, syms.annotationType, env); + + if (tc == null) { + continue; + } + + if (annotated.containsKey(a.type.tsym)) { + if (!allowRepeatedAnnos) { + log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); + allowRepeatedAnnos = true; + } + ListBuffer l = annotated.get(a.type.tsym); + l = l.append(tc); + annotated.put(a.type.tsym, l); + pos.put(tc, a.pos()); + } else { + annotated.put(a.type.tsym, ListBuffer.of(tc)); + pos.put(tc, a.pos()); + } + } + + if (s != null) { + s.appendTypeAttributesWithCompletion( + new AnnotateRepeatedContext<>(env, annotated, pos, log, true)); + } + } + + public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym, DiagnosticPosition deferPos) { + if (allowTypeAnnos) { + tree.accept(new TypeAnnotate(env, sym, deferPos)); + } + } + + /** + * We need to use a TreeScanner, because it is not enough to visit the top-level + * annotations. We also need to visit type arguments, etc. + */ + private class TypeAnnotate extends TreeScanner { + private Env env; + private Symbol sym; + private DiagnosticPosition deferPos; + + public TypeAnnotate(final Env env, final Symbol sym, DiagnosticPosition deferPos) { + this.env = env; + this.sym = sym; + this.deferPos = deferPos; + } + + void annotateTypeLater(final List annotations) { + if (annotations.isEmpty()) { + return; + } + + final DiagnosticPosition deferPos = this.deferPos; + + normal(new Annotate.Worker() { + @Override + public String toString() { + return "type annotate " + annotations + " onto " + sym + " in " + sym.owner; + } + @Override + public void run() { + JavaFileObject prev = log.useSource(env.toplevel.sourcefile); + DiagnosticPosition prevLintPos = null; + + if (deferPos != null) { + prevLintPos = deferredLintHandler.setPos(deferPos); + } + try { + actualEnterTypeAnnotations(annotations, env, sym); + } finally { + if (prevLintPos != null) + deferredLintHandler.setPos(prevLintPos); + log.useSource(prev); + } + } + }); + } + + @Override + public void visitAnnotatedType(final JCAnnotatedType tree) { + annotateTypeLater(tree.annotations); + super.visitAnnotatedType(tree); + } + + @Override + public void visitTypeParameter(final JCTypeParameter tree) { + annotateTypeLater(tree.annotations); + super.visitTypeParameter(tree); + } + + @Override + public void visitNewArray(final JCNewArray tree) { + annotateTypeLater(tree.annotations); + for (List dimAnnos : tree.dimAnnotations) + annotateTypeLater(dimAnnos); + super.visitNewArray(tree); + } + + @Override + public void visitMethodDef(final JCMethodDecl tree) { + scan(tree.mods); + scan(tree.restype); + scan(tree.typarams); + scan(tree.recvparam); + scan(tree.params); + scan(tree.thrown); + scan(tree.defaultValue); + // Do not annotate the body, just the signature. + // scan(tree.body); + } + + @Override + public void visitVarDef(final JCVariableDecl tree) { + DiagnosticPosition prevPos = deferPos; + deferPos = tree.pos(); + try { + if (sym != null && sym.kind == Kinds.VAR) { + // Don't visit a parameter once when the sym is the method + // and once when the sym is the parameter. + scan(tree.mods); + scan(tree.vartype); + } + scan(tree.init); + } finally { + deferPos = prevPos; + } + } + + @Override + public void visitClassDef(JCClassDecl tree) { + // We can only hit a classdef if it is declared within + // a method. Ignore it - the class will be visited + // separately later. + } + + @Override + public void visitNewClass(JCNewClass tree) { + if (tree.def == null) { + // For an anonymous class instantiation the class + // will be visited separately. + super.visitNewClass(tree); + } + } + } } diff -r 63050cb08583 -r 1994a0d3b8de langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Sat Feb 22 17:42:10 2014 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Feb 25 14:06:48 2014 -0500 @@ -774,7 +774,7 @@ // to the symbol. // This prevents having multiple type annotations, just because of // lazy constant value evaluation. - memberEnter.typeAnnotate(variable.init, env, null, variable.pos()); + annotate.typeAnnotate(variable.init, env, null, variable.pos()); annotate.flush(); Type itype = attribExpr(variable.init, env, type); if (itype.constValue() != null) { @@ -1021,7 +1021,7 @@ } // Attribute all type annotations in the body - memberEnter.typeAnnotate(tree.body, localEnv, m, null); + annotate.typeAnnotate(tree.body, localEnv, m, null); annotate.flush(); // Attribute method body. @@ -1050,7 +1050,7 @@ } else { if (tree.init != null) { // Field initializer expression need to be entered. - memberEnter.typeAnnotate(tree.init, env, tree.sym, tree.pos()); + annotate.typeAnnotate(tree.init, env, tree.sym, tree.pos()); annotate.flush(); } } @@ -1111,7 +1111,7 @@ if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; // Attribute all type annotations in the block - memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner, null); + annotate.typeAnnotate(tree, localEnv, localEnv.info.scope.owner, null); annotate.flush(); { diff -r 63050cb08583 -r 1994a0d3b8de langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Sat Feb 22 17:42:10 2014 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Feb 25 14:06:48 2014 -0500 @@ -113,15 +113,12 @@ deferredLintHandler = DeferredLintHandler.instance(context); lint = Lint.instance(context); allowTypeAnnos = source.allowTypeAnnotations(); - allowRepeatedAnnos = source.allowRepeatedAnnotations(); } /** Switch: support type annotations. */ boolean allowTypeAnnos; - boolean allowRepeatedAnnos; - /** A queue for classes whose members still need to be entered into the * symbol table. */ @@ -512,7 +509,7 @@ } // process package annotations - annotateLater(tree.packageAnnotations, env, tree.packge, null); + annotate.annotateLater(tree.packageAnnotations, env, tree.packge, null); DiagnosticPosition prevLintPos = deferredLintHandler.immediate(); Lint prevLint = chk.setLint(lint); @@ -607,10 +604,10 @@ enclScope.enter(m); } - annotateLater(tree.mods.annotations, localEnv, m, tree.pos()); + annotate.annotateLater(tree.mods.annotations, localEnv, m, tree.pos()); // Visit the signature of the method. Note that // TypeAnnotate doesn't descend into the body. - typeAnnotate(tree, localEnv, m, tree.pos()); + annotate.typeAnnotate(tree, localEnv, m, tree.pos()); if (tree.defaultValue != null) annotateDefaultValueLater(tree.defaultValue, localEnv, m); @@ -700,8 +697,8 @@ chk.checkTransparentVar(tree.pos(), v, enclScope); enclScope.enter(v); } - annotateLater(tree.mods.annotations, localEnv, v, tree.pos()); - typeAnnotate(tree.vartype, env, v, tree.pos()); + annotate.annotateLater(tree.mods.annotations, localEnv, v, tree.pos()); + annotate.typeAnnotate(tree.vartype, env, v, tree.pos()); v.pos = tree.pos; } finally { annotate.enterDone(); @@ -838,65 +835,6 @@ } } -/* ******************************************************************** - * Annotation processing - *********************************************************************/ - - /** Queue annotations for later processing. */ - void annotateLater(final List annotations, - final Env localEnv, - final Symbol s, - final DiagnosticPosition deferPos) { - if (annotations.isEmpty()) { - return; - } - if (s.kind != PCK) { - s.resetAnnotations(); // mark Annotations as incomplete for now - } - annotate.normal(new Annotate.Worker() { - @Override - public String toString() { - return "annotate " + annotations + " onto " + s + " in " + s.owner; - } - - @Override - public void run() { - Assert.check(s.kind == PCK || s.annotationsPendingCompletion()); - JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); - DiagnosticPosition prevLintPos = - deferPos != null - ? deferredLintHandler.setPos(deferPos) - : deferredLintHandler.immediate(); - Lint prevLint = deferPos != null ? null : chk.setLint(lint); - try { - if (s.hasAnnotations() && - annotations.nonEmpty()) - log.error(annotations.head.pos, - "already.annotated", - kindName(s), s); - actualEnterAnnotations(annotations, localEnv, s); - } finally { - if (prevLint != null) - chk.setLint(prevLint); - deferredLintHandler.setPos(prevLintPos); - log.useSource(prev); - } - } - }); - - annotate.validate(new Annotate.Worker() { //validate annotations - @Override - public void run() { - JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); - try { - chk.validateAnnotations(annotations, s); - } finally { - log.useSource(prev); - } - } - }); - } - /** * Check if a list of annotations contains a reference to * java.lang.Deprecated. @@ -910,48 +848,6 @@ return false; } - /** Enter a set of annotations. */ - private void actualEnterAnnotations(List annotations, - Env env, - Symbol s) { - Map> annotated = new LinkedHashMap<>(); - Map pos = new HashMap<>(); - - for (List al = annotations; !al.isEmpty(); al = al.tail) { - JCAnnotation a = al.head; - Attribute.Compound c = annotate.enterAnnotation(a, - syms.annotationType, - env); - if (c == null) { - continue; - } - - if (annotated.containsKey(a.type.tsym)) { - if (!allowRepeatedAnnos) { - log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); - allowRepeatedAnnos = true; - } - ListBuffer l = annotated.get(a.type.tsym); - l = l.append(c); - annotated.put(a.type.tsym, l); - pos.put(c, a.pos()); - } else { - annotated.put(a.type.tsym, ListBuffer.of(c)); - pos.put(c, a.pos()); - } - - // Note: @Deprecated has no effect on local variables and parameters - if (!c.type.isErroneous() - && s.owner.kind != MTH - && types.isSameType(c.type, syms.deprecatedType)) { - s.flags_field |= Flags.DEPRECATED; - } - } - - s.setDeclarationAttributesWithCompletion( - annotate.new AnnotateRepeatedContext<>(env, annotated, pos, log, false)); - } - /** Queue processing of an attribute default value. */ void annotateDefaultValueLater(final JCExpression defaultValue, final Env localEnv, @@ -1043,9 +939,9 @@ Env baseEnv = baseEnv(tree, env); if (tree.extending != null) - typeAnnotate(tree.extending, baseEnv, sym, tree.pos()); + annotate.typeAnnotate(tree.extending, baseEnv, sym, tree.pos()); for (JCExpression impl : tree.implementing) - typeAnnotate(impl, baseEnv, sym, tree.pos()); + annotate.typeAnnotate(impl, baseEnv, sym, tree.pos()); annotate.flush(); // Determine supertype. @@ -1106,7 +1002,7 @@ attr.attribAnnotationTypes(tree.mods.annotations, baseEnv); if (hasDeprecatedAnnotation(tree.mods.annotations)) c.flags_field |= DEPRECATED; - annotateLater(tree.mods.annotations, baseEnv, c, tree.pos()); + annotate.annotateLater(tree.mods.annotations, baseEnv, c, tree.pos()); // class type parameters use baseEnv but everything uses env chk.checkNonCyclicDecl(tree); @@ -1114,7 +1010,7 @@ attr.attribTypeVariables(tree.typarams, baseEnv); // Do this here, where we have the symbol. for (JCTypeParameter tp : tree.typarams) - typeAnnotate(tp, baseEnv, sym, tree.pos()); + annotate.typeAnnotate(tp, baseEnv, sym, tree.pos()); // Add default constructor if needed. if ((c.flags() & INTERFACE) == 0 && @@ -1205,165 +1101,6 @@ } } - /* - * If the symbol is non-null, attach the type annotation to it. - */ - private void actualEnterTypeAnnotations(final List annotations, - final Env env, - final Symbol s) { - Map> annotated = new LinkedHashMap<>(); - Map pos = new HashMap<>(); - - for (List al = annotations; !al.isEmpty(); al = al.tail) { - JCAnnotation a = al.head; - Attribute.TypeCompound tc = annotate.enterTypeAnnotation(a, - syms.annotationType, - env); - if (tc == null) { - continue; - } - - if (annotated.containsKey(a.type.tsym)) { - if (source.allowRepeatedAnnotations()) { - ListBuffer l = annotated.get(a.type.tsym); - l = l.append(tc); - annotated.put(a.type.tsym, l); - pos.put(tc, a.pos()); - } else { - log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); - } - } else { - annotated.put(a.type.tsym, ListBuffer.of(tc)); - pos.put(tc, a.pos()); - } - } - - if (s != null) { - s.appendTypeAttributesWithCompletion( - annotate.new AnnotateRepeatedContext<>(env, annotated, pos, log, true)); - } - } - - public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym, DiagnosticPosition deferPos) { - if (allowTypeAnnos) { - tree.accept(new TypeAnnotate(env, sym, deferPos)); - } - } - - /** - * We need to use a TreeScanner, because it is not enough to visit the top-level - * annotations. We also need to visit type arguments, etc. - */ - private class TypeAnnotate extends TreeScanner { - private Env env; - private Symbol sym; - private DiagnosticPosition deferPos; - - public TypeAnnotate(final Env env, final Symbol sym, DiagnosticPosition deferPos) { - this.env = env; - this.sym = sym; - this.deferPos = deferPos; - } - - void annotateTypeLater(final List annotations) { - if (annotations.isEmpty()) { - return; - } - - final DiagnosticPosition deferPos = this.deferPos; - - annotate.normal(new Annotate.Worker() { - @Override - public String toString() { - return "type annotate " + annotations + " onto " + sym + " in " + sym.owner; - } - @Override - public void run() { - JavaFileObject prev = log.useSource(env.toplevel.sourcefile); - DiagnosticPosition prevLintPos = null; - - if (deferPos != null) { - prevLintPos = deferredLintHandler.setPos(deferPos); - } - try { - actualEnterTypeAnnotations(annotations, env, sym); - } finally { - if (prevLintPos != null) - deferredLintHandler.setPos(prevLintPos); - log.useSource(prev); - } - } - }); - } - - @Override - public void visitAnnotatedType(final JCAnnotatedType tree) { - annotateTypeLater(tree.annotations); - super.visitAnnotatedType(tree); - } - - @Override - public void visitTypeParameter(final JCTypeParameter tree) { - annotateTypeLater(tree.annotations); - super.visitTypeParameter(tree); - } - - @Override - public void visitNewArray(final JCNewArray tree) { - annotateTypeLater(tree.annotations); - for (List dimAnnos : tree.dimAnnotations) - annotateTypeLater(dimAnnos); - super.visitNewArray(tree); - } - - @Override - public void visitMethodDef(final JCMethodDecl tree) { - scan(tree.mods); - scan(tree.restype); - scan(tree.typarams); - scan(tree.recvparam); - scan(tree.params); - scan(tree.thrown); - scan(tree.defaultValue); - // Do not annotate the body, just the signature. - // scan(tree.body); - } - - @Override - public void visitVarDef(final JCVariableDecl tree) { - DiagnosticPosition prevPos = deferPos; - deferPos = tree.pos(); - try { - if (sym != null && sym.kind == Kinds.VAR) { - // Don't visit a parameter once when the sym is the method - // and once when the sym is the parameter. - scan(tree.mods); - scan(tree.vartype); - } - scan(tree.init); - } finally { - deferPos = prevPos; - } - } - - @Override - public void visitClassDef(JCClassDecl tree) { - // We can only hit a classdef if it is declared within - // a method. Ignore it - the class will be visited - // separately later. - } - - @Override - public void visitNewClass(JCNewClass tree) { - if (tree.def == null) { - // For an anonymous class instantiation the class - // will be visited separately. - super.visitNewClass(tree); - } - } - } - - private Env baseEnv(JCClassDecl tree, Env env) { Scope baseScope = new Scope(tree.sym); //import already entered local classes into base scope