--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jul 05 19:44:08 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Jun 06 16:00:59 2014 -0400
@@ -91,7 +91,6 @@
final Types types;
final JCDiagnostic.Factory diags;
final Annotate annotate;
- final TypeAnnotations typeAnnotations;
final DeferredLintHandler deferredLintHandler;
public static Attr instance(Context context) {
@@ -120,7 +119,6 @@
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
annotate = Annotate.instance(context);
- typeAnnotations = TypeAnnotations.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
Options options = Options.instance(context);
@@ -434,8 +432,7 @@
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));
}
@@ -638,7 +635,8 @@
/** 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
@@ -650,6 +648,7 @@
/** Derived visitor method: attribute a type tree.
*/
+
public Type attribType(JCTree tree, Env<AttrContext> env) {
Type result = attribType(tree, env, Type.noType);
return result;
@@ -664,6 +663,7 @@
/** Derived visitor method: attribute a statement or definition tree.
*/
+
public Type attribStat(JCTree tree, Env<AttrContext> env) {
return attribTree(tree, env, statInfo);
}
@@ -731,7 +731,8 @@
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());
@@ -765,7 +766,7 @@
* @param type The expected type, or null
* @see VarSymbol#setLazyConstValue
*/
- public Object attribLazyConstantValue(Env<AttrContext> env,
+ public Object attribLazyConstantValue(final Env<AttrContext> env,
JCVariableDecl variable,
Type type) {
@@ -884,6 +885,7 @@
c.flags_field |= NOOUTERTHIS;
}
attribClass(tree.pos(), c);
+
result = tree.type = c.type;
}
}
@@ -1021,10 +1023,6 @@
}
}
- // Attribute all type annotations in the body
- annotate.annotateTypeLater(tree.body, localEnv, m, null);
- annotate.flush();
-
// Attribute method body.
attribStat(tree.body, localEnv);
}
@@ -1038,21 +1036,67 @@
}
}
- public void visitVarDef(JCVariableDecl tree) {
+ 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);
+ }
+ }
+ case CASE:
+ case BLOCK:
+ case FORLOOP:
+ case FOREACHLOOP:
+ case LABELLED:
+ // These are all cases where we can end up with a
+ // local variable.
+ return annotate.localVarCreator(tree.pos);
+ default:
+ // Be strict and throw an error if we see
+ // something we don't expect.
+ throw new AssertionError("Unexpected enclosing tree for variable definition: " + env.tree.getTag());
+ }
+ }
+
+ public void visitVarDef(final JCVariableDecl tree) {
// Local variables have not been entered yet, so we need to do it now:
if (env.info.scope.owner.kind == MTH) {
if (tree.sym != null) {
// parameters have already been entered
env.info.scope.enter(tree.sym);
} else {
- memberEnter.memberEnter(tree, env);
- annotate.flush();
- }
- } else {
- if (tree.init != null) {
- // Field initializer expression need to be entered.
- annotate.annotateTypeLater(tree.init, env, tree.sym, tree.pos());
- annotate.flush();
+ memberEnter.memberEnter(tree, env, getVarCreator(tree));
}
}
@@ -1103,17 +1147,15 @@
// Block is a static or instance initializer;
// let the owner of the environment be a freshly
// created BLOCK-method.
- Env<AttrContext> localEnv =
+ final Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
localEnv.info.scope.owner =
new MethodSymbol(tree.flags | BLOCK |
env.info.scope.owner.flags() & STRICTFP, names.empty, null,
env.info.scope.owner);
+
if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
-
- // Attribute all type annotations in the block
- annotate.annotateTypeLater(tree, localEnv, localEnv.info.scope.owner, null);
- annotate.flush();
+ attribStats(tree.stats, localEnv);
{
// Store init and clinit type annotations with the ClassSymbol
@@ -1126,8 +1168,6 @@
cs.appendInitTypeAttributes(tas);
}
}
-
- attribStats(tree.stats, localEnv);
} else {
// Create a new local environment with a local scope.
Env<AttrContext> localEnv =
@@ -1481,17 +1521,21 @@
isBooleanOrNumeric(env, condTree.falsepart);
case APPLY:
JCMethodInvocation speculativeMethodTree =
- (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
+ (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo,
+ annotate.noCreator);
Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
return types.unboxedTypeOrType(owntype).isPrimitive();
case NEWCLASS:
JCExpression className =
removeClassParams.translate(((JCNewClass)tree).clazz);
JCExpression speculativeNewClassTree =
- (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
+ (JCExpression)deferredAttr.attribSpeculative(className,
+ env,
+ unknownTypeInfo,
+ annotate.newObjCreator(tree.pos));
return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
default:
- Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
+ Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo, annotate.noCreator).type;
speculativeType = types.unboxedTypeOrType(speculativeType);
return speculativeType.isPrimitive();
}
@@ -1754,7 +1798,28 @@
// Attribute arguments, yielding list of argument types.
attribArgs(tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
- typeargtypes = attribTypes(tree.typeargs, localEnv);
+
+ // Attribute and annotate the type arguments
+ ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
+ int i = 0;
+
+ for (List<JCExpression> l = tree.typeargs;
+ l.nonEmpty(); l = l.tail, i++) {
+ final JCExpression arg = l.head;
+ 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());
// Variable `site' points to the class in which the called
// constructor is defined.
@@ -1827,7 +1892,27 @@
// Attribute the arguments, yielding list of argument types, ...
int kind = attribArgs(tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
- typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
+
+ // Attribute and annotate the type arguments
+ ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
+ int i = 0;
+
+ for (List<JCExpression> l = tree.typeargs;
+ l.nonEmpty(); l = l.tail, i++) {
+ final JCExpression arg = l.head;
+ 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();
// ... and attribute the method using as a prototype a methodtype
// whose formal argument types is exactly the list of actual
@@ -1852,6 +1937,7 @@
// current context. Also, capture the return type
result = check(tree, capture(restype), VAL, resultInfo);
}
+
chk.validate(tree.typeargs, localEnv);
}
//where
@@ -1927,14 +2013,12 @@
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
@@ -1956,11 +2040,12 @@
EndPosTable endPosTable = this.env.toplevel.endPositions;
endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable));
- if (clazz.hasTag(ANNOTATED_TYPE)) {
- JCAnnotatedType annoType = (JCAnnotatedType) clazz;
- List<JCAnnotation> annos = annoType.annotations;
-
- if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
+ if (annoclazzid != null) {
+ JCAnnotatedType annoType = annoclazzid;
+ List<JCAnnotation> annos = annoclazzid.annotations;
+
+ if (clazz.hasTag(TYPEAPPLY)) {
+
clazzid1 = make.at(tree.pos).
TypeApply(clazzid1,
((JCTypeApply) clazz).arguments);
@@ -1977,12 +2062,32 @@
clazz = clazzid1;
}
+ Type clazztype;
+
+ try {
+ annotate.enterStart();
// Attribute clazz expression and store
// symbol + type back into the attributed tree.
- Type clazztype = TreeInfo.isEnumInit(env.tree) ?
+ 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) {
@@ -2011,7 +2116,29 @@
ListBuffer<Type> argtypesBuf = new ListBuffer<>();
int pkind = attribArgs(tree.args, localEnv, argtypesBuf);
List<Type> argtypes = argtypesBuf.toList();
- List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
+ List<Type> typeargtypes;
+
+ // Attribute and annotate the type arguments
+ ListBuffer<Type> typeargtypesbuf = new ListBuffer<>();
+ int i = 0;
+
+ for (List<JCExpression> l = tree.typeargs;
+ l.nonEmpty(); l = l.tail, i++) {
+ final JCExpression arg = l.head;
+ 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());
// If we have made no mistakes in the class type...
if (clazztype.hasTag(CLASS)) {
@@ -2194,7 +2321,9 @@
ta.arguments = List.nil();
ResultInfo findDiamondResult = new ResultInfo(VAL,
resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
- Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
+ Type inferred = deferredAttr.attribSpeculative(tree, env,
+ findDiamondResult,
+ annotate.newObjCreator(tree.pos)).type;
Type polyPt = allowPoly ?
syms.objectType :
clazztype;
@@ -2256,8 +2385,20 @@
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) {
@@ -2278,6 +2419,7 @@
elemtype = types.createErrorType(pt());
}
}
+
if (tree.elems != null) {
attribExprs(tree.elems, localEnv, elemtype);
owntype = new ArrayType(elemtype, syms.arrayClass,
@@ -2672,6 +2814,8 @@
@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
@@ -2682,9 +2826,20 @@
}
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
- Type exprType = attribTree(that.expr, env, memberReferenceQualifierResult(that));
+ 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();
+ }
if (that.getMode() == JCMemberReference.ReferenceMode.NEW) {
exprType = chk.checkConstructorRefType(that.expr, exprType);
@@ -2714,7 +2869,24 @@
//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;
@@ -3088,7 +3260,15 @@
}
public void visitTypeCast(final JCTypeCast tree) {
- Type clazztype = attribType(tree.clazz, env);
+ 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();
+ }
chk.validate(tree.clazz, env, false);
//a fresh environment is required for 292 inference to work properly ---
//see Infer.instantiatePolymorphicSignatureInstance()
@@ -3121,7 +3301,16 @@
public void visitTypeTest(JCInstanceOf tree) {
Type exprtype = chk.checkNullOrRefType(
tree.expr.pos(), attribExpr(tree.expr, env));
- Type clazztype = attribType(tree.clazz, 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();
+ }
+
if (!clazztype.hasTag(TYPEVAR)) {
clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype);
}
@@ -3250,9 +3439,12 @@
if ((pkind() & (PCK | TYP)) == 0)
site = capture(site); // Capture field access
+ 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
- if (skind == TYP) {
- Type elt = site;
while (elt.hasTag(ARRAY))
elt = ((ArrayType)elt).elemtype;
if (elt.hasTag(TYPEVAR)) {
@@ -4081,8 +4273,13 @@
Assert.error("should be handled in Annotate");
}
+ /* This needs to be removed or otherwise changed, as it implicitly
+ * relies on the annotated types having previously been visited by
+ * Annotate.TypeAnnotate.
+ */
public void visitAnnotatedType(JCAnnotatedType tree) {
- Type underlyingType = attribType(tree.getUnderlyingType(), env);
+ Type underlyingType = attribTree(tree.getUnderlyingType(), env,
+ resultInfo);
this.attribAnnotationTypes(tree.annotations, env);
annotateType(tree, tree.annotations);
result = tree.type = underlyingType;
@@ -4101,8 +4298,10 @@
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);
}
+ }
});
}
@@ -4353,13 +4552,6 @@
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) {
@@ -4433,233 +4625,6 @@
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">
/**