Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

AjProblemReporter.java 29KB

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