您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

AjProblemReporter.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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 Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.ajdt.internal.compiler.problem;
  13. import java.lang.reflect.Modifier;
  14. import java.util.Iterator;
  15. import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
  16. import org.aspectj.ajdt.internal.compiler.ast.Proceed;
  17. import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
  18. import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
  19. import org.aspectj.org.eclipse.jdt.core.compiler.IProblem;
  20. import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
  21. import org.aspectj.org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
  22. import org.aspectj.org.eclipse.jdt.internal.compiler.IProblemFactory;
  23. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
  24. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  25. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
  26. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
  27. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
  28. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
  29. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding;
  30. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
  31. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
  32. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
  33. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
  34. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  35. import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
  36. import org.aspectj.util.FuzzyBoolean;
  37. import org.aspectj.weaver.AjcMemberMaker;
  38. import org.aspectj.weaver.ConcreteTypeMunger;
  39. import org.aspectj.weaver.ResolvedMember;
  40. import org.aspectj.weaver.ResolvedTypeX;
  41. import org.aspectj.weaver.Shadow;
  42. import org.aspectj.weaver.patterns.DeclareSoft;
  43. /**
  44. * Extends problem reporter to support compiler-side implementation of declare soft.
  45. * Also overrides error reporting for the need to implement abstract methods to
  46. * account for inter-type declarations and pointcut declarations. This second
  47. * job might be better done directly in the SourceTypeBinding/ClassScope classes.
  48. *
  49. * @author Jim Hugunin
  50. */
  51. public class AjProblemReporter extends ProblemReporter {
  52. private static final boolean DUMP_STACK = false;
  53. public EclipseFactory factory;
  54. public AjProblemReporter(
  55. IErrorHandlingPolicy policy,
  56. CompilerOptions options,
  57. IProblemFactory problemFactory) {
  58. super(policy, options, problemFactory);
  59. }
  60. public void unhandledException(
  61. TypeBinding exceptionType,
  62. ASTNode location)
  63. {
  64. if (!factory.getWorld().getDeclareSoft().isEmpty()) {
  65. Shadow callSite = factory.makeShadow(location, referenceContext);
  66. Shadow enclosingExec = factory.makeShadow(referenceContext);
  67. // PR 72157 - calls to super / this within a constructor are not part of the cons join point.
  68. if ((callSite == null) && (enclosingExec.getKind() == Shadow.ConstructorExecution)
  69. && (location instanceof ExplicitConstructorCall)) {
  70. super.unhandledException(exceptionType, location);
  71. return;
  72. }
  73. // System.err.println("about to show error for unhandled exception: " + new String(exceptionType.sourceName()) +
  74. // " at " + location + " in " + referenceContext);
  75. for (Iterator i = factory.getWorld().getDeclareSoft().iterator(); i.hasNext(); ) {
  76. DeclareSoft d = (DeclareSoft)i.next();
  77. // We need the exceptionType to match the type in the declare soft statement
  78. // This means it must either be the same type or a subtype
  79. ResolvedTypeX throwException = factory.fromEclipse((ReferenceBinding)exceptionType);
  80. FuzzyBoolean isExceptionTypeOrSubtype =
  81. d.getException().matchesInstanceof(throwException);
  82. if (!isExceptionTypeOrSubtype.alwaysTrue() ) continue;
  83. if (callSite != null) {
  84. FuzzyBoolean match = d.getPointcut().match(callSite);
  85. if (match.alwaysTrue()) {
  86. //System.err.println("matched callSite: " + callSite + " with " + d);
  87. return;
  88. } else if (!match.alwaysFalse()) {
  89. //!!! need this check to happen much sooner
  90. //throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
  91. }
  92. }
  93. if (enclosingExec != null) {
  94. FuzzyBoolean match = d.getPointcut().match(enclosingExec);
  95. if (match.alwaysTrue()) {
  96. //System.err.println("matched enclosingExec: " + enclosingExec + " with " + d);
  97. return;
  98. } else if (!match.alwaysFalse()) {
  99. //!!! need this check to happen much sooner
  100. //throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
  101. }
  102. }
  103. }
  104. }
  105. //??? is this always correct
  106. if (location instanceof Proceed) {
  107. return;
  108. }
  109. super.unhandledException(exceptionType, location);
  110. }
  111. private boolean isPointcutDeclaration(MethodBinding binding) {
  112. return CharOperation.prefixEquals(PointcutDeclaration.mangledPrefix, binding.selector);
  113. }
  114. public void abstractMethodCannotBeOverridden(
  115. SourceTypeBinding type,
  116. MethodBinding concreteMethod)
  117. {
  118. if (isPointcutDeclaration(concreteMethod)) {
  119. return;
  120. }
  121. super.abstractMethodCannotBeOverridden(type, concreteMethod);
  122. }
  123. public void inheritedMethodReducesVisibility(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
  124. // if we implemented this method by a public inter-type declaration, then there is no error
  125. ResolvedTypeX onTypeX = null;
  126. // If the type is anonymous, look at its supertype
  127. if (!type.isAnonymousType()) {
  128. onTypeX = factory.fromEclipse(type);
  129. } else {
  130. // Hmmm. If the ITD is on an interface that is being 'instantiated' using an anonymous type,
  131. // we sort it out elsewhere and don't come into this method -
  132. // so we don't have to worry about interfaces, just the superclass.
  133. onTypeX = factory.fromEclipse(type.superclass()); //abstractMethod.declaringClass);
  134. }
  135. for (Iterator i = onTypeX.getInterTypeMungersIncludingSupers().iterator(); i.hasNext(); ) {
  136. ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
  137. ResolvedMember sig = m.getSignature();
  138. if (!Modifier.isAbstract(sig.getModifiers())) {
  139. if (ResolvedTypeX
  140. .matches(
  141. AjcMemberMaker.interMethod(
  142. sig,
  143. m.getAspectType(),
  144. sig.getDeclaringType().isInterface(
  145. factory.getWorld())),
  146. EclipseFactory.makeResolvedMember(concreteMethod))) {
  147. return;
  148. }
  149. }
  150. }
  151. super.inheritedMethodReducesVisibility(type,concreteMethod,abstractMethods);
  152. }
  153. public void abstractMethodMustBeImplemented(
  154. SourceTypeBinding type,
  155. MethodBinding abstractMethod)
  156. {
  157. // if this is a PointcutDeclaration then there is no error
  158. if (isPointcutDeclaration(abstractMethod)) {
  159. return;
  160. }
  161. if (CharOperation.prefixEquals("ajc$interField".toCharArray(), abstractMethod.selector)) {
  162. //??? think through how this could go wrong
  163. return;
  164. }
  165. // if we implemented this method by an inter-type declaration, then there is no error
  166. //??? be sure this is always right
  167. ResolvedTypeX onTypeX = null;
  168. // If the type is anonymous, look at its supertype
  169. if (!type.isAnonymousType()) {
  170. onTypeX = factory.fromEclipse(type);
  171. } else {
  172. // Hmmm. If the ITD is on an interface that is being 'instantiated' using an anonymous type,
  173. // we sort it out elsewhere and don't come into this method -
  174. // so we don't have to worry about interfaces, just the superclass.
  175. onTypeX = factory.fromEclipse(type.superclass()); //abstractMethod.declaringClass);
  176. }
  177. for (Iterator i = onTypeX.getInterTypeMungersIncludingSupers().iterator(); i.hasNext(); ) {
  178. ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
  179. ResolvedMember sig = m.getSignature();
  180. if (!Modifier.isAbstract(sig.getModifiers())) {
  181. if (ResolvedTypeX
  182. .matches(
  183. AjcMemberMaker.interMethod(
  184. sig,
  185. m.getAspectType(),
  186. sig.getDeclaringType().isInterface(
  187. factory.getWorld())),
  188. EclipseFactory.makeResolvedMember(abstractMethod))) {
  189. return;
  190. }
  191. }
  192. }
  193. super.abstractMethodMustBeImplemented(type, abstractMethod);
  194. }
  195. /* (non-Javadoc)
  196. * @see org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter#disallowedTargetForAnnotation(org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation)
  197. */
  198. public void disallowedTargetForAnnotation(Annotation annotation) {
  199. // if the annotation's recipient is an ITD, it might be allowed after all...
  200. if (annotation.recipient instanceof MethodBinding) {
  201. MethodBinding binding = (MethodBinding) annotation.recipient;
  202. String name = new String(binding.selector);
  203. if (name.startsWith("ajc$")) {
  204. long metaTagBits = annotation.resolvedType.getAnnotationTagBits(); // could be forward reference
  205. if (name.indexOf("interField") != -1) {
  206. if ((metaTagBits & TagBits.AnnotationForField) != 0) return;
  207. } else if (name.indexOf("InterConstructor") != -1) {
  208. if ((metaTagBits & TagBits.AnnotationForConstructor) != 0) return;
  209. } else if (name.indexOf("interMethod") != -1) {
  210. if ((metaTagBits & TagBits.AnnotationForMethod) != 0) return;
  211. }
  212. }
  213. }
  214. // not our special case, report the problem...
  215. super.disallowedTargetForAnnotation(annotation);
  216. }
  217. public void handle(
  218. int problemId,
  219. String[] problemArguments,
  220. String[] messageArguments,
  221. int severity,
  222. int problemStartPosition,
  223. int problemEndPosition,
  224. ReferenceContext referenceContext,
  225. CompilationResult unitResult)
  226. {
  227. if (severity != Ignore && DUMP_STACK) {
  228. Thread.dumpStack();
  229. }
  230. super.handle(
  231. problemId,
  232. problemArguments,
  233. messageArguments,
  234. severity,
  235. problemStartPosition,
  236. problemEndPosition,
  237. referenceContext,
  238. unitResult);
  239. }
  240. // PR71076
  241. public void javadocMissingParamTag(char[] name, int sourceStart, int sourceEnd, int modifiers) {
  242. boolean reportIt = true;
  243. String sName = new String(name);
  244. if (sName.startsWith("ajc$")) reportIt = false;
  245. if (sName.equals("thisJoinPoint")) reportIt = false;
  246. if (sName.equals("thisJoinPointStaticPart")) reportIt = false;
  247. if (sName.equals("thisEnclosingJoinPointStaticPart")) reportIt = false;
  248. if (sName.equals("ajc_aroundClosure")) reportIt = false;
  249. if (reportIt)
  250. super.javadocMissingParamTag(name,sourceStart,sourceEnd,modifiers);
  251. }
  252. public void abstractMethodInAbstractClass(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
  253. String abstractMethodName = new String(methodDecl.selector);
  254. if (abstractMethodName.startsWith("ajc$pointcut")) {
  255. // This will already have been reported, see: PointcutDeclaration.postParse()
  256. return;
  257. }
  258. String[] arguments = new String[] {new String(type.sourceName()), abstractMethodName};
  259. super.handle(
  260. IProblem.AbstractMethodInAbstractClass,
  261. arguments,
  262. arguments,
  263. methodDecl.sourceStart,
  264. methodDecl.sourceEnd,this.referenceContext,
  265. this.referenceContext == null ? null : this.referenceContext.compilationResult());
  266. }
  267. }