# The AspectJTM 5 Development Kit Developer's Notebook

### the AspectJ Team

Copyright (c) 2004 Contributors, All rights reserved.

Abstract

This guide describes the changes to the AspectJ language and tools in AspectJ 5. These changes are primarily, but not exclusively, to support Java 5 (Tiger) features. If you are new to AspectJ, we recommend you start by reading the programming guide.

This is a draft document and is subject to change before the design and implementation is complete. There is also no guarantee that all of the features in this document will be implemented in a 1.5.0 release - some may be deferred until 1.5.1 or even later. In general, features in which we have more confidence in the design will be implemented earlier, providing a framework for user feedback and direction setting on features for which the use cases are less obvious at time of writing.

## Chapter 1. Join Point Signatures

Many of the extensions to the AspectJ language to address the new features of Java 5 are derived from a simple set of principles for join point matching. In this section, we outline these principles as a foundation for understanding the matching rules in the presence of annotations, generics, covariance, varargs, and autoboxing.

## Join Point Matching

AspectJ supports 11 different kinds of join points. These are the `method call, method execution, constructor call, constructor execution, field get, field set, pre-initialization, initialization, static initialization, handler,` and `advice execution` join points.

The kinded pointcut designators match based on the kind of a join point. These are the `call, execution, get, set, preinitialization, initialization, staticinitialization, handler,` and `adviceexecution` designators.

A kinded pointcut is written using patterns, some of which match based on signature, and some of which match based on modifiers. For example, in the `call` pointcut designator:

            call(ModifierPattern TypePattern TypePattern.IdPattern(TypePatternList) ThrowsPattern)

the modifiers matching patterns are `ModifierPattern` and `ThrowsPattern`, and the signature matching patterns are `TypePattern TypePattern.IdPattern(TypePatternList)`.

A join point has potentially multiple signatures, but only one set of modifiers. A kinded primitive pointcut matches a particular join point if and only if:

1. They are of the same kind
2. The signature pattern (exactly) matches at least one signature of the join point
3. The modifiers pattern matches the modifiers of the subject of the join point

These rules make it very easily to quickly determine whether a given pointcut matches a given join point. In the next two sections, we describe what the signature(s) of a join point are, and what the subjects of join points are.

## Join Point Signatures

Call, execution, get, and set join points may potentially have multiple signatures. All other join points have exactly one signature. The following table summarizes the constituent parts of a join point signature for the different kinds of join point.

Join Point Kind | Return Type | Declaring Type | Id | Parameter Types | Field Type | Exception Type
--- | --- | --- | --- | --- | --- | ---
Method call | + | + | + | + |  |
Method execution | + | + | + | + |  |
Constructor call |  | + |  | + |  |
Constructor execution |  | + |  | + |  |
Field get |  | + | + |  | + |
Field set |  | + | + |  | + |
Pre-initialization |  | + |  | + |  |
Initialization |  | + |  | + |  |
Static initialization |  | + |  |  |  |
Handler |  |  |  |  |  | +
Advice execution |  | + |  | + |  |

Note that whilst an advice excetution join point has a signature comprising the declaring type of the advice and the advice parameter types, the `adviceexecution` pointcut designator does not support matching based on this signature.

The signatures for most of the join point kinds should be self-explanatory, except for field get and set, and method call and execution join points, which can have multiple signatures. Each signature of a method call or execution join point has the same id and parameter types, but the declaring type and return type (with covariance) may vary. Each signature of a field get or set join point has the same id and field type, but the declaring type may vary.

The following sections examine signatures for these join points in more detail.

### Method call join point signatures

For a call join point where a call is made to a method `m(parameter_types)` on a target type `T` (where `T` is the static type of the target):

    		T t = new T();
    		t.m("hello");  <= call join point occurs when this line is executed

Then the signature `R(T) T.m(parameter_types)` is a signature of the call join point, where `R(T)` is the return type of `id` in `T`, and `parameter_types` are the parameter types of `m`. If `T` itself does not declare a definition of `m(parameter_types)`, 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`:

            interface Q {
              R m(String s);
            }

            class P implements Q {
              R m(String s) {...}
            }

            class S extends P {
              R' m(String s) {...}
            }

            class T extends S {}

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(parameter_types)` is defined for that super-type, then `R(A) A.m(parameter_types)` is a signature of the call join point, where `R(A)` is the return type of `m(parameter_types)` as defined in `A`, or as inherited by `A` if `A` itself does not provide a definition of `m(parameter_types)`.

Continuing the example from above,we can deduce that

            R' S.m(String)
            R  P.m(String)
            R  Q.m(String)

are all additional signatures for the call join point arising from the call `t.m("hello")`. Thus this call join point has four signatures in total. Every signature has the same id and parameter types, and a different declaring type.

### Method execution join point signatures

Join point signatures for execution join points are defined in a similar manner to signatures for call join points. Given the hierarchy:

            interface Q {
              R m(String s);
            }

            class P implements Q {
              R m(String s) {...}
            }

            class S extends P {
              R' m(String s) {...}
            }

            class T extends S { }

            class U extends T {
              R' m(String s) {...}
            }

Then the execution join point signatures arising as a result of the call to `u.m("hello")` are:

            R' U.m(String)
            R' S.m(String)
            R  P.m(String)
            R  Q.m(String)

Each signature has the same id and parameter types, and a different declaring type. There is one signature for each type that provides its own declaration of the method. Hence in this example there is no signature `R' T.m(String)` as `T` does not provide its own declaration of the method.

### Field get and set join point signatures

For a field get join point where an access is made to a field `f` of type `F` on a object with declared type `T`, then `F T.f` is a signature of the get join point.

If `T` does not directly declare a member `f`, then for each super type `S` of `T`, up to and including the most specific super type of `T` that does declare the member `f`, `F S.f` is a signature of the join point. For example, given the hierarchy:

            class P  {
              F f;
            }

            class S extends P {
              F f;
            }

            class T extends S { }

Then the join point signatures for a field get join point of the field `f` on an object with declared type `T` are:

            F S.f
            F T.f

The signatures for a field set join point are derived in an identical manner.

## Join Point Modifiers

Every join point has a single set of modifiers - these include the standard Java modifiers such as `public, private, static, abstract` etc., any annotations, and the throws clauses of methods and constructors. These modifiers are the modifiers of the subject of the join point.

