963 } |
963 } |
964 // validate annotation method's return type (could be an annotation type) |
964 // validate annotation method's return type (could be an annotation type) |
965 chk.validateAnnotationType(tree.restype); |
965 chk.validateAnnotationType(tree.restype); |
966 // ensure that annotation method does not clash with members of Object/Annotation |
966 // ensure that annotation method does not clash with members of Object/Annotation |
967 chk.validateAnnotationMethod(tree.pos(), m); |
967 chk.validateAnnotationMethod(tree.pos(), m); |
968 |
|
969 if (tree.defaultValue != null) { |
|
970 // if default value is an annotation, check it is a well-formed |
|
971 // annotation value (e.g. no duplicate values, no missing values, etc.) |
|
972 chk.validateAnnotationTree(tree.defaultValue); |
|
973 } |
|
974 } |
968 } |
975 |
969 |
976 for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail) |
970 for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail) |
977 chk.checkType(l.head.pos(), l.head.type, syms.throwableType); |
971 chk.checkType(l.head.pos(), l.head.type, syms.throwableType); |
978 |
972 |
1030 attribStat(tree.body, localEnv); |
1024 attribStat(tree.body, localEnv); |
1031 } |
1025 } |
1032 |
1026 |
1033 localEnv.info.scope.leave(); |
1027 localEnv.info.scope.leave(); |
1034 result = tree.type = m.type; |
1028 result = tree.type = m.type; |
1035 chk.validateAnnotations(tree.mods.annotations, m); |
|
1036 } |
1029 } |
1037 finally { |
1030 finally { |
1038 chk.setLint(prevLint); |
1031 chk.setLint(prevLint); |
1039 chk.setMethod(prevMethod); |
1032 chk.setMethod(prevMethod); |
1040 } |
1033 } |
1088 initEnv.info.enclVar = v; |
1081 initEnv.info.enclVar = v; |
1089 attribExpr(tree.init, initEnv, v.type); |
1082 attribExpr(tree.init, initEnv, v.type); |
1090 } |
1083 } |
1091 } |
1084 } |
1092 result = tree.type = v.type; |
1085 result = tree.type = v.type; |
1093 chk.validateAnnotations(tree.mods.annotations, v); |
|
1094 } |
1086 } |
1095 finally { |
1087 finally { |
1096 chk.setLint(prevLint); |
1088 chk.setLint(prevLint); |
1097 } |
1089 } |
1098 } |
1090 } |
4153 */ |
4145 */ |
4154 public void attribTopLevel(Env<AttrContext> env) { |
4146 public void attribTopLevel(Env<AttrContext> env) { |
4155 JCCompilationUnit toplevel = env.toplevel; |
4147 JCCompilationUnit toplevel = env.toplevel; |
4156 try { |
4148 try { |
4157 annotate.flush(); |
4149 annotate.flush(); |
4158 chk.validateAnnotations(toplevel.packageAnnotations, toplevel.packge); |
|
4159 } catch (CompletionFailure ex) { |
4150 } catch (CompletionFailure ex) { |
4160 chk.completionError(toplevel.pos(), ex); |
4151 chk.completionError(toplevel.pos(), ex); |
4161 } |
4152 } |
4162 } |
4153 } |
4163 |
4154 |
4238 } |
4229 } |
4239 attribClassBody(env, c); |
4230 attribClassBody(env, c); |
4240 |
4231 |
4241 chk.checkDeprecatedAnnotation(env.tree.pos(), c); |
4232 chk.checkDeprecatedAnnotation(env.tree.pos(), c); |
4242 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c); |
4233 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c); |
|
4234 chk.checkFunctionalInterface((JCClassDecl) env.tree, c); |
4243 } finally { |
4235 } finally { |
4244 env.info.returnResult = prevReturnRes; |
4236 env.info.returnResult = prevReturnRes; |
4245 log.useSource(prev); |
4237 log.useSource(prev); |
4246 chk.setLint(prevLint); |
4238 chk.setLint(prevLint); |
4247 } |
4239 } |
4255 |
4247 |
4256 /** Finish the attribution of a class. */ |
4248 /** Finish the attribution of a class. */ |
4257 private void attribClassBody(Env<AttrContext> env, ClassSymbol c) { |
4249 private void attribClassBody(Env<AttrContext> env, ClassSymbol c) { |
4258 JCClassDecl tree = (JCClassDecl)env.tree; |
4250 JCClassDecl tree = (JCClassDecl)env.tree; |
4259 Assert.check(c == tree.sym); |
4251 Assert.check(c == tree.sym); |
4260 |
|
4261 // Validate annotations |
|
4262 chk.validateAnnotations(tree.mods.annotations, c); |
|
4263 |
4252 |
4264 // Validate type parameters, supertype and interfaces. |
4253 // Validate type parameters, supertype and interfaces. |
4265 attribStats(tree.typarams, env); |
4254 attribStats(tree.typarams, env); |
4266 if (!c.isAnonymous()) { |
4255 if (!c.isAnonymous()) { |
4267 //already checked if anonymous |
4256 //already checked if anonymous |
4359 if (allowTypeAnnos) { |
4348 if (allowTypeAnnos) { |
4360 // Correctly organize the postions of the type annotations |
4349 // Correctly organize the postions of the type annotations |
4361 typeAnnotations.organizeTypeAnnotationsBodies(tree); |
4350 typeAnnotations.organizeTypeAnnotationsBodies(tree); |
4362 |
4351 |
4363 // Check type annotations applicability rules |
4352 // Check type annotations applicability rules |
4364 validateTypeAnnotations(tree); |
4353 validateTypeAnnotations(tree, false); |
4365 } |
4354 } |
4366 } |
4355 } |
4367 // where |
4356 // where |
4368 boolean checkForSerial(ClassSymbol c) { |
4357 boolean checkForSerial(ClassSymbol c) { |
4369 if ((c.flags() & ABSTRACT) == 0) { |
4358 if ((c.flags() & ABSTRACT) == 0) { |
4434 |
4423 |
4435 private Type capture(Type type) { |
4424 private Type capture(Type type) { |
4436 return types.capture(type); |
4425 return types.capture(type); |
4437 } |
4426 } |
4438 |
4427 |
4439 private void validateTypeAnnotations(JCTree tree) { |
4428 public void validateTypeAnnotations(JCTree tree, boolean sigOnly) { |
4440 tree.accept(typeAnnotationsValidator); |
4429 tree.accept(new TypeAnnotationsValidator(sigOnly)); |
4441 } |
4430 } |
4442 //where |
4431 //where |
4443 private final JCTree.Visitor typeAnnotationsValidator = new TreeScanner() { |
4432 private final class TypeAnnotationsValidator extends TreeScanner { |
4444 |
4433 |
|
4434 private final boolean sigOnly; |
4445 private boolean checkAllAnnotations = false; |
4435 private boolean checkAllAnnotations = false; |
|
4436 |
|
4437 public TypeAnnotationsValidator(boolean sigOnly) { |
|
4438 this.sigOnly = sigOnly; |
|
4439 } |
4446 |
4440 |
4447 public void visitAnnotation(JCAnnotation tree) { |
4441 public void visitAnnotation(JCAnnotation tree) { |
4448 if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) { |
4442 if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) { |
4449 chk.validateTypeAnnotation(tree, false); |
4443 chk.validateTypeAnnotation(tree, false); |
4450 } |
4444 } |
4465 tree.recvparam.vartype.type.tsym); |
4459 tree.recvparam.vartype.type.tsym); |
4466 } |
4460 } |
4467 if (tree.restype != null && tree.restype.type != null) { |
4461 if (tree.restype != null && tree.restype.type != null) { |
4468 validateAnnotatedType(tree.restype, tree.restype.type); |
4462 validateAnnotatedType(tree.restype, tree.restype.type); |
4469 } |
4463 } |
4470 super.visitMethodDef(tree); |
4464 if (sigOnly) { |
|
4465 scan(tree.mods); |
|
4466 scan(tree.restype); |
|
4467 scan(tree.typarams); |
|
4468 scan(tree.recvparam); |
|
4469 scan(tree.params); |
|
4470 scan(tree.thrown); |
|
4471 } else { |
|
4472 scan(tree.defaultValue); |
|
4473 scan(tree.body); |
|
4474 } |
4471 } |
4475 } |
4472 public void visitVarDef(final JCVariableDecl tree) { |
4476 public void visitVarDef(final JCVariableDecl tree) { |
4473 if (tree.sym != null && tree.sym.type != null) |
4477 if (tree.sym != null && tree.sym.type != null) |
4474 validateAnnotatedType(tree, tree.sym.type); |
4478 validateAnnotatedType(tree, tree.sym.type); |
4475 super.visitVarDef(tree); |
4479 scan(tree.mods); |
|
4480 scan(tree.vartype); |
|
4481 if (!sigOnly) { |
|
4482 scan(tree.init); |
|
4483 } |
4476 } |
4484 } |
4477 public void visitTypeCast(JCTypeCast tree) { |
4485 public void visitTypeCast(JCTypeCast tree) { |
4478 if (tree.clazz != null && tree.clazz.type != null) |
4486 if (tree.clazz != null && tree.clazz.type != null) |
4479 validateAnnotatedType(tree.clazz, tree.clazz.type); |
4487 validateAnnotatedType(tree.clazz, tree.clazz.type); |
4480 super.visitTypeCast(tree); |
4488 super.visitTypeCast(tree); |
4505 } finally { |
4513 } finally { |
4506 this.checkAllAnnotations = prevCheck; |
4514 this.checkAllAnnotations = prevCheck; |
4507 } |
4515 } |
4508 } |
4516 } |
4509 super.visitNewArray(tree); |
4517 super.visitNewArray(tree); |
|
4518 } |
|
4519 |
|
4520 @Override |
|
4521 public void visitClassDef(JCClassDecl tree) { |
|
4522 if (sigOnly) { |
|
4523 scan(tree.mods); |
|
4524 scan(tree.typarams); |
|
4525 scan(tree.extending); |
|
4526 scan(tree.implementing); |
|
4527 } |
|
4528 for (JCTree member : tree.defs) { |
|
4529 if (member.hasTag(Tag.CLASSDEF)) { |
|
4530 continue; |
|
4531 } |
|
4532 scan(member); |
|
4533 } |
|
4534 } |
|
4535 |
|
4536 @Override |
|
4537 public void visitBlock(JCBlock tree) { |
|
4538 if (!sigOnly) { |
|
4539 scan(tree.stats); |
|
4540 } |
4510 } |
4541 } |
4511 |
4542 |
4512 /* I would want to model this after |
4543 /* I would want to model this after |
4513 * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess) |
4544 * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess) |
4514 * and override visitSelect and visitTypeApply. |
4545 * and override visitSelect and visitTypeApply. |