public class InheritedThrows {
static aspect A {
- declare warning : execution (* *.*(..) throws Ex1) : "one";
-// declare warning : execution (* *.*(..) throws Ex2) : "two";
-// declare warning : execution (* *.*(..) throws !(Ex1||Ex2)) : "neither";
-// declare warning : execution (* *.*(..) throws Ex1, Ex2) : "both";
+ after() throwing(Ex1 a): execution(* *.*(..) throws Ex1) {}
}
public static class Ex1 extends Exception {}
}
private static class NestedClass1 implements MyInterface {
- public void m() throws Ex1 {}
+ public void m() throws Ex1 {} // MATCHES HERE
}
private static class NestedClass2 implements MyInterface {
}
private static class NestedClassBoth implements MyInterface {
- public void m() throws Ex1, Ex2 {}
+ public void m() throws Ex1, Ex2 {} // MATCHES HERE
}
private static class NestedClassNeither implements MyInterface {
public void testCunningDeclareParents_pr92311() { runTest("cunning declare parents");}
public void testGenericITDsAndAbstractMethodError_pr102357() { runTest("generic itds and abstract method error");}
*/
- //public void testIncorrectSignatureMatchingWithExceptions_pr119749() { runTest("incorrect exception signature matching");}
+ public void testIncorrectSignatureMatchingWithExceptions_pr119749() { runTest("incorrect exception signature matching");}
public void testGeneratingCodeForAnOldRuntime_pr116679_1() { runTest("generating code for a 1.2.1 runtime - 1");}
public void testGeneratingCodeForAnOldRuntime_pr116679_2() { runTest("generating code for a 1.2.1 runtime - 2");}
public void testAmbiguousMethod_pr118599_1() { runTest("ambiguous method when binary weaving - 1");}
</ajc-test>
<ajc-test dir="bugs150/pr119749" pr="119749" title="incorrect exception signature matching">
- <compile files="InheritedThrows.java" options="">
- <message kind="warning" line="19" text="one"/>
- <message kind="warning" line="27" text="one"/>
+ <compile files="InheritedThrows.java" options="-showWeaveInfo">
+ <message kind="weave" text="Join point 'method-execution(void InheritedThrows$NestedClassBoth.m())' in Type 'InheritedThrows$NestedClassBoth' (InheritedThrows.java:24) advised by afterThrowing advice from 'InheritedThrows$A' (InheritedThrows.java:4)"/>
+ <message kind="weave" text="Join point 'method-execution(void InheritedThrows$NestedClass1.m())' in Type 'InheritedThrows$NestedClass1' (InheritedThrows.java:16) advised by afterThrowing advice from 'InheritedThrows$A' (InheritedThrows.java:4)"/>
</compile>
</ajc-test>
}
}
-
- if (hasExtraParameter() && kind == AdviceKind.AfterReturning) {
+
+ if (hasExtraParameter() && kind == AdviceKind.AfterReturning) {
ResolvedType resolvedExtraParameterType = getExtraParameterType().resolve(world);
ResolvedType shadowReturnType = shadow.getReturnType().resolve(world);
boolean matches =
maybeIssueUncheckedMatchWarning(resolvedExtraParameterType,shadowReturnType,shadow,world);
}
return matches;
+ } else if (hasExtraParameter() && kind==AdviceKind.AfterThrowing) { // pr119749
+ ResolvedType exceptionType = getExtraParameterType().resolve(world);
+ if (!exceptionType.isCheckedException()) return true;
+ UnresolvedType[] shadowThrows = shadow.getSignature().getExceptions(world);
+ boolean matches = false;
+ for (int i = 0; i < shadowThrows.length && !matches; i++) {
+ ResolvedType type = shadowThrows[i].resolve(world);
+ if (exceptionType.isAssignableFrom(type)) matches=true;
+ }
+ return matches;
} else if (kind == AdviceKind.PerTargetEntry) {
return shadow.hasTarget();
} else if (kind == AdviceKind.PerThisEntry) {
public ResolvedPointcutDefinition findPointcut(String name, World world) {
throw new UnsupportedOperationException("Not yet implemenented");
}
+
+ /**
+ * @return true if assignable to java.lang.Exception
+ */
+ public boolean isException() {
+ return (world.getCoreType(UnresolvedType.JAVA_LANG_EXCEPTION).isAssignableFrom(this));
+ }
+
+ /**
+ * @return true if it is an exception and it is a checked one, false otherwise.
+ */
+ public boolean isCheckedException() {
+ if (!isException()) return false;
+ if (world.getCoreType(UnresolvedType.RUNTIME_EXCEPTION).isAssignableFrom(this)) return false;
+ return true;
+ }
/**
* Determines if variables of this type could be assigned values of another