The following table defines the join point subject for each kind of join point.

Join Point Kind | Subject
--- | ---
Method call | The method picked out by Java as the static target of the method call.
Method execution | The method that is executing.
Constructor call | The constructor being called.
Constructor execution | The constructor executing.
Field get | The field being accessed.
Field set | The field being set.
Pre-initialization | The first constructor executing in this constructor chain.
Initialization | The first constructor executing in this constructor chain.
Static initialization | The type being initialized.
Handler | The declared type of the exception being handled.
Advice execution | The advice being executed.

For example, given the following types

            public class X {
              @Foo
              protected void doIt() {...}
            }

            public class Y extends X {
              public void doIt() {...}
            }

Then the modifiers for a call to `(Y y) y.doIt()` are simply `{public}`. The modifiers for a call to `(X x) x.doIt()` are `{@Foo,protected}`.

## Summary of Join Point Matching

A join point has potentially multiple signatures, but only one set of modifiers. A kinded primitive pointcut matches a particular join point if and only if:

1. They are of the same kind
2. The signature pattern (exactly) matches at least one signature of the join point
3. The modifiers pattern matches the modifiers of the subject of the join point

Given the hierarchy

            interface Q {
              R m(String s);
            }

            class P implements Q {
              @Foo
              public R m(String s) {...}
            }

            class S extends P {
              @Bar
              public R' m(String s) {...}
            }

            class T extends S {}

and the program fragment:

            P p = new P();
            S s = new S();
            T t = new T();
            ...
            p.m("hello");
            s.m("hello");
            t.m("hello");

The the pointcut `call(@Foo R P.m(String))` matches the call `p.m("hello")` since both the signature and the modifiers match. It does not match the call `s.m("hello")` because even though the signature pattern matches one of the signatures of the join point, the modifiers pattern does not match the modifiers of the method m in S which is the static target of the call.

The pointcut `call(R' m(String))` matches the calls `t.m("hello")` and `s.m("hello")`. It does not match the call `p.m("hello")` since the signature pattern does not match any signature for the call join point of m in P.

## Chapter 2. Annotations

## Annotations in Java 5

This section provides the essential information about annotations in Java 5 needed to understand how annotations are treated in AspectJ 5. For a full introduction to annotations in Java, please see the documentation for the Java 5 SDK.

### Using Annotations

Java 5 introduces annotation types which can be used to express metadata relating to program members in the form of annotations. Annotations in Java 5 can be applied to package and type declarations (classes, interfaces, enums, and annotations), constructors, methods, fields, parameters, and variables. Annotations are specified in the program source by using the `@` symbol. For example, the following piece of code uses the `@Deprecated` annotation to indicate that the `obsoleteMethod()` has been deprecated:

    		@Deprecated
    		public void obsoleteMethod() { ... }

Annotations may be marker annotations, single-valued annotations, or multi-valued annotations. Annotation types with no members or that provide default values for all members may be used simply as marker annotations, as in the deprecation example above. Single-value annotation types have a single member, and the annotation may be written in one of two equivalent forms:

    		@SuppressWarnings({"unchecked"})
    		public void someMethod() {...}

or

    		@SuppressWarnings(value={"unchecked"})
    		public void someMethod() {...}

Multi-value annotations must use the `member-name=value` syntax to specify annotation values. For example:

    		@Authenticated(role="supervisor",clearanceLevel=5)
    		public void someMethod() {...}

### Retention Policies

Annotations can have one of three retention policies:

Source-file retention

  Annotations with source-file retention are read by the compiler during the compilation process, but are not rendered in the generated `.class` files.

Class-file retention

  This is the default retention policy. Annotations with class-file retention are read by the compiler and also retained in the generated `.class` files.

Runtime retention

  Annotations with runtime retention are read by the compiler, retained in the generated `.class` files, and also made available at runtime.

Local variable annotations are not retained in class files (or at runtime) regardless of the retention policy set on the annotation type. See JLS 9.6.1.2.

### Accessing Annotations at Runtime

Java 5 supports a new interface, `java.lang.reflect.AnnotatedElement`, that is implemented by the reflection classes in Java (`Class`, `Constructor`, `Field`, `Method`, and `Package`). This interface gives you access to annotations that have runtime retention via the `getAnnotation`, `getAnnotations`, and `isAnnotationPresent`. Because annotation types are just regular Java classes, the annotations returned by these methods can be queried just like any regular Java object.

### Annotation Inheritance

It is important to understand the rules relating to inheritance of annotations, as these have a bearing on join point matching based on the presence or absence of annotations.

By default annotations are not inherited. Given the following program

    			@MyAnnotation
    			class Super {
    			  @Oneway public void foo() {}
    			}

    			class Sub extends Super {
    			  public void foo() {}
    			}

Then `Sub` does not have the `MyAnnotation` annotation, and `Sub.foo()` is not an `@Oneway` method, despite the fact that it overrides `Super.foo()` which is.

If an annotation type has the meta-annotation `@Inherited` then an annotation of that type on a class will cause the annotation to be inherited by sub-classes. So, in the example above, if the `MyAnnotation` type had the `@Inherited` attribute, then `Sub` would have the `MyAnnotation` annotation.

`@Inherited` annotations are not inherited when used to annotate anything other than a type. A type that implements one or more interfaces never inherits any annotations from the interfaces it implements.

## Annotating Aspects

AspectJ 5 supports annotations on aspects, and on method, field, constructor, advice, and inter-type declarations within aspects. Method and advice parameters may also be annotated. Annotations are not permitted on pointcut declarations or on `declare` statements.

The following example illustrates the use of annotations in aspects:

    		@AspectAnnotation
    		public abstract aspect ObserverProtocol {

    			@InterfaceAnnotation
    			interface Subject {}

    			@ITDFieldAnnotation
    			private List Subject.observers;

    			@ITDMethodAnnotation
    			public void Subject.addObserver() { ... }

    			@ITDMethodAnnotation
    			public void Subject.removeObserver() { ... }

    			@MethodAnnotation
    			private void notifyObservers(Subject subject) { ... }

    			/**
    			 * Delegate to concrete sub-aspect the actual form of
    			 * notification for a given type of Subject.
    			 */
    			@MethodAnnotation
    			protected abstract void notifySubject(Subject s);

    			/* no annotations on pointcuts */
    			abstract pointcut observedEvent(Subject subject);

    			@AdviceAnnotation
    			after(Subject subject) returning : observedEvent(subject) {
    				notifyObservers(subject);
    			}
    		}

