From acbb4e5b1a7c107d0f3897431b15a78d9026c381 Mon Sep 17 00:00:00 2001 From: acolyer Date: Wed, 24 Nov 2004 19:57:59 +0000 Subject: [PATCH] more updates to 1.5 design --- docs/adk15ProgGuideDB/adk15notebook.xml | 2 + docs/adk15ProgGuideDB/annotations.xml | 412 ++++++++++++------ docs/adk15ProgGuideDB/autoboxing.xml | 21 + docs/adk15ProgGuideDB/covariance.xml | 174 ++++++++ docs/adk15ProgGuideDB/joinpointsignatures.xml | 131 ++++++ docs/adk15ProgGuideDB/pertypewithin.xml | 14 + docs/adk15ProgGuideDB/varargs.xml | 57 ++- 7 files changed, 669 insertions(+), 142 deletions(-) create mode 100644 docs/adk15ProgGuideDB/joinpointsignatures.xml diff --git a/docs/adk15ProgGuideDB/adk15notebook.xml b/docs/adk15ProgGuideDB/adk15notebook.xml index 62f6ca68a..c3ed62924 100644 --- a/docs/adk15ProgGuideDB/adk15notebook.xml +++ b/docs/adk15ProgGuideDB/adk15notebook.xml @@ -3,6 +3,7 @@ @@ -55,6 +56,7 @@ + &jpsigs; &annotations; &generics; &enumeratedtypes; diff --git a/docs/adk15ProgGuideDB/annotations.xml b/docs/adk15ProgGuideDB/annotations.xml index 48773ac76..30e495c48 100644 --- a/docs/adk15ProgGuideDB/annotations.xml +++ b/docs/adk15ProgGuideDB/annotations.xml @@ -639,132 +639,19 @@ - - Package and Parameter Annotations - - - Note: A previous design allowed package annotation patterns to be specified - directly in type patterns, and parameter annotation patterns to be - specified directly in method and constructor signature patterns. Because - this made some pointcut expressions hard to read and understand, we moved - in favour of the design presented below, which also has its drawbacks. - Matching on package and parameter annotations is one feature likely to be - deferred until after the 1.5.0 release so that we can gain more understanding - of the kinds of uses AspectJ users are making of annotations in pointcut - expressions before commiting to any one approach. - - - - Java 5 allows both packages and parameters to be annotated. To allow matching on package and parameter annotations, - AspectJ 1.5 introduces the @package and @parameters pointcut designators. - Note: we could consider deferring implementation of these to a dot release after 1.5.0? - - - - - The @package pointcut matches any join point - occuring within the scope of a package with - annotations matching the giving AnnotationPattern. For - example: - - - - - - Matches any join point occuring within the scope of a package with the - @Model annotation. - - - - - Note: we added @package as a result of a conscious decision not to allow the - specification of package annotation patterns within a general TypePattern. A - consequence of this decision is that we lose the ability to say the following - things: "a call to a method defined in a type in a package with annotations - matching..." ; "the set of a field defined in a type in a package with annotations - matching..." ; "the get of a field defined in a type in a package with annotations - matching...". As well as the package of the target at these join points, there is - also the package of the runtime type of the target (call/target difference). So - there are at least three possible sets of package annotations you could theoretically - want to match on at a call, get, or set join point. We have chosen to provide the - means to express the simplest of these, and could consider extending the language - to allow for the others in the future when we better understanding how users will - really use both package annotations and these features. - - - - - The @parameter pointcut designator acts in a similar manner to - args in that it matches based on number and position of arguments - at a join point (and supports the same wildcard options of * and - ... - - - - - The * wildcard matches a single parameter regardless of its annotations. - The .. wildcard matches zero or more parameters with any annotations. An - annotation pattern in a given parameter position matches a parameter in that position with annotations - matching the given annotation pattern. For example, the method signature - - - - - Is matched by: - - - + + Runtime type matching and context exposure - - It is not matched by: + AspectJ 1.5 supports a set of "@" pointcut designators which + can be used both to match based on the presence of an annotation at + runtime, and to expose the annotation value as context in a pointcut or + advice definition. These designators are @args, @this, @target, + @within, @withincode, @call, @execution, @adviceexecution, @get, @set, + @staticinitialization, @initialization,, and @preinitialization - - - - This last example will result in a compilation error since int is not a - valid annotation pattern. - - - - - - Runtime type matching and context exposure + It is a compilation error to attempt to match on an annotation type + that does not have runtime retention using one of these pointcut designators. The this(), target(), and @@ -896,7 +783,154 @@ library to Java 5. A sub-interface and downcast solution could be used if these helpers were felt to be sufficiently important. + + + The @within and @withincode pointcut designators + match any join point where the enclosing type (@within), or + method/constructor (@withincode) has an annotation of the specified + type. The form of these designators is: + + + + + Some examples of using these designators follow: + + + + + @within(@Foo) + + + Matches any join point where the enclosing type + has an annotation of type Foo. + + + + + + pointcut insideCriticalMethod(Critical c) : + @withincode(c); + + + Matches any join point whose shadow is lexically enclosed + in a method which has an annotation of type @Critical, + and exposes the value of the annotation in the parameter + c. + + + + + + The remaining annotation-based pointcut designators are defined in a + similar fashion: + + + + + + + @call(@Foo) + + + Matches any call join point where the most specific join point + signature has an annotation of type @Foo. + + + + + + @execution(@Foo) + + + Matches any execution join point where the most specific join point + signature has an annotation of type @Foo. + + + + + + @adviceexecution(@Foo) + + + Matches any advice execution join point where the advice + has an annotation of type @Foo. + + + + + + @get(@Foo) + + + Matches any get join point where the target field + has an annotation of type @Foo. + + + + + + @set(@Foo) + + + Matches any set join point where the target field + has an annotation of type @Foo. + + + + + + @initialization(@Foo) + + + Matches any initialization join point where the initiating + constructor an annotation of type @Foo. + + + + + + @preinitialization(@Foo) + + + Matches any preinitialization join point where the initiating + constructor an annotation of type @Foo. + + + + + + @staticinitialization(@Foo) + + + Matches any staticinitialization join point where the type being + initialized has an annotation of type @Foo. + + + + + + Access to annotation information on members at a matched join point is available through the getSignature method of the JoinPoint @@ -922,18 +956,134 @@ to Java 5. + + + + Package and Parameter Annotations + + + Note: A previous design allowed package annotation patterns to be specified + directly in type patterns, and parameter annotation patterns to be + specified directly in method and constructor signature patterns. Because + this made some pointcut expressions hard to read and understand, we moved + in favour of the design presented below, which also has its drawbacks. + Matching on package and parameter annotations is one feature likely to be + deferred until after the 1.5.0 release so that we can gain more understanding + of the kinds of uses AspectJ users are making of annotations in pointcut + expressions before commiting to any one approach. + + + + Java 5 allows both packages and parameters to be annotated. To allow matching on package and parameter annotations, + AspectJ 1.5 introduces the @package and @parameters pointcut designators. + Note: we could consider deferring implementation of these to a dot release after 1.5.0? + + + + + The @package pointcut matches any join point + occuring within the scope of a package with + annotations matching the giving AnnotationPattern. For + example: + + + + + + Matches any join point occuring within the scope of a package with the + @Model annotation. + + + + + Note: we added @package as a result of a conscious decision not to allow the + specification of package annotation patterns within a general TypePattern. A + consequence of this decision is that we lose the ability to say the following + things: "a call to a method defined in a type in a package with annotations + matching..." ; "the set of a field defined in a type in a package with annotations + matching..." ; "the get of a field defined in a type in a package with annotations + matching...". As well as the package of the target at these join points, there is + also the package of the runtime type of the target (call/target difference). So + there are at least three possible sets of package annotations you could theoretically + want to match on at a call, get, or set join point. We have chosen to provide the + means to express the simplest of these, and could consider extending the language + to allow for the others in the future when we better understanding how users will + really use both package annotations and these features. + + + + + The @parameter pointcut designator acts in a similar manner to + args in that it matches based on number and position of arguments + at a join point (and supports the same wildcard options of * and + ... + + + + + The * wildcard matches a single parameter regardless of its annotations. + The .. wildcard matches zero or more parameters with any annotations. An + annotation pattern in a given parameter position matches a parameter in that position with annotations + matching the given annotation pattern. For example, the method signature + + + + + Is matched by: + + + + + + It is not matched by: + + + + - Note: the use case of matching call/execution/get/set join points based - on member annotations is expected to be a common one. If it is also common - practice to want to access the annotation value in the advice body, then the - route via thisJoinPointStaticPart and the Signature interface will be too - cumbersome. In this case we need to find a form of context-exposing pcd - that will allow the annotation value to be directly exposed as an advice - parameter. What form should this take, and what join points should it match? - + This last example will result in a compilation error since int is not a + valid annotation pattern. + + + Annotation Inheritance and pointcut matching diff --git a/docs/adk15ProgGuideDB/autoboxing.xml b/docs/adk15ProgGuideDB/autoboxing.xml index 5a3c454ad..ded805fb0 100644 --- a/docs/adk15ProgGuideDB/autoboxing.xml +++ b/docs/adk15ProgGuideDB/autoboxing.xml @@ -2,5 +2,26 @@ Autoboxing and Unboxing + + Autoboxing and Unboxing in Java 5 + + + Java 5 (and hence AspectJ 1.5) ... . For example: + + + + + + + + Autoboxing and Join Point matching in AspectJ 1.5 + + + + Inter-type method declarations and method dispatch + + + diff --git a/docs/adk15ProgGuideDB/covariance.xml b/docs/adk15ProgGuideDB/covariance.xml index d182e157e..4e1e2f8de 100644 --- a/docs/adk15ProgGuideDB/covariance.xml +++ b/docs/adk15ProgGuideDB/covariance.xml @@ -2,5 +2,179 @@ Covariance + + Covariance in Java 5 + + + Java 5 (and hence AspectJ 1.5) allows you to narrow the return type + in an overriding method. For example: + + + + + + + + Covariant methods and Join Point matching + + The join point matching rules for call + and execution pointcut designators are extended + to match against covariant methods. + + + Given the classes A and B + as defined in the previous section, and the program fragment + + + + + Then the call and execution join points for whoAreYou + are matched as follows: + + + + + call(* whoAreYou()) + + Matches both calls, (since it places no constraint on the + return type of the join point signature). + + + + + + call(* A.whoAreYou()) + + Matches both calls, (since the original declaring type + of whoAreYou is A). + + + + + + call(A whoAreYou()) + + Matches both calls, (since the signature of + whoAreYou) in the original declaring type + has a return type of A). + + + + + + call(A B.whoAreYou()) + + Does not match anything - the signature of whoAreYou + as overriden in B has a return type of + B, not A. A lint warning is + given for the call a.whoAreYou() ("does not match + because declaring type is A, if match required use target(B)"). + + + + + + call(A+ B.whoAreYou()) + + Matches the call to b.whoAreYou() since + the return type B in the method signature + is matched by the type pattern A+. A lint warning is + given for the call a.whoAreYou() ("does not match + because declaring type is A, if match required use target(B)"). + + + + + + call(B A.whoAreYou()) + + Does not match anything - there is no method declared in + A with a return type of B. + + + + + + call(B whoAreYou()) + + Matches the call to b.whoAreYou() only. + + + + + + call(B B.whoAreYou()) + + Matches the call to b.whoAreYou() only. + + + + + + + The rule for signature matching at call and execution join points + is unchanged from AspectJ 1.2: a call or execution pointcut matches if + the signature pattern matches at least one of the signatures of the + join point, and if the most-specific matched signature is also matched + by any modifier pattern or annotation pattern that may be present. + + For a call or execution join point, the signatures of a join point + for the call or execution of a method Rtype T.m(params) + are determined as follows: + + + If m(params) is defined in T, + then the signature of m(params) in T is + a signature of the join point: Rtype T.m(params). + If T does not + provide its own definition of m, then the signature + Rtype' T.m(params) + is a signature of the join point, where Rtype' is the return type of + the definition of m inherited by T. + + + For each super-type S of T that is a valid receiver + for a call to m, then the signature of m(params) in + S is a signature + of the join point: Rtype S.m(params). + If S does not provide its + own definition of m, then the signature + Rtype' S.m(params) is a + signature of the join point, where Rtype' is the return type of the + definition of m inherited by S. + + + + A call to b.whoAreYou() has the join point signatures + + + + B B.whoAreYou() + A A.whoAreYou() + + + Following the rule given, it is easy to see why for example + call(B A.whoAreYou()) does not match anything as + this pattern matches neither of the signatures at the join point. In + contrast, the pointcut expression call(A+ B.whoAreYou()) + does match the call to b.whoAreYou() because it matches + the second of the signatures at the join point. + + + diff --git a/docs/adk15ProgGuideDB/joinpointsignatures.xml b/docs/adk15ProgGuideDB/joinpointsignatures.xml new file mode 100644 index 000000000..0c3473034 --- /dev/null +++ b/docs/adk15ProgGuideDB/joinpointsignatures.xml @@ -0,0 +1,131 @@ + + + Join Point Signatures + + To understand join point matching for annotations, generics, and + covariance, it is first necessary to understand the concepts of + join point signatures and join point signature matching, for call and + execution join points. + + + Join Point Signatures for Call Join Points + + A call join point can have more than one signature. For a + call pointcut expression to match a given call join point, at + least one of the join point signatures must be matched by the + pointcut's signature pattern. + + + For a call join point where a call is made to a method + m(args) on a target type T (where + T is the static type of the target): + + + + + + Then the signature R(T) T.m(args) is a signature + of the call join point, where R(T) is the return + type of m in T, and + args represents the types of the arguments to + m. If T itself does not + declare a definition of m(args), then + R(T) is the return type in the definition of + m that T inherits. Given the + call above, and the definition of T.m: + + + + + Then R' T.m(String) is a signature of the + call join point for t.m("hello"). + + + For each ancestor (super-type) A of T, + if m(args) is defined for that super-type, then + R(A) A.m(args) is a signature of the call join + point, where R(A) is the return type of + m(args) as defined in A, or as inherited + by A if A itself does not + provide a definition of m(args). + + + + Continuing the example from above,we can deduce that + + + + + are all additional signatures for the call join point arising + from the call t.m("hello"). Thus the call + join point has four signatures in total. Amongst these signatures, + we say that the most-specific signature is the + signature with the most-specific declaring type - that is, the + signature of the static type of the target of the call + (R' T.m(String)) in this case. + + + + + Join Point Signatures for Execution Join Points + + Join point signatures for execution join points are defined + in a similar manner to signatures for call join points. Given the + same hierarchy as in the call example in the previous section: + + + + + + Then the execution join point signatures arising as a result + of the call to t.m("hello") are: + + + + + + Pointcut matching based on Join Point Signatures + + Explain signature + modifiers split, plus notion of "most-specific" + join point. + + + + diff --git a/docs/adk15ProgGuideDB/pertypewithin.xml b/docs/adk15ProgGuideDB/pertypewithin.xml index 5f5b8fd66..e870f10e5 100644 --- a/docs/adk15ProgGuideDB/pertypewithin.xml +++ b/docs/adk15ProgGuideDB/pertypewithin.xml @@ -2,5 +2,19 @@ The pertypewithin Aspect Instantiation Model + This is a placeholder to stimulate discussion around a possible new + instantiation model : pertypewithin(OptionalParensTypePattern). + The semantics of pertypewithin are that a new aspect + instance will be created at the staticinitialization + join point of each type matching the given type pattern. + + Discussion must include motivating use cases. Raise the issue that + pertypewithin takes a type pattern, not a pointcut. + + We will only do this if we believe we can generate an implementation + that is significantly more efficient than hand-coded alternatives. + + Need to define aspectOf(Class), hasAspect(Class). + diff --git a/docs/adk15ProgGuideDB/varargs.xml b/docs/adk15ProgGuideDB/varargs.xml index 91a389b52..ceadfed05 100644 --- a/docs/adk15ProgGuideDB/varargs.xml +++ b/docs/adk15ProgGuideDB/varargs.xml @@ -2,7 +2,7 @@ Varargs - + Variable-length Argument Lists in Java 5 @@ -169,21 +169,56 @@ execution(* *.*(String[])) matches the execution join point for bar but not foo. - - - The args pointcut designator can also now take a varargs - pattern as the last argument in the list. For example, you can write: - - - - + Exposing variable-length arguments as context in pointcuts and advice + + + When a varargs parameter is used within the body of a method, it has + an array type, as discussed in the introduction to this section. We follow the + same convention when binding a varargs parameter via the args + pointcut designator. Given a method + + + + + + The call or execution join points for foo will be matched + by the pointcut args(int,String[]). It is not permitted + to use the varargs syntax within an args pointcut designator - so you + cannot write args(int,String...). + + + + Binding of a varargs parameter in an advice statement is straightforward: + + + + + Since you cannot use the varargs syntax in the args + pointcut designator, you also cannot use the varargs syntax to declare + advice parameters. + + Note: the proposal in this section does not allow you to + distinguish between a join point with a signature (int, String...) + and a join point with a signature (int, String[]) based + solely on the use of the args + pointcut designator. If this distinction is required, args + can always be coupled with call or + execution. + + -- 2.39.5