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

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. }