Bläddra i källkod

support for annotations on ITDs, and declare annotation

tags/V1_5_0M2
acolyer 19 år sedan
förälder
incheckning
b4574b90b2
23 ändrade filer med 605 tillägg och 5 borttagningar
  1. 52
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareAnnotationDeclaration.java
  2. 10
    1
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java
  3. 11
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoTokens.java
  4. 0
    1
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java
  5. 1
    1
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java
  6. 14
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/DeclarationFactory.java
  7. 27
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java
  8. 23
    0
      tests/java5/annotations/aspectMembers/a/AnnotatedAspect.aj
  9. 22
    0
      tests/java5/annotations/aspectMembers/a/AnnotatedAspect02.aj
  10. 26
    0
      tests/java5/annotations/aspectMembers/a/AnnotatedAspect03.aj
  11. 15
    0
      tests/java5/annotations/aspectMembers/a/AnnotatedAspect04.aj
  12. 29
    0
      tests/java5/annotations/aspectMembers/a/Annotations.java
  13. 17
    0
      tests/java5/annotations/aspectMembers/a/Foo.java
  14. 15
    0
      tests/java5/annotations/declare/BasicParseTest.aj
  15. 3
    0
      tests/java5/pseudoKeywords/MethodCalledAround.java
  16. 3
    0
      tests/java5/pseudoKeywords/MethodCalledAroundAspect.java
  17. 8
    0
      tests/src/org/aspectj/systemtest/ajc150/Ajc150Tests.java
  18. 42
    0
      tests/src/org/aspectj/systemtest/ajc150/Annotations.java
  19. 91
    1
      tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
  20. 3
    0
      weaver/src/org/aspectj/weaver/CrosscuttingMembers.java
  21. 3
    0
      weaver/src/org/aspectj/weaver/patterns/Declare.java
  22. 143
    0
      weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java
  23. 47
    1
      weaver/src/org/aspectj/weaver/patterns/PatternParser.java

+ 52
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareAnnotationDeclaration.java Visa fil

@@ -0,0 +1,52 @@
/* *******************************************************************
* Copyright (c) 2005 IBM Corporation.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Common Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* Adrian Colyer initial implementation
* ******************************************************************/

package org.aspectj.ajdt.internal.compiler.ast;

import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.aspectj.weaver.patterns.DeclareAnnotation;

public class DeclareAnnotationDeclaration extends DeclareDeclaration {
private Annotation annotation;
public DeclareAnnotationDeclaration(CompilationResult result, DeclareAnnotation symbolicDeclare, Annotation annotation) {
super(result,symbolicDeclare);
this.annotation = annotation;
addAnnotation(annotation);
symbolicDeclare.setAnnotationString(annotation.toString());
symbolicDeclare.setAnnotationMethod(new String(selector));
}
public Annotation getDeclaredAnnotation() {
return annotation;
}
/* (non-Javadoc)
* @see org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration#shouldDelegateCodeGeneration()
*/
protected boolean shouldDelegateCodeGeneration() {
return true; // declare annotation needs a method to be written out.
}
private void addAnnotation(Annotation ann) {
if (this.annotations == null) {
this.annotations = new Annotation[1];
} else {
Annotation[] old = this.annotations;
this.annotations = new Annotation[old.length + 1];
System.arraycopy(old,0,this.annotations,1,old.length);
}
this.annotations[0] = ann;
}
}

+ 10
- 1
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/DeclareDeclaration.java Visa fil

