Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

AjProblemReporter.java 9.0KB

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