Bug 49457 - No error on overloaded pointcuts unless binding variables
Summary: No error on overloaded pointcuts unless binding variables
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.1.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.2   Edit
Assignee: Andrew Clement CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 42842 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-01-02 00:21 EST by Wes Isberg CLA
Modified: 2004-01-27 20:29 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wes Isberg CLA 2004-01-02 00:21:30 EST
The compiler might not be detecting overloaded pointcut names when parameters
are not bound, and/or might not be implementing the pointcut correctly.  Below
is the context from my reply to Ron Bodkin on aspectj-dev "Proper behavior of
overloaded pointcut definitions".  (I have not checked this code recently or
submitted a test case, nor have I evaluated whether my code below actually
replicates Ron's bug.)

---- context from the email
The programming guide says,

  It is an error for two pointcuts to be named with the same
  name in the same class or aspect declaration.

When I compile with overloaded pointcut names, I do get an error.

    pointcut pc(Runnable r) : target(r) && call(void run());
    pointcut pc(SubRunnable r) : target(r) && call(void run());

 $ aspectj-1.1.1 -classpath $ajrt11 OverloadedPointcut.java
 ...\OverloadedPointcut.java:14 duplicate pointcut name: pc
 ...\OverloadedPointcut.java:15 duplicate pointcut name: pc

...

When I use these pointcuts with bound parameters, I get an error.

    before(Runnable r) : pc(r) { log("pc(Runnable r)"); }
    before(SubRunnable r) : pc(r) { log("pc(SubRunnable r)"); }

When I use these pointcuts with type parameters, I get no errors.

    before() : pc(Runnable) { log("pc(Runnable)"); }
    before() : pc(SubRunnable) { log("pc(SubRunnable)"); }
    before() : pc(*) { log("pc(*)"); }

[...]

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

aspect A {
    declare parents: C implements Runnable;
    declare parents: C implements SubRunnable;
    interface SubRunnable extends Runnable {}

    pointcut pc(Runnable r) : target(r) && call(void run());
    pointcut pc(SubRunnable r) : target(r) && call(void run());
    before(Runnable r) : pc(r) { log("pc(Runnable r)"); }
    before(SubRunnable r) : pc(r) { log("pc(SubRunnable r)"); }
    before() : pc(Runnable) { log("pc(Runnable)"); }
    before() : pc(SubRunnable) { log("pc(SubRunnable)"); }
    before() : pc(*) { log("pc(*)"); }
    void log(String s) { System.out.println(s); }
} 

---- Ron's code
[...] the following program compiles with no warnings, produces no output when
run under AspectJ 1.1.1.  It appears to behave as if the more specific
definition is the only definition of the pointcut
[...]
Here is a simple program that illustrates the question and odd behavior:

package lib;

public class RunnablePointcuts {
    public pointcut runnableCalls(Runnable runnable, Object caller) :
        call(* run(..)) && target(runnable) && this(caller);

    //public pointcut specialRunnableCalls(SpecialRunnable runnable, Object
caller) :
    public pointcut runnableCalls(SpecialRunnable runnable, Object caller) :
        call(* run(..)) && target(runnable) && this(caller);
}
---
package lib;

public interface SpecialRunnable extends Runnable {
}
---
package client;

import lib.RunnablePointcuts;
import lib.SpecialRunnable;

public aspect Use {
    before(Object caller) : RunnablePointcuts.runnableCalls(*, caller) &&
target(MyRunnable) {
        System.out.println("my runnable called from "+caller);
    }
    public static void main(String args[]) {
	Use.aspectOf().doIt();
    }
    public void doIt() {
        new MyRunnable().run();
    }
}

// the advice will run if you make this implement SpecialRunnable
//class MyRunnable implements SpecialRunnable {
class MyRunnable implements Runnable {
    public void run() {}
}
Comment 1 Andrew Clement CLA 2004-01-07 06:07:38 EST
The bug is that the compiler is not policing the case when two pointcuts with 
the same name are declared in a CLASS.  In Rons program he should get errors 
against his RunnablePointcuts class at compile time.  The fix is to add 
behaviour to AjLookupEnvironment.resolvePointcutDeclarations such that if the 
ClassScope being processed has pointcut definitions in it, we do the check.
Comment 2 Andrew Clement CLA 2004-01-07 06:26:07 EST
Patch sent to Adrian.
Comment 3 Jim Hugunin CLA 2004-01-27 20:29:42 EST
*** Bug 42842 has been marked as a duplicate of this bug. ***