--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Attribute.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Attribute.java Wed Sep 10 19:38:20 2014 -0700
@@ -151,7 +151,7 @@
* access this attribute.
*/
public final List<Pair<MethodSymbol,Attribute>> values;
- public final TypeAnnotationPosition position;
+ public TypeAnnotationPosition position;
private boolean synthesized = false;
@@ -179,9 +179,53 @@
@Override
public TypeAnnotationPosition getPosition() {
+ if (hasUnknownPosition()) {
+ if (values.size() != 0) {
+ Name valueName = values.head.fst.name.table.names.value;
+ Pair<MethodSymbol, Attribute> res = getElemPair(valueName);
+ position = res == null ? null : res.snd.getPosition();
+ }
+ }
return position;
}
+ public boolean isContainerTypeCompound() {
+ if (isSynthesized() && values.size() == 1)
+ return getFirstEmbeddedTC() != null;
+ return false;
+ }
+
+ private Compound getFirstEmbeddedTC() {
+ if (values.size() == 1) {
+ Pair<MethodSymbol, Attribute> val = values.get(0);
+ if (val.fst.getSimpleName().contentEquals("value")
+ && val.snd instanceof Array) {
+ Array arr = (Array) val.snd;
+ if (arr.values.length != 0
+ && arr.values[0] instanceof Attribute.TypeCompound)
+ return (Attribute.TypeCompound) arr.values[0];
+ }
+ }
+ return null;
+ }
+
+ public boolean tryFixPosition() {
+ if (!isContainerTypeCompound())
+ return false;
+
+ Compound from = getFirstEmbeddedTC();
+ if (from != null && from.position != null &&
+ from.position.type != TargetType.UNKNOWN) {
+ position = from.position;
+ return true;
+ }
+ return false;
+ }
+
+ public boolean hasUnknownPosition() {
+ return position.type == TargetType.UNKNOWN;
+ }
+
public void accept(Visitor v) { v.visitCompound(this); }
/**
@@ -250,12 +294,6 @@
valmap.put(value.fst, value.snd);
return valmap;
}
-
- public TypeCompound toTypeCompound() {
- // It is safe to alias the position.
- return new TypeCompound(this, this.position);
- }
-
}
public static class TypeCompound extends Compound {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TargetType.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TargetType.java Wed Sep 10 19:38:20 2014 -0700
@@ -107,7 +107,10 @@
CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
/** For annotations on a type argument of a method reference. */
- METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true);
+ METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
+
+ /** For annotations with an unknown target. */
+ UNKNOWN(0xFF);
private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
@@ -147,15 +150,26 @@
targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
TargetType[] alltargets = values();
for (TargetType target : alltargets) {
+ if (target.targetTypeValue != UNKNOWN.targetTypeValue)
targets[target.targetTypeValue] = target;
}
+ for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) {
+ if (targets[i] == null)
+ targets[i] = UNKNOWN;
+ }
}
public static boolean isValidTargetTypeValue(int tag) {
+ if (tag == UNKNOWN.targetTypeValue)
+ return true;
+
return (tag >= 0 && tag < targets.length);
}
public static TargetType fromTargetTypeValue(int tag) {
+ if (tag == UNKNOWN.targetTypeValue)
+ return UNKNOWN;
+
if (tag < 0 || tag >= targets.length)
Assert.error("Unknown TargetType: " + tag);
return targets[tag];
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java Wed Sep 10 19:38:20 2014 -0700
@@ -256,6 +256,9 @@
case METHOD_RETURN:
case FIELD:
break;
+ case UNKNOWN:
+ sb.append(", position UNKNOWN!");
+ break;
default:
Assert.error("Unknown target type: " + type);
}
@@ -658,11 +661,10 @@
public static TypeAnnotationPosition
exceptionParameter(final List<TypePathEntry> location,
final JCLambda onLambda,
- final int type_index,
final int pos) {
return new TypeAnnotationPosition(TargetType.EXCEPTION_PARAMETER, pos,
Integer.MIN_VALUE, onLambda,
- type_index, Integer.MIN_VALUE,
+ Integer.MIN_VALUE, Integer.MIN_VALUE,
location);
}
@@ -675,7 +677,7 @@
public static TypeAnnotationPosition
exceptionParameter(final JCLambda onLambda,
final int pos) {
- return exceptionParameter(emptyPath, onLambda, Integer.MIN_VALUE, pos);
+ return exceptionParameter(emptyPath, onLambda, pos);
}
/**
@@ -685,7 +687,7 @@
*/
public static TypeAnnotationPosition
exceptionParameter(final List<TypePathEntry> location) {
- return exceptionParameter(location, null, Integer.MIN_VALUE, -1);
+ return exceptionParameter(location, null, -1);
}
@@ -1199,4 +1201,12 @@
return methodTypeParameterBound(location, null, parameter_index,
bound_index, -1);
}
+
+ // Consider this deprecated on arrival. We eventually want to get
+ // rid of this value altogether. Do not use it for anything new.
+ public static final TypeAnnotationPosition unknown =
+ new TypeAnnotationPosition(TargetType.UNKNOWN, -1,
+ Integer.MIN_VALUE, null,
+ Integer.MIN_VALUE, Integer.MIN_VALUE,
+ emptyPath);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,1397 @@
+/*
+ * Copyright (c) 2009, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.type.TypeKind;
+
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Type.ArrayType;
+import com.sun.tools.javac.code.Type.CapturedType;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.Type.ErrorType;
+import com.sun.tools.javac.code.Type.ForAll;
+import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.code.Type.PackageType;
+import com.sun.tools.javac.code.Type.TypeVar;
+import com.sun.tools.javac.code.Type.UndetVar;
+import com.sun.tools.javac.code.Type.Visitor;
+import com.sun.tools.javac.code.Type.WildcardType;
+import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
+import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.comp.Annotate.Worker;
+import com.sun.tools.javac.comp.Attr;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
+import com.sun.tools.javac.tree.JCTree.JCNewClass;
+import com.sun.tools.javac.tree.JCTree.JCTypeApply;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Names;
+import com.sun.tools.javac.util.Options;
+
+/**
+ * Contains operations specific to processing type annotations.
+ * This class has two functions:
+ * separate declaration from type annotations and insert the type
+ * annotations to their types;
+ * and determine the TypeAnnotationPositions for all type annotations.
+ */
+public class TypeAnnotations {
+ protected static final Context.Key<TypeAnnotations> typeAnnosKey = new Context.Key<>();
+
+ public static TypeAnnotations instance(Context context) {
+ TypeAnnotations instance = context.get(typeAnnosKey);
+ if (instance == null)
+ instance = new TypeAnnotations(context);
+ return instance;
+ }
+
+ final Log log;
+ final Names names;
+ final Symtab syms;
+ final Annotate annotate;
+ final Attr attr;
+
+ protected TypeAnnotations(Context context) {
+ context.put(typeAnnosKey, this);
+ names = Names.instance(context);
+ log = Log.instance(context);
+ syms = Symtab.instance(context);
+ annotate = Annotate.instance(context);
+ attr = Attr.instance(context);
+ Options options = Options.instance(context);
+ }
+
+ /**
+ * Separate type annotations from declaration annotations and
+ * determine the correct positions for type annotations.
+ * This version only visits types in signatures and should be
+ * called from MemberEnter.
+ * The method takes the Annotate object as parameter and
+ * adds an Annotate.Worker to the correct Annotate queue for
+ * later processing.
+ */
+ public void organizeTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) {
+ annotate.afterRepeated( new Worker() {
+ @Override
+ public void run() {
+ JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
+
+ try {
+ new TypeAnnotationPositions(true).scan(tree);
+ } finally {
+ log.useSource(oldSource);
+ }
+ }
+ } );
+ }
+
+ public void validateTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) {
+ annotate.validate(new Worker() { //validate annotations
+ @Override
+ public void run() {
+ JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
+
+ try {
+ attr.validateTypeAnnotations(tree, true);
+ } finally {
+ log.useSource(oldSource);
+ }
+ }
+ } );
+ }
+
+ /**
+ * This version only visits types in bodies, that is, field initializers,
+ * top-level blocks, and method bodies, and should be called from Attr.
+ */
+ public void organizeTypeAnnotationsBodies(JCClassDecl tree) {
+ new TypeAnnotationPositions(false).scan(tree);
+ }
+
+ public enum AnnotationType { DECLARATION, TYPE, BOTH }
+
+ /**
+ * Determine whether an annotation is a declaration annotation,
+ * a type annotation, or both.
+ */
+ public AnnotationType annotationType(Attribute.Compound a, Symbol s) {
+ Attribute.Compound atTarget =
+ a.type.tsym.attribute(syms.annotationTargetType.tsym);
+ if (atTarget == null) {
+ return inferTargetMetaInfo(a, s);
+ }
+ Attribute atValue = atTarget.member(names.value);
+ if (!(atValue instanceof Attribute.Array)) {
+ Assert.error("annotationType(): bad @Target argument " + atValue +
+ " (" + atValue.getClass() + ")");
+ return AnnotationType.DECLARATION; // error recovery
+ }
+ Attribute.Array arr = (Attribute.Array) atValue;
+ boolean isDecl = false, isType = false;
+ for (Attribute app : arr.values) {
+ if (!(app instanceof Attribute.Enum)) {
+ Assert.error("annotationType(): unrecognized Attribute kind " + app +
+ " (" + app.getClass() + ")");
+ isDecl = true;
+ continue;
+ }
+ Attribute.Enum e = (Attribute.Enum) app;
+ if (e.value.name == names.TYPE) {
+ if (s.kind == Kinds.TYP)
+ isDecl = true;
+ } else if (e.value.name == names.FIELD) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind != Kinds.MTH)
+ isDecl = true;
+ } else if (e.value.name == names.METHOD) {
+ if (s.kind == Kinds.MTH &&
+ !s.isConstructor())
+ isDecl = true;
+ } else if (e.value.name == names.PARAMETER) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind == Kinds.MTH &&
+ (s.flags() & Flags.PARAMETER) != 0)
+ isDecl = true;
+ } else if (e.value.name == names.CONSTRUCTOR) {
+ if (s.kind == Kinds.MTH &&
+ s.isConstructor())
+ isDecl = true;
+ } else if (e.value.name == names.LOCAL_VARIABLE) {
+ if (s.kind == Kinds.VAR &&
+ s.owner.kind == Kinds.MTH &&
+ (s.flags() & Flags.PARAMETER) == 0)
+ isDecl = true;
+ } else if (e.value.name == names.ANNOTATION_TYPE) {
+ if (s.kind == Kinds.TYP &&
+ (s.flags() & Flags.ANNOTATION) != 0)
+ isDecl = true;
+ } else if (e.value.name == names.PACKAGE) {
+ if (s.kind == Kinds.PCK)
+ isDecl = true;
+ } else if (e.value.name == names.TYPE_USE) {
+ if (s.kind == Kinds.TYP ||
+ s.kind == Kinds.VAR ||
+ (s.kind == Kinds.MTH && !s.isConstructor() &&
+ !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
+ (s.kind == Kinds.MTH && s.isConstructor()))
+ isType = true;
+ } else if (e.value.name == names.TYPE_PARAMETER) {
+ /* Irrelevant in this case */
+ // TYPE_PARAMETER doesn't aid in distinguishing between
+ // Type annotations and declaration annotations on an
+ // Element
+ } else {
+ Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
+ " (" + e.value.name.getClass() + ")");
+ isDecl = true;
+ }
+ }
+ if (isDecl && isType) {
+ return AnnotationType.BOTH;
+ } else if (isType) {
+ return AnnotationType.TYPE;
+ } else {
+ return AnnotationType.DECLARATION;
+ }
+ }
+
+ /** Infer the target annotation kind, if none is give.
+ * We only infer declaration annotations.
+ */
+ private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
+ return AnnotationType.DECLARATION;
+ }
+
+
+ private class TypeAnnotationPositions extends TreeScanner {
+
+ private final boolean sigOnly;
+
+ TypeAnnotationPositions(boolean sigOnly) {
+ this.sigOnly = sigOnly;
+ }
+
+ /*
+ * When traversing the AST we keep the "frames" of visited
+ * trees in order to determine the position of annotations.
+ */
+ private ListBuffer<JCTree> frames = new ListBuffer<>();
+
+ protected void push(JCTree t) { frames = frames.prepend(t); }
+ protected JCTree pop() { return frames.next(); }
+ // could this be frames.elems.tail.head?
+ private JCTree peek2() { return frames.toList().tail.head; }
+
+ @Override
+ public void scan(JCTree tree) {
+ push(tree);
+ super.scan(tree);
+ pop();
+ }
+
+ /**
+ * Separates type annotations from declaration annotations.
+ * This step is needed because in certain locations (where declaration
+ * and type annotations can be mixed, e.g. the type of a field)
+ * we never build an JCAnnotatedType. This step finds these
+ * annotations and marks them as if they were part of the type.
+ */
+ private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym,
+ TypeAnnotationPosition pos) {
+ List<Attribute.Compound> annotations = sym.getRawAttributes();
+ ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>();
+ ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>();
+ ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>();
+
+ for (Attribute.Compound a : annotations) {
+ switch (annotationType(a, sym)) {
+ case DECLARATION:
+ declAnnos.append(a);
+ break;
+ case BOTH: {
+ declAnnos.append(a);
+ Attribute.TypeCompound ta = toTypeCompound(a, pos);
+ typeAnnos.append(ta);
+ break;
+ }
+ case TYPE: {
+ Attribute.TypeCompound ta = toTypeCompound(a, pos);
+ typeAnnos.append(ta);
+ // Also keep track which annotations are only type annotations
+ onlyTypeAnnos.append(ta);
+ break;
+ }
+ }
+ }
+
+ sym.resetAnnotations();
+ sym.setDeclarationAttributes(declAnnos.toList());
+
+ if (typeAnnos.isEmpty()) {
+ return;
+ }
+
+ List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList();
+
+ if (type == null) {
+ // When type is null, put the type annotations to the symbol.
+ // This is used for constructor return annotations, for which
+ // we use the type of the enclosing class.
+ type = sym.getEnclosingElement().asType();
+
+ // Declaration annotations are always allowed on constructor returns.
+ // Therefore, use typeAnnotations instead of onlyTypeAnnos.
+ type = typeWithAnnotations(typetree, type, typeAnnotations, typeAnnotations);
+ // Note that we don't use the result, the call to
+ // typeWithAnnotations side-effects the type annotation positions.
+ // This is important for constructors of nested classes.
+ sym.appendUniqueTypeAttributes(typeAnnotations);
+ return;
+ }
+
+ // type is non-null and annotations are added to that type
+ type = typeWithAnnotations(typetree, type, typeAnnotations, onlyTypeAnnos.toList());
+
+ if (sym.getKind() == ElementKind.METHOD) {
+ sym.type.asMethodType().restype = type;
+ } else if (sym.getKind() == ElementKind.PARAMETER) {
+ sym.type = type;
+ if (sym.getQualifiedName().equals(names._this)) {
+ sym.owner.type.asMethodType().recvtype = type;
+ // note that the typeAnnotations will also be added to the owner below.
+ } else {
+ MethodType methType = sym.owner.type.asMethodType();
+ List<VarSymbol> params = ((MethodSymbol)sym.owner).params;
+ List<Type> oldArgs = methType.argtypes;
+ ListBuffer<Type> newArgs = new ListBuffer<>();
+ while (params.nonEmpty()) {
+ if (params.head == sym) {
+ newArgs.add(type);
+ } else {
+ newArgs.add(oldArgs.head);
+ }
+ oldArgs = oldArgs.tail;
+ params = params.tail;
+ }
+ methType.argtypes = newArgs.toList();
+ }
+ } else {
+ sym.type = type;
+ }
+
+ sym.appendUniqueTypeAttributes(typeAnnotations);
+
+ if (sym.getKind() == ElementKind.PARAMETER ||
+ sym.getKind() == ElementKind.LOCAL_VARIABLE ||
+ sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
+ sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
+ // Make sure all type annotations from the symbol are also
+ // on the owner.
+ sym.owner.appendUniqueTypeAttributes(sym.getRawTypeAttributes());
+ }
+ }
+
+ // This method has a similar purpose as
+ // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)}
+ // We found a type annotation in a declaration annotation position,
+ // for example, on the return type.
+ // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
+ // need to set its position explicitly.
+ // The method returns a copy of type that contains these annotations.
+ //
+ // As a side effect the method sets the type annotation position of "annotations".
+ // Note that it is assumed that all annotations share the same position.
+ private Type typeWithAnnotations(final JCTree typetree, final Type type,
+ final List<Attribute.TypeCompound> annotations,
+ final List<Attribute.TypeCompound> onlyTypeAnnotations) {
+ //System.err.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s, onlyTypeAnnotations: %s)%n",
+ // typetree, type, annotations, onlyTypeAnnotations);
+ if (annotations.isEmpty()) {
+ return type;
+ }
+ if (type.hasTag(TypeTag.ARRAY)) {
+ Type.ArrayType arType = (Type.ArrayType) type;
+ Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym,
+ Type.noAnnotations);
+ Type toreturn;
+ if (type.isAnnotated()) {
+ toreturn = tomodify.annotatedType(type.getAnnotationMirrors());
+ } else {
+ toreturn = tomodify;
+ }
+
+ JCArrayTypeTree arTree = arrayTypeTree(typetree);
+
+ ListBuffer<TypePathEntry> depth = new ListBuffer<>();
+ depth = depth.append(TypePathEntry.ARRAY);
+ while (arType.elemtype.hasTag(TypeTag.ARRAY)) {
+ if (arType.elemtype.isAnnotated()) {
+ Type aelemtype = arType.elemtype;
+ arType = (Type.ArrayType) aelemtype;
+ ArrayType prevToMod = tomodify;
+ tomodify = new Type.ArrayType(null, arType.tsym,
+ Type.noAnnotations);
+ prevToMod.elemtype = tomodify.annotatedType(arType.elemtype.getAnnotationMirrors());
+ } else {
+ arType = (Type.ArrayType) arType.elemtype;
+ tomodify.elemtype = new Type.ArrayType(null, arType.tsym,
+ Type.noAnnotations);
+ tomodify = (Type.ArrayType) tomodify.elemtype;
+ }
+ arTree = arrayTypeTree(arTree.elemtype);
+ depth = depth.append(TypePathEntry.ARRAY);
+ }
+ Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, onlyTypeAnnotations);
+ tomodify.elemtype = arelemType;
+ {
+ // All annotations share the same position; modify the first one.
+ Attribute.TypeCompound a = annotations.get(0);
+ TypeAnnotationPosition p = a.position;
+ p.location = p.location.prependList(depth.toList());
+ }
+ typetree.type = toreturn;
+ return toreturn;
+ } else if (type.hasTag(TypeTag.TYPEVAR)) {
+ // Nothing to do for type variables.
+ return type;
+ } else if (type.getKind() == TypeKind.UNION) {
+ // There is a TypeKind, but no TypeTag.
+ JCTypeUnion tutree = (JCTypeUnion) typetree;
+ JCExpression fst = tutree.alternatives.get(0);
+ Type res = typeWithAnnotations(fst, fst.type, annotations, onlyTypeAnnotations);
+ fst.type = res;
+ // TODO: do we want to set res as first element in uct.alternatives?
+ // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type;
+ // Return the un-annotated union-type.
+ return type;
+ } else {
+ Type enclTy = type;
+ Element enclEl = type.asElement();
+ JCTree enclTr = typetree;
+
+ while (enclEl != null &&
+ enclEl.getKind() != ElementKind.PACKAGE &&
+ enclTy != null &&
+ enclTy.getKind() != TypeKind.NONE &&
+ enclTy.getKind() != TypeKind.ERROR &&
+ (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT ||
+ enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE ||
+ enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) {
+ // Iterate also over the type tree, not just the type: the type is already
+ // completely resolved and we cannot distinguish where the annotation
+ // belongs for a nested type.
+ if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) {
+ // only change encl in this case.
+ enclTy = enclTy.getEnclosingType();
+ enclEl = enclEl.getEnclosingElement();
+ enclTr = ((JCFieldAccess)enclTr).getExpression();
+ } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) {
+ enclTr = ((JCTypeApply)enclTr).getType();
+ } else {
+ // only other option because of while condition
+ enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType();
+ }
+ }
+
+ /** We are trying to annotate some enclosing type,
+ * but nothing more exists.
+ */
+ if (enclTy != null &&
+ enclTy.hasTag(TypeTag.NONE)) {
+ switch (onlyTypeAnnotations.size()) {
+ case 0:
+ // Don't issue an error if all type annotations are
+ // also declaration annotations.
+ // If the annotations are also declaration annotations, they are
+ // illegal as type annotations but might be legal as declaration annotations.
+ // The normal declaration annotation checks make sure that the use is valid.
+ break;
+ case 1:
+ log.error(typetree.pos(), "cant.type.annotate.scoping.1",
+ onlyTypeAnnotations);
+ break;
+ default:
+ log.error(typetree.pos(), "cant.type.annotate.scoping",
+ onlyTypeAnnotations);
+ }
+ return type;
+ }
+
+ // At this point we have visited the part of the nested
+ // type that is written in the source code.
+ // Now count from here to the actual top-level class to determine
+ // the correct nesting.
+
+ // The genericLocation for the annotation.
+ ListBuffer<TypePathEntry> depth = new ListBuffer<>();
+
+ Type topTy = enclTy;
+ while (enclEl != null &&
+ enclEl.getKind() != ElementKind.PACKAGE &&
+ topTy != null &&
+ topTy.getKind() != TypeKind.NONE &&
+ topTy.getKind() != TypeKind.ERROR) {
+ topTy = topTy.getEnclosingType();
+ enclEl = enclEl.getEnclosingElement();
+
+ if (topTy != null && topTy.getKind() != TypeKind.NONE) {
+ // Only count enclosing types.
+ depth = depth.append(TypePathEntry.INNER_TYPE);
+ }
+ }
+
+ if (depth.nonEmpty()) {
+ // Only need to change the annotation positions
+ // if they are on an enclosed type.
+ // All annotations share the same position; modify the first one.
+ Attribute.TypeCompound a = annotations.get(0);
+ TypeAnnotationPosition p = a.position;
+ p.location = p.location.appendList(depth.toList());
+ }
+
+ Type ret = typeWithAnnotations(type, enclTy, annotations);
+ typetree.type = ret;
+ return ret;
+ }
+ }
+
+ private JCArrayTypeTree arrayTypeTree(JCTree typetree) {
+ if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) {
+ return (JCArrayTypeTree) typetree;
+ } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) {
+ return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType;
+ } else {
+ Assert.error("Could not determine array type from type tree: " + typetree);
+ return null;
+ }
+ }
+
+ /** Return a copy of the first type that only differs by
+ * inserting the annotations to the left-most/inner-most type
+ * or the type given by stopAt.
+ *
+ * We need the stopAt parameter to know where on a type to
+ * put the annotations.
+ * If we have nested classes Outer > Middle > Inner, and we
+ * have the source type "@A Middle.Inner", we will invoke
+ * this method with type = Outer.Middle.Inner,
+ * stopAt = Middle.Inner, and annotations = @A.
+ *
+ * @param type The type to copy.
+ * @param stopAt The type to stop at.
+ * @param annotations The annotations to insert.
+ * @return A copy of type that contains the annotations.
+ */
+ private Type typeWithAnnotations(final Type type,
+ final Type stopAt,
+ final List<Attribute.TypeCompound> annotations) {
+ //System.err.println("typeWithAnnotations " + type + " " + annotations + " stopAt " + stopAt);
+ Visitor<Type, List<TypeCompound>> visitor =
+ new Type.Visitor<Type, List<Attribute.TypeCompound>>() {
+ @Override
+ public Type visitClassType(ClassType t, List<TypeCompound> s) {
+ // assert that t.constValue() == null?
+ if (t == stopAt ||
+ t.getEnclosingType() == Type.noType) {
+ return t.annotatedType(s);
+ } else {
+ ClassType ret = new ClassType(t.getEnclosingType().accept(this, s),
+ t.typarams_field, t.tsym,
+ t.getAnnotationMirrors());
+ ret.all_interfaces_field = t.all_interfaces_field;
+ ret.allparams_field = t.allparams_field;
+ ret.interfaces_field = t.interfaces_field;
+ ret.rank_field = t.rank_field;
+ ret.supertype_field = t.supertype_field;
+ return ret;
+ }
+ }
+
+ @Override
+ public Type visitWildcardType(WildcardType t, List<TypeCompound> s) {
+ return t.annotatedType(s);
+ }
+
+ @Override
+ public Type visitArrayType(ArrayType t, List<TypeCompound> s) {
+ ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym,
+ t.getAnnotationMirrors());
+ return ret;
+ }
+
+ @Override
+ public Type visitMethodType(MethodType t, List<TypeCompound> s) {
+ // Impossible?
+ return t;
+ }
+
+ @Override
+ public Type visitPackageType(PackageType t, List<TypeCompound> s) {
+ // Impossible?
+ return t;
+ }
+
+ @Override
+ public Type visitTypeVar(TypeVar t, List<TypeCompound> s) {
+ return t.annotatedType(s);
+ }
+
+ @Override
+ public Type visitCapturedType(CapturedType t, List<TypeCompound> s) {
+ return t.annotatedType(s);
+ }
+
+ @Override
+ public Type visitForAll(ForAll t, List<TypeCompound> s) {
+ // Impossible?
+ return t;
+ }
+
+ @Override
+ public Type visitUndetVar(UndetVar t, List<TypeCompound> s) {
+ // Impossible?
+ return t;
+ }
+
+ @Override
+ public Type visitErrorType(ErrorType t, List<TypeCompound> s) {
+ return t.annotatedType(s);
+ }
+
+ @Override
+ public Type visitType(Type t, List<TypeCompound> s) {
+ return t.annotatedType(s);
+ }
+ };
+
+ return type.accept(visitor, annotations);
+ }
+
+ private Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) {
+ // It is safe to alias the position.
+ return new Attribute.TypeCompound(a, p);
+ }
+
+
+ /* This is the beginning of the second part of organizing
+ * type annotations: determine the type annotation positions.
+ */
+
+ // This method is considered deprecated, and will be removed
+ // in the near future. Don't use it for anything new.
+ private TypeAnnotationPosition
+ resolveFrame(JCTree tree,
+ JCTree frame,
+ List<JCTree> path,
+ JCLambda currentLambda,
+ int outer_type_index,
+ ListBuffer<TypePathEntry> location) {
+ /*
+ System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
+ System.out.println(" Framing tree: " + frame + " kind: " + frame.getKind());
+ */
+
+ // Note that p.offset is set in
+ // com.sun.tools.javac.jvm.Gen.setTypeAnnotationPositions(int)
+
+ switch (frame.getKind()) {
+ case TYPE_CAST:
+ return TypeAnnotationPosition.typeCast(location.toList(),
+ currentLambda,
+ outer_type_index,
+ frame.pos);
+
+ case INSTANCE_OF:
+ return TypeAnnotationPosition.instanceOf(location.toList(),
+ currentLambda,
+ frame.pos);
+
+ case NEW_CLASS:
+ final JCNewClass frameNewClass = (JCNewClass) frame;
+ if (frameNewClass.def != null) {
+ // Special handling for anonymous class instantiations
+ final JCClassDecl frameClassDecl = frameNewClass.def;
+ if (frameClassDecl.extending == tree) {
+ return TypeAnnotationPosition
+ .classExtends(location.toList(), currentLambda,
+ frame.pos);
+ } else if (frameClassDecl.implementing.contains(tree)) {
+ final int type_index =
+ frameClassDecl.implementing.indexOf(tree);
+ return TypeAnnotationPosition
+ .classExtends(location.toList(), currentLambda,
+ type_index, frame.pos);
+ } else {
+ // In contrast to CLASS below, typarams cannot occur here.
+ throw new AssertionError("Could not determine position of tree " + tree +
+ " within frame " + frame);
+ }
+ } else if (frameNewClass.typeargs.contains(tree)) {
+ final int type_index =
+ frameNewClass.typeargs.indexOf(tree);
+ return TypeAnnotationPosition
+ .constructorInvocationTypeArg(location.toList(),
+ currentLambda,
+ type_index,
+ frame.pos);
+ } else {
+ return TypeAnnotationPosition
+ .newObj(location.toList(), currentLambda,
+ frame.pos);
+ }
+
+ case NEW_ARRAY:
+ return TypeAnnotationPosition
+ .newObj(location.toList(), currentLambda, frame.pos);
+
+ case ANNOTATION_TYPE:
+ case CLASS:
+ case ENUM:
+ case INTERFACE:
+ if (((JCClassDecl)frame).extending == tree) {
+ return TypeAnnotationPosition
+ .classExtends(location.toList(), currentLambda,
+ frame.pos);
+ } else if (((JCClassDecl)frame).implementing.contains(tree)) {
+ final int type_index =
+ ((JCClassDecl)frame).implementing.indexOf(tree);
+ return TypeAnnotationPosition
+ .classExtends(location.toList(), currentLambda,
+ type_index, frame.pos);
+ } else if (((JCClassDecl)frame).typarams.contains(tree)) {
+ final int parameter_index =
+ ((JCClassDecl)frame).typarams.indexOf(tree);
+ return TypeAnnotationPosition
+ .typeParameter(location.toList(), currentLambda,
+ parameter_index, frame.pos);
+ } else {
+ throw new AssertionError("Could not determine position of tree " +
+ tree + " within frame " + frame);
+ }
+
+ case METHOD: {
+ final JCMethodDecl frameMethod = (JCMethodDecl) frame;
+ if (frameMethod.thrown.contains(tree)) {
+ final int type_index = frameMethod.thrown.indexOf(tree);
+ return TypeAnnotationPosition
+ .methodThrows(location.toList(), currentLambda,
+ type_index, frame.pos);
+ } else if (frameMethod.restype == tree) {
+ return TypeAnnotationPosition
+ .methodReturn(location.toList(), currentLambda,
+ frame.pos);
+ } else if (frameMethod.typarams.contains(tree)) {
+ final int parameter_index =
+ frameMethod.typarams.indexOf(tree);
+ return TypeAnnotationPosition
+ .methodTypeParameter(location.toList(),
+ currentLambda,
+ parameter_index, frame.pos);
+ } else {
+ throw new AssertionError("Could not determine position of tree " + tree +
+ " within frame " + frame);
+ }
+ }
+
+ case PARAMETERIZED_TYPE: {
+ List<JCTree> newPath = path.tail;
+
+ if (((JCTypeApply)frame).clazz == tree) {
+ // generic: RAW; noop
+ } else if (((JCTypeApply)frame).arguments.contains(tree)) {
+ JCTypeApply taframe = (JCTypeApply) frame;
+ int arg = taframe.arguments.indexOf(tree);
+ location = location.prepend(
+ new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT,
+ arg));
+
+ Type typeToUse;
+ if (newPath.tail != null &&
+ newPath.tail.head.hasTag(Tag.NEWCLASS)) {
+ // If we are within an anonymous class
+ // instantiation, use its type, because it
+ // contains a correctly nested type.
+ typeToUse = newPath.tail.head.type;
+ } else {
+ typeToUse = taframe.type;
+ }
+
+ location = locateNestedTypes(typeToUse, location);
+ } else {
+ throw new AssertionError("Could not determine type argument position of tree " + tree +
+ " within frame " + frame);
+ }
+
+ return resolveFrame(newPath.head, newPath.tail.head,
+ newPath, currentLambda,
+ outer_type_index, location);
+ }
+
+ case MEMBER_REFERENCE: {
+ JCMemberReference mrframe = (JCMemberReference) frame;
+
+ if (mrframe.expr == tree) {
+ switch (mrframe.mode) {
+ case INVOKE:
+ return TypeAnnotationPosition
+ .methodRef(location.toList(), currentLambda,
+ frame.pos);
+ case NEW:
+ return TypeAnnotationPosition
+ .constructorRef(location.toList(),
+ currentLambda,
+ frame.pos);
+ default:
+ throw new AssertionError("Unknown method reference mode " + mrframe.mode +
+ " for tree " + tree + " within frame " + frame);
+ }
+ } else if (mrframe.typeargs != null &&
+ mrframe.typeargs.contains(tree)) {
+ final int type_index = mrframe.typeargs.indexOf(tree);
+ switch (mrframe.mode) {
+ case INVOKE:
+ return TypeAnnotationPosition
+ .methodRefTypeArg(location.toList(),
+ currentLambda,
+ type_index, frame.pos);
+ case NEW:
+ return TypeAnnotationPosition
+ .constructorRefTypeArg(location.toList(),
+ currentLambda,
+ type_index, frame.pos);
+ default:
+ throw new AssertionError("Unknown method reference mode " + mrframe.mode +
+ " for tree " + tree + " within frame " + frame);
+ }
+ } else {
+ throw new AssertionError("Could not determine type argument position of tree " + tree +
+ " within frame " + frame);
+ }
+ }
+
+ case ARRAY_TYPE: {
+ location = location.prepend(TypePathEntry.ARRAY);
+ List<JCTree> newPath = path.tail;
+ while (true) {
+ JCTree npHead = newPath.tail.head;
+ if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) {
+ newPath = newPath.tail;
+ location = location.prepend(TypePathEntry.ARRAY);
+ } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
+ newPath = newPath.tail;
+ } else {
+ break;
+ }
+ }
+ return resolveFrame(newPath.head, newPath.tail.head,
+ newPath, currentLambda,
+ outer_type_index, location);
+ }
+
+ case TYPE_PARAMETER:
+ if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) {
+ final JCClassDecl clazz =
+ (JCClassDecl)path.tail.tail.head;
+ final int parameter_index =
+ clazz.typarams.indexOf(path.tail.head);
+ final int bound_index =
+ ((JCTypeParameter)frame).bounds.get(0)
+ .type.isInterface() ?
+ ((JCTypeParameter)frame).bounds.indexOf(tree) + 1:
+ ((JCTypeParameter)frame).bounds.indexOf(tree);
+ return TypeAnnotationPosition
+ .typeParameterBound(location.toList(),
+ currentLambda,
+ parameter_index, bound_index,
+ frame.pos);
+ } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) {
+ final JCMethodDecl method =
+ (JCMethodDecl)path.tail.tail.head;
+ final int parameter_index =
+ method.typarams.indexOf(path.tail.head);
+ final int bound_index =
+ ((JCTypeParameter)frame).bounds.get(0)
+ .type.isInterface() ?
+ ((JCTypeParameter)frame).bounds.indexOf(tree) + 1:
+ ((JCTypeParameter)frame).bounds.indexOf(tree);
+ return TypeAnnotationPosition
+ .methodTypeParameterBound(location.toList(),
+ currentLambda,
+ parameter_index,
+ bound_index,
+ frame.pos);
+ } else {
+ throw new AssertionError("Could not determine position of tree " + tree +
+ " within frame " + frame);
+ }
+
+ case VARIABLE:
+ VarSymbol v = ((JCVariableDecl)frame).sym;
+ if (v.getKind() != ElementKind.FIELD) {
+ v.owner.appendUniqueTypeAttributes(v.getRawTypeAttributes());
+ }
+ switch (v.getKind()) {
+ case LOCAL_VARIABLE:
+ return TypeAnnotationPosition
+ .localVariable(location.toList(), currentLambda,
+ frame.pos);
+ case FIELD:
+ return TypeAnnotationPosition.field(location.toList(),
+ currentLambda,
+ frame.pos);
+ case PARAMETER:
+ if (v.getQualifiedName().equals(names._this)) {
+ return TypeAnnotationPosition
+ .methodReceiver(location.toList(),
+ currentLambda,
+ frame.pos);
+ } else {
+ final int parameter_index =
+ methodParamIndex(path, frame);
+ return TypeAnnotationPosition
+ .methodParameter(location.toList(),
+ currentLambda,
+ parameter_index,
+ frame.pos);
+ }
+ case EXCEPTION_PARAMETER:
+ return TypeAnnotationPosition
+ .exceptionParameter(location.toList(),
+ currentLambda,
+ frame.pos);
+ case RESOURCE_VARIABLE:
+ return TypeAnnotationPosition
+ .resourceVariable(location.toList(),
+ currentLambda,
+ frame.pos);
+ default:
+ throw new AssertionError("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
+ }
+
+ case ANNOTATED_TYPE: {
+ if (frame == tree) {
+ // This is only true for the first annotated type we see.
+ // For any other annotated types along the path, we do
+ // not care about inner types.
+ JCAnnotatedType atypetree = (JCAnnotatedType) frame;
+ final Type utype = atypetree.underlyingType.type;
+ Assert.checkNonNull(utype);
+ Symbol tsym = utype.tsym;
+ if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) ||
+ utype.getKind().equals(TypeKind.WILDCARD) ||
+ utype.getKind().equals(TypeKind.ARRAY)) {
+ // Type parameters, wildcards, and arrays have the declaring
+ // class/method as enclosing elements.
+ // There is actually nothing to do for them.
+ } else {
+ location = locateNestedTypes(utype, location);
+ }
+ }
+ List<JCTree> newPath = path.tail;
+ return resolveFrame(newPath.head, newPath.tail.head,
+ newPath, currentLambda,
+ outer_type_index, location);
+ }
+
+ case UNION_TYPE: {
+ List<JCTree> newPath = path.tail;
+ return resolveFrame(newPath.head, newPath.tail.head,
+ newPath, currentLambda,
+ outer_type_index, location);
+ }
+
+ case INTERSECTION_TYPE: {
+ JCTypeIntersection isect = (JCTypeIntersection)frame;
+ final List<JCTree> newPath = path.tail;
+ return resolveFrame(newPath.head, newPath.tail.head,
+ newPath, currentLambda,
+ isect.bounds.indexOf(tree), location);
+ }
+
+ case METHOD_INVOCATION: {
+ JCMethodInvocation invocation = (JCMethodInvocation)frame;
+ if (!invocation.typeargs.contains(tree)) {
+ throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation);
+ }
+ MethodSymbol exsym = (MethodSymbol) TreeInfo.symbol(invocation.getMethodSelect());
+ final int type_index = invocation.typeargs.indexOf(tree);
+ if (exsym == null) {
+ throw new AssertionError("could not determine symbol for {" + invocation + "}");
+ } else if (exsym.isConstructor()) {
+ return TypeAnnotationPosition
+ .constructorInvocationTypeArg(location.toList(),
+ currentLambda,
+ type_index,
+ invocation.pos);
+ } else {
+ return TypeAnnotationPosition
+ .methodInvocationTypeArg(location.toList(),
+ currentLambda,
+ type_index,
+ invocation.pos);
+ }
+ }
+
+ case EXTENDS_WILDCARD:
+ case SUPER_WILDCARD: {
+ // Annotations in wildcard bounds
+ final List<JCTree> newPath = path.tail;
+ return resolveFrame(newPath.head, newPath.tail.head,
+ newPath, currentLambda,
+ outer_type_index,
+ location.prepend(TypePathEntry.WILDCARD));
+ }
+
+ case MEMBER_SELECT: {
+ final List<JCTree> newPath = path.tail;
+ return resolveFrame(newPath.head, newPath.tail.head,
+ newPath, currentLambda,
+ outer_type_index, location);
+ }
+
+ default:
+ throw new AssertionError("Unresolved frame: " + frame +
+ " of kind: " + frame.getKind() +
+ "\n Looking for tree: " + tree);
+ }
+ }
+
+ private ListBuffer<TypePathEntry>
+ locateNestedTypes(Type type,
+ ListBuffer<TypePathEntry> depth) {
+ Type encl = type.getEnclosingType();
+ while (encl != null &&
+ encl.getKind() != TypeKind.NONE &&
+ encl.getKind() != TypeKind.ERROR) {
+ depth = depth.prepend(TypePathEntry.INNER_TYPE);
+ encl = encl.getEnclosingType();
+ }
+ return depth;
+ }
+
+ private int methodParamIndex(List<JCTree> path, JCTree param) {
+ List<JCTree> curr = path;
+ while (curr.head.getTag() != Tag.METHODDEF &&
+ curr.head.getTag() != Tag.LAMBDA) {
+ curr = curr.tail;
+ }
+ if (curr.head.getTag() == Tag.METHODDEF) {
+ JCMethodDecl method = (JCMethodDecl)curr.head;
+ return method.params.indexOf(param);
+ } else if (curr.head.getTag() == Tag.LAMBDA) {
+ JCLambda lambda = (JCLambda)curr.head;
+ return lambda.params.indexOf(param);
+ } else {
+ Assert.error("methodParamIndex expected to find method or lambda for param: " + param);
+ return -1;
+ }
+ }
+
+ // Each class (including enclosed inner classes) is visited separately.
+ // This flag is used to prevent from visiting inner classes.
+ private boolean isInClass = false;
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ if (isInClass)
+ return;
+ isInClass = true;
+
+ if (sigOnly) {
+ scan(tree.mods);
+ scan(tree.typarams);
+ scan(tree.extending);
+ scan(tree.implementing);
+ }
+ scan(tree.defs);
+ }
+
+ /**
+ * Resolve declaration vs. type annotations in methods and
+ * then determine the positions.
+ */
+ @Override
+ public void visitMethodDef(final JCMethodDecl tree) {
+ if (tree.sym == null) {
+ Assert.error("Visiting tree node before memberEnter");
+ }
+ if (sigOnly) {
+ if (!tree.mods.annotations.isEmpty()) {
+ if (tree.sym.isConstructor()) {
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.methodReturn(tree.pos);
+ // Use null to mark that the annotations go
+ // with the symbol.
+ separateAnnotationsKinds(tree, null, tree.sym, pos);
+ } else {
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.methodReturn(tree.restype.pos);
+ separateAnnotationsKinds(tree.restype,
+ tree.sym.type.getReturnType(),
+ tree.sym, pos);
+ }
+ }
+ if (tree.recvparam != null && tree.recvparam.sym != null &&
+ !tree.recvparam.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ // TODO: make sure there are no declaration annotations.
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.methodReceiver(tree.recvparam.vartype.pos);
+ separateAnnotationsKinds(tree.recvparam.vartype,
+ tree.recvparam.sym.type,
+ tree.recvparam.sym, pos);
+ }
+ int i = 0;
+ for (JCVariableDecl param : tree.params) {
+ if (!param.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.methodParameter(i, param.vartype.pos);
+ separateAnnotationsKinds(param.vartype,
+ param.sym.type,
+ param.sym, pos);
+ }
+ ++i;
+ }
+ }
+
+ push(tree);
+ // super.visitMethodDef(tree);
+ if (sigOnly) {
+ scan(tree.mods);
+ scan(tree.restype);
+ scan(tree.typarams);
+ scan(tree.recvparam);
+ scan(tree.params);
+ scan(tree.thrown);
+ } else {
+ scan(tree.defaultValue);
+ scan(tree.body);
+ }
+ pop();
+ }
+
+ /* Store a reference to the current lambda expression, to
+ * be used by all type annotations within this expression.
+ */
+ private JCLambda currentLambda = null;
+
+ public void visitLambda(JCLambda tree) {
+ JCLambda prevLambda = currentLambda;
+ try {
+ currentLambda = tree;
+
+ int i = 0;
+ for (JCVariableDecl param : tree.params) {
+ if (!param.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.methodParameter(tree, i,
+ param.vartype.pos);
+ separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+ }
+ ++i;
+ }
+
+ push(tree);
+ scan(tree.body);
+ scan(tree.params);
+ pop();
+ } finally {
+ currentLambda = prevLambda;
+ }
+ }
+
+ /**
+ * Resolve declaration vs. type annotations in variable declarations and
+ * then determine the positions.
+ */
+ @Override
+ public void visitVarDef(final JCVariableDecl tree) {
+ if (tree.mods.annotations.isEmpty()) {
+ // Nothing to do for separateAnnotationsKinds if
+ // there are no annotations of either kind.
+ } else if (tree.sym == null) {
+ Assert.error("Visiting tree node before memberEnter");
+ } else if (tree.sym.getKind() == ElementKind.PARAMETER) {
+ // Parameters are handled in visitMethodDef or visitLambda.
+ } else if (tree.sym.getKind() == ElementKind.FIELD) {
+ if (sigOnly) {
+ TypeAnnotationPosition pos =
+ TypeAnnotationPosition.field(tree.pos);
+ separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+ }
+ } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) {
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.localVariable(currentLambda,
+ tree.pos);
+ separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+ } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.exceptionParameter(currentLambda,
+ tree.pos);
+ separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+ } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.resourceVariable(currentLambda,
+ tree.pos);
+ separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+ } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
+ // No type annotations can occur here.
+ } else {
+ // There is nothing else in a variable declaration that needs separation.
+ Assert.error("Unhandled variable kind: " + tree + " of kind: " + tree.sym.getKind());
+ }
+
+ push(tree);
+ // super.visitVarDef(tree);
+ scan(tree.mods);
+ scan(tree.vartype);
+ if (!sigOnly) {
+ scan(tree.init);
+ }
+ pop();
+ }
+
+ @Override
+ public void visitBlock(JCBlock tree) {
+ // Do not descend into top-level blocks when only interested
+ // in the signature.
+ if (!sigOnly) {
+ scan(tree.stats);
+ }
+ }
+
+ @Override
+ public void visitAnnotatedType(JCAnnotatedType tree) {
+ push(tree);
+ findPosition(tree, tree, tree.annotations);
+ pop();
+ super.visitAnnotatedType(tree);
+ }
+
+ @Override
+ public void visitTypeParameter(JCTypeParameter tree) {
+ findPosition(tree, peek2(), tree.annotations);
+ super.visitTypeParameter(tree);
+ }
+
+ private void copyNewClassAnnotationsToOwner(JCNewClass tree) {
+ Symbol sym = tree.def.sym;
+ final TypeAnnotationPosition pos =
+ TypeAnnotationPosition.newObj(tree.pos);
+ ListBuffer<Attribute.TypeCompound> newattrs = new ListBuffer<>();
+
+ for (Attribute.TypeCompound old : sym.getRawTypeAttributes()) {
+ newattrs.append(new Attribute.TypeCompound(old.type, old.values,
+ pos));
+ }
+
+ sym.owner.appendUniqueTypeAttributes(newattrs.toList());
+ }
+
+ @Override
+ public void visitNewClass(JCNewClass tree) {
+ if (tree.def != null &&
+ !tree.def.mods.annotations.isEmpty()) {
+ JCClassDecl classdecl = tree.def;
+ TypeAnnotationPosition pos;
+
+ if (classdecl.extending == tree.clazz) {
+ pos = TypeAnnotationPosition.classExtends(tree.pos);
+ } else if (classdecl.implementing.contains(tree.clazz)) {
+ final int index = classdecl.implementing.indexOf(tree.clazz);
+ pos = TypeAnnotationPosition.classExtends(index, tree.pos);
+ } else {
+ // In contrast to CLASS elsewhere, typarams cannot occur here.
+ throw new AssertionError("Could not determine position of tree " + tree);
+ }
+ Type before = classdecl.sym.type;
+ separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos);
+ copyNewClassAnnotationsToOwner(tree);
+ // classdecl.sym.type now contains an annotated type, which
+ // is not what we want there.
+ // TODO: should we put this type somewhere in the superclass/interface?
+ classdecl.sym.type = before;
+ }
+
+ scan(tree.encl);
+ scan(tree.typeargs);
+ scan(tree.clazz);
+ scan(tree.args);
+
+ // The class body will already be scanned.
+ // scan(tree.def);
+ }
+
+ @Override
+ public void visitNewArray(JCNewArray tree) {
+ findPosition(tree, tree, tree.annotations);
+ int dimAnnosCount = tree.dimAnnotations.size();
+ ListBuffer<TypePathEntry> depth = new ListBuffer<>();
+
+ // handle annotations associated with dimensions
+ for (int i = 0; i < dimAnnosCount; ++i) {
+ ListBuffer<TypePathEntry> location =
+ new ListBuffer<TypePathEntry>();
+ if (i != 0) {
+ depth = depth.append(TypePathEntry.ARRAY);
+ location = location.appendList(depth.toList());
+ }
+ final TypeAnnotationPosition p =
+ TypeAnnotationPosition.newObj(location.toList(),
+ currentLambda,
+ tree.pos);
+
+ setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
+ }
+
+ // handle "free" annotations
+ // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
+ // TODO: is depth.size == i here?
+ JCExpression elemType = tree.elemtype;
+ depth = depth.append(TypePathEntry.ARRAY);
+ while (elemType != null) {
+ if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
+ JCAnnotatedType at = (JCAnnotatedType)elemType;
+ final ListBuffer<TypePathEntry> locationbuf =
+ locateNestedTypes(elemType.type,
+ new ListBuffer<TypePathEntry>());
+ final List<TypePathEntry> location =
+ locationbuf.toList().prependList(depth.toList());
+ final TypeAnnotationPosition p =
+ TypeAnnotationPosition.newObj(location, currentLambda,
+ tree.pos);
+ setTypeAnnotationPos(at.annotations, p);
+ elemType = at.underlyingType;
+ } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
+ depth = depth.append(TypePathEntry.ARRAY);
+ elemType = ((JCArrayTypeTree)elemType).elemtype;
+ } else if (elemType.hasTag(JCTree.Tag.SELECT)) {
+ elemType = ((JCFieldAccess)elemType).selected;
+ } else {
+ break;
+ }
+ }
+ scan(tree.elems);
+ }
+
+ private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) {
+ if (!annotations.isEmpty()) {
+ /*
+ System.err.println("Finding pos for: " + annotations);
+ System.err.println(" tree: " + tree + " kind: " + tree.getKind());
+ System.err.println(" frame: " + frame + " kind: " + frame.getKind());
+ */
+ final TypeAnnotationPosition p =
+ resolveFrame(tree, frame, frames.toList(), currentLambda, 0,
+ new ListBuffer<TypePathEntry>());
+ setTypeAnnotationPos(annotations, p);
+ }
+ }
+
+ private void setTypeAnnotationPos(List<JCAnnotation> annotations,
+ TypeAnnotationPosition position) {
+ for (JCAnnotation anno : annotations) {
+ // attribute might be null during DeferredAttr;
+ // we will be back later.
+ if (anno.attribute != null) {
+ ((Attribute.TypeCompound) anno.attribute).position = position;
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + ": sigOnly: " + sigOnly;
+ }
+ }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Sep 10 19:38:20 2014 -0700
@@ -29,8 +29,6 @@
import java.util.LinkedHashMap;
import java.util.Map;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.type.TypeKind;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.util.*;
@@ -38,7 +36,6 @@
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.code.TypeAnnotationPosition.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
@@ -263,78 +260,36 @@
* Compute an attribute from its annotation.
*********************************************************************/
- /**
- * Enter (and attribute) a single regular annotation, returning
- * its Attribute. We give these annotations a position in case we
- * end up creating a type annotation from using toTypeCompound.
- *
- * In some cases, namely on annotations that can never be type
- * annotations (like package annotations), the position can be
- * null; however, if this annotation is in a place where it might
- * possibly denote a type annotation, it will have a non-null
- * position.
- *
- * @param a Annotation to attribute.
- * @param expected Expected annotation type.
- * @param env The environment.
- * @param position The type annotation position this will have if
- * it's converted to a type annotation.
- * @return The Attribute.Compound representing this annotation.
+ /** Process a single compound annotation, returning its
+ * Attribute. Used from MemberEnter for attaching the attributes
+ * to the annotated symbol.
*/
Attribute.Compound enterAnnotation(JCAnnotation a,
Type expected,
- Env<AttrContext> env,
- TypeAnnotationPosition position) {
- List<Pair<MethodSymbol,Attribute>> buf =
- enterAttributeValues(a, expected, env, position);
- Attribute.Compound ac =
- new Attribute.Compound(a.type, buf, position);
+ Env<AttrContext> env) {
+ List<Pair<MethodSymbol,Attribute>> elems =
+ enterAttributeValues(a, expected, env);
+ Attribute.Compound ac = new Attribute.Compound(a.type, elems);
a.attribute = ac;
return ac;
}
- /**
- * Enter (and attribute) a single type annotation, returning its
- * Attribute.
- *
- * Things are a bit complicated, though, because a single source
- * annotation (JCAnnotation) might give rise to several bytecode
- * annotations (Attribute.TypeCompound), but we can only associate
- * a source annotation with one bytecode annotation. Thus, we
- * have to distinguish between the "primary" (which will be stored
- * to the JCAnnotation) and "secondary" (which won't) annotations.
- * The primary place this gets used is for anonymous classes.
- *
- * The annotations we generate for the new instruction are the
- * primary, and the ones we generate for the class are the
- * secondaries. (Note: this choice is arbitrary, and it does not
- * appear to cause any problems if these roles are reversed)
- *
- * @param a The annotation to attribute.
- * @param expected The expected annotation type.
- * @param env The environment.
- * @param position The type annotation position to give the type
- * annotation.
- * @param secondaryAttr Whether or not this is a secondary (ie
- * will ignore the .attribute field on a).
- * @return The Attribute.TypeCompound representing the annotation.
- */
Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
Type expected,
- Env<AttrContext> env,
- TypeAnnotationPosition position,
- boolean secondaryAttr) {
- List<Pair<MethodSymbol,Attribute>> buf =
- enterAttributeValues(a, expected, env, position);
+ Env<AttrContext> env) {
+ List<Pair<MethodSymbol,Attribute>> elems =
+ enterAttributeValues(a, expected, env);
+
+ if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) {
+ // Create a new TypeCompound
- // Secondary attr means we do not set the .attribute field of
- // the JCAnnotation, nor do we pay attention to it.
- if (!secondaryAttr || a.attribute == null ||
- !(a.attribute instanceof Attribute.TypeCompound)) {
- // Create a new TypeCompound
Attribute.TypeCompound tc =
- new Attribute.TypeCompound(a.type, buf, position);
+ new Attribute.TypeCompound(a.type, elems,
+ // TODO: Eventually, we will get rid of this use of
+ // unknown, because we'll get a position from
+ // MemberEnter (task 8027262).
+ TypeAnnotationPosition.unknown);
a.attribute = tc;
return tc;
} else {
@@ -343,12 +298,10 @@
}
}
- // Attribute all the annotation's values.
private List<Pair<MethodSymbol,Attribute>>
enterAttributeValues(JCAnnotation a,
Type expected,
- Env<AttrContext> env,
- TypeAnnotationPosition position) {
+ Env<AttrContext> env) {
// The annotation might have had its type attributed (but not
// checked) by attr.attribAnnotationTypes during MemberEnter,
// in which case we do not need to do it again.
@@ -373,13 +326,13 @@
JCExpression t = tl.head;
if (!t.hasTag(ASSIGN)) {
log.error(t.pos(), "annotation.value.must.be.name.value");
- enterAttributeValue(t.type = syms.errType, t, env, position);
+ enterAttributeValue(t.type = syms.errType, t, env);
continue;
}
JCAssign assign = (JCAssign)t;
if (!assign.lhs.hasTag(IDENT)) {
log.error(t.pos(), "annotation.value.must.be.name.value");
- enterAttributeValue(t.type = syms.errType, t, env, position);
+ enterAttributeValue(t.type = syms.errType, t, env);
continue;
}
JCIdent left = (JCIdent)assign.lhs;
@@ -394,7 +347,7 @@
if (method.owner != a.type.tsym && !isError)
log.error(left.pos(), "no.annotation.member", left.name, a.type);
Type result = method.type.getReturnType();
- Attribute value = enterAttributeValue(result, assign.rhs, env, position);
+ Attribute value = enterAttributeValue(result, assign.rhs, env);
if (!method.type.isErroneous())
buf.append(new Pair<>((MethodSymbol)method, value));
t.type = result;
@@ -405,13 +358,6 @@
Attribute enterAttributeValue(Type expected,
JCExpression tree,
Env<AttrContext> env) {
- return enterAttributeValue(expected, tree, env, null);
- }
-
- Attribute enterAttributeValue(Type expected,
- JCExpression tree,
- Env<AttrContext> env,
- TypeAnnotationPosition position) {
//first, try completing the attribution value sym - if a completion
//error is thrown, we should recover gracefully, and display an
//ordinary resolution diagnostic.
@@ -433,7 +379,8 @@
ListBuffer<Attribute> buf = new ListBuffer<>();
for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
buf.append(enterAttributeValue(types.elemtype(expected),
- l.head, env, position));
+ l.head,
+ env));
}
na.type = expected;
return new Attribute.
@@ -447,13 +394,15 @@
log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
}
for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
- enterAttributeValue(syms.errType, l.head, env, position);
+ enterAttributeValue(syms.errType,
+ l.head,
+ env);
}
return new Attribute.Error(syms.errType);
}
if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) {
if (tree.hasTag(ANNOTATION)) {
- return enterAnnotation((JCAnnotation)tree, expected, env, position);
+ return enterAnnotation((JCAnnotation)tree, expected, env);
} else {
log.error(tree.pos(), "annotation.value.must.be.annotation");
expected = syms.errType;
@@ -462,7 +411,7 @@
if (tree.hasTag(ANNOTATION)) { //error recovery
if (!expected.isErroneous())
log.error(tree.pos(), "annotation.not.valid.for.type", expected);
- enterAnnotation((JCAnnotation)tree, syms.errType, env, position);
+ enterAnnotation((JCAnnotation)tree, syms.errType, env);
return new Attribute.Error(((JCAnnotation)tree).annotationType.type);
}
if (expected.isPrimitive() ||
@@ -529,11 +478,9 @@
* synthesized container annotation or null IFF all repeating
* annotation are invalid. This method reports errors/warnings.
*/
- private <T extends Attribute.Compound> T processRepeatedAnnotations(
- List<T> annotations,
+ private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
AnnotationContext<T> ctx,
- Symbol on,
- TypeAnnotationPosition position) {
+ Symbol on) {
T firstOccurrence = annotations.head;
List<Attribute> repeated = List.nil();
Type origAnnoType = null;
@@ -545,8 +492,12 @@
!annotations.tail.isEmpty()); // i.e. size() > 1
int count = 0;
- for (List<T> al = annotations; !al.isEmpty(); al = al.tail) {
+ for (List<T> al = annotations;
+ !al.isEmpty();
+ al = al.tail)
+ {
count++;
+
// There must be more than a single anno in the annotation list
Assert.check(count > 1 || !al.tail.isEmpty());
@@ -586,16 +537,26 @@
new Pair<MethodSymbol, Attribute>(containerValueSymbol,
new Attribute.Array(arrayOfOrigAnnoType, repeated));
if (ctx.isTypeCompound) {
- Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), position);
+ /* TODO: the following code would be cleaner:
+ Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
+ ((Attribute.TypeCompound)annotations.head).position);
+ JCTypeAnnotation annoTree = m.TypeAnnotation(at);
+ at = enterTypeAnnotation(annoTree, targetContainerType, ctx.env);
+ */
+ // However, we directly construct the TypeCompound to keep the
+ // direct relation to the contained TypeCompounds.
+ Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
+ ((Attribute.TypeCompound)annotations.head).position);
+
+ // TODO: annotation applicability checks from below?
+
at.setSynthesized(true);
@SuppressWarnings("unchecked")
T x = (T) at;
return x;
} else {
- Attribute.Compound c = new Attribute.Compound(targetContainerType,
- List.of(p),
- position);
+ Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p));
JCAnnotation annoTree = m.Annotation(c);
if (!chk.annotationApplicable(annoTree, on))
@@ -604,7 +565,7 @@
if (!chk.validateAnnotationDeferErrors(annoTree))
log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
- c = enterAnnotation(annoTree, targetContainerType, ctx.env, position);
+ c = enterAnnotation(annoTree, targetContainerType, ctx.env);
c.setSynthesized(true);
@SuppressWarnings("unchecked")
@@ -616,7 +577,6 @@
}
}
-
/** Fetches the actual Type that should be the containing annotation. */
private Type getContainingType(Attribute.Compound currentAnno,
DiagnosticPosition pos,
@@ -746,53 +706,31 @@
return fatalError ? null : containerValueSymbol;
}
- /**
- * First step of repeating annotations handling: go through a list
- * of annotations, and gather up all the repeated ones into a map,
- * which we use to build an AnnotationContext.
- *
- * Because we do this, we need to get all the annotations for a
- * given AST node at once (ie. if we have "@A @B @A int foo;", we
- * have to get "@A @B @A" at the same time).
- *
- * @param annotations The annotations being attached.
- * @param env The environment.
- * @param sym The symbol to which the annotations will be attached.
- * @param creator The attribute creator used to enter the annotations.
- * @param position The position for any type annotations.
- * @return The AnnotaionContext for use in the next phase.
- */
private <T extends Attribute.Compound> AnnotationContext<T>
prepareEnterAnnotations(List<JCAnnotation> annotations,
Env<AttrContext> env,
Symbol sym,
AttributeCreator<T> creator,
- TypeAnnotationPosition position) {
+ boolean isTypeCompound) {
Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>();
Map<T, DiagnosticPosition> pos = new HashMap<>();
- // Go through the annotation list, build up a map from
- // annotation types to lists of annotations.
for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
- T c = creator.create(a, syms.annotationType, env, position);
+ T c = creator.create(a, syms.annotationType, env);
Assert.checkNonNull(c, "Failed to create annotation");
if (annotated.containsKey(a.type.tsym)) {
- // Make sure we even allow repeating annotations.
if (!allowRepeatedAnnos) {
log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
allowRepeatedAnnos = true;
}
- // Append the annotation to the list for this kind of
- // annotation.
ListBuffer<T> l = annotated.get(a.type.tsym);
l = l.append(c);
annotated.put(a.type.tsym, l);
pos.put(c, a.pos());
} else {
- // We are seeing the first annotation of this kind.
annotated.put(a.type.tsym, ListBuffer.of(c));
pos.put(c, a.pos());
}
@@ -806,54 +744,25 @@
}
return new AnnotationContext<>(env, annotated, pos,
- creator.createsTypeCompound());
+ isTypeCompound);
}
- /**
- * Entry-point for repeating annotations handling. At this point,
- * we should know the type annotation position, and we should have
- * all the annotations for a given source location.
- *
- * We first gather up all the repeated annotations and build an
- * AnnotationContext. Then create Placeholder's for any repeated
- * annotations and send them further down the pipeline.
- *
- * Something to keep in mind here is that even if we are handling
- * "declaration" annotations, it is still possible that those
- * might turn into type annotations (consider "@A @B int foo;",
- * for example).
- *
- * The pipeline uses a sort of continuation-passing like style,
- * with creator and attacher. This allows two things. First, it
- * allows for a single pipeline for repeating annotations,
- * regardless of what eventually happens to the annotations.
- * Second, it allows us to avoid some unsafe casts we would
- * otherwise have to make.
- *
- * @param annotations The annotations to handle.
- * @param env The environment.
- * @param sym The symbol to which to attach annotations.
- * @param position The position for type annotations.
- * @param creator The creator to use to enter annotations.
- * @param attacher The attacher to use to attach annotations.
- */
+ // Gather up annotations into a map from type symbols to lists of
+ // Compound attributes, then continue on with repeating
+ // annotations processing
private <T extends Attribute.Compound>
void attachAttributesLater(final List<JCAnnotation> annotations,
final Env<AttrContext> env,
final Symbol sym,
- final TypeAnnotationPosition position,
+ final boolean isTypeCompound,
final AttributeCreator<T> creator,
final AttributeAttacher<T> attacher) {
- // First, gather up all the repeated annotations.
final AnnotationContext<T> ctx =
- prepareEnterAnnotations(annotations, env, sym, creator, position);
+ prepareEnterAnnotations(annotations, env, sym, creator, isTypeCompound);
final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated =
ctx.annotated;
boolean hasRepeated = false;
- // Now run through all the annotation types in the
- // AnnotationContext. If there are any that have more than
- // one entry, then we set up a Placeholder for them.
List<T> buf = List.<T>nil();
for (ListBuffer<T> lb : annotated.values()) {
if (lb.size() == 1) {
@@ -868,62 +777,14 @@
final List<T> attrs = buf.reverse();
- if (!creator.createsTypeCompound()) {
+ if (!isTypeCompound) {
// Attach declaration attributes early, so
// that @Repeatable and other annotations get attached.
// Since the attacher uses setDeclarationAttributes, this
// will be overwritten later.
- //
- // The root cause of this is that annotations are
- // themselves defined using annotations. However, it is
- // never the case that a type annotation affects the
- // definition of an annotation, so we don't have to do
- // this.
- //
- // We really should find a better way to do this.
- @SuppressWarnings("unchecked")
- List<Attribute.Compound> tempattrs = (List<Attribute.Compound>) attrs;
- sym.setDeclarationAttributes(tempattrs);
+ attacher.attach(sym, attrs);
}
-
if (hasRepeated) {
- // If we have repeated annotations, then we go to the next
- // pipeline step, which replaces all the placeholders.
- replacePlaceholdersAndAttach(attrs, ctx, env, sym, attacher);
- } else {
- // If we don't have repeated annotations, then we still
- // have to run the annotations through the rest of the
- // pipeline.
- //
- // For type annotations, we might have error-reporting to
- // do, and the attacher might end up attaching the
- // annotation to the symbol's owner as well.
- //
- // For regular annotations, we might have a
- // classifyingAttacher, in which case we have to pull the
- // annotations off the symbol, classify them, and then put
- // them in the right place.
- attachAttributesAfterRepeated(attrs, env, attacher);
- }
- }
-
- /**
- * Next pipeline step for repeated annotations: replate all the
- * placeholders, and then send the result further down the pipe.
- *
- * @param attrs The Attributes representing the annotations.
- * @param ctx The AnnotationContext being used.
- * @param env The environment.
- * @param sym The symbol to which to attach annotations.
- * @param attacher The attacher to use to attach annotations.
- */
- private <T extends Attribute.Compound>
- void replacePlaceholdersAndAttach(final List<T> attrs,
- final AnnotationContext<T> ctx,
- final Env<AttrContext> env,
- final Symbol sym,
- final AttributeAttacher<T> attacher) {
- // Set up a Worker.
repeated(new Annotate.Worker() {
@Override
public String toString() {
@@ -935,493 +796,38 @@
JavaFileObject oldSource =
log.useSource(env.toplevel.sourcefile);
try {
- // Replace placeholders
- final List<T> replaced =
- replacePlaceholders(attrs, ctx, sym);
- // Then send the result to the final pipeline stage.
- attachAttributesAfterRepeated(replaced, env, attacher);
+ attacher.attach(sym, replacePlaceholders(attrs, ctx, sym));
} finally {
log.useSource(oldSource);
}
}
});
- }
-
- /**
- * Final pipeline stage. Simply use the attacher to deal with the
- * annotations however we want to deal with them. Note that
- * attachers may do a number of things, like attach annotations to
- * other symbols (as is the case with some type annotations, which
- * get attached to their symbol's owner as well), report errors,
- * or even create copies (as is the case with classifyingAttacher)
- *
- * At this point, we have to be able to guarantee that we don't
- * see any Placeholders.
- *
- * @param attrs The Attributes representing the annotations.
- * @param env The environment.
- * @param attacher The attacher we use to finish handling the
- * annotations.
- */
- private <T extends Attribute.Compound>
- void attachAttributesAfterRepeated(final List<T> attrs,
- final Env<AttrContext> env,
- final AttributeAttacher<T> attacher) {
- // Set up a Worker that just calls the attacher.
- afterRepeated(new Worker() {
- @Override
- public String toString() {
- return "attach pass for: " + attrs;
- }
-
- @Override
- public void run() {
- JavaFileObject oldSource =
- log.useSource(env.toplevel.sourcefile);
- try {
- attacher.attach(attrs);
- } finally {
- log.useSource(oldSource);
- }
- }
- });
- }
-
- /**
- * AttributeAttachers are similar to continuations. That contains
- * the behavior of the final stage of the annotation pipeline,
- * when we've creted Attributes (which have a type annotation
- * position), and we've dealt with repeating annotations. Once we
- * have done all that, we simply hand off the list of attributes
- * to the attacher and let it do its work.
- *
- * If we didn't have the multiple deferred steps, we could
- * implement this by returning a list of Attributes from a
- * top-level method representing the entire repeating annotations
- * pipeline. Since we have to handle annotations in multiple
- * steps, we can't do that. Therefore, in this light, we can
- * think of an attacher as being essentially a return
- * continuation.
- *
- * We also have ways to "build" more complex attachers out of
- * simple ones, such as classifyingAttacher. This allows us
- * considerable flexibility in how we deal with annotations at the
- * end of the pipeline (which is necessary, because there are a
- * lot of cases).
- */
- public interface AttributeAttacher<T extends Attribute.Compound> {
- public void attach(List<T> attrs);
- }
-
- /**
- * An interface for describing error reporting behaviors for
- * type-only annotations. Sometimes, we need to report errors if
- * any annotations wind up being type-only annotations (the best
- * example being for illegal scoping). But at the point where we
- * know this, we don't always know if a given annotation will be a
- * type-only annotation, a regular annotation, or both. So we
- * have to defer the error-reporting until we do know.
- */
- public interface Reporter<T extends Attribute.Compound> {
- public void report(List<T> attrs);
- }
-
- public enum AnnotationKind { DECLARATION, TYPE, BOTH }
-
- public Attribute[] getTargetTypes(Attribute.Compound a) {
- Attribute.Compound atTarget =
- a.type.tsym.attribute(syms.annotationTargetType.tsym);
- if (atTarget == null) {
- return null;
- }
- Attribute atValue = atTarget.member(names.value);
- Assert.check(atValue instanceof Attribute.Array);
- return ((Attribute.Array) atValue).values;
- }
-
- public boolean hasTypeUseTarget(Attribute.Compound a,
- boolean isTypeParameter) {
- Attribute[] targets = getTargetTypes(a);
- if (targets != null) {
- for (Attribute app : targets) {
- Assert.check(app instanceof Attribute.Enum);
- Attribute.Enum e = (Attribute.Enum) app;
- if (e.value.name == names.TYPE_USE ||
- (isTypeParameter && e.value.name == names.TYPE_PARAMETER)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Determine whether an annotation is a declaration annotation,
- * a type annotation, or both.
- */
- public AnnotationKind annotationKind(Attribute.Compound a, Symbol s) {
- Attribute[] targets = getTargetTypes(a);
- if (targets == null) {
- return AnnotationKind.DECLARATION;
- }
- boolean isDecl = false, isType = false;
- for (Attribute app : targets) {
- Assert.check(app instanceof Attribute.Enum);
- Attribute.Enum e = (Attribute.Enum) app;
- if (e.value.name == names.TYPE) {
- if (s.kind == Kinds.TYP) {
- ElementKind skind = s.getKind();
- // The only symbols we should see here correspond
- // to definitions.
- Assert.check(skind == ElementKind.ANNOTATION_TYPE ||
- skind == ElementKind.INTERFACE ||
- skind == ElementKind.ENUM ||
- skind == ElementKind.CLASS);
- isDecl = true;
- }
- } else if (e.value.name == names.FIELD) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind != Kinds.MTH)
- isDecl = true;
- } else if (e.value.name == names.METHOD) {
- if (s.kind == Kinds.MTH &&
- !s.isConstructor())
- isDecl = true;
- } else if (e.value.name == names.PARAMETER) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind == Kinds.MTH &&
- (s.flags() & Flags.PARAMETER) != 0)
- isDecl = true;
- } else if (e.value.name == names.CONSTRUCTOR) {
- if (s.kind == Kinds.MTH &&
- s.isConstructor())
- isDecl = true;
- } else if (e.value.name == names.LOCAL_VARIABLE) {
- if (s.kind == Kinds.VAR &&
- s.owner.kind == Kinds.MTH &&
- (s.flags() & Flags.PARAMETER) == 0)
- isDecl = true;
- } else if (e.value.name == names.ANNOTATION_TYPE) {
- if (s.kind == Kinds.TYP &&
- (s.flags() & Flags.ANNOTATION) != 0)
- isDecl = true;
- } else if (e.value.name == names.PACKAGE) {
- if (s.kind == Kinds.PCK)
- isDecl = true;
- } else if (e.value.name == names.TYPE_USE) {
- if (s.kind == Kinds.TYP ||
- s.kind == Kinds.VAR ||
- (s.kind == Kinds.MTH && !s.isConstructor() &&
- !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
- (s.kind == Kinds.MTH && s.isConstructor()))
- isType = true;
- } else if (e.value.name == names.TYPE_PARAMETER) {
- /* Irrelevant in this case: we will never see symbols
- * that are type parameters, as we never attach
- * declaration annotations to them. */
- Assert.check(s.getKind() != ElementKind.TYPE_PARAMETER);
- } else {
- Assert.error("annotationKind(): unrecognized Attribute name " + e.value.name +
- " (" + e.value.name.getClass() + ")");
- }
- }
- if (isDecl && isType) {
- return AnnotationKind.BOTH;
- } else if (isType) {
- return AnnotationKind.TYPE;
} else {
- return AnnotationKind.DECLARATION;
+ attacher.attach(sym, attrs);
}
}
- /**
- * An attacher that just attaches annotations as declaration
- * annotations. This is used in places where we know for a fact
- * that type annotations cannot occur.
- */
- private AttributeAttacher<Attribute.Compound>
- declAnnotationsAttacher(final Symbol sym) {
- return new AttributeAttacher<Attribute.Compound>() {
+ private interface AttributeAttacher<T extends Attribute.Compound> {
+ public void attach(Symbol sym, List<T> attrs);
+ }
+
+ private final AttributeAttacher<Attribute.Compound> declAnnotationsAttacher =
+ new AttributeAttacher<Attribute.Compound>() {
@Override
- public String toString() {
- return "Attacher for strictly declaration annotations, for " +
- sym;
- }
-
- @Override
- public void attach(List<Attribute.Compound> attrs) {
+ public void attach(Symbol sym, List<Attribute.Compound> attrs) {
sym.resetAnnotations();
sym.setDeclarationAttributes(attrs);
}
};
- }
- /**
- * An attacher that just attaches annotations as type annotations.
- * We use this in places where only type annotations can occur.
- * The most common use for this is any annotation where we have to
- * "parse" a type (arrays, inner classes, type arguments, bounds,
- * etc.). We also use this for base types for non-declarations
- * (ie. casts, instanceofs, etc). A more subtle case is for
- * anonymous classes and receiver parameters, both of which cannot
- * have regular annotations.
- */
- private AttributeAttacher<Attribute.TypeCompound>
- typeAnnotationsAttacher(final Symbol sym) {
- return new AttributeAttacher<Attribute.TypeCompound>() {
- @Override
- public String toString() {
- return "Attacher for strictly type annotations, for " + sym;
- }
-
- @Override
- public void attach(List<Attribute.TypeCompound> attrs) {
- if (!attrs.isEmpty()) {
- attachTypeAnnotations(sym, attrs);
- }
- }
- };
- }
-
- /**
- * Attach type-only annotations using an attacher, and run a
- * reporter. Either the reporter or the attacher may be null, in
- * which case we skip that step.
- */
- private AttributeAttacher<Attribute.TypeCompound>
- reportingTypeAnnotationsAttacher(final AttributeAttacher<Attribute.TypeCompound> attacher,
- final Reporter<Attribute.TypeCompound> reporter) {
- return new AttributeAttacher<Attribute.TypeCompound>() {
- @Override
- public String toString() {
- return "Error-reporting type annotation, attacher is: " + attacher +
- "\n reporter is: " + reporter;
- }
-
+ private final AttributeAttacher<Attribute.TypeCompound> typeAnnotationsAttacher =
+ new AttributeAttacher<Attribute.TypeCompound>() {
@Override
- public void attach(List<Attribute.TypeCompound> attrs) {
- if (attacher != null)
- attacher.attach(attrs);
-
- if (reporter != null)
- reporter.report(attrs);
- }
- };
- }
-
- /**
- * Attach type-only annotations to a symbol and also update the
- * .type field on a tree (unless it is a package type). This is
- * used to put annotations on to a type as well as a symbol.
- */
- private AttributeAttacher<Attribute.TypeCompound>
- typeUpdatingTypeAnnotationsAttacher(final AttributeAttacher<Attribute.TypeCompound> attacher,
- final JCTree tree) {
- return new AttributeAttacher<Attribute.TypeCompound>() {
- @Override
- public String toString() {
- return "Type-updating type annotation attacher, attacher is: " + attacher +
- "\n tree is: " + tree;
- }
-
- @Override
- public void attach(List<Attribute.TypeCompound> attrs) {
- if (null != attacher)
- attacher.attach(attrs);
-
- if (!attrs.isEmpty() && !tree.type.hasTag(TypeTag.PACKAGE)) {
- tree.type = tree.type.annotatedType(attrs);
- }
- }
- };
- }
-
- /**
- * A Reporter for illegal scoping. We set one of these up in
- * TypeAnnotate whenever we are in a place that corresponds to a
- * package or static class that cannot be annotated.
- */
- private void reportIllegalScoping(List<Attribute.TypeCompound> attrs,
- int pos) {
- switch (attrs.size()) {
- case 0:
- // Don't issue an error if all type annotations are
- // also declaration annotations.
- // If the annotations are also declaration annotations, they are
- // illegal as type annotations but might be legal as declaration annotations.
- // The normal declaration annotation checks make sure that the use is valid.
- break;
- case 1:
- log.error(pos, "cant.type.annotate.scoping.1", attrs);
- break;
- default:
- log.error(pos, "cant.type.annotate.scoping", attrs);
- }
- }
-
- private Reporter<Attribute.TypeCompound>
- illegalScopingReporter(final int pos) {
- return new Reporter<Attribute.TypeCompound>() {
- @Override
- public String toString() {
- return "Illegal scoping reporter at position " + pos;
- }
-
- @Override
- public void report(List<Attribute.TypeCompound> attrs) {
- reportIllegalScoping(attrs, pos);
+ public void attach(Symbol sym, List<Attribute.TypeCompound> attrs) {
+ sym.appendUniqueTypeAttributes(attrs);
}
};
- }
- // Create the "simple case": just attach type and regular
- // annotations, no reporting.
- private AttributeAttacher<Attribute.Compound>
- classifyingAttacher(final Symbol sym) {
- return classifyingAttacher(sym, declAnnotationsAttacher(sym),
- typeAnnotationsAttacher(sym),
- null);
- }
-
-
- /**
- * Build an attacher for handling the case where we have
- * annotations, but we don't know for sure whether they are
- * declaration annotations, type annotations, or both.
- *
- * We do this by taking an attacher for declaration annotations,
- * another one for type annotations, and (possibly) a reporter for
- * type-only annotations. We then use the logic from
- * annotationKind to figure out what kind each annotation is and
- * deal with it accordingly.
- *
- * Any of the declAttacher, the typeAttacher, or the Reporter can
- * be null, in which case we skip it.
- *
- * We have to have the reporter *separate* from the type
- * annotation attacher, because we might be attaching type
- * annotations that are also declaration annotations. But the
- * semantics of reporters are that they get called for type-only
- * annotations. For an example of where this matters, consider
- * "@A java.lang.Object foo;", where @A can annotate packages and
- * type uses. We would create the classifyingAttacher with null
- * for the type attacher and an illegal scoping reporter. Both
- * attachers would end up getting called on @A (which, we'd skip
- * the type attacher, because it's null), the result being that @A
- * goes on foo as a declaration annotation. The reporter would
- * not get called, because there are no type-only annotations.
- * However, if @A can only annotate type uses, then it's a
- * type-only annotation, and we report an illegal scoping error.
- *
- * Note: there is a case where we want both attachers to be null:
- * speculative attribution.
- *
- * @param sym The symbol to which to attach annotations.
- * @param declAttacher The attacher to use for declaration (and
- * both) annotations, or null.
- * @param typeAttacher The attacher to use for type (and both)
- * annotations, or null.
- * @param reporter The reporter to use for type-only annotations, or null.
- * @return The created attacher.
- */
- private AttributeAttacher<Attribute.Compound>
- classifyingAttacher(final Symbol sym,
- final AttributeAttacher<Attribute.Compound> declAttacher,
- final AttributeAttacher<Attribute.TypeCompound> typeAttacher,
- final Reporter<Attribute.TypeCompound> reporter) {
- return new AttributeAttacher<Attribute.Compound>() {
- @Override
- public String toString() {
- return "Classifying attacher, attaching to " + sym +
- "\n declaration annotation attacher is: " + declAttacher +
- "\n type annotation attacher is: " + typeAttacher +
- "\n reporter for strictly type annotations is: " + reporter;
- }
-
- @Override
- public void attach(List<Attribute.Compound> attrs) {
- // We sort annotations into "buckets" based on what
- // kind they are.
- ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>();
- ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>();
- // We also need to keep track of the type-only
- // annotations, in case we have a reporting action.
- ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>();
-
- for (Attribute.Compound a : attrs) {
- Assert.check(!(a instanceof Placeholder),
- "Placeholders found in annotations being attached!");
- switch (annotationKind(a, sym)) {
- case DECLARATION:
- declAnnos.append(a);
- break;
- case BOTH: {
- declAnnos.append(a);
- Attribute.TypeCompound ta = a.toTypeCompound();
- Assert.checkNonNull(ta.position);
- typeAnnos.append(ta);
- break;
- }
- case TYPE: {
- Attribute.TypeCompound ta = a.toTypeCompound();
- Assert.checkNonNull(ta.position);
- typeAnnos.append(ta);
- // Also keep track which annotations are only type annotations
- onlyTypeAnnos.append(ta);
- break;
- }
- default:
- throw new AssertionError("Unknown annotation type");
- }
- }
-
- if (declAttacher != null)
- declAttacher.attach(declAnnos.toList());
-
- if (typeAttacher != null)
- typeAttacher.attach(typeAnnos.toList());
-
- if (reporter != null)
- reporter.report(onlyTypeAnnos.toList());
- }
- };
- }
-
- /**
- * Actually attach a list of type annotations to a symbol. For
- * variables defined in methods, we need to attach to both the
- * variable symbol, as well as the method symbol. This takes care
- * of that.
- *
- * @param sym The symbol to which to attach.
- * @param attrs The annotations to attach.
- */
- public void attachTypeAnnotations(Symbol sym, List<Attribute.TypeCompound> attrs) {
- sym.appendUniqueTypeAttributes(attrs);
-
- // For type annotations on variables in methods, make
- // sure they are attached to the owner too.
- switch(sym.getKind()) {
- case PARAMETER:
- case LOCAL_VARIABLE:
- case RESOURCE_VARIABLE:
- case EXCEPTION_PARAMETER:
- // Make sure all type annotations from the symbol are also
- // on the owner.
- sym.owner.appendUniqueTypeAttributes(attrs);
- break;
- }
- }
-
- /**
- * Final task for repeating annotations: go through a list of
- * Attributes and replace all the placeholders with containers.
- *
- * @param buf The list of Attributes.
- * @param ctx The AnnotationContext.
- * @param sym The symbol to which we are attaching.
- * @return The list of attributes with all placeholders replaced.
- */
private <T extends Attribute.Compound> List<T>
replacePlaceholders(List<T> buf,
Annotate.AnnotationContext<T> ctx,
@@ -1443,16 +849,13 @@
return result.reverse();
}
- /**
- * Replace one placeholder with a container.
- */
private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder,
Annotate.AnnotationContext<T> ctx,
Symbol sym) {
// Process repeated annotations
T validRepeated =
processRepeatedAnnotations(placeholder.getPlaceholderFor(),
- ctx, sym, placeholder.position);
+ ctx, sym);
if (validRepeated != null) {
// Check that the container isn't manually
@@ -1473,65 +876,16 @@
* Annotation processing
*********************************************************************/
- /**
- * Run a list of annotations through the repeating annotations
- * pipeline, and attach them. We don't have any diagnostic
- * position.
- */
- void annotateLater(final List<JCAnnotation> annotations,
- final Env<AttrContext> localEnv,
- final Symbol s) {
- annotateLater(annotations, localEnv, s, null);
- }
-
- /**
- * Run a list of annotations through the repeating annotations
- * pipeline and attach them. This is for when we have annotations
- * that cannot possibly be type annotations (thus, we have no type
- * annotation position).
- */
+ /** Queue annotations for later processing. */
void annotateLater(final List<JCAnnotation> annotations,
final Env<AttrContext> localEnv,
final Symbol s,
final DiagnosticPosition deferPos) {
- // Only attach declaration annotations.
- doAnnotateLater(annotations, localEnv, s, deferPos, null,
- declAnnotationsAttacher(s));
- }
-
- /**
- * Run a list of annotations through the repeating annotation
- * pipeline, and then classify and attach them. This is used
- * whenever we have annotations that might be regular annotations,
- * type annotations, or both.
- */
- void annotateWithClassifyLater(final List<JCAnnotation> annotations,
- final Env<AttrContext> localEnv,
- final Symbol s,
- final DiagnosticPosition deferPos,
- final TypeAnnotationPosition tapos) {
- // Set up just the basic classifying attacher.
- doAnnotateLater(annotations, localEnv, s, deferPos, tapos,
- classifyingAttacher(s));
- }
-
- /**
- * Set up a worker for handling annotations without parsing a type tree.
- */
- private void doAnnotateLater(final List<JCAnnotation> annotations,
- final Env<AttrContext> localEnv,
- final Symbol s,
- final DiagnosticPosition deferPos,
- final TypeAnnotationPosition tapos,
- final AttributeAttacher<Attribute.Compound> attacher) {
if (annotations.isEmpty()) {
return;
}
- // Mark annotations as incomplete for now.
- //
- // This should probably get redesigned at some point.
if (s.kind != PCK) {
- s.resetAnnotations();
+ s.resetAnnotations(); // mark Annotations as incomplete for now
}
normal(new Annotate.Worker() {
@Override
@@ -1541,44 +895,12 @@
@Override
public void run() {
- annotateNow(annotations, localEnv, s, deferPos,
- tapos, attacher);
- }
- });
-
- validate(annotationValidator(annotations, localEnv, s));
- }
-
- /**
- * Run a list of declaration (meaning they are in a declaration
- * position) annotations through the repeating annotations
- * pipeline.
- *
- * Note that in some cases, these annotations might end up being
- * type annotations, or both declaration and type annotations.
- *
- * @param annotations The annotations to handle.
- * @param localEnv the environment.
- * @param s The symbol to which to attach.
- * @param deferPos The diagnostic position to use.
- * @param position The type annotation position to use if some of
- * the annotations end up being type annotations.
- * @param attacher The attacher to use.
- */
- private void annotateNow(final List<JCAnnotation> annotations,
- final Env<AttrContext> localEnv,
- final Symbol s,
- final DiagnosticPosition deferPos,
- final TypeAnnotationPosition position,
- final AttributeAttacher<Attribute.Compound> attacher) {
- if (annotations.isEmpty()) {
- return;
- }
Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
- DiagnosticPosition prevLintPos = deferPos != null ?
- deferredLintHandler.setPos(deferPos) :
- deferredLintHandler.immediate();
+ DiagnosticPosition prevLintPos =
+ deferPos != null
+ ? deferredLintHandler.setPos(deferPos)
+ : deferredLintHandler.immediate();
Lint prevLint = deferPos != null ? null : chk.setLint(lint);
try {
if (s.hasAnnotations() &&
@@ -1586,7 +908,7 @@
log.error(annotations.head.pos,
"already.annotated",
kindName(s), s);
- actualEnterAnnotations(annotations, localEnv, s, position, attacher);
+ actualEnterAnnotations(annotations, localEnv, s);
} finally {
if (prevLint != null)
chk.setLint(prevLint);
@@ -1594,12 +916,9 @@
log.useSource(prev);
}
}
+ });
- // Set up a validator to enforce some rules on regular annotations.
- private Annotate.Worker annotationValidator(final List<JCAnnotation> annotations,
- final Env<AttrContext> localEnv,
- final Symbol s) {
- return new Annotate.Worker() { //validate annotations
+ validate(new Annotate.Worker() { //validate annotations
@Override
public void run() {
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
@@ -1609,140 +928,52 @@
log.useSource(prev);
}
}
- };
- }
-
- private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
- boolean isTypeParameter) {
- // 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);
- Assert.checkNonNull(ai.attribute);
-
- if (!ai.type.isErroneous() &&
- !hasTypeUseTarget(ai.attribute, isTypeParameter)) {
- log.error(ai.pos(), "annotation.type.not.applicable");
- }
- }
+ });
}
- // Set up a validator to enforce some rules on type annotations.
- // In addition to those enforced by Check.validateTypeAnnotations,
- // this enforces that declaration annotations cannot occur on type
- // parameters.
- private Annotate.Worker typeAnnotationValidator(final List<JCAnnotation> annotations,
- final Env<AttrContext> localEnv,
- final boolean isTypeParameter) {
- return new Annotate.Worker() { //validate annotations
- @Override
- public void run() {
- JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
- try {
- checkForDeclarationAnnotations(annotations, isTypeParameter);
- chk.validateTypeAnnotations(annotations, isTypeParameter);
- } finally {
- log.useSource(prev);
- }
- }
- };
+ private interface AttributeCreator<T extends Attribute.Compound> {
+ public T create(JCAnnotation a, Type expected, Env<AttrContext> env);
}
- /**
- * This is an interface that wraps up the functionality of
- * enterAnnotations and enterTypeAnnotations. This allows some
- * code duplication to be removed from the original repeating
- * annotations pipeline. It also allows for some unsafe casts to
- * be eliminated.
- *
- * Note: when Lambdas can be used in the compiler, we can just use
- * method refs for enterAnnotations and enterTypeAnnotations.
- */
- private interface AttributeCreator<T extends Attribute.Compound> {
- public T create(JCAnnotation a,
- Type expected,
- Env<AttrContext> env,
- TypeAnnotationPosition position);
- public abstract boolean createsTypeCompound();
- }
-
- // Note: try to avoid doing anything that makes these any more
- // than just the equivalent of method refs in a pre-lambda
- // setting. That way, they can go away when we are allowed to use
- // lambda.
+ // TODO: When SE8 features can be used, these can go away and be
+ // replaced by method refs.
private final AttributeCreator<Attribute.Compound> enterAnnotationsCreator =
new AttributeCreator<Attribute.Compound>() {
@Override
- public String toString() {
- return "Attribute creator for regular declaration annotations";
- }
-
- @Override
public Attribute.Compound create(JCAnnotation a,
Type expected,
- Env<AttrContext> env,
- TypeAnnotationPosition position) {
- return enterAnnotation(a, syms.annotationType, env, position);
+ Env<AttrContext> env) {
+ return enterAnnotation(a, syms.annotationType, env);
}
-
- @Override
- public boolean createsTypeCompound() { return false; }
};
-
- private AttributeCreator<Attribute.TypeCompound>
- enterTypeAnnotationsCreator(final boolean secondaryAttr) {
- return new AttributeCreator<Attribute.TypeCompound>() {
- @Override
- public String toString() {
- if (!secondaryAttr) {
- return "Attribute creator for regular type annotations";
- } else {
- return "Attribute creator for regular type annotations, ignores cached attributes";
- }
- }
-
+ private final AttributeCreator<Attribute.TypeCompound> enterTypeAnnotationsCreator =
+ new AttributeCreator<Attribute.TypeCompound>() {
@Override
public Attribute.TypeCompound create(JCAnnotation a,
Type expected,
- Env<AttrContext> env,
- TypeAnnotationPosition position) {
- return enterTypeAnnotation(a, syms.annotationType,
- env, position, secondaryAttr);
+ Env<AttrContext> env) {
+ return enterTypeAnnotation(a, syms.annotationType, env);
}
+ };
- @Override
- public boolean createsTypeCompound() { return true; }
- };
+ /** Enter a set of annotations. */
+ private void actualEnterAnnotations(List<JCAnnotation> annotations,
+ Env<AttrContext> env,
+ Symbol s) {
+ Assert.checkNonNull(s, "Symbol argument to actualEnterAnnotations is null");
+ attachAttributesLater(annotations, env, s, false,
+ enterAnnotationsCreator,
+ declAnnotationsAttacher);
}
- /**
- * Send a list of annotations (which occurred in a declaration
- * position) into the repeating annotations pipeline.
- */
- private void actualEnterAnnotations(List<JCAnnotation> annotations,
- Env<AttrContext> env,
- Symbol s,
- TypeAnnotationPosition position,
- AttributeAttacher<Attribute.Compound> attacher) {
- Assert.checkNonNull(s);
- attachAttributesLater(annotations, env, s, position,
- enterAnnotationsCreator, attacher);
- }
-
- /**
- * Send a list of annotations (which occurred in a type-use
- * position) into the repeating annotations pipeline.
+ /*
+ * If the symbol is non-null, attach the type annotation to it.
*/
private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
final Env<AttrContext> env,
final Symbol s,
- final DiagnosticPosition deferPos,
- final boolean secondaryAttr,
- final TypeAnnotationPosition position,
- final AttributeAttacher<Attribute.TypeCompound> attacher) {
- Assert.checkNonNull(s);
+ final DiagnosticPosition deferPos) {
+ Assert.checkNonNull(s, "Symbol argument to actualEnterTypeAnnotations is nul/");
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
DiagnosticPosition prevLintPos = null;
@@ -1750,9 +981,9 @@
prevLintPos = deferredLintHandler.setPos(deferPos);
}
try {
- attachAttributesLater(annotations, env, s, position,
- enterTypeAnnotationsCreator(secondaryAttr),
- attacher);
+ attachAttributesLater(annotations, env, s, true,
+ enterTypeAnnotationsCreator,
+ typeAnnotationsAttacher);
} finally {
if (prevLintPos != null)
deferredLintHandler.setPos(prevLintPos);
@@ -1760,114 +991,11 @@
}
}
- /**
- * Given a type tree, walk down it and handle any annotations we
- * find.
- *
- * @param tree The type tree to scan.
- * @param env The environment.
- * @param sym The symbol to which to attach any annotations we
- * might find.
- * @param deferPos The diagnostic position to use.
- * @param creator The creator to use for making positions.
- */
public void annotateTypeLater(final JCTree tree,
final Env<AttrContext> env,
final Symbol sym,
- final DiagnosticPosition deferPos,
- final PositionCreator creator) {
- doAnnotateTypeLater(tree, List.<JCAnnotation>nil(), env,
- sym, deferPos, creator, false, false);
- }
-
- /**
- * Given a type tree, walk down it and handle any annotations we
- * find. We also have a set of base-type annotations (which
- * occurred in a declaration position in source), which may either
- * be declaration annotations or annotations on the base type.
- * For an example, in "@A int @B []", we would have the type tree
- * "int @B []" with base-type annotations "@A".
- *
- * @param tree The type tree to scan.
- * @param baseTypeAnnos The base-type annotations.
- * @param env The environment.
- * @param sym The symbol to which to attach any annotations we
- * might find.
- * @param deferPos The diagnostic position to use.
- * @param creator The creator to use for making positions.
- */
- public void annotateTypeLater(final JCTree tree,
- final List<JCAnnotation> baseTypeAnnos,
- final Env<AttrContext> env,
- final Symbol sym,
- final DiagnosticPosition deferPos,
- final PositionCreator creator) {
- doAnnotateTypeLater(tree, baseTypeAnnos, env, sym, deferPos,
- creator, false, false);
- }
-
- /**
- * Given a type tree, walk down it and handle any annotations we
- * find. We also have a set of base-type annotations (which
- * occurred in a declaration position in source), which must be
- * type annotations on the base type.
- *
- * @param tree The type tree to scan.
- * @param baseTypeAnnos The base-type annotations.
- * @param env The environment.
- * @param sym The symbol to which to attach any annotations we
- * might find.
- * @param deferPos The diagnostic position to use.
- * @param creator The creator to use for making positions.
- */
- public void annotateStrictTypeLater(final JCTree tree,
- final List<JCAnnotation> baseTypeAnnos,
- final Env<AttrContext> env,
- final Symbol sym,
- final DiagnosticPosition deferPos,
- final PositionCreator creator) {
- doAnnotateTypeLater(tree, baseTypeAnnos, env, sym, deferPos,
- creator, true, false);
- }
-
- /**
- * Given a type tree representing an anonymous class' supertype,
- * walk down it and handle any annotations we find. We also have
- * a set of base-type annotations (which occurred in a declaration
- * position in source), which must be type annotations on the base
- * type.
- *
- * @param tree The type tree to scan.
- * @param baseTypeAnnos The base-type annotations.
- * @param env The environment.
- * @param sym The symbol to which to attach any annotations we
- * might find.
- * @param deferPos The diagnostic position to use.
- * @param creator The creator to use for making positions.
- */
- public void annotateAnonClassDefLater(final JCTree tree,
- final List<JCAnnotation> baseTypeAnnos,
- final Env<AttrContext> env,
- final Symbol sym,
- final DiagnosticPosition deferPos,
- final PositionCreator creator) {
- doAnnotateTypeLater(tree, baseTypeAnnos, env, sym, deferPos,
- creator, true, true);
- }
-
- // The combined worker function for the annotateTypeLater family.
- public void doAnnotateTypeLater(final JCTree tree,
- final List<JCAnnotation> baseTypeAnnos,
- final Env<AttrContext> env,
- final Symbol sym,
- final DiagnosticPosition deferPos,
- final PositionCreator creator,
- final boolean onlyTypeAnnos,
- final boolean secondaryAttr) {
+ final DiagnosticPosition deferPos) {
Assert.checkNonNull(sym);
- Assert.checkNonNull(baseTypeAnnos);
- Assert.checkNonNull(creator);
-
normal(new Annotate.Worker() {
@Override
public String toString() {
@@ -1875,912 +1003,93 @@
}
@Override
public void run() {
- if (!baseTypeAnnos.isEmpty()) {
- sym.resetAnnotations(); // mark Annotations as incomplete for now
- }
-
- tree.accept(typeAnnotator(baseTypeAnnos, sym, env, deferPos,
- creator, onlyTypeAnnos,
- secondaryAttr));
+ tree.accept(new TypeAnnotate(env, sym, deferPos));
}
});
}
/**
- * A client passed into various visitors that takes a type path as
- * an argument and performs an action (typically creating a
- * TypeAnnotationPosition and then creating a {@code Worker} and
- * adding it to a queue.
+ * 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.
*/
- public abstract class PositionCreator {
- public abstract TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex);
- }
+ private class TypeAnnotate extends TreeScanner {
+ private final Env<AttrContext> env;
+ private final Symbol sym;
+ private DiagnosticPosition deferPos;
- // For when we don't have a creator. Throws an exception.
- public final PositionCreator noCreator =
- new PositionCreator() {
- @Override
- public String toString() {
- return "Sentinel null position creator";
- }
+ public TypeAnnotate(final Env<AttrContext> env,
+ final Symbol sym,
+ final DiagnosticPosition deferPos) {
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- throw new AssertionError("No annotation position creator registered");
- }
- };
-
- // For when we are creating annotations that will inevitably
- // trigger errors. Creates null.
- public final PositionCreator errorCreator =
- new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for annotations that represent errors";
+ this.env = env;
+ this.sym = sym;
+ this.deferPos = deferPos;
}
@Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return null;
- }
- };
-
- // Create class extension positions
- public final PositionCreator extendsCreator =
- new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for extends";
+ public void visitAnnotatedType(final JCAnnotatedType tree) {
+ actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos);
+ super.visitAnnotatedType(tree);
}
@Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.classExtends(path, lambda, -1);
- }
- };
-
- // Create interface implementation positions
- public PositionCreator implementsCreator(final int idx) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for implements, index " + idx;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.classExtends(path, lambda, idx, -1);
- }
- };
- }
-
- // Create method parameter positions
- public final PositionCreator paramCreator(final int idx) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for parameter " + idx;
+ public void visitTypeParameter(final JCTypeParameter tree) {
+ actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos);
+ super.visitTypeParameter(tree);
}
@Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.methodParameter(path, lambda, idx, -1);
- }
- };
- }
-
- // Create class type parameter positions
- public PositionCreator typeParamCreator(final int idx) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for class type parameter " + idx;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.typeParameter(path, lambda, idx, -1);
- }
- };
- }
-
- public PositionCreator typeParamBoundCreator(final JCTypeParameter typaram,
- final int param_idx,
- final int bound_idx) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for class type parameter " + param_idx +
- ", bound " + bound_idx;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- final int real_bound_idx =
- typaram.bounds.head.type.isInterface() ? bound_idx + 1 : bound_idx;
- return TypeAnnotationPosition
- .typeParameterBound(path, lambda, param_idx, real_bound_idx, -1);
- }
- };
- }
-
- // Create field positions
- public final PositionCreator fieldCreator =
- new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for field declaration";
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.field(path, lambda, -1);
- }
- };
-
- // Create local variable positions
- public PositionCreator localVarCreator(final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for local variable declaration at " +
- pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.localVariable(path, lambda, pos);
- }
- };
- }
-
- // Create resource variable positions.
- public PositionCreator resourceVarCreator(final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for resource variable declaration at " +
- pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.resourceVariable(path, lambda, pos);
- }
- };
- }
-
- // Create exception parameter positions.
- public PositionCreator exceptionParamCreator(final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for exception param declaration at " +
- pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.exceptionParameter(path, lambda,
- typeIndex, pos);
- }
- };
- }
-
- // Create constructor reference type argument positions.
- public PositionCreator constructorRefTypeArgCreator(final int idx,
- final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for constructor reference type argument " + idx +
- " at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition
- .constructorRefTypeArg(path, lambda, idx, pos);
- }
- };
- }
-
- public PositionCreator methodInvokeTypeArgCreator(final int idx,
- final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for method invoke type argument " + idx +
- " at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.methodInvocationTypeArg(path, lambda, idx, pos);
- }
- };
- }
-
- public PositionCreator methodTypeParamCreator(final int idx) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for method type parameter " + idx;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.methodTypeParameter(path, lambda, idx, -1);
- }
- };
- }
-
- public PositionCreator methodTypeParamBoundCreator(final JCTypeParameter typaram,
- final int param_idx,
- final int bound_idx) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for method type parameter " + param_idx +
- " bound " + bound_idx;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- final int real_bound_idx =
- typaram.bounds.head.type.isInterface() ? bound_idx + 1 : bound_idx;
- return TypeAnnotationPosition
- .methodTypeParameterBound(path, lambda, param_idx, real_bound_idx, -1);
- }
- };
- }
-
- public PositionCreator throwCreator(final int idx) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for throw, type index " + idx;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.methodThrows(path, lambda, idx, -1);
- }
- };
- }
-
- public final PositionCreator returnCreator =
- new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for method return type";
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.methodReturn(path, lambda, -1);
- }
- };
-
- public PositionCreator receiverCreator =
- new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for method receiver parameter type";
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.methodReceiver(path, lambda, -1);
- }
- };
-
- public PositionCreator methodRefCreator(final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for method reference at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.methodRef(path, lambda, pos);
- }
- };
- }
-
- public PositionCreator methodRefTypeArgCreator(final int idx,
- final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for method reference type argument " + idx +
- " at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.methodRefTypeArg(path, lambda, idx, pos);
- }
- };
- }
-
- public PositionCreator constructorRefCreator(final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for constructor reference at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.constructorRef(path, lambda, pos);
- }
- };
- }
-
- public PositionCreator constructorInvokeTypeArgCreator(final int idx,
- final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for constructor invoke type argument " + idx +
- " at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.constructorInvocationTypeArg(path, lambda, idx, pos);
- }
- };
- }
-
- public PositionCreator instanceOfCreator(final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for instanceof at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.instanceOf(path, lambda, pos);
- }
- };
- }
-
- public PositionCreator newObjCreator(final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for new at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.newObj(path, lambda, pos);
- }
- };
- }
-
- public PositionCreator castCreator(final int pos) {
- return new PositionCreator() {
- @Override
- public String toString() {
- return "Position creator for cast at " + pos;
- }
-
- @Override
- public TypeAnnotationPosition create(List<TypePathEntry> path,
- JCLambda lambda,
- int typeIndex) {
- return TypeAnnotationPosition.typeCast(path, lambda, typeIndex, pos);
- }
- };
- }
-
- public static List<TypePathEntry> makeInners(Type type) {
- return addInners(type, List.<TypePathEntry>nil());
- }
-
- private static List<TypePathEntry> addInners(Type type,
- List<TypePathEntry> typepath) {
- Type encl = type.getEnclosingType();
- while (encl != null && encl.getKind() != TypeKind.NONE &&
- encl.getKind() != TypeKind.ERROR) {
- typepath = typepath.append(TypePathEntry.INNER_TYPE);
- encl = encl.getEnclosingType();
- }
- return typepath;
- }
-
- /**
- * Set up the visitor to scan the type tree and handle any
- * annotations we find. If we are in speculative attribution, we
- * will not actually attach anything, we will just enter the
- * annotations and run them through the pipeline to pick up any
- * errors that might occur.
- *
- * @param baseTypeAnnos Annotations on the base type, which need
- * to be classified if onlyTypeAnnos is false.
- * @param sym The symbol to which to attach.
- * @param env The environment.
- * @param creator The position creator to use.
- * @param onlyTypeAnnos Whether or not baseTypeAnnos can represent
- * declaration annotations.
- * @param secondaryAttr Whether or not we are creating secondary
- * attributes (see enterTypeAnnotations).
- */
- public TypeAnnotate typeAnnotator(final List<JCAnnotation> baseTypeAnnos,
- final Symbol sym,
- final Env<AttrContext> env,
- final DiagnosticPosition deferPos,
- final PositionCreator creator,
- final boolean onlyTypeAnnos,
- final boolean secondaryAttr) {
- if (!env.info.isSpeculative) {
- return new TypeAnnotate(baseTypeAnnos, sym, env, deferPos, creator,
- declAnnotationsAttacher(sym),
- typeAnnotationsAttacher(sym),
- onlyTypeAnnos, secondaryAttr);
- } else {
- return new TypeAnnotate(baseTypeAnnos, sym, env, deferPos, creator,
- null, null, onlyTypeAnnos, secondaryAttr);
- }
- }
-
- /**
- * A visitor that scans a type tree and handles an annotations it finds.
- *
- */
- private class TypeAnnotate extends TreeScanner {
- // The creator we use to create positions.
- protected PositionCreator creator;
- // The current type path
- private List<TypePathEntry> typepath = List.nil();
- // The current innermost lambda
- private JCLambda currentLambda;
- // The current type index, if we are looking at an
- // intersection type.
- private int type_index = 0;
- // Whether or not we are looking at the innermost type. This
- // gets used to figure out where to attach base type
- // annotations.
- private boolean innermost;
- // The attachers and reporter we use.
- private AttributeAttacher<Attribute.Compound> declAttacher;
- private AttributeAttacher<Attribute.TypeCompound> typeAttacher;
- private Reporter<Attribute.TypeCompound> reporter;
- // The symbol to which we are attaching.
- private final Symbol sym;
- // The diagnostic position we use.
- private final DiagnosticPosition deferPos;
- // The environment
- private final Env<AttrContext> env;
- private final List<JCAnnotation> baseTypeAnnos;
- // Whether or not baseTypeAnnos can be declaration
- // annotations, or just strictly type annotations.
- private final boolean onlyTypeAnnos;
- // Whether or not we are creating secondary attributes (see
- // enterTypeAnnotations).
- private final boolean secondaryAttr;
-
- public TypeAnnotate(final List<JCAnnotation> baseTypeAnnos,
- final Symbol sym,
- final Env<AttrContext> env,
- final DiagnosticPosition deferPos,
- final PositionCreator creator,
- final AttributeAttacher<Attribute.Compound> declAttacher,
- final AttributeAttacher<Attribute.TypeCompound> typeAttacher,
- final boolean onlyTypeAnnos,
- final boolean secondaryAttr) {
- this.baseTypeAnnos = baseTypeAnnos;
- this.sym = sym;
- this.env = env;
- this.deferPos = deferPos;
- this.currentLambda = env.getLambda();
- this.creator = creator;
- this.innermost = true;
- this.declAttacher = declAttacher;
- this.typeAttacher = typeAttacher;
- this.reporter = null;
- this.onlyTypeAnnos = onlyTypeAnnos;
- this.secondaryAttr = secondaryAttr;
+ public void visitNewArray(final JCNewArray tree) {
+ actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos);
+ for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
+ actualEnterTypeAnnotations(dimAnnos, env, sym, deferPos);
+ super.visitNewArray(tree);
}
- // Deal with the base-type annotations. This should only get
- // called when we are at the inner-most type.
- private void doBaseTypeAnnos() {
- if (onlyTypeAnnos) {
- // If the base type annotations can only be type
- // annotations, then handle them as such.
- doTypeAnnos(baseTypeAnnos, false);
- } else if (!baseTypeAnnos.isEmpty()) {
- // Otherwise, send them into the repeating annotations
- // pipeline with a classifying attacher we build based
- // on the current state.
- final TypeAnnotationPosition tapos =
- creator.create(typepath, currentLambda, type_index);
- annotateNow(baseTypeAnnos, env, sym, deferPos, tapos,
- classifyingAttacher(sym, declAttacher,
- typeAttacher, reporter));
- // Also set up a validator.
- validate(annotationValidator(baseTypeAnnos, env, sym));
- }
+ @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);
}
- // Deal with type annotations we found while scanning the tree.
- private void doTypeAnnos(List<JCAnnotation> annos,
- boolean isTypeParameter) {
- if (!annos.isEmpty()) {
- // Grab the reporter and the type attacher (which,
- // it's ok for either to be null), and combine them
- // into a reporting attacher.
- final AttributeAttacher<Attribute.TypeCompound> attacher =
- reportingTypeAnnotationsAttacher(typeAttacher, reporter);
- // Create the position using the current type path and
- // type index.
- final TypeAnnotationPosition tapos =
- creator.create(typepath, currentLambda, type_index);
- // Send the annotations into the repeating annotations
- // pipeline, and set up a validator.
- actualEnterTypeAnnotations(annos, env, sym, deferPos, secondaryAttr,
- tapos, attacher);
- validate(typeAnnotationValidator(annos, env, isTypeParameter));
+ @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 visitTypeIdent(final JCPrimitiveTypeTree tree) {
- // This is one place that can represent the base type.
- // But we need to make sure we're actually in the
- // innermost type (ie not a type argument or something).
- if (innermost) {
- final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher;
- // We want to update the Type to have annotations.
- typeAttacher = typeUpdatingTypeAnnotationsAttacher(oldTypeAttacher,
- tree);
- // We can't possibly have any INNER_TYPE type path
- // elements, because these are all primitives.
- doBaseTypeAnnos();
- typeAttacher = oldTypeAttacher;
- }
- }
-
- @Override
- public void visitIdent(final JCIdent tree) {
- // This is one place that can represent the base type.
- // But we need to make sure we're actually in the
- // innermost type (ie not a type argument or something).
- if (innermost) {
- final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher;
- // Set up an attacher that updates the Type, so we get
- // the annotations.
- typeAttacher = typeUpdatingTypeAnnotationsAttacher(oldTypeAttacher,
- tree);
- // Add any INNER_TYPE type path elements we might need.
- if (tree.type != null) {
- final List<TypePathEntry> oldpath = typepath;
- typepath = addInners(tree.type, typepath);
- doBaseTypeAnnos();
- typepath = oldpath;
- } else {
- doBaseTypeAnnos();
- }
- typeAttacher = oldTypeAttacher;
- }
- }
-
- @Override
- public void visitAnnotatedType(JCAnnotatedType tree) {
- // This is one place where we run into pure type
- // annotations.
- Assert.checkNonNull(tree.getUnderlyingType().type);
- final boolean oldinnermost = innermost;
- // Make sure we don't consider ourselves "innermost" when
- // scanning the annotations.
- innermost = false;
- scan(tree.annotations);
- innermost = oldinnermost;
- scan(tree.underlyingType);
- final List<TypePathEntry> oldpath = typepath;
- typepath = addInners(tree.getUnderlyingType().type, typepath);
- doTypeAnnos(tree.annotations, false);
- typepath = oldpath;
- }
-
- @Override
- public void visitTypeArray(JCArrayTypeTree tree) {
- // This case is simple: just add an ARRAY to the type path.
- final List<TypePathEntry> oldpath = typepath;
- typepath = typepath.append(TypePathEntry.ARRAY);
- super.visitTypeArray(tree);
- typepath = oldpath;
- }
-
- @Override
- public void visitTypeApply(JCTypeApply tree) {
- // Handle type arguments
- Assert.checkNonNull(tree.getType().type);
- final List<TypePathEntry> oldpath = typepath;
- // First, look at the base type.
- scan(tree.clazz);
-
- // Add any INNER_TYPE path elements we need first
- if (tree.getType() != null && tree.getType().type != null) {
- typepath = addInners(tree.getType().type, typepath);
- }
- // Make sure we're not considering ourselves innermost
- // when looking at type arguments.
- final boolean oldinnermost = innermost;
- innermost = false;
- // For each type argument, add a TYPE_ARGUMENT path
- // element for the right index.
- int i = 0;
- for (List<JCExpression> l = tree.arguments; l.nonEmpty();
- l = l.tail, i++) {
- final JCExpression arg = l.head;
- final List<TypePathEntry> noargpath = typepath;
- typepath = typepath.append(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, i));
- scan(arg);
- typepath = noargpath;
- }
- typepath = oldpath;
- innermost = oldinnermost;
- }
-
- @Override
- public void visitNewArray(JCNewArray tree) {
- // We can also run into type annotations here, on dimAnnos.
- final List<TypePathEntry> oldpath = typepath;
- final PositionCreator oldcreator = creator;
- creator = newObjCreator(tree.pos);
- doTypeAnnos(tree.annotations, false);
-
- // Go through the dimensions, set up the type path, and
- // handle any annetations we find.
- for (int i = 0; i < tree.dimAnnotations.size(); i++) {
- final List<JCAnnotation> dimAnnos = tree.dimAnnotations.get(i);
- doTypeAnnos(dimAnnos, false);
- // This is right. As per the type annotations spec,
- // the first array dimension has no arrays in the type
- // path, the second has one, and so on, and the
- // element type has n for n dimensions.
- typepath = typepath.append(TypePathEntry.ARRAY);
- }
-
- // The element type is sometimes null, in the case of
- // array literals.
- scan(tree.elemtype);
- typepath = oldpath;
- creator = oldcreator;
- }
-
- @Override
- public void visitWildcard(JCWildcard tree) {
- // Simple: add a WILDCARD type path element and continue.
- final List<TypePathEntry> oldpath = typepath;
- typepath = typepath.append(TypePathEntry.WILDCARD);
- super.visitWildcard(tree);
- typepath = oldpath;
- }
-
- @Override
- public void visitTypeParameter(JCTypeParameter tree) {
- // This is another place where we can run into pure type
- // annotations.
- scan(tree.annotations);
- Assert.checkNonNull(tree.type);
- doTypeAnnos(tree.annotations, true);
- }
-
- @Override
- public void visitLambda(JCLambda tree) {
- // If we run into a lambda, set the current lambda to it.
- final JCLambda oldLambda = currentLambda;
- currentLambda = tree;
- scan(tree.body);
- scan(tree.params);
- currentLambda = oldLambda;
- }
-
- @Override
- public void visitTypeIntersection(JCTypeIntersection tree) {
- final boolean oldinnermost = innermost;
- // Run through the options, and update the type_index
- // accordingly.
- for (List<JCExpression> l = tree.bounds; l.nonEmpty();
- l = l.tail, type_index++) {
- scan(l.head);
- // Set innermost to false after the first element
- innermost = false;
- }
- innermost = oldinnermost;
- }
-
- @Override
- public void visitTypeUnion(JCTypeUnion tree) {
- final boolean oldinnermost = innermost;
- // Run through the options, and update the type_index
- // accordingly.
- for (List<JCExpression> l = tree.alternatives; l.nonEmpty();
- l = l.tail, type_index++) {
- scan(l.head);
- // Set innermost to false after the first element
- innermost = false;
- }
- innermost = oldinnermost;
- }
-
- @Override
- public void visitSelect(JCFieldAccess tree) {
- // In this case, we need to possibly set up an
- // illegalScopingReporter, if the selected type cannot be
- // annotated.
- Symbol sym = tree.sym;
- final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher;
- final Reporter<Attribute.TypeCompound> oldReporter = reporter;
- // If we're selecting from an interface or a static class,
- // set up attachers that will only attach declaration
- // annotations and will report type annotations as errors.
- Type selectedTy = tree.selected.type;
- if ((sym != null && (sym.isStatic() || sym.isInterface() ||
- selectedTy.hasTag(TypeTag.PACKAGE))) ||
- tree.name == names._class) {
- typeAttacher = null;
- reporter = illegalScopingReporter(tree.pos);
- }
- super.visitSelect(tree);
- typeAttacher = oldTypeAttacher;
- reporter = oldReporter;
- }
-
- // These methods stop the visitor from continuing on when it
- // sees a definition.
- @Override
- public void visitVarDef(final JCVariableDecl tree) {
- }
-
- @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);
}
}
-
- // A derived TypeAnnotate visitor that also scans expressions
- // within Deferred attribution.
- private class TypeAnnotateExpr extends TypeAnnotate {
- // This constructor creates an instance suitable for deferred
- // attribution.
- public TypeAnnotateExpr(final Symbol sym,
- final Env<AttrContext> env,
- final DiagnosticPosition deferPos,
- final PositionCreator creator) {
- super(List.<JCAnnotation>nil(), sym, env, deferPos,
- creator, null, null, false, false);
- }
-
- @Override
- public void visitTypeCast(final JCTypeCast tree) {
- final PositionCreator oldcreator = creator;
- creator = castCreator(tree.pos);
- super.visitTypeCast(tree);
- creator = oldcreator;
- }
-
- @Override
- public void visitTypeTest(JCInstanceOf tree) {
- final PositionCreator oldcreator = creator;
- creator = instanceOfCreator(tree.pos);
- super.visitTypeTest(tree);
- creator = oldcreator;
- }
-
- @Override
- public void visitReference(JCMemberReference that) {
- final boolean isConstructor = that.getName() == names.init;
- final PositionCreator oldcreator = creator;
- creator = isConstructor ? constructorRefCreator(that.pos) :
- methodRefCreator(that.pos);
- scan(that.expr);
-
- if (null != that.typeargs) {
- int i = 0;
- for (List<JCExpression> l = that.typeargs;
- l.nonEmpty(); l = l.tail, i++) {
- final Annotate.PositionCreator typeArgCreator =
- isConstructor ? constructorRefTypeArgCreator(i, that.pos) :
- methodRefTypeArgCreator(i, that.pos);
- final JCExpression arg = l.head;
- scan(that.expr);
- }
- }
-
- creator = oldcreator;
- }
-
- @Override
- public void visitNewClass(JCNewClass tree) {
- // This will be visited by Attr later, so don't do
- // anything.
- }
- }
-
- /**
- * Set up a visitor to scan an expression and handle any type
- * annotations it finds, within a deferred attribution context.
- */
- public void typeAnnotateExprLater(final JCTree tree,
- final Env<AttrContext> env,
- final Symbol sym,
- final DiagnosticPosition deferPos,
- final PositionCreator creator) {
- Assert.checkNonNull(sym);
- Assert.checkNonNull(creator);
-
- normal(new Annotate.Worker() {
- @Override
- public String toString() {
- return "type annotate " + tree + " onto " + sym + " in " + sym.owner;
- }
- @Override
- public void run() {
- tree.accept(new TypeAnnotateExpr(sym, env, deferPos, creator));
- }
- });
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Sep 10 19:38:20 2014 -0700
@@ -94,6 +94,7 @@
final Types types;
final JCDiagnostic.Factory diags;
final Annotate annotate;
+ final TypeAnnotations typeAnnotations;
final DeferredLintHandler deferredLintHandler;
final TypeEnvs typeEnvs;
final Dependencies dependencies;
@@ -124,6 +125,7 @@
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
annotate = Annotate.instance(context);
+ typeAnnotations = TypeAnnotations.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
typeEnvs = TypeEnvs.instance(context);
dependencies = Dependencies.instance(context);
@@ -372,7 +374,8 @@
public Type attribImportQualifier(JCImport tree, Env<AttrContext> env) {
// Attribute qualifying package or class.
JCFieldAccess s = (JCFieldAccess)tree.qualid;
- return attribTree(s.selected, env,
+ return attribTree(s.selected,
+ env,
new ResultInfo(tree.staticImport ? TYP : (TYP | PCK),
Type.noType));
}
@@ -572,8 +575,7 @@
/** Derived visitor method: attribute an expression tree.
*/
public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
- return attribTree(tree, env,
- new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType));
+ return attribTree(tree, env, new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType));
}
/** Derived visitor method: attribute an expression tree with
@@ -585,7 +587,6 @@
/** Derived visitor method: attribute a type tree.
*/
-
public Type attribType(JCTree tree, Env<AttrContext> env) {
Type result = attribType(tree, env, Type.noType);
return result;
@@ -600,7 +601,6 @@
/** Derived visitor method: attribute a statement or definition tree.
*/
-
public Type attribStat(JCTree tree, Env<AttrContext> env) {
return attribTree(tree, env, statInfo);
}
@@ -669,8 +669,7 @@
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));
for (JCExpression bound : tvar.bounds.tail)
bounds = bounds.prepend(attribType(bound, env));
types.setBounds(a, bounds.reverse());
@@ -705,7 +704,7 @@
* @param type The expected type, or null
* @see VarSymbol#setLazyConstValue
*/
- public Object attribLazyConstantValue(final Env<AttrContext> env,
+ public Object attribLazyConstantValue(Env<AttrContext> env,
JCVariableDecl variable,
Type type) {
@@ -824,7 +823,6 @@
c.flags_field |= NOOUTERTHIS;
}
attribClass(tree.pos(), c);
-
result = tree.type = c.type;
}
}
@@ -867,9 +865,9 @@
ClassSymbol owner = env.enclClass.sym;
if ((owner.flags() & ANNOTATION) != 0 &&
- tree.params.nonEmpty())
+ tree.params.nonEmpty())
log.error(tree.params.head.pos(),
- "intf.annotation.members.cant.have.params");
+ "intf.annotation.members.cant.have.params");
// Attribute all value parameters.
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
@@ -943,91 +941,56 @@
if (tree.name == names.init && owner.type != syms.objectType) {
JCBlock body = tree.body;
if (body.stats.isEmpty() ||
- !TreeInfo.isSelfCall(body.stats.head)) {
+ !TreeInfo.isSelfCall(body.stats.head)) {
body.stats = body.stats.
- prepend(memberEnter.SuperCall(make.at(body.pos),
- List.<Type>nil(),
- List.<JCVariableDecl>nil(),
- false));
+ prepend(memberEnter.SuperCall(make.at(body.pos),
+ List.<Type>nil(),
+ List.<JCVariableDecl>nil(),
+ false));
} else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
- (tree.mods.flags & GENERATEDCONSTR) == 0 &&
- TreeInfo.isSuperCall(body.stats.head)) {
+ (tree.mods.flags & GENERATEDCONSTR) == 0 &&
+ TreeInfo.isSuperCall(body.stats.head)) {
// enum constructors are not allowed to call super
// directly, so make sure there aren't any super calls
// in enum constructors, except in the compiler
// generated one.
log.error(tree.body.stats.head.pos(),
- "call.to.super.not.allowed.in.enum.ctor",
- env.enclClass.sym);
+ "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();
result = tree.type = m.type;
- }
- finally {
+ } finally {
chk.setLint(prevLint);
chk.setMethod(prevMethod);
}
}
- public Annotate.PositionCreator getVarCreator(final JCVariableDecl tree) {
- // Form the enclosing tree node, figure out what kind
- // of definition we are looking at.
- switch(env.tree.getTag()) {
- case TRY:
- // If it's a try, then we have a resource variable
- return annotate.resourceVarCreator(tree.pos);
- case CATCH:
- // If it's a catch, then we have an exception parameter
- return annotate.exceptionParamCreator(tree.pos);
- case LAMBDA: {
- // If it's a lambda, then we could have a local
- // variable or a parameter.
- final JCLambda lambda = (JCLambda) env.tree;
- // We have to figure out what the index of the
- // parameter is, and unfortunately, the visitor
- // and tree APIs don't help us much here. If we
- // don't find the declaration in the parameter
- // list, then it must be a local variable.
- //
- // This could easily be replaced by an index
- // parameter, which is -1 for non-indexed
- // definitions.
- int index = -1;
- int i = 0;
- for (List<JCVariableDecl> l = lambda.params;
- l.nonEmpty(); l = l.tail, i++) {
- if (l.head == tree) {
- index = i;
- break;
- }
- }
- if (index == -1) {
- return annotate.localVarCreator(tree.pos);
- } else {
- return annotate.paramCreator(index);
- }
- }
- default:
- // The default case is to treat any declaration as a local
- // variable.
- return annotate.localVarCreator(tree.pos);
- }
- }
-
- public void visitVarDef(final JCVariableDecl tree) {
+ public void visitVarDef(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, getVarCreator(tree));
+ memberEnter.memberEnter(tree, env);
+ annotate.flush();
+ }
+ } else {
+ if (tree.init != null) {
+ // Field initializer expression need to be entered.
+ annotate.annotateTypeLater(tree.init, env, tree.sym, tree.pos());
+ annotate.flush();
}
}
@@ -1086,6 +1049,9 @@
env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
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();
attribStats(tree.stats, localEnv);
{
@@ -1449,21 +1415,17 @@
isBooleanOrNumeric(env, condTree.falsepart);
case APPLY:
JCMethodInvocation speculativeMethodTree =
- (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo,
- annotate.noCreator);
+ (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
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,
- annotate.newObjCreator(tree.pos));
+ (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
default:
- Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo, annotate.noCreator).type;
+ Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
speculativeType = types.unboxedTypeOrType(speculativeType);
return speculativeType.isPrimitive();
}
@@ -1724,28 +1686,7 @@
// Attribute arguments, yielding list of argument types.
attribArgs(tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
-
- // 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;
- try {
- annotate.enterStart();
- typeargtypesbuf.append(attribType(arg, localEnv));
- annotate.annotateTypeLater(arg, localEnv,
- localEnv.info.scope.owner,
- tree.pos(),
- annotate.constructorInvokeTypeArgCreator(i, tree.pos));
- } finally {
- annotate.enterDone();
- }
- }
-
- typeargtypes =
- chk.checkRefTypes(tree.typeargs, typeargtypesbuf.toList());
+ typeargtypes = attribTypes(tree.typeargs, localEnv);
// Variable `site' points to the class in which the called
// constructor is defined.
@@ -1818,27 +1759,7 @@
// Attribute the arguments, yielding list of argument types, ...
int kind = attribArgs(tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
-
- // 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;
- try {
- annotate.enterStart();
- typeargtypesbuf.append(attribType(arg, localEnv));
- annotate.annotateTypeLater(arg, localEnv,
- localEnv.info.scope.owner,
- tree.pos(),
- annotate.methodInvokeTypeArgCreator(i, tree.pos));
- } finally {
- annotate.enterDone();
- }
- }
-
- typeargtypes = typeargtypesbuf.toList();
+ typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
// ... and attribute the method using as a prototype a methodtype
// whose formal argument types is exactly the list of actual
@@ -1863,7 +1784,6 @@
// current context. Also, capture the return type
result = check(tree, capture(restype), VAL, resultInfo);
}
-
chk.validate(tree.typeargs, localEnv);
}
//where
@@ -1935,12 +1855,14 @@
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
@@ -1962,12 +1884,11 @@
EndPosTable endPosTable = this.env.toplevel.endPositions;
endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable));
- if (annoclazzid != null) {
- JCAnnotatedType annoType = annoclazzid;
- List<JCAnnotation> annos = annoclazzid.annotations;
-
- if (clazz.hasTag(TYPEAPPLY)) {
-
+ if (clazz.hasTag(ANNOTATED_TYPE)) {
+ JCAnnotatedType annoType = (JCAnnotatedType) clazz;
+ List<JCAnnotation> annos = annoType.annotations;
+
+ if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
clazzid1 = make.at(tree.pos).
TypeApply(clazzid1,
((JCTypeApply) clazz).arguments);
@@ -1984,32 +1905,12 @@
clazz = clazzid1;
}
- Type clazztype;
-
- try {
- annotate.enterStart();
// Attribute clazz expression and store
// symbol + type back into the attributed tree.
- clazztype = TreeInfo.isEnumInit(env.tree) ?
+ Type clazztype = TreeInfo.isEnumInit(env.tree) ?
attribIdentAsEnumType(env, (JCIdent)clazz) :
attribType(clazz, env);
- if (cdef != null) {
- // If we are looking at an anonymous class creation, then
- // we are not allowed to have declaration annotations on
- // the base type.
- annotate.annotateStrictTypeLater(clazz, cdef.mods.annotations, localEnv,
- env.info.scope.owner, tree.pos(),
- annotate.newObjCreator(tree.pos));
- } else {
- // Otherwise, we are.
- annotate.annotateTypeLater(clazz, localEnv, env.info.scope.owner,
- tree.pos(), annotate.newObjCreator(tree.pos));
- }
- } finally {
- annotate.enterDone();
- }
-
clazztype = chk.checkDiamond(tree, clazztype);
chk.validate(clazz, localEnv);
if (tree.encl != null) {
@@ -2038,29 +1939,7 @@
ListBuffer<Type> argtypesBuf = new ListBuffer<>();
int pkind = attribArgs(tree.args, localEnv, argtypesBuf);
List<Type> argtypes = argtypesBuf.toList();
- 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;
- try {
- annotate.enterStart();
- typeargtypesbuf.append(attribType(arg, localEnv));
- annotate.annotateTypeLater(arg, localEnv,
- localEnv.info.scope.owner,
- tree.pos(),
- annotate.constructorInvokeTypeArgCreator(i, tree.pos));
- } finally {
- annotate.enterDone();
- }
- }
-
- typeargtypes =
- chk.checkRefTypes(tree.typeargs, typeargtypesbuf.toList());
+ List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
// If we have made no mistakes in the class type...
if (clazztype.hasTag(CLASS)) {
@@ -2242,9 +2121,7 @@
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,
- annotate.newObjCreator(tree.pos)).type;
+ Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
Type polyPt = allowPoly ?
syms.objectType :
clazztype;
@@ -2306,20 +2183,8 @@
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) {
- try {
- annotate.enterStart();
elemtype = attribType(tree.elemtype, localEnv);
- annotate.annotateTypeLater(tree, env, env.info.scope.owner, tree.pos(),
- annotate.newObjCreator(tree.pos));
- } finally {
- annotate.enterDone();
- }
chk.validate(tree.elemtype, localEnv);
owntype = elemtype;
for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
@@ -2340,7 +2205,6 @@
elemtype = types.createErrorType(pt());
}
}
-
if (tree.elems != null) {
attribExprs(tree.elems, localEnv, elemtype);
owntype = new ArrayType(elemtype, syms.arrayClass,
@@ -2737,8 +2601,6 @@
@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
@@ -2749,20 +2611,9 @@
}
final Env<AttrContext> localEnv = env.dup(that);
try {
- Type exprType;
- try {
- annotate.enterStart();
//attribute member reference qualifier - if this is a constructor
//reference, the expected kind must be a 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(), creator);
- } finally {
- annotate.enterDone();
- }
+ Type exprType = attribTree(that.expr, env, memberReferenceQualifierResult(that));
if (that.getMode() == JCMemberReference.ReferenceMode.NEW) {
exprType = chk.checkConstructorRefType(that.expr, exprType);
@@ -2792,24 +2643,7 @@
//attrib type-arguments
List<Type> typeargtypes = List.nil();
if (that.typeargs != null) {
- try {
- 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(), typeArgCreator);
- }
- } finally {
- annotate.enterDone();
- }
}
Type desc;
@@ -3192,15 +3026,7 @@
}
public void visitTypeCast(final JCTypeCast tree) {
- Type clazztype;
- try {
- annotate.enterStart();
- clazztype = attribType(tree.clazz, env);
- annotate.annotateTypeLater(tree.clazz, env, env.info.scope.owner,
- tree.pos(), annotate.castCreator(tree.pos));
- } finally {
- annotate.enterDone();
- }
+ Type clazztype = attribType(tree.clazz, env);
chk.validate(tree.clazz, env, false);
//a fresh environment is required for 292 inference to work properly ---
//see Infer.instantiatePolymorphicSignatureInstance()
@@ -3233,16 +3059,7 @@
public void visitTypeTest(JCInstanceOf tree) {
Type exprtype = chk.checkNullOrRefType(
tree.expr.pos(), attribExpr(tree.expr, env));
- Type clazztype;
- try {
- annotate.enterStart();
- clazztype = attribType(tree.clazz, env);
- annotate.annotateTypeLater(tree.clazz, env, env.info.scope.owner, tree.pos(),
- annotate.instanceOfCreator(tree.pos));
- } finally {
- annotate.enterDone();
- }
-
+ Type clazztype = attribType(tree.clazz, env);
if (!clazztype.hasTag(TYPEVAR)) {
clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype);
}
@@ -3371,12 +3188,9 @@
if ((pkind() & (PCK | TYP)) == 0)
site = capture(site); // Capture field access
+ // don't allow T.class T[].class, etc
if (skind == TYP) {
- // If the qualifier is a type, annotate it
- annotate.annotateTypeLater(tree, env, env.info.scope.owner,
- tree.pos(), annotate.errorCreator);
Type elt = site;
- // don't allow T.class T[].class, etc
while (elt.hasTag(ARRAY))
elt = ((ArrayType)elt).elemtype;
if (elt.hasTag(TYPEVAR)) {
@@ -4224,13 +4038,8 @@
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 = attribTree(tree.getUnderlyingType(), env,
- resultInfo);
+ Type underlyingType = attribType(tree.getUnderlyingType(), env);
this.attribAnnotationTypes(tree.annotations, env);
annotateType(tree, tree.annotations);
result = tree.type = underlyingType;
@@ -4249,10 +4058,8 @@
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);
}
- }
});
}
@@ -4503,6 +4310,13 @@
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) {
@@ -4581,6 +4395,233 @@
return types.capture(type);
}
+ public void validateTypeAnnotations(JCTree tree, boolean sigOnly) {
+ tree.accept(new TypeAnnotationsValidator(sigOnly));
+ }
+ //where
+ private final class TypeAnnotationsValidator extends TreeScanner {
+
+ private final boolean sigOnly;
+ public TypeAnnotationsValidator(boolean sigOnly) {
+ this.sigOnly = sigOnly;
+ }
+
+ public void visitAnnotation(JCAnnotation tree) {
+ chk.validateTypeAnnotation(tree, false);
+ super.visitAnnotation(tree);
+ }
+ public void visitAnnotatedType(JCAnnotatedType tree) {
+ if (!tree.underlyingType.type.isErroneous()) {
+ super.visitAnnotatedType(tree);
+ }
+ }
+ public void visitTypeParameter(JCTypeParameter tree) {
+ chk.validateTypeAnnotations(tree.annotations, true);
+ scan(tree.bounds);
+ // Don't call super.
+ // This is needed because above we call validateTypeAnnotation with
+ // false, which would forbid annotations on type parameters.
+ // super.visitTypeParameter(tree);
+ }
+ public void visitMethodDef(JCMethodDecl tree) {
+ if (tree.recvparam != null &&
+ !tree.recvparam.vartype.type.isErroneous()) {
+ checkForDeclarationAnnotations(tree.recvparam.mods.annotations,
+ tree.recvparam.vartype.type.tsym);
+ }
+ if (tree.restype != null && tree.restype.type != null) {
+ validateAnnotatedType(tree.restype, tree.restype.type);
+ }
+ if (sigOnly) {
+ scan(tree.mods);
+ scan(tree.restype);
+ scan(tree.typarams);
+ scan(tree.recvparam);
+ scan(tree.params);
+ scan(tree.thrown);
+ } else {
+ 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) {
+ scan(tree.init);
+ }
+ }
+ public void visitTypeCast(JCTypeCast tree) {
+ if (tree.clazz != null && tree.clazz.type != null)
+ validateAnnotatedType(tree.clazz, tree.clazz.type);
+ super.visitTypeCast(tree);
+ }
+ public void visitTypeTest(JCInstanceOf tree) {
+ if (tree.clazz != null && tree.clazz.type != null)
+ validateAnnotatedType(tree.clazz, tree.clazz.type);
+ super.visitTypeTest(tree);
+ }
+ public void visitNewClass(JCNewClass tree) {
+ if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
+ tree.clazz.type.tsym);
+ }
+ if (tree.def != null) {
+ checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
+ }
+ if (tree.clazz.type != null) {
+ validateAnnotatedType(tree.clazz, tree.clazz.type);
+ }
+ super.visitNewClass(tree);
+ }
+ public void visitNewArray(JCNewArray tree) {
+ if (tree.elemtype != null && tree.elemtype.type != null) {
+ if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
+ tree.elemtype.type.tsym);
+ }
+ 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);
+ }
+ for (JCTree member : tree.defs) {
+ if (member.hasTag(Tag.CLASSDEF)) {
+ continue;
+ }
+ scan(member);
+ }
+ }
+ public void visitBlock(JCBlock tree) {
+ if (!sigOnly) {
+ scan(tree.stats);
+ }
+ }
+
+ /* I would want to model this after
+ * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
+ * and override visitSelect and visitTypeApply.
+ * However, we only set the annotated type in the top-level type
+ * 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;
+ }
+
+ JCTree enclTr = errtree;
+ Type enclTy = type;
+
+ boolean repeat = true;
+ while (repeat) {
+ if (enclTr.hasTag(TYPEAPPLY)) {
+ List<Type> tyargs = enclTy.getTypeArguments();
+ List<JCExpression> trargs = ((JCTypeApply)enclTr).getTypeArguments();
+ if (trargs.length() > 0) {
+ // Nothing to do for diamonds
+ if (tyargs.length() == trargs.length()) {
+ for (int i = 0; i < tyargs.length(); ++i) {
+ validateAnnotatedType(trargs.get(i), tyargs.get(i));
+ }
+ }
+ // If the lengths don't match, it's either a diamond
+ // or some nested type that redundantly provides
+ // type arguments in the tree.
+ }
+
+ // Look at the clazz part of a generic type
+ enclTr = ((JCTree.JCTypeApply)enclTr).clazz;
+ }
+
+ if (enclTr.hasTag(SELECT)) {
+ enclTr = ((JCTree.JCFieldAccess)enclTr).getExpression();
+ if (enclTy != null &&
+ !enclTy.hasTag(NONE)) {
+ enclTy = enclTy.getEnclosingType();
+ }
+ } 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);
+ } 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());
+ }
+ repeat = false;
+ }
+ enclTr = at.underlyingType;
+ // enclTy doesn't need to be changed
+ } else if (enclTr.hasTag(IDENT)) {
+ repeat = false;
+ } else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) {
+ JCWildcard wc = (JCWildcard) enclTr;
+ if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD) {
+ validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getExtendsBound());
+ } else if (wc.getKind() == JCTree.Kind.SUPER_WILDCARD) {
+ validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getSuperBound());
+ } else {
+ // Nothing to do for UNBOUND
+ }
+ repeat = false;
+ } else if (enclTr.hasTag(TYPEARRAY)) {
+ JCArrayTypeTree art = (JCArrayTypeTree) enclTr;
+ validateAnnotatedType(art.getType(), ((ArrayType)enclTy).getComponentType());
+ repeat = false;
+ } else if (enclTr.hasTag(TYPEUNION)) {
+ JCTypeUnion ut = (JCTypeUnion) enclTr;
+ for (JCTree t : ut.getTypeAlternatives()) {
+ validateAnnotatedType(t, t.type);
+ }
+ repeat = false;
+ } else if (enclTr.hasTag(TYPEINTERSECTION)) {
+ JCTypeIntersection it = (JCTypeIntersection) enclTr;
+ for (JCTree t : it.getBounds()) {
+ validateAnnotatedType(t, t.type);
+ }
+ repeat = false;
+ } else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE ||
+ enclTr.getKind() == JCTree.Kind.ERRONEOUS) {
+ repeat = false;
+ } else {
+ Assert.error("Unexpected tree: " + enclTr + " with kind: " + enclTr.getKind() +
+ " within: "+ errtree + " with kind: " + errtree.getKind());
+ }
+ }
+ }
+
+ private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
+ Symbol sym) {
+ // 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) {
+ if (!ai.type.isErroneous() &&
+ typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
+ log.error(ai.pos(), "annotation.type.not.applicable");
+ }
+ }
+ }
+ }
+
// <editor-fold desc="post-attribution visitor">
/**
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Wed Sep 10 19:38:20 2014 -0700
@@ -59,11 +59,6 @@
*/
boolean isSerializable = false;
- /**
- * Are we doing speculative attribution?
- */
- boolean isSpeculative = false;
-
/** Are arguments to current function applications boxed into an array for varargs?
*/
Resolve.MethodResolutionPhase pendingResolutionPhase = null;
@@ -100,7 +95,6 @@
info.returnResult = returnResult;
info.defaultSuperCallSite = defaultSuperCallSite;
info.isSerializable = isSerializable;
- info.isSpeculative = isSpeculative;
return info;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Sep 10 19:38:20 2014 -0700
@@ -25,7 +25,6 @@
package com.sun.tools.javac.comp;
-import com.sun.source.tree.*;
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.tree.*;
@@ -78,7 +77,6 @@
final Types types;
final Flow flow;
final Names names;
- final Annotate annotate;
final TypeEnvs typeEnvs;
public static DeferredAttr instance(Context context) {
@@ -103,7 +101,6 @@
flow = Flow.instance(context);
names = Names.instance(context);
stuckTree = make.Ident(names.empty).setType(Type.stuckType);
- annotate = Annotate.instance(context);
typeEnvs = TypeEnvs.instance(context);
emptyDeferredAttrContext =
new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) {
@@ -139,8 +136,7 @@
AttrMode mode;
SpeculativeCache speculativeCache;
- DeferredType(JCExpression tree,
- Env<AttrContext> env) {
+ DeferredType(JCExpression tree, Env<AttrContext> env) {
super(null, noAnnotations);
this.tree = tree;
this.env = attr.copyEnv(env);
@@ -284,18 +280,12 @@
//Note: if a symbol is imported twice we might do two identical
//speculative rounds...
Assert.check(dt.mode == null || dt.mode == AttrMode.SPECULATIVE);
- JCTree speculativeTree = attribSpeculative(dt.tree, dt.env,
- resultInfo,
- annotate.noCreator);
+ JCTree speculativeTree = attribSpeculative(dt.tree, dt.env, resultInfo);
dt.speculativeCache.put(speculativeTree, resultInfo);
return speculativeTree.type;
case CHECK:
Assert.check(dt.mode != null);
- final boolean oldSpeculative = dt.env.info.isSpeculative;
- dt.env.info.isSpeculative = false;
- Type out = attr.attribTree(dt.tree, dt.env, resultInfo);
- dt.env.info.isSpeculative = oldSpeculative;
- return out;
+ return attr.attribTree(dt.tree, dt.env, resultInfo);
}
Assert.error();
return null;
@@ -372,13 +362,9 @@
* restored after type-checking. All diagnostics (but critical ones) are
* disabled during speculative type-checking.
*/
- JCTree attribSpeculative(JCTree tree,
- Env<AttrContext> env,
- ResultInfo resultInfo,
- Annotate.PositionCreator creator) {
+ JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
final JCTree newTree = new TreeCopier<>(make).copy(tree);
Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner)));
- speculativeEnv.info.isSpeculative = true;
Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
new Log.DeferredDiagnosticHandler(log, new Filter<JCDiagnostic>() {
public boolean accepts(final JCDiagnostic d) {
@@ -401,9 +387,6 @@
});
try {
attr.attribTree(newTree, speculativeEnv, resultInfo);
- annotate.typeAnnotateExprLater(newTree, speculativeEnv,
- speculativeEnv.info.scope.owner,
- newTree.pos(), creator);
unenterScanner.scan(newTree);
return newTree;
} finally {
@@ -771,11 +754,8 @@
checkContext.report(null, ex.getDiagnostic());
}
Env<AttrContext> localEnv = env.dup(tree);
- JCExpression exprTree =
- (JCExpression)attribSpeculative(tree.getQualifierExpression(),
- localEnv,
- attr.memberReferenceQualifierResult(tree),
- annotate.methodRefCreator(tree.pos));
+ JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
+ attr.memberReferenceQualifierResult(tree));
ListBuffer<Type> argtypes = new ListBuffer<>();
for (Type t : types.findDescriptorType(pt).getParameterTypes()) {
argtypes.append(Type.noType);
@@ -1197,11 +1177,8 @@
public void visitReference(JCMemberReference tree) {
//perform arity-based check
Env<AttrContext> localEnv = env.dup(tree);
- JCExpression exprTree =
- (JCExpression)attribSpeculative(tree.getQualifierExpression(),
- localEnv,
- attr.memberReferenceQualifierResult(tree),
- annotate.methodRefCreator(tree.pos));
+ JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
+ attr.memberReferenceQualifierResult(tree));
JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
mref2.expr = exprTree;
Symbol res =
@@ -1345,12 +1322,18 @@
return null;
site = resolvedReturnType.type;
} else {
- site = attribSpeculative(rec, env, attr.unknownTypeExprInfo, annotate.noCreator).type;
+ site = attribSpeculative(rec, env, attr.unknownTypeExprInfo).type;
}
} else {
site = env.enclClass.sym.type;
}
+ while (site.hasTag(TYPEVAR)) {
+ site = site.getUpperBound();
+ }
+
+ site = types.capture(site);
+
List<Type> args = rs.dummyArgs(tree.args.length());
Name name = TreeInfo.name(tree.meth);
@@ -1374,7 +1357,9 @@
@Override
public Symbol process(MethodSymbol ms) {
ArgumentExpressionKind kind = ArgumentExpressionKind.methodKind(ms, types);
- return kind != ArgumentExpressionKind.POLY ? ms.getReturnType().tsym : null;
+ if (kind == ArgumentExpressionKind.POLY || ms.getReturnType().hasTag(TYPEVAR))
+ return null;
+ return ms.getReturnType().tsym;
}
@Override
public Symbol reduce(Symbol s1, Symbol s2) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Env.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Env.java Wed Sep 10 19:38:20 2014 -0700
@@ -26,7 +26,6 @@
package com.sun.tools.javac.comp;
import com.sun.tools.javac.tree.*;
-import com.sun.tools.javac.tree.JCTree.JCLambda;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -157,10 +156,4 @@
}
};
}
-
- public JCLambda getLambda() {
- Env<A> out = enclosing(JCTree.Tag.LAMBDA);
-
- return out != null ? (JCLambda) out.tree : null;
- }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Sep 10 19:38:20 2014 -0700
@@ -208,7 +208,7 @@
public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
new AliveAnalyzer().analyzeTree(env, make);
- new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
+ new AssignAnalyzer().analyzeTree(env);
new FlowAnalyzer().analyzeTree(env, make);
new CaptureAnalyzer().analyzeTree(env, make);
}
@@ -241,13 +241,13 @@
//related errors, which will allow for more errors to be detected
Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
try {
- new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit) {
+ new AssignAnalyzer() {
@Override
protected boolean trackable(VarSymbol sym) {
return !env.info.scope.includes(sym) &&
sym.owner.kind == MTH;
}
- }.analyzeTree(env);
+ }.analyzeTree(env, that);
LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
flowAnalyzer.analyzeTree(env, that, make);
return flowAnalyzer.inferredThrownTypes;
@@ -1369,12 +1369,12 @@
* effectively-final local variables/parameters.
*/
- public abstract static class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer.AbstractAssignPendingExit>
+ public abstract class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer<P>.AbstractAssignPendingExit>
extends BaseAnalyzer<P> {
/** The set of definitely assigned variables.
*/
- protected final Bits inits;
+ protected Bits inits;
/** The set of definitely unassigned variables.
*/
@@ -1428,13 +1428,7 @@
/** The starting position of the analysed tree */
int startPos;
- final Symtab syms;
-
- protected Names names;
-
- final boolean enforceThisDotInit;
-
- public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
+ public class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
final Bits inits;
final Bits uninits;
@@ -1456,17 +1450,14 @@
}
}
- public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) {
- this.inits = inits;
+ public AbstractAssignAnalyzer() {
+ this.inits = new Bits();
uninits = new Bits();
uninitsTry = new Bits();
initsWhenTrue = new Bits(true);
initsWhenFalse = new Bits(true);
uninitsWhenTrue = new Bits(true);
uninitsWhenFalse = new Bits(true);
- this.syms = syms;
- this.names = names;
- this.enforceThisDotInit = enforceThisDotInit;
}
private boolean isInitialConstructor = false;
@@ -2431,26 +2422,15 @@
}
}
- public static class AssignAnalyzer
- extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
+ public class AssignAnalyzer extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
- Log log;
- Lint lint;
-
- public static class AssignPendingExit
- extends AbstractAssignAnalyzer.AbstractAssignPendingExit {
+ public class AssignPendingExit extends AbstractAssignAnalyzer<AssignPendingExit>.AbstractAssignPendingExit {
public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
super(tree, inits, uninits);
}
}
- public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) {
- super(new Bits(), syms, names, enforceThisDotInit);
- this.log = log;
- this.lint = lint;
- }
-
@Override
protected AssignPendingExit createNewPendingExit(JCTree tree,
Bits inits, Bits uninits) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Sep 10 19:38:20 2014 -0700
@@ -44,7 +44,6 @@
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.tree.JCTree.*;
import static com.sun.tools.javac.code.Flags.*;
@@ -85,6 +84,7 @@
private final TreeMaker make;
private final Todo todo;
private final Annotate annotate;
+ private final TypeAnnotations typeAnnotations;
private final Types types;
private final JCDiagnostic.Factory diags;
private final Source source;
@@ -112,6 +112,7 @@
make = TreeMaker.instance(context);
todo = Todo.instance(context);
annotate = Annotate.instance(context);
+ typeAnnotations = TypeAnnotations.instance(context);
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
source = Source.instance(context);
@@ -143,13 +144,6 @@
*/
boolean completionEnabled = true;
- /** The creator that will be used for any varDef's we visit. This
- * is used to create the position for any type annotations (or
- * annotations that potentially are type annotations) that we
- * encounter.
- */
- Annotate.PositionCreator creator;
-
/* ---------- Processing import clauses ----------------
*/
@@ -278,7 +272,6 @@
}
/** Construct method type from method signature.
- * @param msym The MethodSymbol for the method.
* @param typarams The method's type parameters.
* @param params The method's value parameters.
* @param res The method's result type,
@@ -287,89 +280,33 @@
* null if none given; TODO: or already set here?
* @param thrown The method's thrown exceptions.
* @param env The method's (local) environment.
- * @param declAnnos The annotations on the method declaration,
- * some of which may be type annotations on
- * the return type.
- * @param deferPos The deferred diagnostic position for error
- * reporting.
*/
- Type signature(final MethodSymbol msym,
- final List<JCTypeParameter> typarams,
- final List<JCVariableDecl> params,
- final JCTree res,
- final JCVariableDecl recvparam,
- final List<JCExpression> thrown,
- final Env<AttrContext> env,
- final List<JCAnnotation> declAnnos,
- final DiagnosticPosition deferPos) {
- int i;
+ Type signature(MethodSymbol msym,
+ List<JCTypeParameter> typarams,
+ List<JCVariableDecl> params,
+ JCTree res,
+ JCVariableDecl recvparam,
+ List<JCExpression> thrown,
+ Env<AttrContext> env) {
// Enter and attribute type parameters.
List<Type> tvars = enter.classEnter(typarams, env);
attr.attribTypeVariables(typarams, env);
- // Handle type annotations on type parameters.
- i = 0;
- for (List<JCTypeParameter> l = typarams; l.nonEmpty();
- l = l.tail, i++) {
- final JCTypeParameter param = l.head;
- annotate.annotateTypeLater(param, env, msym, deferPos,
- annotate.methodTypeParamCreator(i));
- // ...and bounds on type parameters.
- int j = 0;
- for (List<JCExpression> bounds = param.bounds;
- bounds.nonEmpty(); bounds = bounds.tail, j++) {
- annotate.annotateTypeLater(bounds.head, env, msym, deferPos,
- annotate.methodTypeParamBoundCreator(param, i, j));
- }
- }
-
- // Enter and attribute value parameters. Type annotations get
- // METHOD_FORMAL_PARAMETER positions.
+ // Enter and attribute value parameters.
ListBuffer<Type> argbuf = new ListBuffer<>();
- i = 0;
- for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail, i++) {
- // The types will get annotated by visitVarDef
- memberEnter(l.head, env, annotate.paramCreator(i));
+ for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) {
+ memberEnter(l.head, env);
argbuf.append(l.head.vartype.type);
}
// Attribute result type, if one is given.
- Type restype;
-
- if (res != null) {
- // If we have any declaration annotations, they might
- // be/also be type annotations on the return type. We
- // pass them in, so they get classified and then attached
- // to the method, or the return type, or both.
- restype = attr.attribType(res, env);
- annotate.annotateTypeLater(res, declAnnos, env, msym, deferPos,
- annotate.returnCreator);
- } else {
- // For constructors, we don't actually have a type, so we
- // can't have a type path (except for INNER_TYPE), and we
- // don't have annotations on arrays, type arguments, and
- // the like.
-
- // The only type path we have is if we are in an inner type.
- List<TypePathEntry> typepath = Annotate.makeInners(msym.owner.type);
- TypeAnnotationPosition tapos =
- TypeAnnotationPosition.methodReturn(typepath, env.getLambda(), -1);
-
- // We don't have to walk down a type. We just have to do
- // repeating annotation handling, then classify and attach
- // the annotations.
- annotate.annotateWithClassifyLater(declAnnos, env, msym,
- deferPos, tapos);
- restype = syms.voidType;
- }
-
+ Type restype = res == null ? syms.voidType : attr.attribType(res, env);
// Attribute receiver type, if one is given.
Type recvtype;
if (recvparam!=null) {
- // The type will get annotated by visitVarDef
- memberEnter(recvparam, env, annotate.receiverCreator);
+ memberEnter(recvparam, env);
recvtype = recvparam.vartype.type;
} else {
recvtype = null;
@@ -377,12 +314,8 @@
// Attribute thrown exceptions.
ListBuffer<Type> thrownbuf = new ListBuffer<>();
- i = 0;
- for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail, i++) {
+ for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
Type exc = attr.attribType(l.head, env);
- // Annotate each exception type.
- annotate.annotateTypeLater(l.head, env, msym, deferPos,
- annotate.throwCreator(i));
if (!exc.hasTag(TYPEVAR)) {
exc = chk.checkClassType(l.head.pos(), exc);
} else if (exc.tsym.owner == msym) {
@@ -437,49 +370,33 @@
/** Enter field and method definitions and process import
* clauses, catching any completion failure exceptions.
*/
- protected void memberEnter(JCTree tree, Env<AttrContext> env,
- Annotate.PositionCreator creator) {
+ protected void memberEnter(JCTree tree, Env<AttrContext> env) {
Env<AttrContext> prevEnv = this.env;
- Annotate.PositionCreator prevCreator = this.creator;
try {
this.env = env;
- this.creator = creator;
tree.accept(this);
} catch (CompletionFailure ex) {
chk.completionError(tree.pos(), ex);
} finally {
- this.creator = prevCreator;
this.env = prevEnv;
}
}
-
- protected void memberEnter(JCTree tree, Env<AttrContext> env) {
- memberEnter(tree, env, annotate.noCreator);
- }
-
/** Enter members from a list of trees.
*/
- void memberEnter(List<? extends JCTree> trees,
- Env<AttrContext> env,
- Annotate.PositionCreator creator) {
+ void memberEnter(List<? extends JCTree> trees, Env<AttrContext> env) {
for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
- memberEnter(l.head, env, creator);
- }
-
- void memberEnter(List<? extends JCTree> trees,
- Env<AttrContext> env) {
- memberEnter(trees, env, annotate.noCreator);
+ memberEnter(l.head, env);
}
/** Enter members for a class.
*/
- void finishClass(final JCClassDecl tree, final Env<AttrContext> env) {
+ void finishClass(JCClassDecl tree, Env<AttrContext> 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, annotate.fieldCreator);
+ memberEnter(tree.defs, env);
}
/** Add the implicit members for an enum type
@@ -554,7 +471,7 @@
}
}
// process package annotations
- annotate.annotateLater(tree.annotations, env, env.toplevel.packge);
+ annotate.annotateLater(tree.annotations, env, env.toplevel.packge, null);
}
// process the non-static imports and the static imports of types.
@@ -602,13 +519,15 @@
Env<AttrContext> localEnv = methodEnv(tree, env);
+ annotate.enterStart();
+ try {
DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
try {
// Compute the method type
m.type = signature(m, tree.typarams, tree.params,
tree.restype, tree.recvparam,
- tree.thrown, localEnv,
- tree.mods.annotations, tree.pos());
+ tree.thrown,
+ localEnv);
} finally {
deferredLintHandler.setPos(prevLintPos);
}
@@ -635,9 +554,16 @@
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, annotate.noCreator);
+ annotateDefaultValueLater(tree.defaultValue, localEnv, m);
+ } finally {
+ annotate.enterDone();
+ }
}
/** Create a fresh environment for method bodies.
@@ -706,18 +632,10 @@
chk.checkTransparentVar(tree.pos(), v, enclScope);
enclScope.enter(v);
}
- if (TreeInfo.isReceiverParam(tree)) {
- // If we are dealing with a receiver parameter, then
- // we only allow base type annotations to be type
- // annotations. Receivers are not allowed to have
- // declaration annotations.
- annotate.annotateStrictTypeLater(tree.vartype, tree.mods.annotations,
- localEnv, v, tree.pos(), creator);
- } else {
- // Otherwise, we annotate the type.
- annotate.annotateTypeLater(tree.vartype, tree.mods.annotations,
- localEnv, v, tree.pos(), creator);
- }
+
+ annotate.annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
+ annotate.annotateTypeLater(tree.vartype, localEnv, v, tree.pos());
+
v.pos = tree.pos;
} finally {
annotate.enterDone();
@@ -889,8 +807,7 @@
/** Queue processing of an attribute default value. */
void annotateDefaultValueLater(final JCExpression defaultValue,
final Env<AttrContext> localEnv,
- final MethodSymbol m,
- final Annotate.PositionCreator creator) {
+ final MethodSymbol m) {
annotate.normal(new Annotate.Worker() {
@Override
public String toString() {
@@ -979,38 +896,19 @@
// create an environment for evaluating the base clauses
Env<AttrContext> baseEnv = baseEnv(tree, env);
- // Annotations.
- // 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);
- if (hasDeprecatedAnnotation(tree.mods.annotations))
- c.flags_field |= DEPRECATED;
-
- // Don't attach declaration annotations to anonymous
- // classes, they get handled specially below.
- if (!sym.isAnonymous()) {
- annotate.annotateLater(tree.mods.annotations, baseEnv,
- c, tree.pos());
- }
+ 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;
-
if (tree.extending != null) {
dependencies.push(AttributionKind.EXTENDS, tree.extending);
try {
supertype = attr.attribBase(tree.extending, baseEnv,
true, false, true);
- if (sym.isAnonymous()) {
- annotate.annotateAnonClassDefLater(tree.extending,
- tree.mods.annotations,
- baseEnv, sym, tree.pos(),
- annotate.extendsCreator);
- } else {
- annotate.annotateTypeLater(tree.extending, baseEnv, sym,
- tree.pos(), annotate.extendsCreator);
- }
} finally {
dependencies.pop();
}
@@ -1029,7 +927,6 @@
ListBuffer<Type> all_interfaces = null; // lazy init
Set<Type> interfaceSet = new HashSet<>();
List<JCExpression> interfaceTrees = tree.implementing;
- int i = 0;
for (JCExpression iface : interfaceTrees) {
dependencies.push(AttributionKind.IMPLEMENTS, iface);
try {
@@ -1042,19 +939,6 @@
if (all_interfaces == null)
all_interfaces = new ListBuffer<Type>().appendList(interfaces);
all_interfaces.append(modelMissingTypes(it, iface, true));
-
- }
- if (sym.isAnonymous()) {
- // Note: if an anonymous class ever has more than
- // one supertype for some reason, this will
- // incorrectly attach tree.mods.annotations to ALL
- // supertypes, not just the first.
- annotate.annotateAnonClassDefLater(iface, tree.mods.annotations,
- baseEnv, sym, tree.pos(),
- annotate.implementsCreator(i++));
- } else {
- annotate.annotateTypeLater(iface, baseEnv, sym, tree.pos(),
- annotate.implementsCreator(i++));
}
} finally {
dependencies.pop();
@@ -1083,28 +967,22 @@
}
}
- // class type parameters use baseEnv but everything uses env
+ // Annotations.
+ // 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);
+ if (hasDeprecatedAnnotation(tree.mods.annotations))
+ c.flags_field |= DEPRECATED;
+ annotate.annotateLater(tree.mods.annotations, baseEnv,
+ c, tree.pos());
chk.checkNonCyclicDecl(tree);
+ // class type parameters use baseEnv but everything uses env
attr.attribTypeVariables(tree.typarams, baseEnv);
- // Do this here, where we have the symbol.
- int j = 0;
- for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty();
- l = l.tail, j++) {
- final JCTypeParameter typaram = l.head;
- annotate.annotateTypeLater(typaram, baseEnv, sym, tree.pos(),
- annotate.typeParamCreator(j));
-
- int k = 0;
- for(List<JCExpression> b = typaram.bounds; b.nonEmpty();
- b = b.tail, k++) {
- final JCExpression bound = b.head;
- annotate.annotateTypeLater(bound, baseEnv, sym, tree.pos(),
- annotate.typeParamBoundCreator(typaram, j, k));
- }
-
- }
+ for (JCTypeParameter tp : tree.typarams)
+ annotate.annotateTypeLater(tp, baseEnv, sym, tree.pos());
// Add default constructor if needed.
if ((c.flags() & INTERFACE) == 0 &&
@@ -1187,6 +1065,10 @@
Env<AttrContext> toFinish = halfcompleted.next();
topLevels.add(toFinish.toplevel);
finish(toFinish);
+ if (allowTypeAnnos) {
+ typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
+ typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
+ }
}
} finally {
isFirst = true;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Sep 10 19:38:20 2014 -0700
@@ -2992,7 +2992,7 @@
/**
* Should lookup stop at given phase with given result
*/
- protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
+ final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
return phase.ordinal() > maxPhase.ordinal() ||
sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
}
@@ -4174,15 +4174,39 @@
VARARITY(true, true) {
@Override
public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
- switch (sym.kind) {
- case WRONG_MTH:
- return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ?
- bestSoFar :
- sym;
- case ABSENT_MTH:
- return bestSoFar;
- default:
- return sym;
+ //Check invariants (see {@code LookupHelper.shouldStop})
+ Assert.check(bestSoFar.kind >= ERRONEOUS && bestSoFar.kind != AMBIGUOUS);
+ if (sym.kind < ERRONEOUS) {
+ //varargs resolution successful
+ return sym;
+ } else {
+ //pick best error
+ switch (bestSoFar.kind) {
+ case WRONG_MTH:
+ case WRONG_MTHS:
+ //Override previous errors if they were caused by argument mismatch.
+ //This generally means preferring current symbols - but we need to pay
+ //attention to the fact that the varargs lookup returns 'less' candidates
+ //than the previous rounds, and adjust that accordingly.
+ switch (sym.kind) {
+ case WRONG_MTH:
+ //if the previous round matched more than one method, return that
+ //result instead
+ return bestSoFar.kind == WRONG_MTHS ?
+ bestSoFar : sym;
+ case ABSENT_MTH:
+ //do not override erroneous symbol if the arity lookup did not
+ //match any method
+ return bestSoFar;
+ case WRONG_MTHS:
+ default:
+ //safe to override
+ return sym;
+ }
+ default:
+ //otherwise, return first error
+ return bestSoFar;
+ }
}
}
};
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Wed Sep 10 19:38:20 2014 -0700
@@ -82,10 +82,10 @@
for (StringTokenizer st = new StringTokenizer(path);
st.hasMoreTokens(); ) {
String elt = st.nextToken();
- try {
- File f = parent == null ? new File(elt): new File(file.toURI().resolve(elt));
- list.add(f);
- } catch (IllegalArgumentException ex) {}
+ File f = new File(elt);
+ if (!f.isAbsolute() && parent != null)
+ f = new File(parent,elt).getAbsoluteFile();
+ list.add(f);
}
return list;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Sep 10 19:38:20 2014 -0700
@@ -1588,6 +1588,8 @@
return TypeAnnotationPosition.methodReturn(readTypePath());
case FIELD:
return TypeAnnotationPosition.field(readTypePath());
+ case UNKNOWN:
+ throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
default:
throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + type);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Sep 10 19:38:20 2014 -0700
@@ -740,13 +740,25 @@
ListBuffer<Attribute.TypeCompound> invisibles = new ListBuffer<>();
for (Attribute.TypeCompound tc : typeAnnos) {
- Assert.checkNonNull(tc.position);
- if (tc.position.type.isLocal() != inCode) {
+ if (tc.hasUnknownPosition()) {
+ boolean fixed = tc.tryFixPosition();
+
+ // Could we fix it?
+ if (!fixed) {
+ // This happens for nested types like @A Outer. @B Inner.
+ // For method parameters we get the annotation twice! Once with
+ // a valid position, once unknown.
+ // TODO: find a cleaner solution.
+ PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+ pw.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
continue;
}
- if (!tc.position.emitToClassfile()) {
+ }
+
+ if (tc.position.type.isLocal() != inCode)
continue;
- }
+ if (!tc.position.emitToClassfile())
+ continue;
switch (types.getRetention(tc)) {
case SOURCE: break;
case CLASS: invisibles.append(tc); break;
@@ -927,6 +939,8 @@
case METHOD_RETURN:
case FIELD:
break;
+ case UNKNOWN:
+ throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!");
default:
throw new AssertionError("jvm.ClassWriter: Unknown target type for position: " + p);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Sep 10 19:38:20 2014 -0700
@@ -74,6 +74,7 @@
private Name accessDollar;
private final Types types;
private final Lower lower;
+ private final Flow flow;
/** Format of stackmap tables to be generated. */
private final Code.StackMapFormat stackMap;
@@ -113,6 +114,7 @@
stringBufferAppend = new HashMap<>();
accessDollar = names.
fromString("access" + target.syntheticNameChar());
+ flow = Flow.instance(context);
lower = Lower.instance(context);
Options options = Options.instance(context);
@@ -519,6 +521,7 @@
ListBuffer<Attribute.TypeCompound> fieldTAs = new ListBuffer<>();
ListBuffer<Attribute.TypeCompound> nonfieldTAs = new ListBuffer<>();
for (TypeCompound ta : tas) {
+ Assert.check(ta.getPosition().type != TargetType.UNKNOWN);
if (ta.getPosition().type == TargetType.FIELD) {
fieldTAs.add(ta);
} else {
@@ -1818,7 +1821,10 @@
|| code.meth.getKind() == javax.lang.model.element.ElementKind.STATIC_INIT;
for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) {
- if (ta.position != null && ta.position.matchesPos(treePos))
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
ta.position.updatePosOffset(code.cp);
}
@@ -1826,7 +1832,10 @@
return;
for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) {
- if (ta.position != null && ta.position.matchesPos(treePos))
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
ta.position.updatePosOffset(code.cp);
}
@@ -1836,7 +1845,10 @@
continue;
for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) {
- if (ta.position != null && ta.position.matchesPos(treePos))
+ if (ta.hasUnknownPosition())
+ ta.tryFixPosition();
+
+ if (ta.position.matchesPos(treePos))
ta.position.updatePosOffset(code.cp);
}
}
@@ -2208,8 +2220,8 @@
}
public void visitTypeTest(JCInstanceOf tree) {
+ setTypeAnnotationPositions(tree.pos);
genExpr(tree.expr, tree.expr.type).load();
- setTypeAnnotationPositions(tree.pos);
code.emitop2(instanceof_, makeRef(tree.pos(), tree.clazz.type));
result = items.makeStackItem(syms.booleanType);
}
@@ -2373,9 +2385,7 @@
*/
if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) {
try {
- LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make(
- lvtRanges, syms, names);
- lvtAssignAnalyzer.analyzeTree(localEnv);
+ new LVTAssignAnalyzer().analyzeTree(localEnv);
} catch (Throwable e) {
throw e;
}
@@ -2466,11 +2476,10 @@
}
}
- static class LVTAssignAnalyzer
+ class LVTAssignAnalyzer
extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> {
final LVTBits lvtInits;
- final LVTRanges lvtRanges;
/* This class is anchored to a context dependent tree. The tree can
* vary inside the same instruction for example in the switch instruction
@@ -2478,35 +2487,12 @@
* to a given case. The aim is to always anchor the bits to the tree
* capable of closing a DA range.
*/
- static class LVTBits extends Bits {
-
- enum BitsOpKind {
- INIT,
- CLEAR,
- INCL_BIT,
- EXCL_BIT,
- ASSIGN,
- AND_SET,
- OR_SET,
- DIFF_SET,
- XOR_SET,
- INCL_RANGE,
- EXCL_RANGE,
- }
+ class LVTBits extends Bits {
JCTree currentTree;
- LVTAssignAnalyzer analyzer;
private int[] oldBits = null;
BitsState stateBeforeOp;
- LVTBits() {
- super(false);
- }
-
- LVTBits(int[] bits, BitsState initState) {
- super(bits, initState);
- }
-
@Override
public void clear() {
generalOp(null, -1, BitsOpKind.CLEAR);
@@ -2614,12 +2600,11 @@
if (currentTree != null &&
stateBeforeOp != BitsState.UNKNOWN &&
trackTree(currentTree)) {
- List<VarSymbol> locals =
- analyzer.lvtRanges
- .getVars(analyzer.currentMethod, currentTree);
+ List<VarSymbol> locals = lvtRanges
+ .getVars(currentMethod, currentTree);
locals = locals != null ?
locals : List.<VarSymbol>nil();
- for (JCVariableDecl vardecl : analyzer.vardecls) {
+ for (JCVariableDecl vardecl : vardecls) {
//once the first is null, the rest will be so.
if (vardecl == null) {
break;
@@ -2629,7 +2614,7 @@
}
}
if (!locals.isEmpty()) {
- analyzer.lvtRanges.setEntry(analyzer.currentMethod,
+ lvtRanges.setEntry(currentMethod,
currentTree, locals);
}
}
@@ -2647,7 +2632,7 @@
boolean trackVar(VarSymbol var) {
return (var.owner.kind == MTH &&
(var.flags() & PARAMETER) == 0 &&
- analyzer.trackable(var));
+ trackable(var));
}
boolean trackTree(JCTree tree) {
@@ -2663,7 +2648,8 @@
}
- public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit {
+ public class LVTAssignPendingExit extends
+ Flow.AbstractAssignAnalyzer<LVTAssignPendingExit>.AbstractAssignPendingExit {
LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
super(tree, inits, uninits);
@@ -2676,16 +2662,10 @@
}
}
- private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) {
- super(new LVTBits(), syms, names, false);
- lvtInits = (LVTBits)inits;
- this.lvtRanges = lvtRanges;
- }
-
- public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) {
- LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names);
- result.lvtInits.analyzer = result;
- return result;
+ private LVTAssignAnalyzer() {
+ flow.super();
+ lvtInits = new LVTBits();
+ inits = lvtInits;
}
@Override
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java Wed Sep 10 19:38:20 2014 -0700
@@ -84,6 +84,20 @@
}
+ public enum BitsOpKind {
+ INIT,
+ CLEAR,
+ INCL_BIT,
+ EXCL_BIT,
+ ASSIGN,
+ AND_SET,
+ OR_SET,
+ DIFF_SET,
+ XOR_SET,
+ INCL_RANGE,
+ EXCL_RANGE,
+ }
+
private final static int wordlen = 32;
private final static int wordshift = 5;
private final static int wordmask = wordlen - 1;
--- a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java Wed Sep 10 19:38:20 2014 -0700
@@ -27,7 +27,7 @@
* @summary Make sure that type annotations are displayed correctly
* @author Bhavesh Patel
* @library ../lib
- * @ignore
+ * @ignore 8006735 output type annotations in javadoc
* @build JavadocTester
* @run main TestTypeAnnotations
*/
--- a/langtools/test/tools/javac/ConditionalWithVoid.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/ConditionalWithVoid.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4974927
* @summary The compiler was allowing void types in its parsing of conditional expressions.
* @author tball
*
- * @compile/fail ConditionalWithVoid.java
+ * @compile/fail/ref=ConditionalWithVoid.out -XDrawDiagnostics ConditionalWithVoid.java
*/
public class ConditionalWithVoid {
public int test(Object o) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/ConditionalWithVoid.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+ConditionalWithVoid.java:12:48: compiler.err.neither.conditional.subtype: java.lang.Integer, void
+1 error
--- a/langtools/test/tools/javac/DuplicateClass.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/DuplicateClass.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2001, 2002, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4531500
* @summary Cascade of problems from duplicate class can cause compiler crash.
* @author gafter
*
- * @compile/fail DuplicateClass.java
+ * @compile/fail/ref=DuplicateClass.out -XDrawDiagnostics DuplicateClass.java
*/
/**
@@ -36,7 +13,7 @@
* processing it.
*/
public class DuplicateClass {
- protected void clone() {
+ protected Object clone() {
super.clone();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/DuplicateClass.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+DuplicateClass.java:21:8: compiler.err.duplicate.class: DuplicateClass
+1 error
--- a/langtools/test/tools/javac/EOI.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/EOI.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5016879
* @summary REGRESSION: translation unit ending in identifier crashes javac
* @author gafter
*
- * @compile/fail EOI.java
+ * @compile/fail/ref=EOI.out -XDrawDiagnostics EOI.java
*/
class foobar {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/EOI.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+EOI.java:11:1: compiler.err.premature.eof
+1 error
--- a/langtools/test/tools/javac/ExceptionalFinally2.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/ExceptionalFinally2.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2002, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4630634
* @summary missing warn about exception not thrown in try block if finally can't complete
* @author gafter
*
- * @compile/fail ExceptionalFinally2.java
+ * @compile/fail/ref=ExceptionalFinally2.out -XDrawDiagnostics ExceptionalFinally2.java
*/
class ExceptionalFinally2 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/ExceptionalFinally2.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+ExceptionalFinally2.java:22:11: compiler.err.except.never.thrown.in.try: ExceptionalFinally2.E
+1 error
--- a/langtools/test/tools/javac/ExprQualifiedType.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/ExprQualifiedType.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2000, 2001, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4347611 4440249 4508227
* @summary Check that qualified reference to type via an expression does not crash compiler.
* @author maddox
*
- * @compile/fail ExprQualifiedType.java
+ * @compile/fail/ref=ExprQualifiedType.out -XDrawDiagnostics ExprQualifiedType.java
*/
public class ExprQualifiedType {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/ExprQualifiedType.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,3 @@
+ExprQualifiedType.java:18:9: compiler.err.unexpected.type: kindname.class,kindname.package, kindname.value
+ExprQualifiedType.java:19:9: compiler.err.unexpected.type: kindname.class,kindname.package, kindname.value
+2 errors
--- a/langtools/test/tools/javac/ExtendsScope.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/ExtendsScope.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,34 +1,11 @@
/*
- * Copyright (c) 2002, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4402884
* @summary javac improperly extends superclass's scope to implements clause
* @author gafter
*
* @clean I
- * @compile/fail ExtendsScope.java
+ * @compile/fail/ref=ExtendsScope.out -XDrawDiagnostics ExtendsScope.java
*/
class P {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/ExtendsScope.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+ExtendsScope.java:15:30: compiler.err.cant.resolve: kindname.class, I, ,
+1 error
--- a/langtools/test/tools/javac/ExtraneousEquals.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/ExtraneousEquals.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2004, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
+ * @test /nodynamiccopyright/
* @bug 5019614
* @summary variance prototype syntax leftover
*
- * @compile/fail ExtraneousEquals.java
+ * @compile/fail/ref=ExtraneousEquals.out -XDrawDiagnostics ExtraneousEquals.java
*/
public class ExtraneousEquals {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/ExtraneousEquals.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,6 @@
+ExtraneousEquals.java:10:23: compiler.err.illegal.start.of.expr
+ExtraneousEquals.java:10:24: compiler.err.illegal.start.of.expr
+ExtraneousEquals.java:10:25: compiler.err.expected: ';'
+ExtraneousEquals.java:10:28: compiler.err.not.stmt
+ExtraneousEquals.java:10:29: compiler.err.expected: ';'
+5 errors
--- a/langtools/test/tools/javac/FlatnameClash2.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/FlatnameClash2.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2002, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4629327
* @summary Compiler crash on explicit use of synthetic name for inner class.
* @author Neal Gafter
*
- * @compile/fail FlatnameClash2.java
+ * @compile/fail/ref=FlatnameClash2.out -XDrawDiagnostics FlatnameClash2.java
*/
package tests;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/FlatnameClash2.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,3 @@
+FlatnameClash2.java:32:22: compiler.err.cant.resolve.location: kindname.class, T1$Inner1, , , (compiler.misc.location: kindname.package, tests, null)
+FlatnameClash2.java:28:14: compiler.err.cant.apply.symbol: kindname.method, print, tests.T1.Inner1, tests.T2.Inner2, kindname.class, tests.T1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: tests.T2.Inner2, tests.T1.Inner1))
+2 errors
--- a/langtools/test/tools/javac/InconsistentInheritedSignature.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/InconsistentInheritedSignature.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,34 +1,11 @@
/*
- * Copyright (c) 1997, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4041948
* @summary javac previously allowed interfaces to inherit methods with
* inconsistent signatures.
* @author turnidge
*
- * @compile/fail InconsistentInheritedSignature.java
+ * @compile/fail/ref=InconsistentInheritedSignature.out -XDrawDiagnostics InconsistentInheritedSignature.java
*/
interface I1{
int f();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/InconsistentInheritedSignature.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+InconsistentInheritedSignature.java:17:1: compiler.err.types.incompatible.diff.ret: I2, I1, f()
+1 error
--- a/langtools/test/tools/javac/InterfaceObjectIncompatibility.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/InterfaceObjectIncompatibility.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2002, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4479164
* @summary Throws clauses incompatible with Object methods allowed in interfaces
* @author gafter
*
- * @compile/fail InterfaceObjectIncompatibility.java
+ * @compile/fail/ref=InterfaceObjectIncompatibility.out -XDrawDiagnostics InterfaceObjectIncompatibility.java
*/
interface InterfaceObjectIncompatibility {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/InterfaceObjectIncompatibility.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,3 @@
+InterfaceObjectIncompatibility.java:12:12: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.override: toString(), InterfaceObjectIncompatibility, toString(), java.lang.Object), java.io.IOException
+InterfaceObjectIncompatibility.java:13:9: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.override: hashCode(), InterfaceObjectIncompatibility, hashCode(), java.lang.Object), java.lang.Exception
+2 errors
--- a/langtools/test/tools/javac/InterfaceObjectInheritance.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/InterfaceObjectInheritance.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2002, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4526026
* @summary javac allows access to interface members inherited protected from Object
* @author gafter
*
- * @compile/fail InterfaceObjectInheritance.java
+ * @compile/fail/ref=InterfaceObjectInheritance.out -XDrawDiagnostics InterfaceObjectInheritance.java
*/
interface InterfaceObjectInheritance {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/InterfaceObjectInheritance.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+InterfaceObjectInheritance.java:17:18: compiler.err.cant.resolve.location.args: kindname.method, finalize, , , (compiler.misc.location.1: kindname.variable, i, InterfaceObjectInheritance)
+1 error
--- a/langtools/test/tools/javac/InterfaceOverrideFinal.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/InterfaceOverrideFinal.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,31 +1,9 @@
/*
- * Copyright (c) 2002, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
+ * @test /nodynamiccopyright/
+ * @bug 4668238 4721069
+ * @summary compiler must reject interface "overriding" final Object meth.
+ * @compile/fail/ref=InterfaceOverrideFinal.out -XDrawDiagnostics InterfaceOverrideFinal.java
*/
-
-/* @test
- @bug 4668238 4721069
- @summary compiler must reject interface "overriding" final Object meth.
- @compile/fail InterfaceOverrideFinal.java
-*/
public interface InterfaceOverrideFinal {
void notify();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/InterfaceOverrideFinal.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+InterfaceOverrideFinal.java:8:10: compiler.err.override.meth: (compiler.misc.cant.override: notify(), InterfaceOverrideFinal, notify(), java.lang.Object), final
+1 error
--- a/langtools/test/tools/javac/LabeledDeclaration.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/LabeledDeclaration.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 1998, 2001, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4039843
* @summary The compiler should not allow labeled declarations.
* @author turnidge
*
- * @compile/fail LabeledDeclaration.java
+ * @compile/fail/ref=LabeledDeclaration.out -XDrawDiagnostics LabeledDeclaration.java
*/
class LabeledDeclaration {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/LabeledDeclaration.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,3 @@
+LabeledDeclaration.java:12:14: compiler.err.dot.class.expected
+LabeledDeclaration.java:12:10: compiler.err.not.stmt
+2 errors
--- a/langtools/test/tools/javac/NestedDuplicateLabels.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/NestedDuplicateLabels.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 1998, 2001, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 1241001
* @summary The compiler failed to detect duplicate, nested labels.
* @author turnidge
*
- * @compile/fail NestedDuplicateLabels.java
+ * @compile/fail/ref=NestedDuplicateLabels.out -XDrawDiagnostics NestedDuplicateLabels.java
*/
class NestedDuplicateLabels {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/NestedDuplicateLabels.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+NestedDuplicateLabels.java:12:14: compiler.err.label.already.in.use: foo
+1 error
--- a/langtools/test/tools/javac/NewGeneric.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/NewGeneric.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4959929
* @summary unclear diagnostic for "new T()"
* @author never
*
- * @compile/fail NewGeneric.java
+ * @compile/fail/ref=NewGeneric.out -XDrawDiagnostics NewGeneric.java
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/NewGeneric.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+NewGeneric.java:13:28: compiler.err.type.found.req: (compiler.misc.type.parameter: T), (compiler.misc.type.req.class)
+1 error
--- a/langtools/test/tools/javac/NoClass.java Wed Jul 05 20:00:07 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 1998, 2001, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 4041851
- * @summary The gramamr allows java files without class or interface
- * declarations; when the compiler encountered this, it failed
- * to check the validity of import declarations.
- * @author turnidge
- *
- * @compile/fail NoClass.java
- */
-
-import nonexistent.pack.cls;
--- a/langtools/test/tools/javac/Object1.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/Object1.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2001, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4091755
* @summary java.lang.Object can't be redefined without crashing javac
* @author gafter
*
- * @compile/fail Object1.java
+ * @compile/fail/ref=Object1.out -XDrawDiagnostics Object1.java
*/
package java.lang;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/Object1.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+Object1.java:11:22: compiler.err.cyclic.inheritance: java.lang.Throwable
+1 error
--- a/langtools/test/tools/javac/Object2.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/Object2.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2001, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4091755
* @summary java.lang.Object can't be redefined without crashing javac
* @author gafter
*
- * @compile/fail Object2.java
+ * @compile/fail/ref=Object2.out -XDrawDiagnostics Object2.java
*/
package java.lang;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/Object2.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,2 @@
+Object2.java:11:25: compiler.err.cyclic.inheritance: java.lang.Cloneable
+1 error
--- a/langtools/test/tools/javac/Paths/AbsolutePathTest.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/Paths/AbsolutePathTest.java Wed Sep 10 19:38:20 2014 -0700
@@ -23,11 +23,11 @@
/*
* @test
- * @ignore 8055500 [javac] fix for 8030046 is incorrect
- * @bug 8030046
+ * @bug 8030046 8055500
* @summary javac incorrectly handles absolute paths in manifest classpath
* @author govereau
* @library /tools/lib
+ * @ignore 8055768 ToolBox does not close opened files
* @build ToolBox
* @run main AbsolutePathTest
*/
--- a/langtools/test/tools/javac/T6725036.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/T6725036.java Wed Sep 10 19:38:20 2014 -0700
@@ -23,8 +23,7 @@
/*
* @test
- * @bug 6725036
- * @ignore 8016760: failure of regression test langtools/tools/javac/T6725036.java
+ * @bug 6725036 8016760
* @summary javac returns incorrect value for lastModifiedTime() when
* source is a zip file archive
*/
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java Wed Sep 10 19:38:20 2014 -0700
@@ -3,6 +3,7 @@
* @bug 8026564
* @summary The parts of a fully-qualified type can't be annotated.
* @author Werner Dietl
+ * @ignore 8057679 clarify error messages trying to annotate scoping
* @compile/fail/ref=CantAnnotatePackages.out -XDrawDiagnostics CantAnnotatePackages.java
*/
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java Wed Sep 10 19:38:20 2014 -0700
@@ -3,6 +3,7 @@
* @bug 8006733 8006775
* @summary Ensure behavior for nested types is correct.
* @author Werner Dietl
+ * @ignore 8057679 clarify error messages trying to annotate scoping
* @compile/fail/ref=CantAnnotateScoping.out -XDrawDiagnostics CantAnnotateScoping.java
*/
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass2.java Wed Sep 10 19:38:20 2014 -0700
@@ -3,6 +3,8 @@
* @bug 8006733 8006775
* @summary Ensure behavior for nested types is correct.
* @author Werner Dietl
+ * @ignore 8057679 clarify error messages trying to annotate scoping
+ * @ignore 8057683 improve ordering of errors with type annotations
* @compile/fail/ref=CantAnnotateStaticClass2.out -XDrawDiagnostics CantAnnotateStaticClass2.java
*/
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass3.java Wed Sep 10 19:38:20 2014 -0700
@@ -3,6 +3,8 @@
* @bug 8006733 8006775 8027262
* @summary Ensure behavior for nested types is correct.
* @author Werner Dietl
+ * @ignore 8057679 clarify error messages trying to annotate scoping
+ * @ignore 8057683 improve order of errors with type annotations
* @compile/fail/ref=CantAnnotateStaticClass3.out -XDrawDiagnostics CantAnnotateStaticClass3.java
*/
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out Wed Sep 10 19:38:20 2014 -0700
@@ -1,5 +1,5 @@
+DeclarationAnnotation.java:13:21: compiler.err.annotation.type.not.applicable
DeclarationAnnotation.java:10:21: compiler.err.annotation.type.not.applicable
DeclarationAnnotation.java:11:21: compiler.err.annotation.type.not.applicable
DeclarationAnnotation.java:12:21: compiler.err.annotation.type.not.applicable
-DeclarationAnnotation.java:13:21: compiler.err.annotation.type.not.applicable
4 errors
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AllLocations.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AllLocations.java Wed Sep 10 19:38:20 2014 -0700
@@ -25,6 +25,7 @@
* @test
* @bug 8027262
* @summary Stress test for type annotatons
+ * @ignore 8057685 javac should not crash compiling type annotations
* @compile AllLocations.java
*/
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java Wed Sep 10 19:38:20 2014 -0700
@@ -28,6 +28,7 @@
* @bug 8006775
* @summary repeating type annotations are possible
* @author Werner Dietl
+ * @ignore 8057683 improve ordering of errors with type annotations
* @compile/fail/ref=RepeatingTypeAnnotations.out -XDrawDiagnostics RepeatingTypeAnnotations.java
*/
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java Wed Sep 10 19:38:20 2014 -0700
@@ -25,7 +25,8 @@
* @test
* @bug 8008077 8029721 8042451 8043974
* @summary Test population of reference info for lambda expressions
- * javac crash for annotated parameter type of lambda in a field
+ * javac crash for annotated parameter type of lambda in a field
+ * @ignore 8057687 emit correct byte code an attributes for type annotations
* @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
* @run main Driver Lambda
* @author Werner Dietl
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java Wed Sep 10 19:38:20 2014 -0700
@@ -27,6 +27,7 @@
* @test
* @bug 8042451 8044009 8044010
* @summary Test population of reference info for nested types
+ * @ignore 8057687 emit correct byte code an attributes for type annotations
* @compile -g Driver.java ReferenceInfoUtil.java NestedTypes.java
* @run main Driver NestedTypes
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/T8042741/LambdaArgumentsTest.java Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8054210
+ * @summary NullPointerException when compiling specific code
+ * @compile LambdaArgumentsTest.java
+ */
+
+public class LambdaArgumentsTest {
+ interface Thrower<E extends Exception> { void apply() throws E; }
+ interface Consumer<E> { void take(E arg); }
+
+ <E extends Exception>
+ void m1(Thrower<E> a1, Consumer<E> a2) {}
+
+ <E extends Exception>
+ void m2(Thrower<E> a1, Consumer<RuntimeException> a2) {}
+
+ void test() {
+ m1(() -> {}, e -> {});
+ m2(() -> {}, (RuntimeException e) -> {});
+ }
+}
--- a/langtools/test/tools/javac/importChecks/InvalidImportsNoClasses.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/importChecks/InvalidImportsNoClasses.java Wed Sep 10 19:38:20 2014 -0700
@@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
- * @bug 4312063
+ * @bug 4041851 4312063
* @summary Verify that nonexistent imports detected when no classes declared in compilation unit.
* @author maddox
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8056014.java Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8056014
+ * @summary Verify that full type inference is used when calling a method on a type variable.
+ * @compile T8056014.java
+ * @run main T8056014
+ */
+
+import java.util.*;
+
+public class T8056014 {
+ public static void main(String[] args) {
+ new T8056014().run();
+ }
+
+ void run() {
+ List<S> l = Arrays.asList(new S());
+ C<S> c = new C<>(new S());
+ foo(l.get(0).copy(1));
+ foo(c.get(0).copy(1));
+ }
+
+ void foo(S d) {
+ }
+}
+
+class B {
+ public B copy(long j) {
+ throw new AssertionError("Should not get here.");
+ }
+}
+
+class S extends B {
+ public <T> T copy(int i) {
+ return null;
+ }
+}
+
+class C<T extends B> {
+ final T t;
+ public C(T t) {
+ this.t = t;
+ }
+ public T get(int i) {
+ return t;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8056984.java Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056984
+ * @summary Ensure that method resolution runs over a captured type variables when checking if
+ * deferred attribution is needed
+ * @compile T8056984.java
+ */
+class T8056984<T1 extends B&C, T2 extends T1> {
+ public T8056984(T1 t1, T2 t2) {
+ System.err.println(t1.hashCode());
+ System.err.println(t2.hashCode());
+ }
+}
+class B {
+}
+interface C {
+ public int hashCode();
+}
--- a/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/type/BasicAnnoTests.java Wed Sep 10 19:38:20 2014 -0700
@@ -26,7 +26,8 @@
* @bug 8013852
* @summary Annotations on types
* @library /tools/javac/lib
- * @ignore
+ * @ignore 8057688 type annotations in type argument position are lost
+ * @ignore 8031744 Annotations on many Language Model elements are not returned
* @build JavacTestingAbstractProcessor DPrinter BasicAnnoTests
* @compile/process -processor BasicAnnoTests -proc:only BasicAnnoTests.java
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/varargs/8055514/T8055514.java Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8055514
+ * @summary Wrong, confusing error when non-static varargs referenced in static context
+ * @compile/fail/ref=T8055514.out -Xlint:varargs -Werror -XDrawDiagnostics T8055514.java
+ */
+class T8055514 {
+ void m(int... args) { }
+
+ void m2(int... args) { }
+ static void m2(String s) { }
+
+ void m3(int... args) { }
+ static void m3(String s) { }
+ static void m3(Runnable r) { }
+
+ void m4(int... args) { }
+ void m4(int i1, int i2, int i3) { }
+
+ static void test() {
+ m(1,2,3); //only one candidate (varargs) - varargs error wins
+ m2(1,2,3); //two candidates - only one applicable (varargs) - varargs error wins
+ m3(1,2,3); //three candidates - only one applicable (varargs) - varargs error wins
+ m4(1,2,3); //two candidates - both applicable - basic error wins
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/varargs/8055514/T8055514.out Wed Sep 10 19:38:20 2014 -0700
@@ -0,0 +1,5 @@
+T8055514.java:21:9: compiler.err.non-static.cant.be.ref: kindname.method, m(int...)
+T8055514.java:22:9: compiler.err.non-static.cant.be.ref: kindname.method, m2(int...)
+T8055514.java:23:9: compiler.err.non-static.cant.be.ref: kindname.method, m3(int...)
+T8055514.java:24:9: compiler.err.non-static.cant.be.ref: kindname.method, m4(int,int,int)
+4 errors
--- a/langtools/test/tools/javac/warnings/6747671/T6747671.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/warnings/6747671/T6747671.java Wed Sep 10 19:38:20 2014 -0700
@@ -34,6 +34,7 @@
}
@TA B @TA[] arr = new @TA B @TA [0];//JDK-8022567: raw warning (2)
+ //todo: 8057688 type annotations in type argument position are lost
Class<B[]> classes1;//no warning
Class<B>[] classes2;//no warning
--- a/langtools/test/tools/javac/warnings/6747671/T6747671.out Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/warnings/6747671/T6747671.out Wed Sep 10 19:38:20 2014 -0700
@@ -8,5 +8,5 @@
T6747671.java:32:20: compiler.warn.raw.class.use: T6747671.A, T6747671<E>.A<X>
T6747671.java:33:16: compiler.warn.raw.class.use: T6747671.A.Z, T6747671<E>.A<X>.Z<Y>
T6747671.java:36:9: compiler.warn.raw.class.use: @T6747671.TA T6747671.B, T6747671.B<X>
-T6747671.java:36:27: compiler.warn.raw.class.use: @T6747671.TA T6747671.B, T6747671.B<X>
+T6747671.java:36:27: compiler.warn.raw.class.use: T6747671.B, T6747671.B<X>
11 warnings
--- a/langtools/test/tools/javac/warnings/suppress/T6480588.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/warnings/suppress/T6480588.java Wed Sep 10 19:38:20 2014 -0700
@@ -7,7 +7,7 @@
* @compile/ref=T6480588.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast T6480588.java
* @run main VerifySuppressWarnings T6480588.java
*/
-
+// TODO: 8057683 improve ordering of errors with type annotations
@DeprecatedAnnotation
class T6480588 extends DeprecatedClass implements DeprecatedInterface {
@DeprecatedAnnotation
--- a/langtools/test/tools/javac/warnings/suppress/T6480588.out Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/warnings/suppress/T6480588.out Wed Sep 10 19:38:20 2014 -0700
@@ -1,6 +1,6 @@
-T6480588.java:11:2: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
T6480588.java:12:24: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6480588.java:12:51: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
+T6480588.java:11:2: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
T6480588.java:14:12: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6480588.java:14:65: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6480588.java:13:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
@@ -12,7 +12,7 @@
T6480588.java:26:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6480588.java:25:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
T6480588.java:26:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
-T6480588.java:28:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
T6480588.java:29:25: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6480588.java:29:52: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
+T6480588.java:28:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
17 warnings
--- a/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.java Wed Sep 10 19:38:20 2014 -0700
@@ -2,6 +2,7 @@
* @test /nodynamiccopyright/
* @bug 8021112
* @summary Verify that \\@SuppressWarnings("unchecked") works for type annotations
+ * @ignore 8057683 improve ordering of errors with type annotations
* @build VerifySuppressWarnings
* @compile/ref=TypeAnnotations.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast TypeAnnotations.java
* @run main VerifySuppressWarnings TypeAnnotations.java
--- a/langtools/test/tools/javap/output/RepeatingTypeAnnotations.java Wed Jul 05 20:00:07 2017 +0200
+++ b/langtools/test/tools/javap/output/RepeatingTypeAnnotations.java Wed Sep 10 19:38:20 2014 -0700
@@ -25,6 +25,7 @@
* @test
* @bug 8005220
* @summary javap must display repeating annotations
+ * @ignore 8057687 emit correct byte code an attributes for type annotations
*/
import java.io.*;
import java.util.*;