You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AjProblemReporter.java 33KB

21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
16 years ago
11 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
11 years ago
21 years ago
21 years ago
21 years ago
11 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
13 years ago
21 years ago
21 years ago
21 years ago
13 years ago
20 years ago
21 years ago
21 years ago
21 years ago
13 years ago
11 years ago
11 years ago
10 years ago
13 years ago
13 years ago
13 years ago
21 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.ajdt.internal.compiler.problem;
  13. import java.io.PrintWriter;
  14. import java.io.StringWriter;
  15. import java.lang.reflect.Modifier;
  16. import java.util.Collection;
  17. import java.util.HashSet;
  18. import java.util.List;
  19. import java.util.Set;
  20. import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration;
  21. import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
  22. import org.aspectj.ajdt.internal.compiler.ast.DeclareAnnotationDeclaration;
  23. import org.aspectj.ajdt.internal.compiler.ast.IfMethodDeclaration;
  24. import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
  25. import org.aspectj.ajdt.internal.compiler.ast.Proceed;
  26. import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
  27. import org.aspectj.ajdt.internal.compiler.lookup.InterTypeMethodBinding;
  28. import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedFieldBinding;
  29. import org.aspectj.bridge.context.CompilationAndWeavingContext;
  30. import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
  31. import org.aspectj.org.eclipse.jdt.core.compiler.IProblem;
  32. import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
  33. import org.aspectj.org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
  34. import org.aspectj.org.eclipse.jdt.internal.compiler.IProblemFactory;
  35. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
  36. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  37. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
  38. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
  39. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
  40. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
  41. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
  42. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
  43. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
  44. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  45. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
  46. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
  47. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
  48. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.IPrivilegedHandler;
  49. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
  50. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
  51. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
  52. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
  53. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
  54. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
  55. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
  56. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  57. import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
  58. import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
  59. import org.aspectj.util.FuzzyBoolean;
  60. import org.aspectj.weaver.AjcMemberMaker;
  61. import org.aspectj.weaver.ConcreteTypeMunger;
  62. import org.aspectj.weaver.ReferenceType;
  63. import org.aspectj.weaver.ResolvedMember;
  64. import org.aspectj.weaver.ResolvedType;
  65. import org.aspectj.weaver.ResolvedTypeMunger;
  66. import org.aspectj.weaver.Shadow;
  67. import org.aspectj.weaver.UnresolvedType;
  68. import org.aspectj.weaver.patterns.Declare;
  69. import org.aspectj.weaver.patterns.DeclareAnnotation;
  70. import org.aspectj.weaver.patterns.DeclareParents;
  71. import org.aspectj.weaver.patterns.DeclareSoft;
  72. import org.aspectj.weaver.patterns.TypePattern;
  73. /**
  74. * Extends problem reporter to support compiler-side implementation of declare soft. Also overrides error reporting for the need to
  75. * implement abstract methods to account for inter-type declarations and pointcut declarations. This second job might be better done
  76. * directly in the SourceTypeBinding/ClassScope classes.
  77. *
  78. * @author Jim Hugunin
  79. */
  80. public class AjProblemReporter extends ProblemReporter {
  81. private static final boolean DUMP_STACK = false;
  82. public EclipseFactory factory;
  83. public AjProblemReporter(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
  84. super(policy, options, problemFactory);
  85. }
  86. public void unhandledException(TypeBinding exceptionType, ASTNode location) {
  87. if (!factory.getWorld().getDeclareSoft().isEmpty()) {
  88. Shadow callSite = factory.makeShadow(location, referenceContext);
  89. Shadow enclosingExec = factory.makeShadow(referenceContext);
  90. // PR 72157 - calls to super / this within a constructor are not part of the cons join point.
  91. if ((callSite == null) && (enclosingExec.getKind() == Shadow.ConstructorExecution)
  92. && (location instanceof ExplicitConstructorCall)) {
  93. super.unhandledException(exceptionType, location);
  94. return;
  95. }
  96. // System.err.println("about to show error for unhandled exception: " + new String(exceptionType.sourceName()) +
  97. // " at " + location + " in " + referenceContext);
  98. for (DeclareSoft d: factory.getWorld().getDeclareSoft()) {
  99. // for (Iterator<DeclareSoft> i = factory.getWorld().getDeclareSoft().iterator(); i.hasNext();) {
  100. // DeclareSoft d = (DeclareSoft) i.next();
  101. // We need the exceptionType to match the type in the declare soft statement
  102. // This means it must either be the same type or a subtype
  103. ResolvedType throwException = factory.fromEclipse((ReferenceBinding) exceptionType);
  104. FuzzyBoolean isExceptionTypeOrSubtype = d.getException().matchesInstanceof(throwException);
  105. if (!isExceptionTypeOrSubtype.alwaysTrue())
  106. continue;
  107. if (callSite != null) {
  108. FuzzyBoolean match = d.getPointcut().match(callSite);
  109. if (match.alwaysTrue()) {
  110. // System.err.println("matched callSite: " + callSite + " with " + d);
  111. return;
  112. } else if (!match.alwaysFalse()) {
  113. // !!! need this check to happen much sooner
  114. // throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
  115. }
  116. }
  117. if (enclosingExec != null) {
  118. FuzzyBoolean match = d.getPointcut().match(enclosingExec);
  119. if (match.alwaysTrue()) {
  120. // System.err.println("matched enclosingExec: " + enclosingExec + " with " + d);
  121. return;
  122. } else if (!match.alwaysFalse()) {
  123. // !!! need this check to happen much sooner
  124. // throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
  125. }
  126. }
  127. }
  128. }
  129. // ??? is this always correct
  130. if (location instanceof Proceed) {
  131. return;
  132. }
  133. super.unhandledException(exceptionType, location);
  134. }
  135. public void unhandledExceptionFromAutoClose(TypeBinding exceptionType, ASTNode location) {
  136. if (!factory.getWorld().getDeclareSoft().isEmpty()) {
  137. Shadow callSite = factory.makeShadow(location, referenceContext);
  138. Shadow enclosingExec = factory.makeShadow(referenceContext);
  139. // PR 72157 - calls to super / this within a constructor are not part of the cons join point.
  140. if ((callSite == null) && (enclosingExec.getKind() == Shadow.ConstructorExecution)
  141. && (location instanceof ExplicitConstructorCall)) {
  142. super.unhandledException(exceptionType, location);
  143. return;
  144. }
  145. // System.err.println("about to show error for unhandled exception: " + new String(exceptionType.sourceName()) +
  146. // " at " + location + " in " + referenceContext);
  147. for (DeclareSoft d: factory.getWorld().getDeclareSoft()) {
  148. // for (Iterator<DeclareSoft> i = factory.getWorld().getDeclareSoft().iterator(); i.hasNext();) {
  149. // DeclareSoft d = (DeclareSoft) i.next();
  150. // We need the exceptionType to match the type in the declare soft statement
  151. // This means it must either be the same type or a subtype
  152. ResolvedType throwException = factory.fromEclipse((ReferenceBinding) exceptionType);
  153. FuzzyBoolean isExceptionTypeOrSubtype = d.getException().matchesInstanceof(throwException);
  154. if (!isExceptionTypeOrSubtype.alwaysTrue())
  155. continue;
  156. if (callSite != null) {
  157. FuzzyBoolean match = d.getPointcut().match(callSite);
  158. if (match.alwaysTrue()) {
  159. // System.err.println("matched callSite: " + callSite + " with " + d);
  160. return;
  161. } else if (!match.alwaysFalse()) {
  162. // !!! need this check to happen much sooner
  163. // throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
  164. }
  165. }
  166. if (enclosingExec != null) {
  167. FuzzyBoolean match = d.getPointcut().match(enclosingExec);
  168. if (match.alwaysTrue()) {
  169. // System.err.println("matched enclosingExec: " + enclosingExec + " with " + d);
  170. return;
  171. } else if (!match.alwaysFalse()) {
  172. // !!! need this check to happen much sooner
  173. // throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
  174. }
  175. }
  176. }
  177. }
  178. // ??? is this always correct
  179. if (location instanceof Proceed) {
  180. return;
  181. }
  182. super.unhandledExceptionFromAutoClose(exceptionType, location);
  183. }
  184. private boolean isPointcutDeclaration(MethodBinding binding) {
  185. return CharOperation.prefixEquals(PointcutDeclaration.mangledPrefix, binding.selector);
  186. }
  187. private boolean isIntertypeDeclaration(MethodBinding binding) {
  188. return (binding instanceof InterTypeMethodBinding);
  189. }
  190. public void abstractMethodCannotBeOverridden(SourceTypeBinding type, MethodBinding concreteMethod) {
  191. if (isPointcutDeclaration(concreteMethod)) {
  192. return;
  193. }
  194. super.abstractMethodCannotBeOverridden(type, concreteMethod);
  195. }
  196. public void inheritedMethodReducesVisibility(SourceTypeBinding type, MethodBinding concreteMethod,
  197. MethodBinding[] abstractMethods) {
  198. // if we implemented this method by a public inter-type declaration, then there is no error
  199. ResolvedType onTypeX = null;
  200. // If the type is anonymous, look at its supertype
  201. if (!type.isAnonymousType()) {
  202. onTypeX = factory.fromEclipse(type);
  203. } else {
  204. // Hmmm. If the ITD is on an interface that is being 'instantiated' using an anonymous type,
  205. // we sort it out elsewhere and don't come into this method -
  206. // so we don't have to worry about interfaces, just the superclass.
  207. onTypeX = factory.fromEclipse(type.superclass()); // abstractMethod.declaringClass);
  208. }
  209. for (ConcreteTypeMunger m : onTypeX.getInterTypeMungersIncludingSupers()) {
  210. ResolvedMember sig = m.getSignature();
  211. if (!Modifier.isAbstract(sig.getModifiers())) {
  212. if (ResolvedType.matches(
  213. AjcMemberMaker.interMethod(sig, m.getAspectType(), sig.getDeclaringType().resolve(factory.getWorld())
  214. .isInterface()), factory.makeResolvedMember(concreteMethod))) {
  215. return;
  216. }
  217. }
  218. }
  219. super.inheritedMethodReducesVisibility(type, concreteMethod, abstractMethods);
  220. }
  221. // if either of the MethodBinding is an ITD, we have already reported it.
  222. public void staticAndInstanceConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) {
  223. if (currentMethod instanceof InterTypeMethodBinding)
  224. return;
  225. if (inheritedMethod instanceof InterTypeMethodBinding)
  226. return;
  227. super.staticAndInstanceConflict(currentMethod, inheritedMethod);
  228. }
  229. public void abstractMethodMustBeImplemented(SourceTypeBinding type, MethodBinding abstractMethod) {
  230. // if this is a PointcutDeclaration then there is no error
  231. if (isPointcutDeclaration(abstractMethod))
  232. return;
  233. if (isIntertypeDeclaration(abstractMethod))
  234. return; // when there is a problem with an ITD not being implemented, it will be reported elsewhere
  235. if (CharOperation.prefixEquals("ajc$interField".toCharArray(), abstractMethod.selector)) {
  236. // ??? think through how this could go wrong
  237. return;
  238. }
  239. // if we implemented this method by an inter-type declaration, then there is no error
  240. // ??? be sure this is always right
  241. ResolvedType onTypeX = null;
  242. // If the type is anonymous, look at its supertype
  243. if (!type.isAnonymousType()) {
  244. onTypeX = factory.fromEclipse(type);
  245. } else {
  246. // Hmmm. If the ITD is on an interface that is being 'instantiated' using an anonymous type,
  247. // we sort it out elsewhere and don't come into this method -
  248. // so we don't have to worry about interfaces, just the superclass.
  249. onTypeX = factory.fromEclipse(type.superclass()); // abstractMethod.declaringClass);
  250. }
  251. if (onTypeX.isRawType())
  252. onTypeX = onTypeX.getGenericType();
  253. List<ConcreteTypeMunger> mungers = onTypeX.getInterTypeMungersIncludingSupers();
  254. for (ConcreteTypeMunger m : mungers) {
  255. ResolvedMember sig = m.getSignature();
  256. if (sig != null && !Modifier.isAbstract(sig.getModifiers())) {
  257. ResolvedMember abstractMember = factory.makeResolvedMember(abstractMethod);
  258. if (abstractMember.getName().startsWith("ajc$interMethodDispatch")) {
  259. ResolvedType dType = factory.getWorld().resolve(sig.getDeclaringType(), false);
  260. if (ResolvedType.matches(AjcMemberMaker.interMethod(sig, m.getAspectType(), dType.isInterface()),
  261. abstractMember)) {
  262. return;
  263. }
  264. } else {
  265. // In this case we have something like:
  266. // interface I {}
  267. // abstract class C implements I { abstract void foo();}
  268. // class D extends C {}
  269. // ITD: public void I.foo() {...}
  270. // The ITD is providing the implementation of foo in the class D but when checking for whether the abstract
  271. // method is overridden, we won't be looking at whether the ITD overrides ajc$interMethodDispath$...foo but
  272. // whether it overrides the foo method from class C
  273. if (ResolvedType.matches(sig, factory.makeResolvedMember(abstractMethod)))
  274. return;
  275. }
  276. }
  277. }
  278. super.abstractMethodMustBeImplemented(type, abstractMethod);
  279. }
  280. /*
  281. * (non-Javadoc)
  282. *
  283. * @see
  284. * org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter#disallowedTargetForAnnotation(org.aspectj.org.eclipse
  285. * .jdt.internal.compiler.ast.Annotation)
  286. */
  287. public void disallowedTargetForAnnotation(Annotation annotation) {
  288. // if the annotation's recipient is an ITD, it might be allowed after all...
  289. if (annotation.recipient instanceof MethodBinding) {
  290. MethodBinding binding = (MethodBinding) annotation.recipient;
  291. String name = new String(binding.selector);
  292. if (name.startsWith("ajc$")) {
  293. long metaTagBits = annotation.resolvedType.getAnnotationTagBits(); // could be forward reference
  294. if (name.contains("interField")) {
  295. if ((metaTagBits & TagBits.AnnotationForField) != 0)
  296. return;
  297. } else if (name.contains("interConstructor")) {
  298. if ((metaTagBits & TagBits.AnnotationForConstructor) != 0)
  299. return;
  300. } else if (name.contains("interMethod")) {
  301. if ((metaTagBits & TagBits.AnnotationForMethod) != 0)
  302. return;
  303. } else if (name.contains("declare_" + DeclareAnnotation.AT_TYPE + "_")) {
  304. if ((metaTagBits & TagBits.AnnotationForAnnotationType) != 0 || (metaTagBits & TagBits.AnnotationForType) != 0)
  305. return;
  306. } else if (name.contains("declare_" + DeclareAnnotation.AT_FIELD + "_")) {
  307. if ((metaTagBits & TagBits.AnnotationForField) != 0)
  308. return;
  309. } else if (name.contains("declare_" + DeclareAnnotation.AT_CONSTRUCTOR + "_")) {
  310. if ((metaTagBits & TagBits.AnnotationForConstructor) != 0)
  311. return;
  312. } else if (name.contains("declare_eow")) {
  313. if ((metaTagBits & TagBits.AnnotationForField) != 0)
  314. return;
  315. }
  316. }
  317. }
  318. // not our special case, report the problem...
  319. super.disallowedTargetForAnnotation(annotation);
  320. }
  321. public void overridesPackageDefaultMethod(MethodBinding localMethod, MethodBinding inheritedMethod) {
  322. if (new String(localMethod.selector).startsWith("ajc$"))
  323. return;
  324. super.overridesPackageDefaultMethod(localMethod, inheritedMethod);
  325. }
  326. public void handle(int problemId, String[] problemArguments, String[] messageArguments, int severity, int problemStartPosition,
  327. int problemEndPosition, ReferenceContext referenceContext, CompilationResult unitResult) {
  328. if (severity != ProblemSeverities.Ignore && DUMP_STACK) {
  329. Thread.dumpStack();
  330. }
  331. super.handle(problemId, problemArguments,
  332. 0, // no message elaboration
  333. messageArguments, severity, problemStartPosition, problemEndPosition,
  334. referenceContext, unitResult);
  335. }
  336. // PR71076
  337. public void javadocMissingParamTag(char[] name, int sourceStart, int sourceEnd, int modifiers) {
  338. boolean reportIt = true;
  339. String sName = new String(name);
  340. if (sName.startsWith("ajc$"))
  341. reportIt = false;
  342. if (sName.equals("thisJoinPoint"))
  343. reportIt = false;
  344. if (sName.equals("thisJoinPointStaticPart"))
  345. reportIt = false;
  346. if (sName.equals("thisEnclosingJoinPointStaticPart"))
  347. reportIt = false;
  348. if (sName.equals("ajc_aroundClosure"))
  349. reportIt = false;
  350. if (reportIt)
  351. super.javadocMissingParamTag(name, sourceStart, sourceEnd, modifiers);
  352. }
  353. public void abstractMethodInAbstractClass(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
  354. String abstractMethodName = new String(methodDecl.selector);
  355. if (abstractMethodName.startsWith("ajc$pointcut")) {
  356. // This will already have been reported, see: PointcutDeclaration.postParse()
  357. return;
  358. }
  359. String[] arguments = new String[] { new String(type.sourceName()), abstractMethodName };
  360. super.handle(IProblem.AbstractMethodInAbstractClass, arguments, arguments, methodDecl.sourceStart, methodDecl.sourceEnd,
  361. this.referenceContext, this.referenceContext == null ? null : this.referenceContext.compilationResult());
  362. }
  363. /**
  364. * Called when there is an ITD marked @override that doesn't override a supertypes method. The method and the binding are passed
  365. * - some information is useful from each. The 'method' knows about source offsets for the message, the 'binding' has the
  366. * signature of what the ITD is trying to be in the target class.
  367. */
  368. public void itdMethodMustOverride(AbstractMethodDeclaration method, MethodBinding binding) {
  369. this.handle(IProblem.MethodMustOverride,
  370. new String[] { new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, false),
  371. new String(binding.declaringClass.readableName()), },
  372. new String[] { new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, true),
  373. new String(binding.declaringClass.shortReadableName()), }, method.sourceStart, method.sourceEnd,
  374. this.referenceContext, this.referenceContext == null ? null : this.referenceContext.compilationResult());
  375. }
  376. /**
  377. * Overrides the implementation in ProblemReporter and is ITD aware. To report a *real* problem with an ITD marked @override,
  378. * the other methodMustOverride() method is used.
  379. */
  380. public void methodMustOverride(AbstractMethodDeclaration method, long complianceLevel) {
  381. // ignore ajc$ methods
  382. if (new String(method.selector).startsWith("ajc$"))
  383. return;
  384. ResolvedMember possiblyErroneousRm = factory.makeResolvedMember(method.binding);
  385. ResolvedType onTypeX = factory.fromEclipse(method.binding.declaringClass);
  386. // Can't use 'getInterTypeMungersIncludingSupers()' since that will exclude abstract ITDs
  387. // on any super classes - so we have to trawl up ourselves.. I wonder if this problem
  388. // affects other code in the problem reporter that looks through ITDs...
  389. ResolvedType supertypeToLookAt = onTypeX.getSuperclass();
  390. while (supertypeToLookAt != null) {
  391. List<ConcreteTypeMunger> itMungers = supertypeToLookAt.getInterTypeMungers();
  392. for (ConcreteTypeMunger m : itMungers) {
  393. if (m.getMunger() != null && m.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) {
  394. continue;
  395. }
  396. ResolvedMember sig = m.getSignature();
  397. if (sig == null)
  398. continue; // we aren't interested in other kinds of munger
  399. UnresolvedType dType = sig.getDeclaringType();
  400. if (dType == null)
  401. continue;
  402. ResolvedType resolvedDeclaringType = dType.resolve(factory.getWorld());
  403. ResolvedMember rm = AjcMemberMaker.interMethod(sig, m.getAspectType(), resolvedDeclaringType.isInterface());
  404. if (ResolvedType.matches(rm, possiblyErroneousRm)) {
  405. // match, so dont need to report a problem!
  406. return;
  407. }
  408. }
  409. supertypeToLookAt = supertypeToLookAt.getSuperclass();
  410. }
  411. // report the error...
  412. super.methodMustOverride(method,complianceLevel);
  413. }
  414. private String typesAsString(boolean isVarargs, TypeBinding[] types, boolean makeShort) {
  415. StringBuilder buffer = new StringBuilder(10);
  416. for (int i = 0, length = types.length; i < length; i++) {
  417. if (i != 0)
  418. buffer.append(", "); //$NON-NLS-1$
  419. TypeBinding type = types[i];
  420. boolean isVarargType = isVarargs && i == length - 1;
  421. if (isVarargType)
  422. type = ((ArrayBinding) type).elementsType();
  423. buffer.append(new String(makeShort ? type.shortReadableName() : type.readableName()));
  424. if (isVarargType)
  425. buffer.append("..."); //$NON-NLS-1$
  426. }
  427. return buffer.toString();
  428. }
  429. public void visibilityConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) {
  430. // Not quite sure if the conditions on this test are right - basically I'm saying
  431. // DONT WORRY if its ITDs since the error will be reported another way...
  432. if (isIntertypeDeclaration(currentMethod) && isIntertypeDeclaration(inheritedMethod)
  433. && Modifier.isPrivate(currentMethod.modifiers) && Modifier.isPrivate(inheritedMethod.modifiers)) {
  434. return;
  435. }
  436. super.visibilityConflict(currentMethod, inheritedMethod);
  437. }
  438. public void unusedPrivateType(TypeDeclaration typeDecl) {
  439. // don't output unused type warnings for aspects!
  440. if (typeDecl instanceof AspectDeclaration)
  441. return;
  442. if (typeDecl.enclosingType != null && (typeDecl.enclosingType instanceof AspectDeclaration)) {
  443. AspectDeclaration ad = (AspectDeclaration) typeDecl.enclosingType;
  444. if (ad.concreteName != null) {
  445. List<Declare> declares = ad.concreteName.declares;
  446. for (Object dec : declares) {
  447. if (dec instanceof DeclareParents) {
  448. DeclareParents decp = (DeclareParents) dec;
  449. TypePattern[] newparents = decp.getParents().getTypePatterns();
  450. for (TypePattern pattern : newparents) {
  451. UnresolvedType ut = pattern.getExactType();
  452. if (ut == null)
  453. continue;
  454. if (CharOperation.compareWith(typeDecl.binding.signature(), ut.getSignature().toCharArray()) == 0)
  455. return;
  456. }
  457. }
  458. }
  459. }
  460. }
  461. super.unusedPrivateType(typeDecl);
  462. }
  463. private final static char[] thisJoinPointName = "thisJoinPoint".toCharArray();
  464. private final static char[] thisJoinPointStaticPartName = "thisJoinPointStaticPart".toCharArray();
  465. private final static char[] thisEnclosingJoinPointStaticPartName = "thisEnclosingJoinPointStaticPart".toCharArray();
  466. private final static char[] thisAspectInstanceName = "thisAspectInstance".toCharArray();
  467. @Override
  468. public void uninitializedLocalVariable(LocalVariableBinding binding, ASTNode location, Scope scope) {
  469. if (CharOperation.equals(binding.name, thisJoinPointName) ||
  470. CharOperation.equals(binding.name, thisJoinPointStaticPartName) ||
  471. CharOperation.equals(binding.name, thisAspectInstanceName) ||
  472. CharOperation.equals(binding.name, thisEnclosingJoinPointStaticPartName)) {
  473. // If in advice, this is not a problem
  474. if (binding.declaringScope!=null && (binding.declaringScope.referenceContext() instanceof AdviceDeclaration ||
  475. binding.declaringScope.referenceContext() instanceof IfMethodDeclaration)) {
  476. return;
  477. }
  478. }
  479. super.uninitializedLocalVariable(binding, location, scope);
  480. }
  481. public void abstractMethodInConcreteClass(SourceTypeBinding type) {
  482. if (type.scope!=null && type.scope.referenceContext instanceof AspectDeclaration) {
  483. // TODO could put out an Aspect specific message here
  484. return;
  485. }
  486. super.abstractMethodInConcreteClass(type);
  487. }
  488. // Don't warn if there is an ITD method/ctor from a privileged aspect
  489. public void unusedPrivateField(FieldDeclaration fieldDecl) {
  490. if (fieldDecl!=null && fieldDecl.binding != null && fieldDecl.binding.declaringClass != null) {
  491. ReferenceBinding type = fieldDecl.binding.declaringClass;
  492. ResolvedType weaverType = null;
  493. if (!type.isAnonymousType()) {
  494. weaverType = factory.fromEclipse(type);
  495. } else {
  496. weaverType = factory.fromEclipse(type.superclass());
  497. }
  498. Set checked = new HashSet();
  499. for (ConcreteTypeMunger m : weaverType.getInterTypeMungersIncludingSupers()) {
  500. ResolvedType theAspect = m.getAspectType();
  501. if (!checked.contains(theAspect)) {
  502. TypeBinding tb = factory.makeTypeBinding(m.getAspectType());
  503. // Let's check the privilegedHandler from that aspect
  504. if (tb instanceof SourceTypeBinding) { // BinaryTypeBinding is also a SourceTypeBinding ;)
  505. IPrivilegedHandler privilegedHandler = ((SourceTypeBinding) tb).privilegedHandler;
  506. if (privilegedHandler != null) {
  507. if (privilegedHandler.definesPrivilegedAccessToField(fieldDecl.binding)) {
  508. return;
  509. }
  510. } else if (theAspect instanceof ReferenceType) {
  511. // ResolvedMember rm = factory.makeResolvedMember(fieldDecl.binding);
  512. String fname = new String(fieldDecl.name);
  513. Collection/* ResolvedMember */privvies = ((ReferenceType) theAspect).getPrivilegedAccesses();
  514. // On an incremental compile the information is in the bcel delegate
  515. if (privvies != null) {
  516. for (Object privvy : privvies) {
  517. ResolvedMember priv = (ResolvedMember) privvy;
  518. if (priv.getName().equals(fname)) {
  519. return;
  520. }
  521. }
  522. }
  523. }
  524. }
  525. checked.add(theAspect);
  526. }
  527. }
  528. }
  529. super.unusedPrivateField(fieldDecl);
  530. }
  531. public void unusedPrivateMethod(AbstractMethodDeclaration methodDecl) {
  532. // don't output unused warnings for pointcuts...
  533. if (!(methodDecl instanceof PointcutDeclaration))
  534. super.unusedPrivateMethod(methodDecl);
  535. }
  536. public void caseExpressionMustBeConstant(Expression expression) {
  537. if (expression instanceof QualifiedNameReference) {
  538. QualifiedNameReference qnr = (QualifiedNameReference) expression;
  539. if (qnr.otherBindings != null && qnr.otherBindings.length > 0 && qnr.otherBindings[0] instanceof PrivilegedFieldBinding) {
  540. super.signalError(expression.sourceStart, expression.sourceEnd,
  541. "Fields accessible due to an aspect being privileged can not be used in switch statements");
  542. referenceContext.tagAsHavingErrors();
  543. return;
  544. }
  545. }
  546. super.caseExpressionMustBeConstant(expression);
  547. }
  548. public void unusedArgument(LocalDeclaration localDecl) {
  549. // don't warn if this is an aj synthetic arg
  550. String argType = new String(localDecl.type.resolvedType.signature());
  551. if (argType.startsWith("Lorg/aspectj/runtime/internal"))
  552. return;
  553. // If the unused argument is in a pointcut, don't report the problem (for now... pr148219)
  554. if (localDecl instanceof Argument) {
  555. Argument arg = (Argument) localDecl;
  556. if (arg.binding != null && arg.binding.declaringScope != null) {
  557. ReferenceContext context = arg.binding.declaringScope.referenceContext();
  558. if (context != null && context instanceof PointcutDeclaration)
  559. return;
  560. }
  561. }
  562. if (new String(localDecl.name).startsWith("ajc$")) {
  563. // Do not report problems for infrastructure variables beyond the users control - pr195090
  564. return;
  565. }
  566. super.unusedArgument(localDecl);
  567. }
  568. /**
  569. * A side-effect of the way that we handle itds on default methods on top-most implementors of interfaces is that a class
  570. * acquiring a final default ITD will erroneously report that it can't override its own member. This method detects that
  571. * situation.
  572. */
  573. public void finalMethodCannotBeOverridden(MethodBinding currentMethod, MethodBinding inheritedMethod) {
  574. if (currentMethod == inheritedMethod)
  575. return;
  576. super.finalMethodCannotBeOverridden(currentMethod, inheritedMethod);
  577. }
  578. /**
  579. * The method verifier is a bit 'keen' and doesn't cope well with ITDMs which are of course to be considered a 'default'
  580. * implementation if the target type doesn't supply one. This test may not be complete - it is possible that it should read if
  581. * *either* is an ITD...but I dont have a testcase that shows that is required. yet. (pr115788)
  582. */
  583. public void duplicateInheritedMethods(SourceTypeBinding type, MethodBinding inheritedMethod1, MethodBinding inheritedMethod2, boolean isJava8) {
  584. if (inheritedMethod1 instanceof InterTypeMethodBinding || inheritedMethod2 instanceof InterTypeMethodBinding)
  585. return;
  586. if ((inheritedMethod1 instanceof ParameterizedMethodBinding)
  587. && ((ParameterizedMethodBinding) inheritedMethod1).original() instanceof InterTypeMethodBinding)
  588. return;
  589. if ((inheritedMethod2 instanceof ParameterizedMethodBinding)
  590. && ((ParameterizedMethodBinding) inheritedMethod2).original() instanceof InterTypeMethodBinding)
  591. return;
  592. super.duplicateInheritedMethods(type, inheritedMethod1, inheritedMethod2, isJava8);
  593. }
  594. /**
  595. * All problems end up routed through here at some point...
  596. */
  597. public IProblem createProblem(char[] fileName, int problemId, String[] problemArguments, String[] messageArguments,
  598. int severity, int problemStartPosition, int problemEndPosition, int lineNumber) {
  599. IProblem problem = super.createProblem(fileName, problemId, problemArguments, messageArguments, severity,
  600. problemStartPosition, problemEndPosition, lineNumber, 0);
  601. if (factory.getWorld().isInPinpointMode()) {
  602. MessageIssued ex = new MessageIssued();
  603. ex.fillInStackTrace();
  604. StringWriter sw = new StringWriter();
  605. ex.printStackTrace(new PrintWriter(sw));
  606. StringBuilder sb = new StringBuilder();
  607. sb.append(CompilationAndWeavingContext.getCurrentContext());
  608. sb.append(sw.toString());
  609. problem = new PinpointedProblem(problem, sb.toString());
  610. }
  611. return problem;
  612. }
  613. private static class MessageIssued extends RuntimeException {
  614. public String getMessage() {
  615. return "message issued...";
  616. }
  617. }
  618. private static class PinpointedProblem implements IProblem {
  619. private IProblem delegate;
  620. private String message;
  621. public PinpointedProblem(IProblem aProblem, String pinpoint) {
  622. this.delegate = aProblem;
  623. // if this was a problem that came via the weaver, it will already have
  624. // pinpoint info, don't do it twice...
  625. if (!delegate.getMessage().contains("message issued...")) {
  626. this.message = delegate.getMessage() + "\n" + pinpoint;
  627. } else {
  628. this.message = delegate.getMessage();
  629. }
  630. }
  631. public String[] getArguments() {
  632. return delegate.getArguments();
  633. }
  634. public int getID() {
  635. return delegate.getID();
  636. }
  637. public String getMessage() {
  638. return message;
  639. }
  640. public char[] getOriginatingFileName() {
  641. return delegate.getOriginatingFileName();
  642. }
  643. public int getSourceEnd() {
  644. return delegate.getSourceEnd();
  645. }
  646. public int getSourceLineNumber() {
  647. return delegate.getSourceLineNumber();
  648. }
  649. public int getSourceStart() {
  650. return delegate.getSourceStart();
  651. }
  652. public boolean isError() {
  653. return delegate.isError();
  654. }
  655. public boolean isWarning() {
  656. return delegate.isWarning();
  657. }
  658. public void setSourceEnd(int sourceEnd) {
  659. delegate.setSourceEnd(sourceEnd);
  660. }
  661. public void setSourceLineNumber(int lineNumber) {
  662. delegate.setSourceLineNumber(lineNumber);
  663. }
  664. public void setSourceStart(int sourceStart) {
  665. delegate.setSourceStart(sourceStart);
  666. }
  667. public void setSeeAlsoProblems(IProblem[] problems) {
  668. delegate.setSeeAlsoProblems(problems);
  669. }
  670. public IProblem[] seeAlso() {
  671. return delegate.seeAlso();
  672. }
  673. public void setSupplementaryMessageInfo(String msg) {
  674. delegate.setSupplementaryMessageInfo(msg);
  675. }
  676. public String getSupplementaryMessageInfo() {
  677. return delegate.getSupplementaryMessageInfo();
  678. }
  679. @Override
  680. public boolean isInfo() {
  681. return delegate.isInfo();
  682. }
  683. }
  684. public void duplicateMethodInType(AbstractMethodDeclaration methodDecl, boolean equalParameters, int severity) {
  685. if (new String(methodDecl.selector).startsWith("ajc$interMethod")) {
  686. // this is an ITD clash and will be reported in another way by AspectJ (173602)
  687. return;
  688. }
  689. super.duplicateMethodInType(methodDecl, equalParameters, severity);
  690. }
  691. // pr246393 - if we are going to complain about privileged, we clearly don't know what is going on, so don't
  692. // confuse the user
  693. public void parseErrorInsertAfterToken(int start, int end, int currentKind, char[] errorTokenSource, String errorTokenName,
  694. String expectedToken) {
  695. if (expectedToken.equals("privileged") || expectedToken.equals("around")) {
  696. super.parseErrorNoSuggestion(start, end, currentKind, errorTokenSource, errorTokenName);
  697. } else {
  698. super.parseErrorInsertAfterToken(start, end, currentKind, errorTokenSource, errorTokenName, expectedToken);
  699. }
  700. }
  701. public void missingValueForAnnotationMember(Annotation annotation, char[] memberName) {
  702. if (referenceContext instanceof DeclareAnnotationDeclaration) {
  703. // If a remover then the values are not necessary
  704. if (((DeclareAnnotationDeclaration) referenceContext).isRemover()) {
  705. return;
  706. }
  707. }
  708. super.missingValueForAnnotationMember(annotation, memberName);
  709. }
  710. }