Bug 151775 - Should match on throws clause from defining signature
Summary: Should match on throws clause from defining signature
Status: RESOLVED INVALID
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.5.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.5.3   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-07-25 17:40 EDT by Ron Bodkin CLA
Modified: 2006-09-27 13:24 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ron Bodkin CLA 2006-07-25 17:40:00 EDT
I believe that this program should print two warnings: one for each run method. The signature for both Base and Derived should match the signature pattern. This is analogous to how Java 5 covariant types are handled in type patterns in AspectJ 5, i.e., I think that the signature of the overridden method still applies even though we removed the throws clause...

public aspect ThrowsSig {
    public static void main(String args[]) throws Exception {
        new Base().run();
        new Derived().run();
    }
    declare warning: execution(* run() throws Exception+): "checked method";
}

class Base {
    public void run() throws Exception {}
}

class Derived extends Base {
    public void run() {}
}

C:\devel\scratch\exception\softenInner>ajc ThrowsSig.aj
C:\devel\scratch\exception\softenInner\ThrowsSig.aj:10 [warning] checked method
public void run() throws Exception {}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        method-execution(void Base.run())
        see also: C:\devel\scratch\exception\softenInner\ThrowsSig.aj:6::0

1 warning
Comment 1 Helen Beeken CLA 2006-09-19 11:20:57 EDT
After some investigation I don't think the signature of the overriden method should match the pointcut. The reason for this is that the following program compiles (with javac) with no errors:

----------------------------------------------------
public class C {
	public static void main(String[] args) {
		new Derived().run();
	}
}

class Base {
    public void run() throws Exception {}
}

class Derived extends Base {
    public void run() {}
}
---------------------------------------------------

It seems from this that the java compiler doesn't see Derived.run() as declaring any exceptions. In which case I don't believe the pointcut "execution(* run() throws Exception+)" should match.
Comment 2 Ron Bodkin CLA 2006-09-20 13:35:19 EDT
I think it has to match for consistency. If you change it to use this warning then it prints twice, matching the derived method execution:

declare warning: execution(* Base.run()): "base method";

Yet if you change it like this it no longer prints. This to me is inconsistent with the way that overriding methods match base method signatures:
declare warning: execution(* Base.run() throws Exception+): "base method";

While Declared.run() doesn't declare any exceptions it should still match the signature of the method it overrides.
Comment 3 Helen Beeken CLA 2006-09-21 05:07:49 EDT
I'm still not sure it should match.....

The definition of "execution(* Base.run())" is that it matches the actual execution of run() as declared within the Base type. Since Derived is a Base type it matches the execution of Derived.run(). By the same definition, "execution(* run() throws Exception+)" matches the actual execution of run() as declared within any type where run() is declared to throw an Exception (or a subtype of Exception). This clearly matches Base.run() however, I don't believe Derived.run() is declared to throw an Exception.

Also, since "execution(* Base.run())" matches the execution of Declared.run() we already have that Declared.run() matches the signature of the method it overrides. I don't think the throws clause is defined to be part of the method signature. As far as I understand it, the method signature consists of the name and the number and types of arguments to the method.
Comment 4 Ron Bodkin CLA 2006-09-21 14:14:39 EDT
Hi Helen

the Programmer's Guide says in semantics-pointcuts.html#signatures "Join points associated with methods typically have method signatures, consisting of a method name, parameter types, return type, the types of the declared (checked) exceptions, and some type that the method could be called on (below called the "qualifying type")."

It also seems much more natural for me to consider the throws clause as part of the signature rather than somehow different than the signature.
Comment 5 Ron Bodkin CLA 2006-09-27 13:24:54 EDT
The analogy to matching modifiers for annotations led to look in the AspectJ 5 developer guide which in this section http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html#annotation-inheritance-and-pointcut-matching  provides an example and formulates a rule "join point matching for modifiers (the visibility modifiers, annotations, and throws clause) is based on the subject of the join point (the method actually being called)" which isn't clear in the AspectJ programmer's guide. 

This rule about matching for modifiers is clearly important for matching annotations, so I have to conceed it's the right one here too.