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 { |
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. |
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"> |