@@ -48,14 +48,23 @@ public class DeclareDeclaration extends AjMethodDeclaration {


/**
* A pointcut declaration exists in a classfile only as an attibute on the
* A declare declaration exists in a classfile only as an attibute on the
* class. Unlike advice and inter-type declarations, it has no corresponding
* method.
* **AMC** changed the above policy in the case of declare annotation, which uses a
* corresponding method as the anchor for the declared annotation
*/
public void generateCode(ClassScope classScope, ClassFile classFile) {
classFile.extraAttributes.add(new EclipseAttributeAdapter(new AjAttribute.DeclareAttribute(declareDecl)));
if (shouldDelegateCodeGeneration()) {
super.generateCode(classScope,classFile);
}
return;
}
protected boolean shouldDelegateCodeGeneration() {
return false;
}

public void parseStatements(
Parser parser,

+ 11
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/PseudoTokens.java Visa fil

@@ -139,6 +139,17 @@ public class PseudoTokens extends ASTNode {
}
}
public Declare parseAnnotationDeclare(Parser parser) {
PatternParser patternParser = new PatternParser(tokenSource);
try {
Declare ret = patternParser.parseDeclareAnnotation();
checkEof(parser);
return ret;
} catch (ParserException pe) {
reportError(parser, pe);
return null;
} }
public void postParse(TypeDeclaration typeDec, MethodDeclaration enclosingDec) {
for (int i=0, len=tokens.length; i < len; i++) {

+ 0
- 1
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeFieldBinding.java Visa fil

@@ -100,7 +100,6 @@ public class InterTypeFieldBinding extends FieldBinding {
return false;
}


public SyntheticMethodBinding getAccessMethod(boolean isReadAccess) {
if (isReadAccess) return reader;
else return writer;

+ 1
- 1
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/InterTypeMethodBinding.java Visa fil

@@ -56,7 +56,7 @@ public class InterTypeMethodBinding extends MethodBinding {

}
//XXX this is identical to InterTypeFieldBinding
public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
scope.compilationUnitScope().recordTypeReference(declaringClass);

+ 14
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/parser/DeclarationFactory.java Visa fil

@@ -16,6 +16,7 @@ import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.AjConstructorDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.AjMethodDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.DeclareAnnotationDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.IfPseudoToken;
import org.aspectj.ajdt.internal.compiler.ast.InterTypeConstructorDeclaration;
@@ -30,8 +31,10 @@ import org.aspectj.ajdt.internal.compiler.ast.PseudoTokens;
import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.patterns.Declare;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
@@ -199,6 +202,17 @@ public class DeclarationFactory implements IDeclarationFactory {
return new DeclareDeclaration(result,declare);
}

/* (non-Javadoc)
* @see org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser.IDeclarationFactory#createDeclareAnnotationDeclaration(org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult, org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode, org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation, org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser)
*/
public MethodDeclaration createDeclareAnnotationDeclaration(
CompilationResult result, ASTNode pseudoTokens,
Annotation annotation, Parser parser) {
DeclareAnnotation declare = (DeclareAnnotation) ((PseudoTokens)pseudoTokens).parseAnnotationDeclare(parser);
DeclareAnnotationDeclaration decl = new DeclareAnnotationDeclaration(result,declare,annotation);
return decl;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.parser.Parser.IDeclarationFactory#createInterTypeFieldDeclaration(org.eclipse.jdt.internal.compiler.CompilationResult, org.eclipse.jdt.internal.compiler.ast.TypeReference)
*/

+ 27
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/problem/AjProblemReporter.java Visa fil

@@ -26,12 +26,15 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.aspectj.org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.aspectj.util.FuzzyBoolean;
@@ -216,6 +219,30 @@ public class AjProblemReporter extends ProblemReporter {
super.abstractMethodMustBeImplemented(type, abstractMethod);
}

/* (non-Javadoc)
* @see org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter#disallowedTargetForAnnotation(org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation)
*/
public void disallowedTargetForAnnotation(Annotation annotation) {
// if the annotation's recipient is an ITD, it might be allowed after all...
if (annotation.recipient instanceof MethodBinding) {
MethodBinding binding = (MethodBinding) annotation.recipient;
String name = new String(binding.selector);
if (name.startsWith("ajc$")) {
long metaTagBits = annotation.resolvedType.getAnnotationTagBits(); // could be forward reference
if (name.indexOf("interField") != -1) {
if ((metaTagBits & TagBits.AnnotationForField) != 0) return;
} else if (name.indexOf("InterConstructor") != -1) {
if ((metaTagBits & TagBits.AnnotationForConstructor) != 0) return;
} else if (name.indexOf("interMethod") != -1) {
if ((metaTagBits & TagBits.AnnotationForMethod) != 0) return;
}
}
}
// not our special case, report the problem...
super.disallowedTargetForAnnotation(annotation);
}
public void handle(
int problemId,
String[] problemArguments,

+ 23
- 0
tests/java5/annotations/aspectMembers/a/AnnotatedAspect.aj Visa fil

@@ -0,0 +1,23 @@
package a;

@TypeAnnotation
public aspect AnnotatedAspect {
@FieldAnnotation int foo = 5;
@MethodAnnotation int getFoo() { return foo; }
@ConstructorAnnotation
public AnnotatedAspect() {}
}

aspect VerifyAnnotations {
declare warning : set(@FieldAnnotation * *) : "annotated field";
declare warning : execution(@MethodAnnotation * *(..)) : "annotated method";
declare warning : execution(@ConstructorAnnotation new(..)) : "annotated constructor";
declare warning : staticinitialization(@TypeAnnotation *) : "annotated type";
}

+ 22
- 0
tests/java5/annotations/aspectMembers/a/AnnotatedAspect02.aj Visa fil

@@ -0,0 +1,22 @@
package a;

@MethodAnnotation
public aspect AnnotatedAspect02 {
@TypeAnnotation int goo;
@FieldAnnotation int getGoo() { return goo; }
@AnnotationAnnotation AnnotatedAspect02() { goo = 5; }
}

aspect VerifyAnnotations {
declare warning : set(@FieldAnnotation * *) : "annotated field";
declare warning : execution(@MethodAnnotation * *(..)) : "annotated method";
declare warning : execution(@ConstructorAnnotation new(..)) : "annotated constructor";
declare warning : staticinitialization(@TypeAnnotation *) : "annotated type";
}

+ 26
- 0
tests/java5/annotations/aspectMembers/a/AnnotatedAspect03.aj Visa fil

@@ -0,0 +1,26 @@
package a;

@TypeAnnotation
public aspect AnnotatedAspect03 {
@FieldAnnotation int foo = 5;
@FieldAnnotation private int ITDMe.goo = 3;
@MethodAnnotation private int ITDMe.getGoo() { return goo; }
@ConstructorAnnotation public ITDMe.new(int x) { goo = x; }
}

class ITDMe {}

aspect VerifyAnnotations {
declare warning : set(@FieldAnnotation * *) : "annotated field";
declare warning : execution(@MethodAnnotation * *(..)) : "annotated method";
declare warning : execution(@ConstructorAnnotation new(..)) : "annotated constructor";
declare warning : staticinitialization(@TypeAnnotation *) : "annotated type";
}

+ 15
- 0
tests/java5/annotations/aspectMembers/a/AnnotatedAspect04.aj Visa fil

@@ -0,0 +1,15 @@
package a;

@TypeAnnotation
public aspect AnnotatedAspect04 {
@ConstructorAnnotation private int ITDMe.goo = 3;
@FieldAnnotation private int ITDMe.getGoo() { return goo; }
@TypeAnnotation public ITDMe.new(int x) { goo = x; }
@MethodAnnotation int ITDMe.foo = 2; // known limitation - no warning
}

class ITDMe {}

+ 29
- 0
tests/java5/annotations/aspectMembers/a/Annotations.java Visa fil

@@ -0,0 +1,29 @@
package a;

import java.lang.annotation.*;

@Target(ElementType.ANNOTATION_TYPE)
@interface AnnotationAnnotation {}

@Target(ElementType.CONSTRUCTOR)
@interface ConstructorAnnotation {}

@Target(ElementType.FIELD)
@interface FieldAnnotation {}

@Target(ElementType.LOCAL_VARIABLE)
@interface LocalVarAnnotation {}

@Target(ElementType.METHOD)
@interface MethodAnnotation {}

@Target(ElementType.PACKAGE)
@interface PackageAnnotation {}

@Target(ElementType.PARAMETER)
@interface ParameterAnnotation {}

@Target(ElementType.TYPE)
@interface TypeAnnotation {}

@interface AnyAnnotation {}

+ 17
- 0
tests/java5/annotations/aspectMembers/a/Foo.java Visa fil

@@ -0,0 +1,17 @@
package a;

/**
* @author colyer
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
@TypeAnnotation
public class Foo {

@FieldAnnotation int foo;
@MethodAnnotation int getFoo() { return foo; }
@MethodAnnotation int goo;
}

+ 15
- 0
tests/java5/annotations/declare/BasicParseTest.aj Visa fil

@@ -0,0 +1,15 @@
public aspect BasicParseTest {
declare warning : set(* *) : "setting";
declare @field: * foo : @MyAnnotation;
declare @method: * foo() : @MyAnnotation;
declare @constructor: Foo*.new(..) : @MyAnnotation;
declare @type: org.xyz..* : @MyAnnotation;
}

@interface MyAnnotation {}

+ 3
- 0
tests/java5/pseudoKeywords/MethodCalledAround.java Visa fil

@@ -0,0 +1,3 @@
public class MethodCalledAround {
void around() { ; }
}

+ 3
- 0
tests/java5/pseudoKeywords/MethodCalledAroundAspect.java Visa fil

@@ -0,0 +1,3 @@
public aspect MethodCalledAroundAspect {
void around() { ; }
}

+ 8
- 0
tests/src/org/aspectj/systemtest/ajc150/Ajc150Tests.java Visa fil

@@ -45,6 +45,14 @@ public class Ajc150Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
}
}
public void test_aroundMethod() {
runTest("method called around in class");
}
public void test_aroundMethodAspect() {
runTest("method called around in aspect");
}
public void test_ambiguousBindingsDetection() {
runTest("Various kinds of ambiguous bindings");
}

+ 42
- 0
tests/src/org/aspectj/systemtest/ajc150/Annotations.java Visa fil

@@ -60,6 +60,48 @@ public class Annotations extends XMLBasedAjcTestCase {
}
}
public void testAnnotatedAnnotations() {
runTest("annotated annotations (@Target)");
}
public void testSimpleAnnotatedAspectMembers() {
runTest("simple annotated aspect members");
}
public void testAnnotatedAspectMembersWithWrongAnnotationType() {
runTest("simple annotated aspect members with bad target");
}
// more implementation work needed before this test passes
// public void testAnnotatedITDs() {
// runTest("annotated itds");
// }

public void testAnnotatedITDsWithWrongAnnotationType() {
runTest("annotated itds with bad target");
}
// these tests to be completed
// public void testAnnotatedAdvice() {
// runTest("annotated advice");
// }
//
// public void testAnnotatedAdviceWithWrongAnnotationType() {
// runTest("annotated advice with bad target");
// }
//
// public void testAnnotatedPointcut() {
// runTest("annotated pointcut");
// }
//
// public void testAnnotatedDeclareStatements() {
// runTest("annotated declare statements");
// }
public void testBasicDeclareAnnotation() {
runTest("basic declare annotation parse test");
}
// helper methods.....
public SyntheticRepository createRepos(File cpentry) {

+ 91
- 1
tests/src/org/aspectj/systemtest/ajc150/ajc150.xml Visa fil

@@ -26,6 +26,19 @@
</compile>
<run class="C"/>
</ajc-test>

<ajc-test dir="java5/pseudoKeywords"
title="method called around in class">
<compile files="MethodCalledAround.java">
</compile>
</ajc-test>

<ajc-test dir="java5/pseudoKeywords"
title="method called around in aspect">
<compile files="MethodCalledAroundAspect.java">
<message kind="error" line="2"/>
</compile>
</ajc-test>
<ajc-test dir="decp" pr="80249" title="Order of types passed to compiler determines weaving behavior">
<compile files="A.java,B.java,AspectX.java"/>
@@ -912,7 +925,84 @@
<message kind="weave" text="Type 'SimpleVarargs' (SimpleVarargs.java:27) advised by before advice from 'VarargsAspect06' (VarargsAspect06.aj:3)"/>
</compile>
</ajc-test>

<!-- ======================================================================================= -->
<!-- annotated aspect members -->
<!-- ======================================================================================= -->

<ajc-test dir="java5/annotations/aspectMembers" title="annotated annotations (@Target)">
<compile files="a/Annotations.java,a/Foo.java" options="-1.5">
<message kind="error" line="16" text="The annotation @MethodAnnotation is disallowed for this location"/>
</compile>
</ajc-test>

<ajc-test dir="java5/annotations/aspectMembers" title="simple annotated aspect members">
<compile files="a/Annotations.java,a/AnnotatedAspect.aj" options="-1.5">
<message kind="warning" line="4" text="annotated type"/>
<message kind="warning" line="6" text="annotated field"/>
<message kind="warning" line="8" text="annotated method"/>
<message kind="warning" line="11" text="annotated constructor"/>
</compile>
</ajc-test>

<ajc-test dir="java5/annotations/aspectMembers" title="simple annotated aspect members with bad target">
<compile files="a/Annotations.java,a/AnnotatedAspect02.aj" options="-1.5">
<message kind="error" line="3" text="The annotation @MethodAnnotation is disallowed for this location"/>
<message kind="error" line="6" text="The annotation @TypeAnnotation is disallowed for this location"/>
<message kind="error" line="8" text="The annotation @FieldAnnotation is disallowed for this location"/>
<message kind="error" line="10" text="The annotation @AnnotationAnnotation is disallowed for this location"/>
</compile>
</ajc-test>

<ajc-test dir="java5/annotations/aspectMembers" title="annotated itds">
<compile files="a/Annotations.java,a/AnnotatedAspect03.aj" options="-1.5">
<message kind="warning" line="4" text="annotated type"/>
<message kind="warning" line="6" text="annotated field"/>
<message kind="warning" line="8" text="annotated field"/>
<message kind="warning" line="10" text="annotated method"/>
<message kind="warning" line="12" text="annotated constructor"/>
</compile>
</ajc-test>

<ajc-test dir="java5/annotations/aspectMembers" title="annotated itds with bad target">
<compile files="a/Annotations.java,a/AnnotatedAspect04.aj" options="-1.5">
<message kind="error" line="6" text="The annotation @ConstructorAnnotation is disallowed for this location"/>
<message kind="error" line="8" text="The annotation @FieldAnnotation is disallowed for this location"/>
<message kind="error" line="10" text="The annotation @TypeAnnotation is disallowed for this location"/>
<!-- known limitation...
<message kind="error" line="12" text="The annotation @MethodAnnotation is disallowed for this location"/>
-->
</compile>
</ajc-test>

<ajc-test dir="java5/annotations/aspectMembers" title="annotated advice">
<compile files="a/Annotations.java,a/AnnotatedAspect05.aj" options="-1.5">
</compile>
</ajc-test>

<ajc-test dir="java5/annotations/aspectMembers" title="annotated advice with bad target">
<compile files="a/Annotations.java,a/AnnotatedAspect06.aj" options="-1.5">
</compile>
</ajc-test>

<ajc-test dir="java5/annotations/aspectMembers" title="annotated pointcut">
<compile files="a/Annotations.java,a/AnnotatedAspect07.aj" options="-1.5">
</compile>
</ajc-test>

<ajc-test dir="java5/annotations/aspectMembers" title="annotated declare statements">
<compile files="a/Annotations.java,a/AnnotatedAspect08.aj" options="-1.5">
</compile>
</ajc-test>

<!-- ======================================================================================= -->
<!-- declare annotation -->
<!-- ======================================================================================= -->

<ajc-test dir="java5/annotations/declare" title="basic declare annotation parse test">
<compile files="BasicParseTest.aj" options="-1.5">
</compile>
</ajc-test>

</suite>


+ 3
- 0
weaver/src/org/aspectj/weaver/CrosscuttingMembers.java Visa fil

@@ -19,6 +19,7 @@ import java.util.Iterator;
import java.util.List;

import org.aspectj.weaver.patterns.Declare;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
import org.aspectj.weaver.patterns.DeclareParents;
import org.aspectj.weaver.patterns.DeclarePrecedence;
@@ -114,6 +115,8 @@ public class CrosscuttingMembers {
m.pointcut = concretePointcut;
declareSofts.add(new DeclareSoft(d.getException(), concretePointcut));
addConcreteShadowMunger(m);
} else if (declare instanceof DeclareAnnotation) {
System.err.println("Need to implement CrosscuttingMembers.addDeclare for annotations");
} else {
throw new RuntimeException("unimplemented");
}

+ 3
- 0
weaver/src/org/aspectj/weaver/patterns/Declare.java Visa fil

@@ -23,6 +23,7 @@ public abstract class Declare extends PatternNode {
public static final byte PARENTS = 2;
public static final byte SOFT = 3;
public static final byte DOMINATES = 4;
public static final byte ANNOTATION = 5;

public static Declare read(VersionedDataInputStream s, ISourceContext context) throws IOException {
byte kind = s.readByte();
@@ -35,6 +36,8 @@ public abstract class Declare extends PatternNode {
return DeclareParents.read(s, context);
case SOFT:
return DeclareSoft.read(s, context);
case ANNOTATION:
return DeclareAnnotation.read(s,context);
default:
throw new RuntimeException("unimplemented");
}

+ 143
- 0
weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java Visa fil

@@ -0,0 +1,143 @@
/* *******************************************************************
* Copyright (c) 2005 IBM Corporation
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Common Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* Adrian Colyer initial implementation
* ******************************************************************/
package org.aspectj.weaver.patterns;

import java.io.DataOutputStream;
import java.io.IOException;

import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.VersionedDataInputStream;

public class DeclareAnnotation extends Declare {
private String kind;
private TypePattern typePattern;
private SignaturePattern sigPattern;
private String annotationMethod = "unknown";
private String annotationString = "@<annotation>";

public DeclareAnnotation(String kind, TypePattern typePattern) {
this.typePattern = typePattern;
this.kind = kind;
}
public DeclareAnnotation(String kind, SignaturePattern sigPattern) {
this.sigPattern = sigPattern;
this.kind = kind;
}
public String toString() {
StringBuffer ret = new StringBuffer();
ret.append("declare @");
ret.append(kind);
ret.append(" : ");
ret.append(typePattern != null ? typePattern.toString() : sigPattern.toString());
ret.append(" : ");
ret.append(annotationString);
return ret.toString();
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Declare#resolve(org.aspectj.weaver.patterns.IScope)
*/
public void resolve(IScope scope) {
if (typePattern != null) typePattern.resolve(scope.getWorld());
}

/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.Declare#isAdviceLike()
*/
public boolean isAdviceLike() {
return false;
}

public void setAnnotationString(String as) {
this.annotationString = as;
}
public void setAnnotationMethod(String methName){
this.annotationMethod = methName;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (!(obj instanceof DeclareAnnotation)) return false;
DeclareAnnotation other = (DeclareAnnotation) obj;
if (!this.kind.equals(other.kind)) return false;
if (!this.annotationString.equals(other.annotationString)) return false;
if (!this.annotationMethod.equals(other.annotationMethod)) return false;
if (this.typePattern != null) {
if (!typePattern.equals(other.typePattern)) return false;
}
if (this.sigPattern != null) {
if (!sigPattern.equals(other.sigPattern)) return false;
}
return true;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
int result = 19;
result = 37*result + kind.hashCode();
result = 37*result + annotationString.hashCode();
result = 37*result + annotationMethod.hashCode();
if (typePattern != null) result = 37*result + typePattern.hashCode();
if (sigPattern != null) result = 37*result + sigPattern.hashCode();
return result;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
*/
public void write(DataOutputStream s) throws IOException {
s.writeByte(Declare.ANNOTATION);
s.writeUTF(kind);
s.writeUTF(annotationString);
s.writeUTF(annotationMethod);
if (typePattern != null) typePattern.write(s);
if (sigPattern != null) sigPattern.write(s);
writeLocation(s);
}

/**
* @param s
* @param context
* @return
* @throws IOException
*/
public static Declare read(VersionedDataInputStream s,
ISourceContext context) throws IOException {
DeclareAnnotation ret = null;
String kind = s.readUTF();
String annotationString = s.readUTF();
String annotationMethod = s.readUTF();
TypePattern tp = null;
SignaturePattern sp = null;
if (kind.equals("type")) {
tp = TypePattern.read(s,context);
ret = new DeclareAnnotation(kind,tp);
} else {
sp = SignaturePattern.read(s,context);
ret = new DeclareAnnotation(kind,sp);
}
ret.setAnnotationString(annotationString);
ret.setAnnotationMethod(annotationMethod);
ret.readLocation(context,s);
return ret;
}
}

+ 47
- 1
weaver/src/org/aspectj/weaver/patterns/PatternParser.java Visa fil

@@ -101,7 +101,6 @@ public class PatternParser {
String kind = parseIdentifier();
eat(":");
Declare ret;
//XXX beta add soft, dominates
if (kind.equals("error")) {
ret = parseErrorOrWarning(true);
} else if (kind.equals("warning")) {
@@ -122,6 +121,53 @@ public class PatternParser {
ret.setLocation(sourceContext, startPos, endPos);
return ret;
}
public Declare parseDeclareAnnotation() {
int startPos = tokenSource.peek().getStart();
eatIdentifier("declare");
eat("@");
String kind = parseIdentifier();
eat(":");
Declare ret;
if (kind.equals("type")) {
ret = parseDeclareAtType();
} else if (kind.equals("method")) {
ret = parseDeclareAtMethod(true);
} else if (kind.equals("field")) {
ret = parseDeclareAtField();
} else if (kind.equals("constructor")) {
ret = parseDeclareAtMethod(false);
} else {
throw new ParserException("expected one of type, method, field, constructor",
tokenSource.peek(-1));
}
eat(";");
int endPos = tokenSource.peek(-1).getEnd();
ret.setLocation(sourceContext, startPos, endPos);
return ret;
}
public DeclareAnnotation parseDeclareAtType() {
return new DeclareAnnotation("type",parseTypePattern());
}

public DeclareAnnotation parseDeclareAtMethod(boolean isMethod) {
SignaturePattern sp = parseMethodOrConstructorSignaturePattern();
boolean isConstructorPattern = (sp.getKind() == Member.CONSTRUCTOR);
if (isMethod && isConstructorPattern) {
throw new ParserException("method signature pattern",tokenSource.peek(-1));
}
if (!isMethod && !isConstructorPattern) {
throw new ParserException("constructor signature pattern",tokenSource.peek(-1));
}
return new DeclareAnnotation("method",sp); // sp itself differentiates...
}

public DeclareAnnotation parseDeclareAtField() {
return new DeclareAnnotation("field",parseFieldSignaturePattern());
}

public DeclarePrecedence parseDominates() {
List l = new ArrayList();

Laddar…
Avbryt
Spara