An annotation on an aspect will be inherited by sub-aspects, iff it has the `@Inherited` meta-annotation.

AspectJ 5 supports a new XLint warning, "the pointcut associated with this advice does not match any join points". The warning is enabled by default and will be emitted by the compiler if the pointcut expression associated with an advice statement can be statically determined to not match any join points. The warning can be suppressed for an individual advice statement by using the `@SuppressWarnings({"unmatched"})` annotation. (See JLS 9.6.1.5).

## Join Point Matching based on Annotations

Note: compared to the previous version, this version restricts the use of annotations in type patterns (package annotations and outer type annotations cannot be specified inline), and requires parenthesis more often. These changes were made to make pointcut expressions easier to read and interpret.

This section discusses changes to type pattern and signature pattern matching in AspectJ 5 that support matching join points based on the presence or absence of annotations. We then discuss means of exposing annotation values within the body of advice.

### Annotation Patterns

For any kind of annotated element (type, method, constructor, package, etc.), an annotation pattern can be used to match against the set of annotations on the annotated element. Annotation patterns are defined by the following grammar.

    		AnnotationPattern := '!'? '@' AnnotationTypePattern AnnotationPattern*

    		AnnotationTypePattern := FullyQualifiedName |
    		                         '(' TypePattern ')'

      		FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*

In simple terms, an annotation pattern element has one of two basic forms:

- @<qualified-name>, for example, @Foo, or @org.xyz.Foo.
- @(<type-pattern>), for example, @(org.xzy..*), or @(Foo || Boo)

These simple elements may be negated using `!`, and combined by simple concatentation. The pattern `@Foo @Boo` matches an annotated element that has both an annotation of type `Foo` and an annotation of type `Boo`.

Some examples of annotation patterns follow:

          @Immutable

Matches any annotated element which has an annotation of type `Immutable`.

          !@Persistent

Matches any annotated element which does not have an annotation of type `Persistent`.

          @Foo @Goo

Matches any annotated element which has both an annotation of type `Foo` and an annotation of type `Goo`.

          @(Foo || Goo)

Matches any annotated element which has either an annotation of a type matching the type pattern `(Foo || Goo)`. In other words, an annotated element with either an annotation of type `Foo` or an annotation of type `Goo` (or both). (The parenthesis are required in this example).

          @(org.xyz..*)

Matches any annotated element which has either an annotation of a type matching the type pattern `(org.xyz..*)`. In other words, an annotated element with an annotation that is declared in the org.xyz package or a sub-package. (The parenthesis are required in this example).

### Type Patterns

AspectJ 1.5 extends type patterns to allow an optional `AnnotationPattern` prefix. (Extensions to this definition for generics are shown in the next chapter).

      	  	TypePattern := SimpleTypePattern |
      	  	               '!' TypePattern |
      	  	               '(' AnnotationPattern? TypePattern ')'
      	  	               TypePattern '&&' TypePattern |
      	  	               TypePattern '||' TypePattern |

      	  	SimpleTypePattern := DottedNamePattern '+'? '[]'*

      		DottedNamePattern := FullyQualifiedName RestOfNamePattern? |
      		                     '*' NotStarNamePattern?

      		RestOfNamePattern := '..' DottedNamePattern |
      		                     '*' NotStarNamePattern?

      		NotStarNamePattern := FullyQualifiedName RestOfNamePattern? |
      		                      '..' DottedNamePattern

      		FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*

