Bug 73073 - Inconsistency between starred and nonstarred type patterns in connection with shadowing.
Summary: Inconsistency between starred and nonstarred type patterns in connection with...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Docs (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: All All
: P3 minor (vote)
Target Milestone: 1.2.1   Edit
Assignee: Erik Hilsdale CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-09-01 11:54 EDT by Aske Simon Christensen CLA
Modified: 2004-10-21 04:31 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 Aske Simon Christensen CLA 2004-09-01 11:54:24 EDT
Class type patterns match any class that, at the lexical point of the pattern, 
could be referred to by a name that textually matches the pattern. Thus, a type 
pattern consisting of just a single identifier matches at most one class - the 
class which that identifier would refer to, if such a class exists. This 
follows normal Java scoping rules, including shadowing. However, if the type 
pattern contains a wildcard, shadowing is ignored.

Consider this program:

public class ShadowingAndAccess {
    void foo() { p("ShadowingAndAccess"); }

    static public class A {
        void foo() { p("ShadowingAndAccess.A"); }
    }

    public static aspect InnerAspect {
        public static class A {
            void foo() { p("ShadowingAndAccess.Aspect.A"); }
        }

        after(): execution(void *.foo())    { p("*.foo()"); }
        after(): execution(void A.foo())    { p("A.foo()"); }
        after(): execution(void A*.foo())   { p("A*.foo()"); }
    }

    private static void p(String s) {
        System.out.println(s);
    }

    public static void main(String[] args) {
        new ShadowingAndAccess().foo();
        new A().foo();
        new InnerAspect.A().foo();
    }
}

The output from this program is:

ShadowingAndAccess
*.foo()
ShadowingAndAccess.A
*.foo()
A*.foo()
ShadowingAndAccess.Aspect.A
*.foo()
A.foo()
A*.foo()

As expected, the universal * type pattern mathces any class whatsoever. The 
type pattern A cannot see the shadowed ShadowingAndAccess.A class, but the A* 
pattern (which textually matches the exact same names as A in this example) 
ignores shadowing and matches both of the ShadowingAndAccess.A and 
ShadowingAndAccess.Aspect.A classes.

I don't know what is considered the correct behaviour of type patterns - 
shadowing or not shadowing - but in any case it should be consistent for all 
patterns and not depend on whether the patterns have wildcards in them or not.
Comment 1 Adrian Colyer CLA 2004-09-08 09:44:33 EDT
This is (somewhat surprisingly?) working as designed. Here's what's going on:

When you specify an exact type pattern, the type is resolved in the scope of the 
declaration (so "A" inside InnerAspect resolves to InnerAspect.A). When you 
specify a wildcard type pattern, the pattern is matched against all types 
exposed to the weaver (ie. not based on the declaration scope). This gives the 
additional matches that you saw.

This point about type visibility constrained matching for exact type patterns 
crops up periodically, and I wanted to point you to the place in the docs where 
it was described, but I couldn't find such a place. Therefore I've made this a 
docs bug to make sure that we state this clearly somewhere.
Comment 2 Erik Hilsdale CLA 2004-09-08 12:34:18 EDT
Fixed by adding verbiage to the Type Patterns section of the semantics document.
Comment 3 Adrian Colyer CLA 2004-10-21 04:31:14 EDT
Fix released as part of AspectJ 1.2.1