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 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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.util.FuzzyBoolean;
  19. import org.aspectj.weaver.AjcMemberMaker;
  20. import org.aspectj.weaver.ConcreteTypeMunger;
  21. import org.aspectj.weaver.ResolvedMember;
  22. import org.aspectj.weaver.ResolvedTypeX;
  23. import org.aspectj.weaver.Shadow;
  24. import org.aspectj.weaver.patterns.DeclareSoft;
  25. import org.eclipse.jdt.internal.compiler.CompilationResult;
  26. import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
  27. import org.eclipse.jdt.internal.compiler.IProblemFactory;
  28. import org.eclipse.jdt.internal.compiler.ast.ASTNode;
  29. import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
  30. import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
  31. import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
  32. import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
  33. import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
  34. import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  35. import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
  36. import org.eclipse.jdt.core.compiler.CharOperation;
  37. /**
  38. * Extends problem reporter to support compiler-side implementation of declare soft.
  39. * Also overrides error reporting for the need to implement abstract methods to
  40. * account for inter-type declarations and pointcut declarations. This second
  41. * job might be better done directly in the SourceTypeBinding/ClassScope classes.
  42. *
  43. * @author Jim Hugunin
  44. */
  45. public class AjProblemReporter extends ProblemReporter {
  46. private static final boolean DUMP_STACK = false;
  47. public EclipseFactory factory;
  48. public AjProblemReporter(
  49. IErrorHandlingPolicy policy,
  50. CompilerOptions options,
  51. IProblemFactory problemFactory) {
  52. super(policy, options, problemFactory);
  53. }
  54. public void unhandledException(
  55. TypeBinding exceptionType,
  56. ASTNode location)
  57. {
  58. if (!factory.getWorld().getDeclareSoft().isEmpty()) {
  59. Shadow callSite = factory.makeShadow(location, referenceContext);
  60. Shadow enclosingExec = factory.makeShadow(referenceContext);
  61. // System.err.println("about to show error for unhandled exception: " + new String(exceptionType.sourceName()) +
  62. // " at " + location + " in " + referenceContext);
  63. for (Iterator i = factory.getWorld().getDeclareSoft().iterator(); i.hasNext(); ) {
  64. DeclareSoft d = (DeclareSoft)i.next();
  65. // We need the exceptionType to match the type in the declare soft statement
  66. // This means it must either be the same type or a subtype
  67. ResolvedTypeX throwException = factory.fromEclipse((ReferenceBinding)exceptionType);
  68. FuzzyBoolean isExceptionTypeOrSubtype =
  69. d.getException().matchesInstanceof(throwException);
  70. if (!isExceptionTypeOrSubtype.alwaysTrue() ) continue;
  71. if (callSite != null) {
  72. FuzzyBoolean match = d.getPointcut().match(callSite);
  73. if (match.alwaysTrue()) {
  74. //System.err.println("matched callSite: " + callSite + " with " + d);
  75. return;
  76. } else if (!match.alwaysFalse()) {
  77. //!!! need this check to happen much sooner
  78. //throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
  79. }
  80. }
  81. if (enclosingExec != null) {
  82. FuzzyBoolean match = d.getPointcut().match(enclosingExec);
  83. if (match.alwaysTrue()) {
  84. //System.err.println("matched enclosingExec: " + enclosingExec + " with " + d);
  85. return;
  86. } else if (!match.alwaysFalse()) {
  87. //!!! need this check to happen much sooner
  88. //throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
  89. }
  90. }
  91. }
  92. }
  93. //??? is this always correct
  94. if (location instanceof Proceed) {
  95. return;
  96. }
  97. super.unhandledException(exceptionType, location);
  98. }
  99. private boolean isPointcutDeclaration(MethodBinding binding) {
  100. return CharOperation.prefixEquals(PointcutDeclaration.mangledPrefix, binding.selector);
  101. }
  102. public void abstractMethodCannotBeOverridden(
  103. SourceTypeBinding type,
  104. MethodBinding concreteMethod)
  105. {
  106. if (isPointcutDeclaration(concreteMethod)) {
  107. return;
  108. }
  109. super.abstractMethodCannotBeOverridden(type, concreteMethod);
  110. }
  111. public void abstractMethodMustBeImplemented(
  112. SourceTypeBinding type,
  113. MethodBinding abstractMethod)
  114. {
  115. // if this is a PointcutDeclaration then there is no error
  116. if (isPointcutDeclaration(abstractMethod)) {
  117. return;
  118. }
  119. if (CharOperation.prefixEquals("ajc$interField".toCharArray(), abstractMethod.selector)) {
  120. //??? think through how this could go wrong
  121. return;
  122. }
  123. // if we implemented this method by an inter-type declaration, then there is no error
  124. //??? be sure this is always right
  125. ResolvedTypeX onTypeX = factory.fromEclipse(type); //abstractMethod.declaringClass);
  126. for (Iterator i = onTypeX.getInterTypeMungers().iterator(); i.hasNext(); ) {
  127. ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
  128. if (m.matches(onTypeX)) {
  129. ResolvedMember sig = m.getSignature();
  130. if (!Modifier.isAbstract(sig.getModifiers())) {
  131. if (ResolvedTypeX
  132. .matches(
  133. AjcMemberMaker.interMethod(
  134. sig,
  135. m.getAspectType(),
  136. sig.getDeclaringType().isInterface(
  137. factory.getWorld())),
  138. EclipseFactory.makeResolvedMember(abstractMethod))) {
  139. return;
  140. }
  141. }
  142. }
  143. }
  144. super.abstractMethodMustBeImplemented(type, abstractMethod);
  145. }
  146. public void handle(
  147. int problemId,
  148. String[] problemArguments,
  149. String[] messageArguments,
  150. int severity,
  151. int problemStartPosition,
  152. int problemEndPosition,
  153. ReferenceContext referenceContext,
  154. CompilationResult unitResult)
  155. {
  156. if (severity != Ignore && DUMP_STACK) {
  157. Thread.currentThread().dumpStack();
  158. }
  159. super.handle(
  160. problemId,
  161. problemArguments,
  162. messageArguments,
  163. severity,
  164. problemStartPosition,
  165. problemEndPosition,
  166. referenceContext,
  167. unitResult);
  168. }
  169. }