Note that in most cases when annotations are used as part of a type pattern, the parenthesis are required (as in `(@Foo Hello+)`). In some cases (such as a type pattern used within a `this` pointcut expression, the parenthesis are optional:

            OptionalParensTypePattern := AnnotationPattern? TypePattern

The following examples illustrate the use of annotations in type patterns:

         (@Immutable *)

Matches any type with an `@Immutable` annotation.

         (!@Immutable *)

Matches any type which does not have an `@Immutable` annotation.

         (@Immutable (org.xyz.* || org.abc.*))

Matches any type in the `org.xyz` or `org.abc` packages with the `@Immutable` annotation.

         ((@Immutable Foo+) || Goo)

Matches a type `Foo` or any of its subtypes, which have the `@Immutable` annotation, or a type `Goo`.

         ((@(Immutable || NonPersistent) org.xyz..*)

Matches any type in a package beginning with the prefix `org.xyz`, which has either the `@Immutable` annotation or the `@NonPersistent` annotation.

         (@Immutable @NonPersistent org.xyz..*)

Matches any type in a package beginning with the prefix `org.xyz`, which has both an `@Immutable` annotation and an `@NonPersistent` annotation.

         (@(@Inherited *) org.xyz..*)

Matches any type in a package beginning with the prefix `org.xyz`, which has an inheritable annotation. The annotation pattern `@(@Inherited *)` matches any annotation of a type matching the type pattern `@Inherited *`, which in turn matches any type with the `@Inherited` annotation.

### Signature Patterns

A `FieldPattern` is described by the following grammar:

      		FieldPattern :=
      		    AnnotationPattern? FieldModifiersPattern?
      		    TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern

    		FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*

    		FieldModifier := 'public' | 'private' | 'protected' | 'static' |
    		                 'transient' | 'final'

    		DotOrDotDot := '.' | '..'

    		SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?

The optional `AnnotationPattern` restricts matches to fields with annotations that match the pattern. For example:

@SensitiveData * *

  Matches a field of any type and any name, that has an annotation of type `@SensitiveData`

@SensitiveData List org.xyz..*.*

  Matches a member field of a type in a package with prefix `org.xzy`, where the field is of type `List`, and has an annotation of type `@SensitiveData`

(@SensitiveData *) org.xyz..*.*

  Matches a member field of a type in a package with prefix `org.xzy`, where the field is of a type which has a `@SensitiveData` annotation.

@Foo (@Goo *) (@Hoo *).*

  Matches a field with an annotation `@Foo`, of a type with an annotation `@Goo`, declared in a type with annotation `@Hoo`.

@Persisted @Classified * *

  Matches a field with an annotation `@Persisted` and an annotation `@Classified`.

A `MethodPattern` is of the form

      		MethodPattern :=
      		    AnnotationPattern? MethodModifiersPattern? TypePattern
      		                       (TypePattern DotOrDotDot)? SimpleNamePattern
      		                       '(' FormalsPattern ')'ThrowsPattern?

    		MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern*

    		MethodModifier := 'public' | 'private' | 'protected' | 'static' |
    		                  'synchronized' | 'final'

    		FormalsPattern := '..' (',' FormalsPatternAfterDotDot)* |
    		                  OptionalParensTypePattern (',' FormalsPattern)* |
    		                  TypePattern '...'

    		FormalsPatternAfterDotDot :=
    		        OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
    		        TypePattern '...'

    		ThrowsPattern := 'throws' TypePatternList

    		TypePatternList := TypePattern (',' TypePattern)*

Note: compared to the previous version, this definition of MethodPattern does not allow parameter annotation matching (only matching on annotations of parameter types).

A `ConstructorPattern` has the form

      		ConstructorPattern :=
      		    AnnotationPattern? ConstructorModifiersPattern?
      		                       (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
      		                       ThrowsPattern?

    		ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*

    		ConstructorModifier := 'public' | 'private' | 'protected'

The optional `AnnotationPattern` at the beginning of a method or constructor pattern restricts matches to methods/constructors with annotations that match the pattern. For example:

@Oneway * *(..)

  Matches a method with any return type and any name, that has an annotation of type `@Oneway`.

@Transaction * (@Persistent org.xyz..*).*(..)

  Matches a method with the `@Transaction` annotation, declared in a type with the `@Persistent` annotation, and in a package beginning with the `org.xyz` prefix.

* *.*(@Immutable *,..)

  Matches any method taking at least one parameter, where the parameter type has an annotation `@Immutable`.

### Example Pointcuts

within(@Secure *)

  Matches any join point where the code executing is declared in a type with an `@Secure` annotation. The format of the `within` pointcut designator in AspectJ 5 is `'within' '(' OptionalParensTypePattern ')'`.

staticinitialization(@Persistent *)

  Matches the staticinitialization join point of any type with the `@Persistent` annotation. The format of the `staticinitialization` pointcut designator in AspectJ 5 is `'staticinitialization' '(' OptionalParensTypePattern ')'`.

call(@Oneway * *(..))

  Matches a call to a method with a `@Oneway` annotation.

execution(public (@Immutable *) org.xyz..*.*(..)

  The execution of any public method in a package with prefix `org.xyz`, where the method returns an immutable result.

set(@Cachable * *)

  Matches the set of any cachable field.

handler(!@Catastrophic *)

  Matches the handler join point for the handling of any exception that is not `Catastrophic`. The format of the `handler` pointcut designator in AspectJ 5 is `'handler' '(' OptionalParensTypePattern ')'`.

### Runtime type matching and context exposure

AspectJ 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`, and `@annotation`

It is a compilation error to attempt to match on an annotation type that does not have runtime retention using `@this, @target` or `@args`. It is a compilation error to attempt to use any of these designators to expose an annotation value that does not have runtime retention.

The `this()`, `target()`, and `args()` pointcut designators allow matching based on the runtime type of an object, as opposed to the statically declared type. In AspectJ 5, these designators are supplemented with three new designators : `@this()` (read, "this annotation"), `@target()`, and `@args()`.

Like their counterparts, these pointcut designators can be used both for join point matching, and to expose context. The format of these new designators is:

      	    AtThis := '@this' '(' AnnotationOrIdentifer ')'

      	    AtTarget := '@target' '(' AnnotationOrIdentifier ')'

      	    AnnotationOrIdentifier := '@' FullyQualifiedName | Identifier

      	    AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'

      	    AnnotationsOrIdentifiersPattern :=
      	                      '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
      	                      AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
      	                      '*' (',' AnnotationsOrIdentifiersPattern)*

      	    AnnotationsOrIdentifiersPatternAfterDotDot :=
    		                  AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
    		                  '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*

The forms of `@this()` and `@target()` that take a single annotation name are analogous to their counterparts that take a single type name. They match at join points where the object bound to `this` (or `target`, respectively) has an annotation of the specified type. For example:

@this(@Foo)

  Matches any join point where the object currently bound to 'this' has an annotation of type `Foo`.

call(* *(..)) && @target(@Classified)

  Matches a call to any object where the target of the call has a `@Classified` annotation.

Annotations can be exposed as context in the body of advice by using the forms of `@this(), @target()` and `@args()` that use bound variables in the place of annotation names. For example:

      	pointcut callToClassifiedObject(Classified classificationInfo) :
      	    call(* *(..)) && @target(classificationInfo);

      	pointcut txRequiredMethod(Tx transactionAnnotation) :
      	    execution(* *(..)) && @this(transactionAnnotation)
      	    && if(transactionAnnotation.policy == Tx.Policy.REQUIRED);

The `@args` pointcut designator behaves as its `args` counterpart, matching join points based on number and position of arguments, and supporting the `*` wildcard and at most one `..` wildcard. An annotation at a given position in an `@args` expression indicates that the runtime type of the argument in that position at a join point must have an annotation of the indicated type. For example:

      	/**
      	 * matches any join point with at least one argument, and where the
      	 * type of the first argument has the @Classified annotation
      	 */
      	pointcut classifiedArgument() : @args(@Classified,..);

      	/**
      	 * matches any join point with three arguments, where the third
      	 * argument has an annotation of type @Untrusted.
      	 */
      	pointcut untrustedData(Untrusted untrustedDataSource) :
      	    @args(*,*,untrustedDataSource);

Note: an alternative design would be to allow both annotation patterns and type patterns to be specified in the existing args pcd. This works well for matching, but is more awkward when it comes to exposing context.

Access to `AnnotatedElement` information is available reflectively with the body of advice through the `thisJoinPoint`, `thisJoinPointStaticPart`, and `thisEnclosingJoinPointStaticPart` variables. To access annotations on the arguments, or object bound to this or target at a join point you can use the following code fragments:

      	Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();
      	Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations();
      	Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();

Note: it would be nicer to provide direct helper methods in the JoinPoint interface or a sub-interface that provide the annotations directly, something like "AnnotatedElement getThisAnnotationInfo()". The problem here is that the "AnnotatedElement" type is only in the Java 5 runtime libraries, and we don't want to tie the AspectJ runtime 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 executing code is defined within a type (`@within`), or a method/constructor (`@withincode`) that has an annotation of the specified type. The form of these designators is:

            AtWithin := '@within' '(' AnnotationOrIdentifier ')'
            AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'

Some examples of using these designators follow:

@within(@Foo)

  Matches any join point where the executing code is defined within a type which has an annotation of type `Foo`.

pointcut insideCriticalMethod(Critical c) : @withincode(c);

  Matches any join point where the executing code is defined in a method or constructor which has an annotation of type `@Critical`, and exposes the value of the annotation in the parameter `c`.

The `@annotation` pointcut designator matches any join point where the subject of the join point has an annotation of the given type. Like the other @pcds, it can also be used for context exposure.

            AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'

The subject of a join point is defined in the table in chapter one of this guide.

Access to annotation information on members at a matched join point is also available through the `getSignature` method of the `JoinPoint` and `JoinPoint.StaticPart` interfaces. The `MemberSignature` interface is extended with the additional operation `java.lang.reflect.AccessibleObject getAccessibleObject()`. The following fragment illustrates an example use of this interface to access annotation information.

      	Signature sig = thisJoinPointStaticPart.getSignature();
      	AnnotatedElement declaringTypeAnnotationInfo = sig.getDeclaringType();
      	if (sig instanceof MemberSignature) {
      	  // this must be an initialization, pre-initialization, call, execution, get, or
      	  // set join point.
      	  AnnotatedElement memberAnnotationInfo = ((MemberSignature)sig).getAccessibleObject();
      	}

Note again that it would be nicer to add the method getAnnotationInfo directly to MemberSignature, but this would once more couple the runtime library to Java 5.

The `@this,@target` and `@args` pointcut designators can only be used to match against annotations that have runtime retention. The `@within, @withincode` and `@annotation` pointcut designators can only be used to match against annotations that have at least class-file retention, and if used in the binding form the annotation must have runtime retention.

### 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 will 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.

### Annotation Inheritance and pointcut matching

According to the Java 5 specification, non-type annotations are not inherited, and annotations on types are only inherited if they have the `@Inherited` meta-annotation. Given the following program:

      	class C1 {
      	  @SomeAnnotation
      	  public void aMethod() {...}
      	}

      	class C2 extends C1 {
      	  public void aMethod() {...}
      	}

      	class Main {
      	  public static void main(String[] args) {
      	    C1 c1 = new C1();
      	    C2 c2 = new C2();
      	    c1.aMethod();
      	    c2.aMethod();
      	  }
      	}

      	aspect X {

      	  pointcut annotatedMethodCall() :
      	    call(@SomeAnnotation * C1.aMethod());

      	  pointcut c1MethodCall() :
      	    call(* C1.aMethod());
      	}

The pointcut `annotatedMethodCall` will match the call to `c1.aMethod()`, but not the call to `c2.aMethod()`.

The pointcut `c1MethodCall` matches both `c1.aMethod()` and `c2.aMethod()`.

### Limitations

It would be useful to be able to match join points based on annotation values, rather than merely the presence of a class-file retention annotation of a given type. This facility may be supported in a future version of AspectJ, by expanding the definition of `AnnotationPattern`. Matching annotation values for annotations with runtime retention can be done by exposing the annotation value as a pointcut parameter and then using an `if` pointcut expression to test the value.

## Using Annotations with declare statements

### Declare error and declare warning

Since pointcut expressions in AspectJ 5 support join point matching based on annotations, this facility can be exploited when writing `declare warning` and `declare error` statements. For example:

      	declare warning : withincode(@PerformanceCritical * *(..)) &&
      	                  call(@ExpensiveOperation * *(..))
      	                : "Expensive operation called from within performance critical section";

      	declare error : call(* org.xyz.model.*.*(..)) &&
      	                !@within(@Trusted *)
      	                : "Untrusted code should not call the model classes directly";

### declare parents

The general form of a `declare parents` statement is:

      	declare parents : TypePattern extends Type;
      	declare parents : TypePattern implements TypeList;

Since AspectJ 5 supports annotations as part of a type pattern specification, it is now possible to match types based on the presence of annotations with either class-file or runtime retention. For example:

declare parents : (@Secured *) implements SecuredObject;

  All types with the `@Secured` annotation implement the `SecuredObject` inteface.

declare parents : (@Secured BankAccount+) implements SecuredObject;

  The subset of types drawn from the `BankAccount` type and any subtype of `BankAccount`, where the `@Secured` annotation is present, implement the `SecuredObject` interface.

An annotation type may not be used as the target of a declare parents statement. If an annotation type is named explicitly as the target of a declare parents statement, a compilation error will result. If an annotation type is matched by a non-explicit type pattern used in a declare parents statement it will be ignored (and an XLint warning issued).

### declare precedence

The general form of a declare precedence statement is:

      	declare precedence : TypePatList;

AspectJ 5 allows the type patterns in the list to include annotation information as part of the pattern specification. For example:

declare precedence : (@Security *),*;

  All aspects with the `@Security` annotation take precedence over any other aspects in the system. (Or, more informally, all security-related aspects take precedence).

## Declare Annotation

AspectJ 5 supports a new kind of declare statement, `declare annotation`. The general form of a `declare annotation` statement is:

      	declare annotation : ElementPattern : Annotation ;

Where annotation is a regular annotation expression as defined in the Java 5 language. If the annotation has the `@Target` meta-annotation, then the elements matched by `ElementPattern` must be of the kind specified by the `@Target` annotation.

`ElementPattern` is defined as follows:

      	        ElementPattern := TypePattern |
      	                          MethodPattern |
      	                          ConstructorPattern |
      	                          FieldPattern

The following examples illustrate the use of `declare annotation`.

declare annotation : org.xyz.model..* : @BusinessDomain ;

  All types defined in a package with the prefix `org.xyz.model` have the `@BusinessDomain` annotation.

declare annotation : public * BankAccount+.*(..) : @Secured(role="supervisor")

  All public methods in `BankAccount` and its subtypes have the annotation `@Secured(role="supervisor")`.

declare annotation : * DAO+.* : @Persisted;

  All fields defined in `DAO` or its subtypes have the `@Persisted` annotation.

## Inter-type Declarations

An annotation type may not be the target of an inter-type declaration.

## Chapter 3. Generics

## Generics in Java 5

This section provides the essential information about generics in Java 5 needed to understand how generics are treated in AspectJ 5. For a full introduction to generics in Java, please see the documentation for the Java 5 SDK.

### Declaring Parameterized Types

### Using Parameterized Types

### Assignments and Wildcards

### Generic Methods

### Parameterized Aspect Types

###

###

###

## Chapter 4. Autoboxing and Unboxing

## Autoboxing and Unboxing in Java 5

Java 5 (and hence AspectJ 1.5) supports automatic conversion of primitive types (int, float, double etc.) to their object equivalents (Integer, Float, Double,...) in assignments and method and constructor invocations. This conversion is know as autoboxing.

Java 5 also supports automatic unboxing, where wrapper types are automatically converted into their primitive equivalents if needed for assignments or method or constructor invocations.

For example:

    		int i = 0;
    		i = new Integer(5); // auto-unboxing

    		Integer i2 = 5;  // autoboxing

## Autoboxing and Join Point matching in AspectJ 5

Most of the pointcut designators match based on signatures, and hence are unaffected by autoboxing. For example, a call to a method

       		public void foo(Integer i);

is not matched by a pointcut `call(void foo(int))` since the signature declares a single `Integer` parameter, not an `int`.

The `args` pointcut designator is affected by autoboxing since it matches based on the runtime type of the arguments. AspectJ 5 applies autoboxing and unboxing in determining argument matching. In other words, `args(Integer)` will match any join point at which there is a single argument of type `Integer` or of type `int`.

- args(Integer) and args(int) are equivalent
- args(Float) and args(float) are equivalent
- args(Double) and args(double) are equivalent
- args(Short) and args(short) are equivalent
- args(Byte) and args(byte) are equivalent
- args(Long) and args(long) are equivalent
- args(Boolean) and args(boolean) are equivalent

Autoboxing and unboxing are also applied when binding pointcut or advice parameters, for example:

       		pointcut foo(int i) : args(i);

       		before(Integer i) : foo(i) {
       		  ...
       		}

## Inter-type method declarations and method dispatch

Autoboxing, unboxing, and also varargs all affect the method dispatch algorithm used in Java 5. In AspectJ 5, the target method of a call is selected according to the following algorithm:

1. Attempt to locate a matching method or inter-type declared method without considering autoboxing, unboxing, or vararg invocations.
2. If no match is found, try again considering autoboxing and unboxing.
3. Finally try again considering both autoboxing, unboxing, and varargs.

One consequence is that a directly matching inter-type declared method will take precedence over a method declared locally in the target class but that only matches via autoboxing.

## Chapter 5. Covariance

## Covariance in Java 5

Java 5 (and hence AspectJ 5) allows you to narrow the return type in an overriding method. For example:

    		class A {
    		  public A whoAreYou() {...}
    		}

    		class B extends A {
    		  // override A.whoAreYou *and* narrow the return type.
    		  public B whoAreYou() {...}
    		}

## 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

    		A a = new A();
    		B b = new B();
    		a.whoAreYou();
    		b.whoAreYou();

The signatures for the call join point `a.whoAreYou()` are simply:

    		A A.whoAreYou()

The signatures for the call join point `b.whoAreYou()` are:

    		A A.whoAreYou()
    		B B.whoAreYou()

Following the join point matching rules given in Join Point Signatures,

call(* whoAreYou())

  Matches both calls, (since each call join point has at least one matching signature).

call(* A.whoAreYou())

  Matches both calls, (since each call join point has at least one matching signature).

call(A whoAreYou())

  Matches both calls, (since each call join point has at least one matching signature).

call(A B.whoAreYou())

  Does not match anything - neither of the call join points has a signature matched by this pattern. 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 signature pattern matches the signature `B B.whoAreYou()`. 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 since neither join point has a signature matched by this pattern.

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 modifiers of the method or constructor are matched by any modifier pattern or annotation pattern that may be present.

## Chapter 6. Varargs

## Variable-length Argument Lists in Java 5

Java 5 (and hence AspectJ 5) allows you to specify methods that take a variable number of arguments of a specified type. This is achieved using an ellipsis (...) in the method signature as shown:

    		public void foo(int i, String... strings) {
    		}

A method or constructor may take at most one variable length argument, and this must always be the last declared argument in the signature.

### Calling Methods and Constructors with variable-length arguments

A varargs method may be called with zero or more arguments in the variable argument position. For example, given the definition of `foo` above, the following calls are all legal:

        	foo(5);
        	foo(5,"One String");
        	foo(7,"One String","Two Strings");
        	foo(3,"One String","Two Strings","Three Strings");

A varargs parameter is treated as an array within the defining member. So in the body of `foo` we could write for example:

        	public void foo(int i, String... strings) {
        	  String[] someStrings = strings;
        	  // rest of method body
        	}

One consequence of this treatment of a varargs parameter as an array is that you can also call a varargs method with an array:

        	foo(7,new String[] {"One String","Two Strings"});

## Using Variable-length arguments in advice and pointcut expressions

AspectJ 5 allows variable-length arguments to be used for methods declared within aspects, and for inter-type declared methods and constructors, in accordance with the rules outlined in the previous section.

AspectJ 5 also allows variable length arguments to be matched by pointcut expressions and bound as formals in advice.

### Matching signatures based on variable length argument types

Recall from the definition of signature patterns given in the chapter on annotations (Signature Patterns), that `MethodPattern` and `ConstructorPattern` are extended to allow a `varargs` pattern in the last argument position of a method or constructor signature.

     		FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? |
    		                  OptionalParensTypePattern (',' FormalsPattern)* |
    		                  TypePattern '...'

    		FormalsPatternAfterDotDot :=
    		        OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
    		        TypePattern '...'

Method and constructor patterns are used in the `call`, `execution`, `initialization`, `preinitialization`, and `withincode` pointcut designators. Some examples of usage follow:

call(* org.xyz.*.*(int, String...))

  Matches a call join point for a call to a method defined in the `org.xyz` package, taking an `int` and a `String vararg`.

execution(* org.xyz.*.*(Integer...))

  Matches an execution join point for the execution of a method defined in the `org.xyz` package, taking an `Integer vararg`.

initialization(org.xyz.*.new((Foo || Goo)...))

  Matches the initialization join point for the construction of an object in the `org.xyz` package via a constructor taking either a variable number of `Foo` parameters or a variable number of `Goo` parameters. (This example illustrating the use of a type pattern with ...).

A variable argument parameter and an array parameter are treated as distinct signature elements, so given the method definitions:

        	void foo(String...);
        	void bar(String[]);

The pointcut `execution(* *.*(String...))` matches the execution join point for `foo`, but not `bar`. The pointcut `execution(* *.*(String[]))` matches the execution join point for `bar` but not `foo`.

### 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

    		public void foo(int i, String... strings) {
    		}

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:

    		before(int i, String[] ss) : call(* foo(int,String...)) && args(i,ss) {
    		  // varargs String... argument is accessible in advice body through ss
    		  // ...
    		}

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`.

## Chapter 7. Enumerated Types

## Enumerated Types in Java 5

Java 5 (and hence AspectJ 5) provides explicit support for enumerated types. In the simplest case, you can declare an enumerated type as follows:

          public enum ProgrammingLanguages {
           COBOL,C,JAVA,ASPECTJ
          }

Enumerated types are just classes, and they can contain method and field declarations, and may implement interfaces. Enums may only have private constructors, and may not be extended.

Enumerated types in Java 5 all implicitly extend the type `java.lang.Enum`. It is illegal to explicitly declare a subtype of this class.

## Enumerated Types in AspectJ 5

AspectJ 5 supports the declaration of enumerated types just as Java 5 does. Because of the special restrictions Java 5 places around enumerated types, AspectJ makes the following additional restrictions:

- You cannot use declare parents to change the super type of an enum.
- You cannot use declare parents to declare java.lang.Enum as the parent of any type.
- You cannot make inter-type constructor declarations on an enum.
- You cannot extend the set of values in an enum via any ITD-like construct.
- You cannot make inter-type method or field declarations on an enum.
- You cannot use declare parents to make an enum type implement an interface.

In theory, the last of these two items could be supported. However, AspectJ 5 follows the simple rule that an enum type cannot be the target of an inter-type declaration or declare parents statement. This position may be relaxed in a future version of AspectJ.

If an enum is named explicitly as the target of a declare parents statement, a compilation error will result. If an enumerated type is matched by a non-explicit type pattern used in a declare parents statement it will be ignored (and an XLint warning issued).

## Chapter 8. The pertypewithin Aspect Instantiation Model

AspectJ 5 defines a new per-clause type for aspect instantiation: `pertypewithin`. Unlike the other per-clauses, `pertypewithin` takes a type pattern:

      	PerTypeWithin := 'pertypewithin' '(' OptionalParensTypePattern ')'

When an aspect is declared using the `pertypewithin` instantiation model, one new aspect instance will be created for each type matched by the associated type pattern.

Pertypewithin aspects have `aspectOf` and `hasAspect` methods with the following signatures:

      	/**
      	 * return true if this aspect has an instance associated with
      	 * the given type.
      	 */
      	public static boolean hasAspect(Class clazz)

      	/**
      	 * return the instance associated with the given type.
      	 * Throws NoAspectBoundException if there is no such
      	 * aspect.
      	 */
      	 public static P aspectOf(Class clazz)

Where `P` is the type of the `pertypewithin` aspect.

In common with the other per-clause instantiation models, the execution of any advice declared within a `pertypewithin` aspect is conditional upon an implicit pointcut condition. In this case, that any join point be `within` the type that the executing aspect is an `aspectOf`. For example, given the aspect definition

      	 public aspect InstanceTracking pertypewithin(org.xyz..*) {

      	   private Set<WeakReference<Object>> instances = new HashSet<WeakReference<Object>>();

      	   after(Object o) returning : execution(new(..)) {
      	     instances.add(new WeakReference<Object>(o);
      	   }

      	   public Set<Object> getInstances() {
      	      Set<Object> result = new HashSet<Object>();
      	      for(WeakReference<Object> ref : instances) {
      	          if (ref.get() != null) {
      	           result.add(ref.get());
      	          }
      	      }
      	      return result;
      	   }
      	 }

Then one aspect instance will be created for each type within `org.xyz..*`. For each aspect instance, the after returning advice will match only the execution of constructors in the type that the aspect is an instance of. The net result is that the aspect tracks all known instances of each type within `org.xyz..*`. To get access to the instances, a programmer can simply write `InstanceTracking.instanceOf(org.xyz.SomeType).getInstances()`.

A `pertypewithin` aspect may optionally be declared with a single generic type parameter. In this case, for each type `T` matched by the type pattern, the aspect instance created will be of type `PerTypeWithinAspect<T>`. So the previous example could also be written as:

      	 public aspect InstanceTracking<T> pertypewithin(org.xyz..*) {

      	   private Set<WeakReference<T>> instances = new HashSet<WeakReference<T>>();

      	   after(T t) returning : execution(new(..)) {
      	     instances.add(new WeakReference<T>(t);
      	   }

      	   public Set<T> getInstances() {
      	      Set<T> result = new HashSet<T>();
      	      for(WeakReference<T> ref : instances) {
      	          if (ref.get() != null) {
      	           result.add(ref.get());
      	          }
      	      }
      	      return result;
      	   }
      	 }

The `pertypewithin` aspect instantiation model should be used when the implementation of a crosscutting concern requires that some state be maintained for each type in a set of types. To maintain state for a single type, it is easier to use a static inter-type declared field. Examples of usage include instance tracking, profiling, and the implementation of a common tracing idiom that uses one Logger per traced class.

## Chapter 9. New Reflection Interfaces

## Chapter 10. Other Changes in AspectJ 5

## Pointcuts

### Binding of formals

Binding of formals (cannot bind same formal more than once in a conjunction, can bind exactly once in each branch of a disjunction, iff the branches are mutually exclusive based on e.g. join point kind).

### Additional lint warnings

Discuss detection of common errors -> warning/error, eg. conjunction of more than one kind of join point. Differing numbers of args in method signature / args / @args / @parameters.

## Declare Soft

Describe change to only soften checked exceptions if we decide to make it.

## Appendix A. A Grammar for the AspectJ 5 Language

            === type patterns ===

            TypePattern := SimpleTypePattern |
      	                   '!' TypePattern |
      	                   '(' AnnotationPattern? TypePattern ')'
      	                   TypePattern '&&' TypePattern |
      	                   TypePattern '||' TypePattern |

            SimpleTypePattern := DottedNamePattern '+'? '[]'*

            DottedNamePattern := FullyQualifiedName RestOfNamePattern? |
      		                     '*' NotStarNamePattern?

            RestOfNamePattern := '..' DottedNamePattern |
      		                     '*' NotStarNamePattern?

            NotStarNamePattern := FullyQualifiedName RestOfNamePattern? |
      		                      '..' DottedNamePattern

            FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*

            === annotation patterns ===

            AnnotationPattern := '!'? '@' AnnotationTypePattern AnnotationPattern*

            AnnotationTypePattern := FullyQualifiedName |
                                     '(' TypePattern ')'

            === signature patterns ===

            -- field --

            FieldPattern :=
      		    AnnotationPattern? FieldModifiersPattern?
      		    TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern

            FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*

            FieldModifier := 'public' | 'private' | 'protected' | 'static' |
    		                 'transient' | 'final'

            DotOrDotDot := '.' | '..'

            SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?

            -- method --

            MethodPattern :=
      		    AnnotationPattern? MethodModifiersPattern? TypePattern
      		                       (TypePattern DotOrDotDot)? SimpleNamePattern
      		                       '(' FormalsPattern ')' ThrowsPattern?

            MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern*

            MethodModifier := 'public' | 'private' | 'protected' | 'static' |
    		                  'synchronized' | 'final'

            FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? |
    		                  OptionalParensTypePattern (',' FormalsPattern)* |
    		                  TypePattern '...'

            FormalsPatternAfterDotDot :=
    		        OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
    		        TypePattern '...'

            ThrowsPattern := 'throws' TypePatternList

            TypePatternList := TypePattern (',' TypePattern)*

            -- constructor --

            ConstructorPattern :=
      		    AnnotationPattern? ConstructorModifiersPattern?
      		                       (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
      		                       ThrowsPattern?

            ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*

            ConstructorModifier := 'public' | 'private' | 'protected'

            === Pointcuts ===

            PointcutPrimitive :=
                        Call | Execution | Get | Set | Handler |
                        Initialization | PreInitialization |
                        StaticInitialization | AdviceExecution |
                        This | Target | Args | CFlow | CFlowBelow |
                        Within | WithinCode | If |
                        AnnotationPointcut

            AnnotationPointcut := AtAnnotation | AtThis | AtTarget |
                                  AtWithin | AtWithinCode | AtArgs

            Call := 'call' '(' MethodOrConstructorPattern ')'

            MethodOrConstructorPattern := MethodPattern | ConstructorPattern

            Execution := 'execution' '(' MethodOrConstructorPattern ')'

            Get := 'get' '(' FieldPattern ')'
            Set := 'set' '(' FieldPattern ')'
            Handler := 'handler' '(' OptionalParensTypePattern ')'
            Initialization := 'initialization' '(' ConstructorPattern ')'
            PreInitialization := 'preinitialization' '(' ConstructorPattern ')'
            StaticInitialization := 'staticinitialization' '(' OptionalParensTypePattern ')'
            AdviceExecution := 'adviceexecution' '(' ')'
            This := 'this' '(' TypeOrIdentifier ')'
            Target := 'target' '(' TypeOrIdentifier ')'
            Args := 'args' '(' FormalsOrIdentifiersPattern ')'
            CFlow := 'cflow' '(' Pointcut ')'
            CFlowBelow := 'cflowbelow' '(' Pointcut ')'
            Within := 'within' '(' OptionalParensTypePattern ')'
            WithinCode := 'withincode' '(' OptionalParensTypePattern ')'
            If := 'if' '(' BooleanJavaExpression ')'

            TypeOrIdentifier := FullyQualifiedName ('[' ']')* | Identifier
            Identifier := JavaIdentifierChar+

            FormalsOrIdentifiersPattern :=
                              '..' (',' FormalsOrIdentifiersPatternAfterDotDot)? |
    		                  TypeOrIdentifier (',' FormalsOrIdentifiersPattern)* |
    		                  '*' (',' FormalsOrIdentifiersPattern)*

            FormalsOrIdentifiersPatternAfterDotDot :=
    		                  TypeOrIdentifier (',' FormalsOrIdentifiersPatternAfterDotDot)* |
    		                  '*' (',' FormalsOrIdentifiersPatternAfterDotDot)*

            AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
            AtThis := '@this' '(' AnnotationOrIdentifer ')'
            AtTarget := '@target' '(' AnnotationOrIdentifier ')'
            AtWithin := '@within' '(' AnnotationOrIdentifier ')'
            AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'

            AnnotationOrIdentifier := '@' FullyQualifiedName | Identifier

            AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'

            AnnotationsOrIdentifiersPattern :=
                              '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
                              AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
                              '*' (',' AnnotationsOrIdentifiersPattern)*

            AnnotationsOrIdentifiersPatternAfterDotDot :=
    		                  AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
    		                  '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*

            PointcutDeclaration := PointcutModifiers? 'pointcut' Identifier Formals
                                   ':' PointcutExpression

            PointcutModifiers := PointcutModifier*

            PointcutModifier :=  'public' | 'private' | 'protected' | 'abstract'

            Formals := '(' ParamList? ')'
            ParamList := FullyQualifiedName Identifier (',' ParamList)*

            ReferencePointcut := (FullyQualifiedName '.')? Identifier Formals

            PointcutExpression := (PointcutPrimitive | ReferencePointcut) |
                                  '!' PointcutExpression |
                                  '(' PointcutExpression ')' |
                                  PointcutExpression '&&' PointcutExpression |
                                  PointcutExpression '||' PointcutExpression

            === Advice ===

            to be written...

            === Inter-type Declarations ===

            to be written...

            === Declare Statements ===

            to be written...

            === Aspects ===

            to be written...