langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 21041 99f5e5e97425
parent 21040 3e32f68d2151
child 21479 e11e5b3aec3d
equal deleted inserted replaced
21040:3e32f68d2151 21041:99f5e5e97425
  3532                     // Tree<Point>.Visitor.
  3532                     // Tree<Point>.Visitor.
  3533                     else if (ownOuter.hasTag(CLASS) && site != ownOuter) {
  3533                     else if (ownOuter.hasTag(CLASS) && site != ownOuter) {
  3534                         Type normOuter = site;
  3534                         Type normOuter = site;
  3535                         if (normOuter.hasTag(CLASS)) {
  3535                         if (normOuter.hasTag(CLASS)) {
  3536                             normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
  3536                             normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
  3537                             if (site.isAnnotated()) {
       
  3538                                 // Propagate any type annotations.
       
  3539                                 // TODO: should asEnclosingSuper do this?
       
  3540                                 // Note that the type annotations in site will be updated
       
  3541                                 // by annotateType. Therefore, modify site instead
       
  3542                                 // of creating a new AnnotatedType.
       
  3543                                 ((AnnotatedType)site).underlyingType = normOuter;
       
  3544                                 normOuter = site;
       
  3545                             }
       
  3546                         }
  3537                         }
  3547                         if (normOuter == null) // perhaps from an import
  3538                         if (normOuter == null) // perhaps from an import
  3548                             normOuter = types.erasure(ownOuter);
  3539                             normOuter = types.erasure(ownOuter);
  3549                         if (normOuter != ownOuter)
  3540                         if (normOuter != ownOuter)
  3550                             owntype = new ClassType(
  3541                             owntype = new ClassType(
  3899                             site = types.erasure(clazzOuter);
  3890                             site = types.erasure(clazzOuter);
  3900                         clazzOuter = site;
  3891                         clazzOuter = site;
  3901                     }
  3892                     }
  3902                 }
  3893                 }
  3903                 owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
  3894                 owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
  3904                 if (clazztype.isAnnotated()) {
       
  3905                     // Use the same AnnotatedType, because it will have
       
  3906                     // its annotations set later.
       
  3907                     ((AnnotatedType)clazztype).underlyingType = owntype;
       
  3908                     owntype = clazztype;
       
  3909                 }
       
  3910             } else {
  3895             } else {
  3911                 if (formals.length() != 0) {
  3896                 if (formals.length() != 0) {
  3912                     log.error(tree.pos(), "wrong.number.type.args",
  3897                     log.error(tree.pos(), "wrong.number.type.args",
  3913                               Integer.toString(formals.length()));
  3898                               Integer.toString(formals.length()));
  3914                 } else {
  3899                 } else {
  3970 
  3955 
  3971     public void visitTypeParameter(JCTypeParameter tree) {
  3956     public void visitTypeParameter(JCTypeParameter tree) {
  3972         TypeVar typeVar = (TypeVar) tree.type;
  3957         TypeVar typeVar = (TypeVar) tree.type;
  3973 
  3958 
  3974         if (tree.annotations != null && tree.annotations.nonEmpty()) {
  3959         if (tree.annotations != null && tree.annotations.nonEmpty()) {
  3975             AnnotatedType antype = new AnnotatedType(typeVar);
  3960             annotateType(tree, tree.annotations);
  3976             annotateType(antype, tree.annotations);
       
  3977             tree.type = antype;
       
  3978         }
  3961         }
  3979 
  3962 
  3980         if (!typeVar.bound.isErroneous()) {
  3963         if (!typeVar.bound.isErroneous()) {
  3981             //fixup type-parameter bound computed in 'attribTypeVariables'
  3964             //fixup type-parameter bound computed in 'attribTypeVariables'
  3982             typeVar.bound = checkIntersection(tree, tree.bounds);
  3965             typeVar.bound = checkIntersection(tree, tree.bounds);
  4072     }
  4055     }
  4073 
  4056 
  4074     public void visitAnnotatedType(JCAnnotatedType tree) {
  4057     public void visitAnnotatedType(JCAnnotatedType tree) {
  4075         Type underlyingType = attribType(tree.getUnderlyingType(), env);
  4058         Type underlyingType = attribType(tree.getUnderlyingType(), env);
  4076         this.attribAnnotationTypes(tree.annotations, env);
  4059         this.attribAnnotationTypes(tree.annotations, env);
  4077         AnnotatedType antype = new AnnotatedType(underlyingType);
  4060         annotateType(tree, tree.annotations);
  4078         annotateType(antype, tree.annotations);
  4061         result = tree.type = underlyingType;
  4079         result = tree.type = antype;
       
  4080     }
  4062     }
  4081 
  4063 
  4082     /**
  4064     /**
  4083      * Apply the annotations to the particular type.
  4065      * Apply the annotations to the particular type.
  4084      */
  4066      */
  4085     public void annotateType(final AnnotatedType type, final List<JCAnnotation> annotations) {
  4067     public void annotateType(final JCTree tree, final List<JCAnnotation> annotations) {
  4086         if (annotations.isEmpty())
  4068         // Callers ensure this.
  4087             return;
  4069         // Assert.check(annotations != null && annotations.nonEmpty());
  4088         annotate.typeAnnotation(new Annotate.Worker() {
  4070         annotate.typeAnnotation(new Annotate.Worker() {
  4089             @Override
  4071             @Override
  4090             public String toString() {
  4072             public String toString() {
  4091                 return "annotate " + annotations + " onto " + type;
  4073                 return "annotate " + annotations + " onto " + tree;
  4092             }
  4074             }
  4093             @Override
  4075             @Override
  4094             public void run() {
  4076             public void run() {
  4095                 List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
  4077                 List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
  4096                 type.typeAnnotations = compounds;
  4078                 if (annotations.size() == compounds.size()) {
       
  4079                     // All annotations were successfully converted into compounds
       
  4080                     tree.type = tree.type.unannotatedType().annotatedType(compounds);
       
  4081                 }
  4097             }
  4082             }
  4098         });
  4083         });
  4099     }
  4084     }
  4100 
  4085 
  4101     private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
  4086     private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
  4430     }
  4415     }
  4431     //where
  4416     //where
  4432     private final class TypeAnnotationsValidator extends TreeScanner {
  4417     private final class TypeAnnotationsValidator extends TreeScanner {
  4433 
  4418 
  4434         private final boolean sigOnly;
  4419         private final boolean sigOnly;
  4435         private boolean checkAllAnnotations = false;
       
  4436 
       
  4437         public TypeAnnotationsValidator(boolean sigOnly) {
  4420         public TypeAnnotationsValidator(boolean sigOnly) {
  4438             this.sigOnly = sigOnly;
  4421             this.sigOnly = sigOnly;
  4439         }
  4422         }
  4440 
  4423 
  4441         public void visitAnnotation(JCAnnotation tree) {
  4424         public void visitAnnotation(JCAnnotation tree) {
  4442             if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) {
  4425             chk.validateTypeAnnotation(tree, false);
  4443                 chk.validateTypeAnnotation(tree, false);
       
  4444             }
       
  4445             super.visitAnnotation(tree);
  4426             super.visitAnnotation(tree);
       
  4427         }
       
  4428         public void visitAnnotatedType(JCAnnotatedType tree) {
       
  4429             if (!tree.underlyingType.type.isErroneous()) {
       
  4430                 super.visitAnnotatedType(tree);
       
  4431             }
  4446         }
  4432         }
  4447         public void visitTypeParameter(JCTypeParameter tree) {
  4433         public void visitTypeParameter(JCTypeParameter tree) {
  4448             chk.validateTypeAnnotations(tree.annotations, true);
  4434             chk.validateTypeAnnotations(tree.annotations, true);
  4449             scan(tree.bounds);
  4435             scan(tree.bounds);
  4450             // Don't call super.
  4436             // Don't call super.
  4473                 scan(tree.body);
  4459                 scan(tree.body);
  4474             }
  4460             }
  4475         }
  4461         }
  4476         public void visitVarDef(final JCVariableDecl tree) {
  4462         public void visitVarDef(final JCVariableDecl tree) {
  4477             if (tree.sym != null && tree.sym.type != null)
  4463             if (tree.sym != null && tree.sym.type != null)
  4478                 validateAnnotatedType(tree, tree.sym.type);
  4464                 validateAnnotatedType(tree.vartype, tree.sym.type);
  4479             scan(tree.mods);
  4465             scan(tree.mods);
  4480             scan(tree.vartype);
  4466             scan(tree.vartype);
  4481             if (!sigOnly) {
  4467             if (!sigOnly) {
  4482                 scan(tree.init);
  4468                 scan(tree.init);
  4483             }
  4469             }
  4491             if (tree.clazz != null && tree.clazz.type != null)
  4477             if (tree.clazz != null && tree.clazz.type != null)
  4492                 validateAnnotatedType(tree.clazz, tree.clazz.type);
  4478                 validateAnnotatedType(tree.clazz, tree.clazz.type);
  4493             super.visitTypeTest(tree);
  4479             super.visitTypeTest(tree);
  4494         }
  4480         }
  4495         public void visitNewClass(JCNewClass tree) {
  4481         public void visitNewClass(JCNewClass tree) {
  4496             if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
  4482             if (tree.clazz.type != null)
  4497                 boolean prevCheck = this.checkAllAnnotations;
  4483                 validateAnnotatedType(tree.clazz, tree.clazz.type);
  4498                 try {
       
  4499                     this.checkAllAnnotations = true;
       
  4500                     scan(((JCAnnotatedType)tree.clazz).annotations);
       
  4501                 } finally {
       
  4502                     this.checkAllAnnotations = prevCheck;
       
  4503                 }
       
  4504             }
       
  4505             super.visitNewClass(tree);
  4484             super.visitNewClass(tree);
  4506         }
  4485         }
  4507         public void visitNewArray(JCNewArray tree) {
  4486         public void visitNewArray(JCNewArray tree) {
  4508             if (tree.elemtype != null && tree.elemtype.hasTag(ANNOTATED_TYPE)) {
  4487             if (tree.elemtype != null && tree.elemtype.type != null)
  4509                 boolean prevCheck = this.checkAllAnnotations;
  4488                 validateAnnotatedType(tree.elemtype, tree.elemtype.type);
  4510                 try {
       
  4511                     this.checkAllAnnotations = true;
       
  4512                     scan(((JCAnnotatedType)tree.elemtype).annotations);
       
  4513                 } finally {
       
  4514                     this.checkAllAnnotations = prevCheck;
       
  4515                 }
       
  4516             }
       
  4517             super.visitNewArray(tree);
  4489             super.visitNewArray(tree);
  4518         }
  4490         }
  4519 
  4491 
  4520         @Override
  4492         @Override
  4521         public void visitClassDef(JCClassDecl tree) {
  4493         public void visitClassDef(JCClassDecl tree) {
  4547          * of the symbol.
  4519          * of the symbol.
  4548          * Therefore, we need to override each individual location where a type
  4520          * Therefore, we need to override each individual location where a type
  4549          * can occur.
  4521          * can occur.
  4550          */
  4522          */
  4551         private void validateAnnotatedType(final JCTree errtree, final Type type) {
  4523         private void validateAnnotatedType(final JCTree errtree, final Type type) {
  4552             if (type.getEnclosingType() != null &&
  4524             // System.out.println("Attr.validateAnnotatedType: " + errtree + " type: " + type);
  4553                     type != type.getEnclosingType()) {
  4525 
  4554                 validateEnclosingAnnotatedType(errtree, type.getEnclosingType());
  4526             if (type.isPrimitiveOrVoid()) {
  4555             }
  4527                 return;
  4556             for (Type targ : type.getTypeArguments()) {
  4528             }
  4557                 validateAnnotatedType(errtree, targ);
  4529 
  4558             }
  4530             JCTree enclTr = errtree;
  4559         }
  4531             Type enclTy = type;
  4560         private void validateEnclosingAnnotatedType(final JCTree errtree, final Type type) {
  4532 
  4561             validateAnnotatedType(errtree, type);
  4533             boolean repeat = true;
  4562             if (type.tsym != null &&
  4534             while (repeat) {
  4563                     type.tsym.isStatic() &&
  4535                 if (enclTr.hasTag(TYPEAPPLY)) {
  4564                     type.getAnnotationMirrors().nonEmpty()) {
  4536                     List<Type> tyargs = enclTy.getTypeArguments();
  4565                     // Enclosing static classes cannot have type annotations.
  4537                     List<JCExpression> trargs = ((JCTypeApply)enclTr).getTypeArguments();
  4566                 log.error(errtree.pos(), "cant.annotate.static.class");
  4538                     if (trargs.length() > 0) {
       
  4539                         // Nothing to do for diamonds
       
  4540                         if (tyargs.length() == trargs.length()) {
       
  4541                             for (int i = 0; i < tyargs.length(); ++i) {
       
  4542                                 validateAnnotatedType(trargs.get(i), tyargs.get(i));
       
  4543                             }
       
  4544                         }
       
  4545                         // If the lengths don't match, it's either a diamond
       
  4546                         // or some nested type that redundantly provides
       
  4547                         // type arguments in the tree.
       
  4548                     }
       
  4549 
       
  4550                     // Look at the clazz part of a generic type
       
  4551                     enclTr = ((JCTree.JCTypeApply)enclTr).clazz;
       
  4552                 }
       
  4553 
       
  4554                 if (enclTr.hasTag(SELECT)) {
       
  4555                     enclTr = ((JCTree.JCFieldAccess)enclTr).getExpression();
       
  4556                     if (enclTy != null &&
       
  4557                             !enclTy.hasTag(NONE)) {
       
  4558                         enclTy = enclTy.getEnclosingType();
       
  4559                     }
       
  4560                 } else if (enclTr.hasTag(ANNOTATED_TYPE)) {
       
  4561                     JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr;
       
  4562                     if (enclTy == null ||
       
  4563                             enclTy.hasTag(NONE)) {
       
  4564                         if (at.getAnnotations().size() == 1) {
       
  4565                             log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute);
       
  4566                         } else {
       
  4567                             ListBuffer<Attribute.Compound> comps = new ListBuffer<Attribute.Compound>();
       
  4568                             for (JCAnnotation an : at.getAnnotations()) {
       
  4569                                 comps.add(an.attribute);
       
  4570                             }
       
  4571                             log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList());
       
  4572                         }
       
  4573                         repeat = false;
       
  4574                     }
       
  4575                     enclTr = at.underlyingType;
       
  4576                     // enclTy doesn't need to be changed
       
  4577                 } else if (enclTr.hasTag(IDENT)) {
       
  4578                     repeat = false;
       
  4579                 } else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) {
       
  4580                     JCWildcard wc = (JCWildcard) enclTr;
       
  4581                     if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD) {
       
  4582                         validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy.unannotatedType()).getExtendsBound());
       
  4583                     } else if (wc.getKind() == JCTree.Kind.SUPER_WILDCARD) {
       
  4584                         validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy.unannotatedType()).getSuperBound());
       
  4585                     } else {
       
  4586                         // Nothing to do for UNBOUND
       
  4587                     }
       
  4588                     repeat = false;
       
  4589                 } else if (enclTr.hasTag(TYPEARRAY)) {
       
  4590                     JCArrayTypeTree art = (JCArrayTypeTree) enclTr;
       
  4591                     validateAnnotatedType(art.getType(), ((ArrayType)enclTy.unannotatedType()).getComponentType());
       
  4592                     repeat = false;
       
  4593                 } else if (enclTr.hasTag(TYPEUNION)) {
       
  4594                     JCTypeUnion ut = (JCTypeUnion) enclTr;
       
  4595                     for (JCTree t : ut.getTypeAlternatives()) {
       
  4596                         validateAnnotatedType(t, t.type);
       
  4597                     }
       
  4598                     repeat = false;
       
  4599                 } else if (enclTr.hasTag(TYPEINTERSECTION)) {
       
  4600                     JCTypeIntersection it = (JCTypeIntersection) enclTr;
       
  4601                     for (JCTree t : it.getBounds()) {
       
  4602                         validateAnnotatedType(t, t.type);
       
  4603                     }
       
  4604                     repeat = false;
       
  4605                 } else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE) {
       
  4606                     // This happens in test TargetTypeTest52.java
       
  4607                     // Is there anything to do?
       
  4608                     repeat = false;
       
  4609                 } else {
       
  4610                     Assert.error("Unexpected tree: " + enclTr + " with kind: " + enclTr.getKind() +
       
  4611                             " within: "+ errtree + " with kind: " + errtree.getKind());
       
  4612                 }
  4567             }
  4613             }
  4568         }
  4614         }
  4569     };
  4615     };
  4570 
  4616 
  4571     // <editor-fold desc="post-attribution visitor">
  4617     // <editor-fold desc="post-attribution visitor">