Преглед изворни кода

big refactoring

refactoring
aclement пре 16 година
родитељ
комит
209f568383
100 измењених фајлова са 3118 додато и 2129 уклоњено
  1. 87
    0
      weaver/rewrite.txt
  2. 4
    3
      weaver/src/org/aspectj/weaver/AdviceKind.java
  3. 8
    2
      weaver/src/org/aspectj/weaver/AjAttribute.java
  4. 1
    3
      weaver/src/org/aspectj/weaver/AjcMemberMaker.java
  5. 2
    1
      weaver/src/org/aspectj/weaver/AnnotatedElement.java
  6. 23
    0
      weaver/src/org/aspectj/weaver/AnnotationAJ.java
  7. 21
    11
      weaver/src/org/aspectj/weaver/AnnotationX.java
  8. 186
    0
      weaver/src/org/aspectj/weaver/ArrayReferenceType.java
  9. 3
    2
      weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java
  10. 0
    29
      weaver/src/org/aspectj/weaver/BetaException.java
  11. 4
    0
      weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java
  12. 19
    0
      weaver/src/org/aspectj/weaver/CrosscuttingMembers.java
  13. 0
    3
      weaver/src/org/aspectj/weaver/CrosscuttingMembersSet.java
  14. 58
    0
      weaver/src/org/aspectj/weaver/CustomMungerFactory.java
  15. 21
    24
      weaver/src/org/aspectj/weaver/JoinPointSignature.java
  16. 3
    0
      weaver/src/org/aspectj/weaver/Lint.java
  17. 26
    78
      weaver/src/org/aspectj/weaver/Member.java
  18. 53
    244
      weaver/src/org/aspectj/weaver/MemberImpl.java
  19. 37
    0
      weaver/src/org/aspectj/weaver/MemberKind.java
  20. 9
    10
      weaver/src/org/aspectj/weaver/NameMangler.java
  21. 9
    0
      weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java
  22. 12
    1
      weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java
  23. 29
    6
      weaver/src/org/aspectj/weaver/ReferenceType.java
  24. 2
    2
      weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java
  25. 17
    1
      weaver/src/org/aspectj/weaver/ResolvedMember.java
  26. 115
    13
      weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java
  27. 97
    10
      weaver/src/org/aspectj/weaver/ResolvedType.java
  28. 16
    0
      weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
  29. 36
    2
      weaver/src/org/aspectj/weaver/Shadow.java
  30. 3
    4
      weaver/src/org/aspectj/weaver/ShadowMunger.java
  31. 2
    3
      weaver/src/org/aspectj/weaver/TypeFactory.java
  32. 1
    1
      weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java
  33. 9
    6
      weaver/src/org/aspectj/weaver/UnresolvedType.java
  34. 4
    0
      weaver/src/org/aspectj/weaver/WeaverMessages.java
  35. 0
    84
      weaver/src/org/aspectj/weaver/WeaverMetrics.java
  36. 1
    1
      weaver/src/org/aspectj/weaver/WeaverStateInfo.java
  37. 66
    11
      weaver/src/org/aspectj/weaver/World.java
  38. 2
    1
      weaver/src/org/aspectj/weaver/XlintDefault.properties
  39. 6
    6
      weaver/src/org/aspectj/weaver/ast/Not.java
  40. 5
    6
      weaver/src/org/aspectj/weaver/ast/Var.java
  41. 59
    102
      weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java
  42. 201
    128
      weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
  43. 16
    16
      weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java
  44. 11
    14
      weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
  45. 55
    25
      weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java
  46. 4
    0
      weaver/src/org/aspectj/weaver/bcel/BcelCflowCounterFieldAdder.java
  47. 30
    29
      weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
  48. 2
    4
      weaver/src/org/aspectj/weaver/bcel/BcelField.java
  49. 7
    5
      weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java
  50. 115
    21
      weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
  51. 8
    15
      weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
  52. 1
    1
      weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java
  53. 92
    73
      weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
  54. 69
    13
      weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
  55. 59
    15
      weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
  56. 4
    62
      weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
  57. 47
    47
      weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
  58. 211
    107
      weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
  59. 13
    1
      weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java
  60. 4
    2
      weaver/src/org/aspectj/weaver/bcel/UnwovenClassFileWithThirdPartyManagedBytecode.java
  61. 37
    61
      weaver/src/org/aspectj/weaver/bcel/Utility.java
  62. 13
    0
      weaver/src/org/aspectj/weaver/loadtime/IWeavingContext.java
  63. 3
    1
      weaver/src/org/aspectj/weaver/ltw/LTWWorld.java
  64. 0
    22
      weaver/src/org/aspectj/weaver/ltw/LTWeaver.java
  65. 18
    2
      weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java
  66. 11
    29
      weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java
  67. 55
    0
      weaver/src/org/aspectj/weaver/patterns/AnyAnnotationTypePattern.java
  68. 2
    2
      weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java
  69. 1
    0
      weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java
  70. 2
    2
      weaver/src/org/aspectj/weaver/patterns/BindingAnnotationTypePattern.java
  71. 10
    35
      weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java
  72. 165
    28
      weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java
  73. 13
    2
      weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
  74. 16
    1
      weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java
  75. 18
    1
      weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java
  76. 0
    512
      weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java
  77. 150
    36
      weaver/src/org/aspectj/weaver/patterns/PatternParser.java
  78. 0
    2
      weaver/src/org/aspectj/weaver/patterns/PointcutRewriter.java
  79. 41
    15
      weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
  80. 13
    2
      weaver/src/org/aspectj/weaver/patterns/TypePattern.java
  81. 23
    3
      weaver/src/org/aspectj/weaver/patterns/TypePatternList.java
  82. 213
    13
      weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java
  83. 3
    3
      weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
  84. 0
    40
      weaver/src/org/aspectj/weaver/raw types.txt
  85. 7
    0
      weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java
  86. 10
    7
      weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java
  87. 32
    4
      weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java
  88. 1
    1
      weaver/src/org/aspectj/weaver/tools/CommonsTraceFactory.java
  89. 2
    1
      weaver/src/org/aspectj/weaver/tools/FuzzyBoolean.java
  90. 1
    0
      weaver/src/org/aspectj/weaver/tools/PointcutParser.java
  91. 41
    28
      weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java
  92. 0
    6
      weaver/src/org/aspectj/weaver/tools/package.html
  93. 4
    0
      weaver/src/org/aspectj/weaver/weaver-messages.properties
  94. 14
    14
      weaver/testsrc/org/aspectj/weaver/MemberTestCase.java
  95. 162
    0
      weaver/testsrc/org/aspectj/weaver/TestUtils.java
  96. 23
    0
      weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java
  97. 1
    1
      weaver/testsrc/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java
  98. 7
    6
      weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java
  99. 1
    1
      weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java
  100. 0
    0
      weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java

+ 87
- 0
weaver/rewrite.txt Прегледај датотеку

@@ -0,0 +1,87 @@
Rewritten...

[bcel] hundreds of classes removed, one class now represents groups of instructions rather than one class per instruction
[bcel] verifier packaged separately purely for use by AspectJ tests, not delivered in aspectj packages now
[weaver] optimized KindedAnnotationAccessVar - renamed to AnnotationAccessVar
[weaver] simplified member/resolvedmember hierarchy - still more to do, trying to remove need for casts, we should *know* what we
are dealing with at each point

todo:

[weaver]
[bcel] remove notion of Gens entirely (LineNumberGen/LocalVariableGen) and switch fully to lighter way tags
[weaver] activate 'assertGoodBody()' code through command line option to catch bugs in the field
[weaver] is reweavable turned off when LTW?

measure performance - lot of hash table things used to keep types lightweight unless they need the extra data - might be a better way?
OPTIMIZE task tag marks places noticed on the way through where we could do better

hierarchies to attack:
ASTNode
UnresolvedType (messy...)
Member


28th April
Looking at LazyMethodGen.pack() - 12% of the cpu usage for what we are testing. pack() is quite tricky to make better, wonder if we
can differentiate amongst targeters to speed things up? Also instructionHandle has 'attributes' - for no good reason that I can see

Removed static in BranchHandle...


Performance analysis, following: http://java.sun.com/developer/technicalArticles/Programming/perfanal/


Reveals of 5415 ticks (weaving rt.jar), we spend 25% of the time in WeaverAdapter.removeFromMap() !
- changed that code to a CharOpt comparison
- further changed to null 'lastReturnedResult' when it is finished with, should reduce ongoing calls
- want to removeFromMap() quickly if we can. we can't usually because we have rebuilt the char array because
post weave we build a new UnwovenClassFile() - I've changed the code to copy across the charname which
means we can do remove() rather than searching all keys because the char array is the same one as what was
used for the key when it was put in.
knocks 25seconds (was 1 minute, now 35s) off the weave time

--- Deliverable sizes: aspectjweaver.jar

1.6.0 = 1,907,848 bytes:1094 classes
26Apr = 1,718,083:893
26Apr = 1,618,024:849 (verifier removed from delivered package)
27Apr = 1,612,996:848


----------------
Finally have a loadtime weaving test

see - d:\e312\eclipse\plugins
ltwToolsProto.bat

of the 20seconds it takes for 1925 classes, 1.81% is:

org.aspectj.weaver.tools.WeavingAdaptor.weaveClass: 57.5% (1142 inclusive / 0 exclusive)
org.aspectj.weaver.tools.WeavingAdaptor.getWovenBytes: 49.14% (976 inclusive / 0 exclusive)
org.aspectj.weaver.bcel.BcelWeaver.weave: 48.94% (972 inclusive / 11 exclusive)
org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify: 45.37% (901 inclusive / 0 exclusive)
org.aspectj.weaver.bcel.BcelWeaver.getClassFilesFor: 22% (437 inclusive / 0 exclusive)
org.aspectj.weaver.bcel.LazyClassGen.getJavaClassBytesIncludingReweavable: 22% (437 inclusive / 0 exclusive)
org.aspectj.weaver.bcel.LazyClassGen.writeBack: 17.88% (355 inclusive / 4 exclusive)
org.aspectj.weaver.bcel.LazyMethodGen.getMethod: 17.42% (346 inclusive / 0 exclusive)
org.aspectj.weaver.bcel.LazyMethodGen.pack: 13.09% (260 inclusive / 3 exclusive)
org.aspectj.weaver.bcel.LazyMethodGen.newPackBody: 8.36% (166 inclusive / 81 exclusive)
org.aspectj.apache.bcel.generic.InstructionList.delete: 1.31% (26 inclusive / 1 exclusive)


29Apr
now the extra bytecode parse in UnwovenClassFile - can we get rid of it by using the ctor that supplies a classname?


2may
looked at the analysis and getSourceLocation() was being called a lot - wasn't sure why given I didn't use tjp in the advice - turns
out a dummy xrefhandler is added in LTWWorld, and so all the guards to avoid doing anything if there is no xrefhandler are worthless.
fixed.

noticed ClassParser ctor messing about remembering if the source is a zip and wrapping a baos in a bufferedinputstream - added new
ctor to avoid that and removed the zip nonsense
2May = 1,588,317:841 but fails tests, buggerit


+ 4
- 3
weaver/src/org/aspectj/weaver/AdviceKind.java Прегледај датотеку

@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/


package org.aspectj.weaver;

import java.io.IOException;
@@ -18,15 +17,17 @@ import java.io.IOException;
import org.aspectj.util.TypeSafeEnum;

/**
* The 5 kinds of advice in AspectJ.
* The five kinds of advice in AspectJ.
*
* @author Erik Hilsdale
* @author Jim Hugunin
*/
public class AdviceKind extends TypeSafeEnum {
private int precedence;
private boolean isAfter;
private boolean isCflow;
public AdviceKind(String name, int key, int precedence, boolean isAfter, boolean isCflow) {
super(name, key);
this.precedence = precedence;
@@ -114,4 +115,4 @@ public class AdviceKind extends TypeSafeEnum {
return this == PerThisEntry || this == PerTargetEntry;
}

}
}

+ 8
- 2
weaver/src/org/aspectj/weaver/AjAttribute.java Прегледај датотеку

@@ -215,10 +215,16 @@ public abstract class AjAttribute {
public static short WEAVER_VERSION_MAJOR_AJ150M4 = 3;
public static short WEAVER_VERSION_MAJOR_AJ150 = 2;
public static short WEAVER_VERSION_MINOR_AJ150 = 0;

// These are the weaver major/minor numbers for AspectJ 1.6.0
public static short WEAVER_VERSION_MAJOR_AJ160M2 = 5;
public static short WEAVER_VERSION_MAJOR_AJ160 = 4;
public static short WEAVER_VERSION_MINOR_AJ160 = 0;

// These are the weaver major/minor versions for *this* weaver
private static short CURRENT_VERSION_MAJOR = WEAVER_VERSION_MAJOR_AJ150M4;
private static short CURRENT_VERSION_MINOR = WEAVER_VERSION_MINOR_AJ150;
private static short CURRENT_VERSION_MAJOR = WEAVER_VERSION_MAJOR_AJ160M2;
private static short CURRENT_VERSION_MINOR = WEAVER_VERSION_MINOR_AJ160;
public static final WeaverVersionInfo UNKNOWN =
new WeaverVersionInfo(WEAVER_VERSION_MAJOR_UNKNOWN,WEAVER_VERSION_MINOR_UNKNOWN);

+ 1
- 3
weaver/src/org/aspectj/weaver/AjcMemberMaker.java Прегледај датотеку

@@ -252,9 +252,7 @@ public class AjcMemberMaker {

public static ResolvedMember perSingletonAspectOfMethod(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.METHOD,
declaringType, PUBLIC_STATIC, "aspectOf",
"()" + declaringType.getSignature());
return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "aspectOf", "()" + declaringType.getSignature());
}
public static ResolvedMember perSingletonHasAspectMethod(UnresolvedType declaringType) {

+ 2
- 1
weaver/src/org/aspectj/weaver/AnnotatedElement.java Прегледај датотеку

@@ -16,5 +16,6 @@ public interface AnnotatedElement {
boolean hasAnnotation(UnresolvedType ofType);
ResolvedType[] getAnnotationTypes();
// SomeType getAnnotation(UnresolvedType ofType);
AnnotationX getAnnotationOfType(UnresolvedType ofType);
}

+ 23
- 0
weaver/src/org/aspectj/weaver/AnnotationAJ.java Прегледај датотеку

@@ -95,4 +95,27 @@ public class AnnotationAJ {
sb.append("]");
return sb.toString();
}

public boolean hasNamedValue(String n) {
if (nvPairs==null) return false;
for (int i=0;i<nvPairs.size();i++) {
AnnotationNameValuePair pair = (AnnotationNameValuePair)nvPairs.get(i);
if (pair.getName().equals(n)) return true;
}
return false;
}

/**
* Return true if the annotation has a value with the specified name (n) and value (v)
*/
public boolean hasNameValuePair(String n, String v) {
if (nvPairs==null) return false;
for (int i=0;i<nvPairs.size();i++) {
AnnotationNameValuePair pair = (AnnotationNameValuePair)nvPairs.get(i);
if (pair.getName().equals(n)) {
if (pair.getValue().stringify().equals(v)) return true;
}
}
return false;
}
}

+ 21
- 11
weaver/src/org/aspectj/weaver/AnnotationX.java Прегледај датотеку

@@ -24,7 +24,7 @@ import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;

/**
* AnnotationX instances are holders for an annotation from either Bcel or
* ASM. We have this holder so that types about the bcel weaver package
* eclipse. We have this holder so that types about the bcel weaver package
* can work with something not bytecode toolkit specific.
*/
public class AnnotationX {
@@ -32,9 +32,9 @@ public class AnnotationX {
public static final AnnotationX[] NONE = new AnnotationX[0];
private AnnotationGen theRealBcelAnnotation;
private AnnotationAJ theRealASMAnnotation;
private AnnotationAJ theRealEclipseAnnotation; // OPTIMIZE push out into compiler, not ever used if purely binary weaving ?
private int mode = -1;
private final static int MODE_ASM = 1;
private final static int MODE_ECLIPSE = 1;
private final static int MODE_BCEL = 2;
private ResolvedType signature = null;
@@ -51,9 +51,9 @@ public class AnnotationX {
}
public AnnotationX(AnnotationAJ a,World world) {
theRealASMAnnotation = a;
signature = UnresolvedType.forSignature(theRealASMAnnotation.getTypeSignature()).resolve(world);
mode= MODE_ASM;
theRealEclipseAnnotation = a;
signature = UnresolvedType.forSignature(theRealEclipseAnnotation.getTypeSignature()).resolve(world);
mode= MODE_ECLIPSE;
}

public AnnotationGen getBcelAnnotation() {
@@ -66,18 +66,18 @@ public class AnnotationX {
public String toString() {
if (mode==MODE_BCEL) return theRealBcelAnnotation.toString();
else return theRealASMAnnotation.toString();
else return theRealEclipseAnnotation.toString();
}


public String getTypeName() {
if (mode==MODE_BCEL) return theRealBcelAnnotation.getTypeName();
else return Utility.signatureToString(theRealASMAnnotation.getTypeSignature());
else return Utility.signatureToString(theRealEclipseAnnotation.getTypeSignature());
}

public String getTypeSignature() {
if (mode==MODE_BCEL) return theRealBcelAnnotation.getTypeSignature();
else return theRealASMAnnotation.getTypeSignature();
else return theRealEclipseAnnotation.getTypeSignature();
}

@@ -176,7 +176,7 @@ public class AnnotationX {
supportedTargets.add(ev.getEnumValueString());
}
} else {
List values = theRealASMAnnotation.getNameValuePairs();
List values = theRealEclipseAnnotation.getNameValuePairs();
AnnotationNameValuePair nvp = (AnnotationNameValuePair)values.get(0);
ArrayAnnotationValue aav = (ArrayAnnotationValue)nvp.getValue();
AnnotationValue[] avs = aav.getValues();
@@ -203,7 +203,17 @@ public class AnnotationX {

public void print(StringBuffer sb) {
if (mode==MODE_BCEL) sb.append(theRealBcelAnnotation.toString());
else sb.append(theRealASMAnnotation.stringify());
else sb.append(theRealEclipseAnnotation.stringify());
}

public boolean hasNameValuePair(String n, String v) {
if (mode==MODE_BCEL) return theRealBcelAnnotation.hasNameValuePair(n,v);
else return theRealEclipseAnnotation.hasNameValuePair(n,v);
}

public boolean hasNamedValue(String n) {
if (mode==MODE_BCEL) return theRealBcelAnnotation.hasNamedValue(n);
else return theRealEclipseAnnotation.hasNamedValue(n);
}

}

+ 186
- 0
weaver/src/org/aspectj/weaver/ArrayReferenceType.java Прегледај датотеку

@@ -0,0 +1,186 @@
/* *******************************************************************
* Copyright (c) 2008 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andy Clement initial implementation
* ******************************************************************/
package org.aspectj.weaver;

import java.lang.reflect.Modifier;

/**
* Represents a resolved array type
*
* @author Andy Clement
*/
public class ArrayReferenceType extends ReferenceType {

private ResolvedType componentType;


public ArrayReferenceType(String sig, String erasureSig, World world, ResolvedType componentType) {
super(sig, erasureSig, world);
this.componentType = componentType;
}

// These methods are from the original implementation when Array was a ResolvedType and not a ReferenceType
public final ResolvedMember[] getDeclaredFields() {
return ResolvedMember.NONE;
}

public final ResolvedMember[] getDeclaredMethods() {
// ??? should this return clone? Probably not...
// If it ever does, here is the code:
// ResolvedMember cloneMethod =
// new ResolvedMember(Member.METHOD,this,Modifier.PUBLIC,UnresolvedType.OBJECT,"clone",new UnresolvedType[]{});
// return new ResolvedMember[]{cloneMethod};
return ResolvedMember.NONE;
}

public final ResolvedType[] getDeclaredInterfaces() {
return new ResolvedType[] { world.getCoreType(CLONEABLE), world.getCoreType(SERIALIZABLE) };
}

public final ResolvedMember[] getDeclaredPointcuts() {
return ResolvedMember.NONE;
}

public boolean hasAnnotation(UnresolvedType ofType) {
return false;
}

public final ResolvedType getSuperclass() {
return world.getCoreType(OBJECT);
}

public final boolean isAssignableFrom(ResolvedType o) {
if (!o.isArray())
return false;
if (o.getComponentType().isPrimitiveType()) {
return o.equals(this);
} else {
return getComponentType().resolve(world).isAssignableFrom(o.getComponentType().resolve(world));
}
}

public boolean isAssignableFrom(ResolvedType o, boolean allowMissing) {
return isAssignableFrom(o);
}

public final boolean isCoerceableFrom(ResolvedType o) {
if (o.equals(UnresolvedType.OBJECT) || o.equals(UnresolvedType.SERIALIZABLE) || o.equals(UnresolvedType.CLONEABLE)) {
return true;
}
if (!o.isArray())
return false;
if (o.getComponentType().isPrimitiveType()) {
return o.equals(this);
} else {
return getComponentType().resolve(world).isCoerceableFrom(o.getComponentType().resolve(world));
}
}

public final int getModifiers() {
int mask = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
return (componentType.getModifiers() & mask) | Modifier.FINAL;
}

public UnresolvedType getComponentType() {
return componentType;
}

public ResolvedType getResolvedComponentType() {
return componentType;
}

public ISourceContext getSourceContext() {
return getResolvedComponentType().getSourceContext();
}


// Methods overridden from ReferenceType follow

public TypeVariable[] getTypeVariables() {
if (this.typeVariables == null && componentType.getTypeVariables() != null) {
this.typeVariables = componentType.getTypeVariables();
for (int i = 0; i < this.typeVariables.length; i++) {
this.typeVariables[i].resolve(world);
}
}
return this.typeVariables;
}

public boolean isAnnotation() {
return false;
}

public boolean isAnonymous() {
return false;
}

public boolean isAnnotationStyleAspect() {
return false;
}

public boolean isAspect() {
return false;
}

public boolean isPrimitiveType() {
return typeKind == TypeKind.PRIMITIVE;
}

public boolean isSimpleType() {
return typeKind == TypeKind.SIMPLE;
}

public boolean isRawType() {
return typeKind == TypeKind.RAW;
}

public boolean isGenericType() {
return typeKind == TypeKind.GENERIC;
}

public boolean isParameterizedType() {
return typeKind == TypeKind.PARAMETERIZED;
}

public boolean isTypeVariableReference() {
return typeKind == TypeKind.TYPE_VARIABLE;
}

public boolean isGenericWildcard() {
return typeKind == TypeKind.WILDCARD;
}
public boolean isEnum() {
return false;
}

public boolean isNested() {
return false;
}

public boolean isClass() {
return false;
}

public boolean canAnnotationTargetType() {
return false;
}
public AnnotationTargetKind[] getAnnotationTargetKinds() {
return null;
}

public boolean isAnnotationWithRuntimeRetention() {
return false;
}
}

+ 3
- 2
weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java Прегледај датотеку

@@ -16,6 +16,7 @@ package org.aspectj.weaver;
import java.util.Iterator;
import java.util.List;

import org.aspectj.apache.bcel.classfile.Field;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Utility;
import org.aspectj.apache.bcel.generic.Type;
@@ -430,7 +431,7 @@ public class AsmRelationshipProvider {
* the fields' type in order to locate it. Currently just fails silently if any of the lookup code
* doesn't find anything...
*/
public void addDeclareAnnotationRelationship(ISourceLocation sourceLocation, String typename,String fieldName) {
public void addDeclareAnnotationRelationship(ISourceLocation sourceLocation, String typename,Field field) {
if (!AsmManager.isCreatingModel()) return;
String pkg = null;
@@ -444,7 +445,7 @@ public class AsmRelationshipProvider {
IProgramElement typeElem = AsmManager.getDefault().getHierarchy().findElementForType(pkg,type);
if (typeElem == null) return;
IProgramElement fieldElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem,IProgramElement.Kind.FIELD,fieldName);
IProgramElement fieldElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem,IProgramElement.Kind.FIELD,field.getName());
if (fieldElem== null) return;

String targetHandle = fieldElem.getHandleIdentifier();

+ 0
- 29
weaver/src/org/aspectj/weaver/BetaException.java Прегледај датотеку

@@ -1,29 +0,0 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* ******************************************************************/


package org.aspectj.weaver;

/**
* Exception to use inside the bcweaver.
*/
public class BetaException extends RuntimeException {

public BetaException() {
super();
}

public BetaException(String s) {
super(s);
}

}

+ 4
- 0
weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java Прегледај датотеку

@@ -13,6 +13,8 @@

package org.aspectj.weaver;

import java.util.Map;

import org.aspectj.bridge.ISourceLocation;
import org.aspectj.util.PartialOrder;

@@ -123,4 +125,6 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab
if (munger==null) return false;
return munger.isLateMunger();
}

public abstract ConcreteTypeMunger parameterizeWith(Map parameterizationMap, World world);
}

+ 19
- 0
weaver/src/org/aspectj/weaver/CrosscuttingMembers.java Прегледај датотеку

@@ -14,8 +14,10 @@ package org.aspectj.weaver;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.weaver.bcel.BcelAdvice;
@@ -71,6 +73,10 @@ public class CrosscuttingMembers {
this.shouldConcretizeIfNeeded = shouldConcretizeIfNeeded;
}

private Hashtable cflowFields = new Hashtable();
private Hashtable cflowBelowFields = new Hashtable();
// public void addConcreteShadowMungers(Collection c) {
// shadowMungers.addAll(c);
// }
@@ -502,4 +508,17 @@ public class CrosscuttingMembers {
return declareAnnotationsOnMethods;
}

public Map getCflowBelowFields() {
return cflowBelowFields;
}

public Map getCflowFields() {
return cflowFields;
}
public void clearCaches() {
cflowFields.clear();
cflowBelowFields.clear();
}

}

+ 0
- 3
weaver/src/org/aspectj/weaver/CrosscuttingMembersSet.java Прегледај датотеку

@@ -78,13 +78,10 @@ public class CrosscuttingMembersSet {
if (xcut == null) {
members.put(aspectType, aspectType.collectCrosscuttingMembers(inWeavingPhase));
clearCaches();
CflowPointcut.clearCaches(aspectType);
change = true;
} else {
if (xcut.replaceWith(aspectType.collectCrosscuttingMembers(inWeavingPhase),inWeavingPhase)) {
clearCaches();

CflowPointcut.clearCaches(aspectType);
change = true;
} else {
if (!AsmManager.getDefault().getHandleProvider().dependsOnLocation()

+ 58
- 0
weaver/src/org/aspectj/weaver/CustomMungerFactory.java Прегледај датотеку

@@ -0,0 +1,58 @@
/* *******************************************************************
* Copyright (c) 2007 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Linton Ye https://bugs.eclipse.org/bugs/show_bug.cgi?id=193065
* ******************************************************************/

package org.aspectj.weaver;

import java.util.Collection;

/**
* <p>
* This interface is introduced to support tools like PointcutDoctor.
* </p>
* <p>
* A CustomMungerFactory is used to create ShadowMungers and/or
* ConcreteTypeMungers so that an extender can extract extra information during
* the weaving process.
* </p>
* <p>
* A CustomMungerFactory is assigned to a weaver through its AjCompiler in
* extenders' code, and gets invoked by the weaver right before the weaving
* starts. The custom shadow/type mungers being created will be added into the
* shadow/type munger list in the weaver and participate the weaving process.
* For example, the match method of each custom shadow munger will be called
* against each shadow.
* </p>
* @author lintonye
*
*/
public interface CustomMungerFactory {

/**
* @param aspectType
* @return a Collection&lt;ShadowMunger&gt; of custom shadow mungers for the
* given aspect
*/
public Collection/* ShadowMunger */createCustomShadowMungers(
ResolvedType aspectType);

/**
* @param aspectType
* @return a Collection&lt;ConcreteTypeMunger&gt; of custom type mungers for the
* given aspect
*/
public Collection/* ConcreteTypeMunger */createCustomTypeMungers(
ResolvedType aspectType);
public Collection/* ShadowMunger */getAllCreatedCustomShadowMungers();

public Collection/* ConcreteTypeMunger */getAllCreatedCustomTypeMungers();
}

+ 21
- 24
weaver/src/org/aspectj/weaver/JoinPointSignature.java Прегледај датотеку

@@ -16,6 +16,7 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute;
@@ -90,6 +91,10 @@ public class JoinPointSignature implements ResolvedMember {
public ResolvedType[] getAnnotationTypes() {
return realMember.getAnnotationTypes();
}
public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
return realMember.getAnnotationOfType(ofType);
}

public void setAnnotationTypes(UnresolvedType[] annotationtypes) {
realMember.setAnnotationTypes(annotationtypes);
@@ -235,15 +240,7 @@ public class JoinPointSignature implements ResolvedMember {
return realMember.resolve(world);
}

public int compareTo(Object other) {
return realMember.compareTo(other);
}

public String toLongString() {
return realMember.toLongString();
}

public Kind getKind() {
public MemberKind getKind() {
return realMember.getKind();
}

@@ -262,6 +259,14 @@ public class JoinPointSignature implements ResolvedMember {
public UnresolvedType[] getParameterTypes() {
return realMember.getParameterTypes();
}
public AnnotationX[][] getParameterAnnotations() {
return realMember.getParameterAnnotations();
}
public ResolvedType[][] getParameterAnnotationTypes() {
return realMember.getParameterAnnotationTypes();
}

public String getSignature() {
return realMember.getSignature();
@@ -279,18 +284,6 @@ public class JoinPointSignature implements ResolvedMember {
return realMember.isCompatibleWith(am);
}

public boolean isProtected(World world) {
return realMember.isProtected(world);
}

public boolean isStatic(World world) {
return realMember.isStatic(world);
}

public boolean isStrict(World world) {
return realMember.isStrict(world);
}

public boolean isStatic() {
return realMember.isStatic();
}
@@ -373,7 +366,7 @@ public class JoinPointSignature implements ResolvedMember {
realMember.resetName(newName);
}

public void resetKind(Kind newKind) {
public void resetKind(MemberKind newKind) {
realMember.resetKind(newKind);
}
@@ -407,7 +400,11 @@ public class JoinPointSignature implements ResolvedMember {

public void evictWeavingState() { realMember.evictWeavingState(); }

public Member slimline() {
return this;
public ResolvedMember parameterizedWith(Map m, World w) {
return realMember.parameterizedWith(m,w);
}

public String getAnnotationDefaultValue() {
return realMember.getAnnotationDefaultValue();
}
}

+ 3
- 0
weaver/src/org/aspectj/weaver/Lint.java Прегледај датотеку

@@ -128,6 +128,9 @@ public class Lint {
public final Kind advisingSynchronizedMethods = new Kind("advisingSynchronizedMethods",
"advice matching the synchronized method shadow ''{0}'' will be executed outside the lock rather than inside (compiler limitation)");

public final Kind mustWeaveXmlDefinedAspects = new Kind("mustWeaveXmlDefinedAspects",
"XML Defined aspects must be woven in cases where cflow pointcuts are involved. Currently the include/exclude patterns exclude ''{0}''");
private static Trace trace = TraceFactory.getTraceFactory().getTrace(Lint.class);
public Lint(World world) {

+ 26
- 78
weaver/src/org/aspectj/weaver/Member.java Прегледај датотеку

@@ -13,71 +13,46 @@
* ******************************************************************/
package org.aspectj.weaver;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;

import org.aspectj.util.TypeSafeEnum;

public interface Member {

public static class Kind extends TypeSafeEnum {
public Kind(String name, int key) { super(name, key); }
public static Kind read(DataInputStream s) throws IOException {
int key = s.readByte();
switch(key) {
case 1: return METHOD;
case 2: return FIELD;
case 3: return CONSTRUCTOR;
case 4: return STATIC_INITIALIZATION;
case 5: return POINTCUT;
case 6: return ADVICE;
case 7: return HANDLER;
case 8: return MONITORENTER;
case 9: return MONITOREXIT;
}
throw new BCException("weird kind " + key);
}
}

public static final Member[] NONE = new Member[0];
public static final Kind METHOD = new Kind("METHOD", 1);
public static final Kind FIELD = new Kind("FIELD", 2);
public static final Kind CONSTRUCTOR = new Kind("CONSTRUCTOR", 3);
public static final Kind STATIC_INITIALIZATION = new Kind("STATIC_INITIALIZATION", 4);
public static final Kind POINTCUT = new Kind("POINTCUT", 5);
public static final Kind ADVICE = new Kind("ADVICE", 6);
public static final Kind HANDLER = new Kind("HANDLER", 7);
public static final Kind MONITORENTER = new Kind("MONITORENTER", 8);
public static final Kind MONITOREXIT = new Kind("MONITOREXIT", 9);


public static final Member[] NONE = new Member[0];
public static final MemberKind METHOD = new MemberKind("METHOD", 1);
public static final MemberKind FIELD = new MemberKind("FIELD", 2);
public static final MemberKind CONSTRUCTOR = new MemberKind("CONSTRUCTOR", 3);
public static final MemberKind STATIC_INITIALIZATION = new MemberKind("STATIC_INITIALIZATION", 4);
public static final MemberKind POINTCUT = new MemberKind("POINTCUT", 5);
public static final MemberKind ADVICE = new MemberKind("ADVICE", 6);
public static final MemberKind HANDLER = new MemberKind("HANDLER", 7);
public static final MemberKind MONITORENTER = new MemberKind("MONITORENTER", 8);
public static final MemberKind MONITOREXIT = new MemberKind("MONITOREXIT", 9);

public static final AnnotationX[][] NO_PARAMETER_ANNOTATIONXS = new AnnotationX[][]{};
public static final ResolvedType[][] NO_PARAMETER_ANNOTATION_TYPES = new ResolvedType[][]{};

public MemberKind getKind();
public ResolvedMember resolve(World world);

public int compareTo(Object other);

public String toLongString();

public Kind getKind();
public String getName();

public UnresolvedType getDeclaringType();

public UnresolvedType getReturnType();
public AnnotationX[] getAnnotations();
public UnresolvedType getReturnType();
public UnresolvedType getType();
public UnresolvedType getGenericReturnType();
public UnresolvedType[] getGenericParameterTypes();

public UnresolvedType getType();

public String getName();

public String[] getParameterNames(World world);
public UnresolvedType[] getParameterTypes();

public UnresolvedType[] getGenericParameterTypes();
/**
* Return full signature, including return type, e.g. "()LFastCar;" for a signature without the return type,
* use getParameterSignature() - it is importnant to choose the right one in the face of covariance.
* use getParameterSignature() - it is important to choose the right one in the face of covariance.
*/
public String getSignature();
@@ -102,52 +77,25 @@ public interface Member {

public UnresolvedType[] getExceptions(World world);

public boolean isProtected(World world);

public boolean isStatic(World world);

public boolean isStrict(World world);

public boolean isStatic();

public boolean isInterface();

public boolean isPrivate();

/**
* Returns true iff the member is generic (NOT parameterized)
* For example, a method declared in a generic type
*/
public boolean canBeParameterized();

public int getCallsiteModifiers();

public String getExtractableName();

/**
* If you want a sensible answer, resolve the member and call
* hasAnnotation() on the ResolvedMember.
*/
public boolean hasAnnotation(UnresolvedType ofType);

/* (non-Javadoc)
* @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
*/
public ResolvedType[] getAnnotationTypes();

public AnnotationX[] getAnnotations();
// public AnnotationX[] getAnnotations();

public Collection/*ResolvedType*/getDeclaringTypes(World world);

// ---- reflective thisJoinPoint stuff
// ---- reflective thisJoinPoint related methods
public String getSignatureMakerName();

public String getSignatureType();

public String getSignatureString(World world);

public String[] getParameterNames(World world);

public Member slimline();

}

+ 53
- 244
weaver/src/org/aspectj/weaver/MemberImpl.java Прегледај датотеку

@@ -21,19 +21,26 @@ import java.util.Iterator;
import java.util.List;


public class MemberImpl implements Comparable, AnnotatedElement,Member {
protected Kind kind;
protected int modifiers;
protected UnresolvedType declaringType;
public class MemberImpl implements Comparable, Member {

protected MemberKind kind;
protected String name;

protected UnresolvedType declaringType;
protected int modifiers;
protected UnresolvedType returnType;
protected UnresolvedType[] parameterTypes;
private final String signature;
private String paramSignature;
// OPTIMIZE move out of the member!
private boolean reportedCantFindDeclaringType = false;
private boolean reportedUnresolvableMember = false;


public AnnotationX[] getAnnotations() {
throw new IllegalStateException("Cannot answer getAnnotations() for MemberImpl "+this.toString());
}
/**
* All the signatures that a join point with this member as its signature has.
@@ -43,7 +50,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
private JoinPointSignatureIterator joinPointSignatures = null;

public MemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
String name,
@@ -53,6 +60,9 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
this.declaringType = declaringType;
this.modifiers = modifiers;
this.name = name;
if (kind!=STATIC_INITIALIZATION && name!=null && name.equals("<clinit>")) {
throw new RuntimeException("!");
}
this.signature = signature;
if (kind == FIELD) {
this.returnType = UnresolvedType.forSignature(signature);
@@ -68,7 +78,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
}

public MemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
UnresolvedType returnType,
@@ -78,7 +88,11 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
super();
this.kind = kind;
this.declaringType = declaringType;
this.modifiers = modifiers;
this.modifiers = modifiers;
if (name!=null && name.equals("<clinit>") && kind!=STATIC_INITIALIZATION) {
throw new RuntimeException("!");
}

this.returnType = returnType;
this.name = name;
this.parameterTypes = parameterTypes;
@@ -232,13 +246,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {


private static MemberImpl field(String declaring, int mods, UnresolvedType ty, String name) {
return new MemberImpl(
FIELD,
UnresolvedType.forName(declaring),
mods,
ty,
name,
UnresolvedType.NONE);
return new MemberImpl(FIELD, UnresolvedType.forName(declaring), mods, ty, name, UnresolvedType.NONE);
}
public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
@@ -270,107 +278,6 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
"(" + catchType.getSignature() + ")V");
}
// ---- parsing methods
/** Takes a string in this form:
*
* <blockquote><pre>
* static? TypeName TypeName.Id
* </pre></blockquote>
* Pretty much just for testing, and as such should perhaps be moved.
*/
public static MemberImpl fieldFromString(String str) {
str = str.trim();
final int len = str.length();
int i = 0;
int mods = 0;
if (str.startsWith("static", i)) {
mods = Modifier.STATIC;
i += 6;
while (Character.isWhitespace(str.charAt(i))) i++;
}
int start = i;
while (! Character.isWhitespace(str.charAt(i))) i++;
UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i));

start = i;
i = str.lastIndexOf('.');
UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
start = ++i;
String name = str.substring(start, len).trim();
return new MemberImpl(
FIELD,
declaringTy,
mods,
retTy,
name,
UnresolvedType.NONE);
}

/** Takes a string in this form:
*
* <blockquote><pre>
* (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
* </pre></blockquote>
* Pretty much just for testing, and as such should perhaps be moved.
*/
public static Member methodFromString(String str) {
str = str.trim();
// final int len = str.length();
int i = 0;

int mods = 0;
if (str.startsWith("static", i)) {
mods = Modifier.STATIC;
i += 6;
} else if (str.startsWith("interface", i)) {
mods = Modifier.INTERFACE;
i += 9;
} else if (str.startsWith("private", i)) {
mods = Modifier.PRIVATE;
i += 7;
}
while (Character.isWhitespace(str.charAt(i))) i++;
int start = i;
while (! Character.isWhitespace(str.charAt(i))) i++;
UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i));

start = i;
i = str.indexOf('(', i);
i = str.lastIndexOf('.', i);
UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
start = ++i;
i = str.indexOf('(', i);
String name = str.substring(start, i).trim();
start = ++i;
i = str.indexOf(')', i);
String[] paramTypeNames = parseIds(str.substring(start, i).trim());

return method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames));
}

private static String[] parseIds(String str) {
if (str.length() == 0) return ZERO_STRINGS;
List l = new ArrayList();
int start = 0;
while (true) {
int i = str.indexOf(',', start);
if (i == -1) {
l.add(str.substring(start).trim());
break;
}
l.add(str.substring(start, i).trim());
start = i+1;
}
return (String[]) l.toArray(new String[l.size()]);
}

private static final String[] ZERO_STRINGS = new String[0];

// ---- things we know without resolution
@@ -433,62 +340,32 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
return buf.toString();
}
// Overridden by subclasses - a method can be advice
public MemberKind getKind() {
return kind;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#toLongString()
*/
public String toLongString() {
StringBuffer buf = new StringBuffer();
buf.append(kind);
buf.append(' ');
if (modifiers != 0) {
buf.append(Modifier.toString(modifiers));
buf.append(' ');
}
buf.append(toString());
buf.append(" <");
buf.append(signature);
buf.append(" >");
return buf.toString();
}

/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getKind()
*/
public Kind getKind() { return kind; }
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getDeclaringType()
*/
public UnresolvedType getDeclaringType() { return declaringType; }
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getReturnType()
*/
public UnresolvedType getReturnType() { return returnType; }
public UnresolvedType getGenericReturnType() { return getReturnType(); }
public UnresolvedType[] getGenericParameterTypes() { return getParameterTypes(); }
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getType()
*/
public UnresolvedType getType() { return returnType; }
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getName()
*/
public String getName() { return name; }
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getParameterTypes()
*/

public UnresolvedType getType() {
return returnType;
}
public String getName() {
return name;
}

public UnresolvedType[] getParameterTypes() { return parameterTypes; }
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getSignature()
*/
public String getSignature() { return signature; }
public int getArity() { return parameterTypes.length; }
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getParameterSignature()
*/
public String getParameterSignature() {
if (paramSignature != null) return paramSignature;
StringBuffer sb = new StringBuffer();
@@ -535,9 +412,6 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
return resolved.getModifiers();
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getExceptions(org.aspectj.weaver.World)
*/
public UnresolvedType[] getExceptions(World world) {
ResolvedMember resolved = resolve(world);
if (resolved == null) {
@@ -546,57 +420,23 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
}
return resolved.getExceptions();
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#isProtected(org.aspectj.weaver.World)
*/
public final boolean isProtected(World world) {
return Modifier.isProtected(resolve(world).getModifiers());
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#isStatic(org.aspectj.weaver.World)
*/
public final boolean isStatic(World world) {
return Modifier.isStatic(resolve(world).getModifiers());
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#isStrict(org.aspectj.weaver.World)
*/
public final boolean isStrict(World world) {
return Modifier.isStrict(resolve(world).getModifiers());
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#isStatic()
*/
public final boolean isStatic() {
return Modifier.isStatic(modifiers);
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#isInterface()
*/
public final boolean isInterface() {
return Modifier.isInterface(modifiers); // this is kinda weird
return Modifier.isInterface(modifiers);
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#isPrivate()
*/
public final boolean isPrivate() {
return Modifier.isPrivate(modifiers);
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#canBeParameterized()
*/
public boolean canBeParameterized() {
return false;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getCallsiteModifiers()
*/
public final int getCallsiteModifiers() {
return modifiers & ~ Modifier.INTERFACE;
}
@@ -605,46 +445,19 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
return modifiers;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getExtractableName()
*/
public final String getExtractableName() {
if (name.equals("<init>")) return "init$";
else if (name.equals("<clinit>")) return "clinit$";
if (kind==CONSTRUCTOR/*name.equals("<init>")*/) return "init$";
else if (kind==STATIC_INITIALIZATION/*name.equals("<clinit>")*/) return "clinit$";
else return name;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.Member#hasAnnotation(org.aspectj.weaver.UnresolvedType)
*/
public boolean hasAnnotation(UnresolvedType ofType) {
throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
}
/* (non-Javadoc)
* @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
*/
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getAnnotationTypes()
*/
public ResolvedType[] getAnnotationTypes() {
throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getAnnotations()
*/
public AnnotationX[] getAnnotations() {
throw new UnsupportedOperationException("You should resolve this member '"+this+"' and call getAnnotations() on the result...");
}
// public AnnotationX[] getAnnotations() {
// throw new UnsupportedOperationException("You should resolve this member '"+this+"' and call getAnnotations() on the result...");
// }

// ---- fields 'n' stuff


/* (non-Javadoc)
* @see org.aspectj.weaver.Member#getDeclaringTypes(org.aspectj.weaver.World)
*/
public Collection/*ResolvedType*/ getDeclaringTypes(World world) {
ResolvedType myType = getDeclaringType().resolve(world);
Collection ret = new HashSet();
@@ -701,9 +514,9 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
* @see org.aspectj.weaver.Member#getSignatureMakerName()
*/
public String getSignatureMakerName() {
if (getName().equals("<clinit>")) return "makeInitializerSig";
// if (getName().equals("<clinit>")) return "makeInitializerSig";
Kind kind = getKind();
MemberKind kind = getKind();
if (kind == METHOD) {
return "makeMethodSig";
} else if (kind == CONSTRUCTOR) {
@@ -732,8 +545,8 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
* @see org.aspectj.weaver.Member#getSignatureType()
*/
public String getSignatureType() {
Kind kind = getKind();
if (getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature";
MemberKind kind = getKind();
// if (getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature";
if (kind == METHOD) {
return "org.aspectj.lang.reflect.MethodSignature";
@@ -761,8 +574,8 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
*/
public String getSignatureString(World world) {
if (getName().equals("<clinit>")) return getStaticInitializationSignatureString(world);
Kind kind = getKind();
//
MemberKind kind = getKind();
if (kind == METHOD) {
return getMethodSignatureString(world);
} else if (kind == CONSTRUCTOR) {
@@ -902,7 +715,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
}

protected String makeString(int i) {
return Integer.toString(i, 16); //??? expensive
return Integer.toString(i, 16);
}


@@ -982,9 +795,5 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
}
}

public Member slimline() {
return this;
}

}

+ 37
- 0
weaver/src/org/aspectj/weaver/MemberKind.java Прегледај датотеку

@@ -0,0 +1,37 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* ******************************************************************/
package org.aspectj.weaver;

import java.io.DataInputStream;
import java.io.IOException;

import org.aspectj.util.TypeSafeEnum;

public class MemberKind extends TypeSafeEnum {
public MemberKind(String name, int key) { super(name, key); }
public static MemberKind read(DataInputStream s) throws IOException {
int key = s.readByte();
switch(key) {
case 1: return Member.METHOD;
case 2: return Member.FIELD;
case 3: return Member.CONSTRUCTOR;
case 4: return Member.STATIC_INITIALIZATION;
case 5: return Member.POINTCUT;
case 6: return Member.ADVICE;
case 7: return Member.HANDLER;
case 8: return Member.MONITORENTER;
case 9: return Member.MONITOREXIT;
}
throw new BCException("weird kind " + key);
}
}

+ 9
- 10
weaver/src/org/aspectj/weaver/NameMangler.java Прегледај датотеку

@@ -104,7 +104,7 @@ public class NameMangler {
}
public static String itdAtDeclareParentsField(UnresolvedType aspectType, UnresolvedType itdType) {
return makeName(aspectType.getNameAsIdentifier(), itdType.getNameAsIdentifier());
return makeName("instance",aspectType.getNameAsIdentifier(), itdType.getNameAsIdentifier());
}

public static String privilegedAccessMethodForMethod(String name, UnresolvedType objectType, UnresolvedType aspectType) {
@@ -358,15 +358,14 @@ public class NameMangler {
return enclosingType.getName() + "$AjcClosure" + index;
}

public static String aroundCallbackMethodName(
Member shadowSig,
LazyClassGen enclosingType)
{
String ret =
shadowSig.getExtractableName()
+ "_aroundBody"
+ enclosingType.getNewGeneratedNameTag();
return ret;
public static String aroundCallbackMethodName(Member shadowSig, LazyClassGen enclosingType) {
StringBuffer ret = new StringBuffer();
ret.append(shadowSig.getExtractableName()).append("_aroundBody").append(enclosingType.getNewGeneratedNameTag());
// String ret =
// shadowSig.getExtractableName()
// + "_aroundBody"
// + enclosingType.getNewGeneratedNameTag();
return ret.toString();
}

public static String proceedMethodName(String adviceMethodName) {

+ 9
- 0
weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java Прегледај датотеку

@@ -16,6 +16,7 @@ package org.aspectj.weaver;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.bridge.ISourceLocation;
@@ -94,6 +95,14 @@ public class NewFieldTypeMunger extends ResolvedTypeMunger {
return nftm;
}

public ResolvedTypeMunger parameterizeWith(Map m, World w) {
ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m,w);
NewFieldTypeMunger nftm = new NewFieldTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases);
nftm.setDeclaredSignature(getSignature());
nftm.setSourceLocation(getSourceLocation());
return nftm;
}

public boolean equals(Object other) {
if (! (other instanceof NewFieldTypeMunger)) return false;
NewFieldTypeMunger o = (NewFieldTypeMunger) other;

+ 12
- 1
weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java Прегледај датотеку

@@ -16,11 +16,14 @@ package org.aspectj.weaver;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.bridge.ISourceLocation;

public class NewMethodTypeMunger extends ResolvedTypeMunger {


public NewMethodTypeMunger(
ResolvedMember signature,
Set superMethodsCalled,
@@ -128,5 +131,13 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger {
result = 37*result + ((typeVariableAliases == null) ? 0 : typeVariableAliases.hashCode());
return result;
}

public ResolvedTypeMunger parameterizeWith(Map m, World w) {
ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m,w);
NewMethodTypeMunger nmtm = new NewMethodTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases);
nmtm.setDeclaredSignature(getSignature());
nmtm.setSourceLocation(getSourceLocation());
return nmtm;
}

}

+ 29
- 6
weaver/src/org/aspectj/weaver/ReferenceType.java Прегледај датотеку

@@ -65,6 +65,7 @@ public class ReferenceType extends ResolvedType {
ResolvedMember[] parameterizedPointcuts = null;
ResolvedType[] parameterizedInterfaces = null;
Collection parameterizedDeclares = null;
Collection parameterizedTypeMungers = null;
//??? should set delegate before any use
public ReferenceType(String signature, World world) {
@@ -127,11 +128,11 @@ public class ReferenceType extends ResolvedType {
typeKind=TypeKind.GENERIC;
}
public final boolean isClass() {
public boolean isClass() {
return delegate.isClass();
}
public final boolean isGenericType() {
public boolean isGenericType() {
return !isParameterizedType() && !isRawType() && delegate.isGeneric();
}

@@ -147,6 +148,7 @@ public class ReferenceType extends ResolvedType {
public void addAnnotation(AnnotationX annotationX) {
delegate.addAnnotation(annotationX);
}
public boolean hasAnnotation(UnresolvedType ofType) {
return delegate.hasAnnotation(ofType);
}
@@ -200,7 +202,7 @@ public class ReferenceType extends ResolvedType {
}
// true iff the statement "this = (ThisType) other" would compile
public final boolean isCoerceableFrom(ResolvedType o) {
public boolean isCoerceableFrom(ResolvedType o) {
ResolvedType other = o.resolve(world);

if (this.isAssignableFrom(other) || other.isAssignableFrom(this)) {
@@ -272,12 +274,12 @@ public class ReferenceType extends ResolvedType {
return false;
}
public final boolean isAssignableFrom(ResolvedType other) {
public boolean isAssignableFrom(ResolvedType other) {
return isAssignableFrom(other,false);
}
// true iff the statement "this = other" would compile.
public final boolean isAssignableFrom(ResolvedType other,boolean allowMissing) {
public boolean isAssignableFrom(ResolvedType other,boolean allowMissing) {
if (other.isPrimitiveType()) {
if (!world.isInJava5Mode()) return false;
if (ResolvedType.validBoxing.contains(this.getSignature()+other.getSignature())) return true;
@@ -596,7 +598,28 @@ public class ReferenceType extends ResolvedType {
return declares;
}
protected Collection getTypeMungers() { return delegate.getTypeMungers(); }
protected Collection getTypeMungers() {
return delegate.getTypeMungers();
}
// GENERICITDFIX
//// Map parameterizationMap = getAjMemberParameterizationMap();
//
// // if (parameterizedTypeMungers != null) return parameterizedTypeMungers;
// Collection ret = null;
// if (ajMembersNeedParameterization()) {
// Collection genericDeclares = delegate.getTypeMungers();
// parameterizedTypeMungers = new ArrayList();
// Map parameterizationMap = getAjMemberParameterizationMap();
// for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) {
// ConcreteTypeMunger munger = (ConcreteTypeMunger)iter.next();
// parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap,world));
// }
// ret = parameterizedTypeMungers;
// } else {
// ret = delegate.getTypeMungers();
// }
// return ret;
// }
protected Collection getPrivilegedAccesses() { return delegate.getPrivilegedAccesses(); }


+ 2
- 2
weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java Прегледај датотеку

@@ -17,8 +17,8 @@ import java.util.Collection;
import org.aspectj.weaver.patterns.PerClause;

/**
* Abstraction over a type. Abstract implementation provided by
* AbstractReferenceTypeDelegate.
* Abstraction over a type - a reference type is Object and a descendant of Object, other types (int/etc) are
* considered primitive types. Abstract implementation provided by AbstractReferenceTypeDelegate.
*/
public interface ReferenceTypeDelegate {

+ 17
- 1
weaver/src/org/aspectj/weaver/ResolvedMember.java Прегледај датотеку

@@ -16,6 +16,7 @@ package org.aspectj.weaver;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.aspectj.bridge.ISourceLocation;

@@ -33,6 +34,19 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe

public ShadowMunger getAssociatedShadowMunger();

public AnnotationX[][] getParameterAnnotations();
public ResolvedType[][] getParameterAnnotationTypes();
public String getAnnotationDefaultValue();
public AnnotationX[] getAnnotations();
/**
* Returns true iff the member is generic (NOT parameterized)
* For example, a method declared in a generic type
*/
public boolean canBeParameterized();
// ??? true or false?
public boolean isAjSynthetic();

@@ -154,9 +168,11 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
public boolean matches(ResolvedMember aCandidateMatch);
public void resetName(String newName);
public void resetKind(Kind newKind);
public void resetKind(MemberKind newKind);
public void resetModifiers(int newModifiers);
public void resetReturnTypeToObjectArray();
public void evictWeavingState();

public ResolvedMember parameterizedWith(Map m, World w);
}

+ 115
- 13
weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java Прегледај датотеку

@@ -40,7 +40,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
public static boolean showParameterNames = true;

private String[] parameterNames = null;
protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE;
protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE; // OPTIMIZE unpack on demand
// private boolean isAjSynthetic = false;
protected int start, end;
protected ISourceContext sourceContext = null;
@@ -67,6 +67,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
// protected ResolvedMember backingGenericMember = null;
protected Set annotationTypes = null;
protected ResolvedType[][] parameterAnnotationTypes = null;
// Some members are 'created' to represent other things (for example ITDs). These
// members have their annotations stored elsewhere, and this flag indicates that is
// the case. It is up to the caller to work out where that is!
@@ -89,7 +91,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
//XXX deprecate this in favor of the constructor below
public ResolvedMemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
UnresolvedType returnType,
@@ -102,7 +104,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
public ResolvedMemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
UnresolvedType returnType,
@@ -115,7 +117,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
public ResolvedMemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
UnresolvedType returnType,
@@ -133,7 +135,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
public ResolvedMemberImpl(
Kind kind,
MemberKind kind,
UnresolvedType declaringType,
int modifiers,
String name,
@@ -339,11 +341,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
if (annotationTypes == null) return null;
return (ResolvedType[])annotationTypes.toArray(new ResolvedType[]{});
}

public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
throw new UnsupportedOperationException("You should resolve this member and call getAnnotationOfType() on the result...");
}
public AnnotationX[] getAnnotations() {
if ((bits&HAS_BACKING_GENERIC_MEMBER)!=0 && metaInfo.backingGenericMember!=null) return metaInfo.backingGenericMember.getAnnotations();
// if (backingGenericMember != null) return backingGenericMember.getAnnotations();
return super.getAnnotations();
// return super.getAnnotations();
throw new IllegalStateException("Unable to answer getAnnotations() for "+this.toString());
}
public void setAnnotationTypes(UnresolvedType[] annotationtypes) {
@@ -354,6 +361,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
}
public ResolvedType[][] getParameterAnnotationTypes() {
if (parameterAnnotationTypes == null) return null;
return parameterAnnotationTypes;
}
public AnnotationX[][] getParameterAnnotations() {
if (hasBackingGenericMember()) return getBackingGenericMember().getParameterAnnotations();
throw new IllegalStateException("Only a resolvedmember with backing generic member can answer this. Member="+toString());
}
public void addAnnotation(AnnotationX annotation) {
// FIXME asc only allows for annotation types, not instances - should it?
if (annotationTypes == null) annotationTypes = new HashSet();
@@ -441,7 +458,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
public static ResolvedMemberImpl readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext) throws IOException {
ResolvedMemberImpl m = new ResolvedMemberImpl(Kind.read(s), UnresolvedType.read(s), s.readInt(),
ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), UnresolvedType.read(s), s.readInt(),
s.readUTF(), s.readUTF());
m.checkedExceptions = UnresolvedType.readArray(s);
@@ -704,6 +721,68 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return ret;
}

/**
* Replace occurrences of type variables in the signature with values contained in the map. The map is of the form A=String,B=Integer and
* so a signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer i) {}
*/
public ResolvedMember parameterizedWith(Map m, World w) {
// if (//isParameterized && <-- might need this bit...
// !getDeclaringType().isGenericType()) {
// throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+" kind("+getDeclaringType().typeKind+")");
// }
declaringType = declaringType.resolve(w);
if (declaringType.isRawType()) declaringType = ((ResolvedType)declaringType).getGenericType();
TypeVariable[] typeVariables = getDeclaringType().getTypeVariables();
// if (isParameterized && (typeVariables.length != typeParameters.length)) {
// throw new IllegalStateException("Wrong number of type parameters supplied");
// }
// Map typeMap = new HashMap();
// boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0;
// if (typeVariables!=null) {
// // If no 'replacements' were supplied in the typeParameters array then collapse
// // type variables to their first bound.
// for (int i = 0; i < typeVariables.length; i++) {
// UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]);
// typeMap.put(typeVariables[i].getName(),ut);
// }
// }
// // For ITDs on generic types that use type variables from the target type, the aliases
// // record the alternative names used throughout the ITD expression that must map to
// // the same value as the type variables real name.
// if (aliases!=null) {
// int posn = 0;
// for (Iterator iter = aliases.iterator(); iter.hasNext();) {
// String typeVariableAlias = (String) iter.next();
// typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn]));
// posn++;
// }
// }
UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),m,true,w);
UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];
UnresolvedType[] genericParameterTypes = getGenericParameterTypes();
for (int i = 0; i < parameterizedParameterTypes.length; i++) {
parameterizedParameterTypes[i] =
parameterize(genericParameterTypes[i], m,true,w);
}
ResolvedMemberImpl ret = new ResolvedMemberImpl(
getKind(),
declaringType,
getModifiers(),
parameterizedReturnType,
getName(),
parameterizedParameterTypes,
getExceptions(),
this
);
ret.setTypeVariables(getTypeVariables());
ret.setSourceContext(getSourceContext());
ret.setPosition(getStart(),getEnd());
ret.setParameterNames(getParameterNames());
return ret;
}
public void setTypeVariables(TypeVariable[] tvars) {
typeVariables = tvars;
}
@@ -713,6 +792,10 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) {
return parameterize(aType,typeVariableMap,inParameterizedType,null);
}
protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType,World w) {
if (aType instanceof TypeVariableReference) {
String variableName = ((TypeVariableReference)aType).getTypeVariable().getName();
if (!typeVariableMap.containsKey(variableName)) {
@@ -721,7 +804,15 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
return (UnresolvedType) typeVariableMap.get(variableName);
} else if (aType.isParameterizedType()) {
if (inParameterizedType) {
if (aType instanceof UnresolvedType) aType= aType.resolve(((ResolvedType)getDeclaringType()).getWorld());
// if (!(getDeclaringType() instanceof ResolvedType)) {
// int stop = 1;
// }
if (aType instanceof UnresolvedType) {
if (w!=null) aType = aType.resolve(w);
else {
aType= aType.resolve(((ResolvedType)getDeclaringType()).getWorld());
}
}
return aType.parameterize(typeVariableMap);
} else {
return aType.getRawType();
@@ -806,7 +897,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
* using this method - this is safe.
*/
public void resetName(String newName) {this.name = newName;}
public void resetKind(Kind newKind) {this.kind=newKind; }
public void resetKind(MemberKind newKind) {this.kind=newKind; }
public void resetModifiers(int newModifiers) {this.modifiers=newModifiers;}

public void resetReturnTypeToObjectArray() {
@@ -854,7 +945,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
StringBuffer sig = new StringBuffer();
UnresolvedType[] myParameterTypes = getGenericParameterTypes();
for (int i = 0; i < myParameterTypes.length; i++) {
appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig);
appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig, new HashSet());
}
myParameterSignatureWithBoundsRemoved = sig.toString();
return myParameterSignatureWithBoundsRemoved;
@@ -878,14 +969,21 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
// does NOT produce a meaningful java signature, but does give a unique string suitable for
// comparison.
private void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, StringBuffer toBuffer) {
public static void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, StringBuffer toBuffer, Set alreadyUsedTypeVars) {
if (aType.isTypeVariableReference()) {
toBuffer.append("T;");
// pr204505
if (alreadyUsedTypeVars.contains(aType)) {
toBuffer.append("...");
} else {
alreadyUsedTypeVars.add(aType);
appendSigWithTypeVarBoundsRemoved(aType.getUpperBound(), toBuffer, alreadyUsedTypeVars);
}
// toBuffer.append("T;");
} else if (aType.isParameterizedType()) {
toBuffer.append(aType.getRawType().getSignature());
toBuffer.append("<");
for (int i = 0; i < aType.getTypeParameters().length; i++) {
appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], toBuffer);
appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], toBuffer, alreadyUsedTypeVars);
}
toBuffer.append(">;");
} else {
@@ -982,5 +1080,9 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

public void evictWeavingState() { }

public String getAnnotationDefaultValue() {
throw new UnsupportedOperationException("You should resolve this member and call getAnnotationDefaultValue() on the result...");
}
}

+ 97
- 10
weaver/src/org/aspectj/weaver/ResolvedType.java Прегледај датотеку

@@ -39,6 +39,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
public static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0];
public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P";
// Set during a type pattern match call - this currently used to hold the annotations
// that may be attached to a type when it used as a parameter
public ResolvedType[] temporaryAnnotationTypes;
private ResolvedType[] resolvedTypeParams;
private String binaryPath;
@@ -113,6 +116,10 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
return EMPTY_RESOLVED_TYPE_ARRAY;
}
public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
return null;
}
public final UnresolvedType getSuperclass(World world) {
return getSuperclass();
}
@@ -286,7 +293,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
boolean shouldSkip = false;
for (int j = 0; j < rtx.interTypeMungers.size(); j++) {
ConcreteTypeMunger munger = (ConcreteTypeMunger) rtx.interTypeMungers.get(j);
if (munger.getMunger()!=null && munger.getMunger().getKind() == ResolvedTypeMunger.Parent) {
if (munger.getMunger()!=null && munger.getMunger().getKind() == ResolvedTypeMunger.Parent
&& ((NewParentTypeMunger)munger.getMunger()).getNewParent().equals(iface) // pr171953
) {
shouldSkip = true;
break;
}
@@ -506,7 +515,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
crosscuttingMembers = new CrosscuttingMembers(this,shouldConcretizeIfNeeded);
crosscuttingMembers.setPerClause(getPerClause());
crosscuttingMembers.addShadowMungers(collectShadowMungers());
crosscuttingMembers.addTypeMungers(getTypeMungers());
// GENERICITDFIX
// crosscuttingMembers.addTypeMungers(collectTypeMungers());
crosscuttingMembers.addTypeMungers(getTypeMungers());
//FIXME AV - skip but needed ?? or ?? crosscuttingMembers.addLateTypeMungers(getLateTypeMungers());
crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
@@ -516,6 +527,41 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
return crosscuttingMembers;
}
public final Collection collectTypeMungers() {
if (! this.isAspect() ) return Collections.EMPTY_LIST;
ArrayList ret = new ArrayList();
//if (this.isAbstract()) {
// for (Iterator i = getDeclares().iterator(); i.hasNext();) {
// Declare dec = (Declare) i.next();
// if (!dec.isAdviceLike()) ret.add(dec);
// }
//
// if (!includeAdviceLike) return ret;
if (!this.isAbstract()) {
final Iterators.Filter dupFilter = Iterators.dupFilter();
Iterators.Getter typeGetter = new Iterators.Getter() {
public Iterator get(Object o) {
return
dupFilter.filter(
((ResolvedType)o).getDirectSupertypes());
}
};
Iterator typeIterator = Iterators.recur(this, typeGetter);
while (typeIterator.hasNext()) {
ResolvedType ty = (ResolvedType) typeIterator.next();
for (Iterator i = ty.getTypeMungers().iterator(); i.hasNext();) {
ConcreteTypeMunger dec = (ConcreteTypeMunger) i.next();
ret.add(dec);
}
}
}
return ret;
}
public final Collection collectDeclares(boolean includeAdviceLike) {
if (! this.isAspect() ) return Collections.EMPTY_LIST;
@@ -802,7 +848,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
// ---- types
public static ResolvedType makeArray(ResolvedType type, int dim) {
if (dim == 0) return type;
ResolvedType array = new Array("[" + type.getSignature(),"["+type.getErasureSignature(),type.getWorld(),type);
ResolvedType array = new ArrayReferenceType("[" + type.getSignature(),"["+type.getErasureSignature(),type.getWorld(),type);
return makeArray(array,dim-1);
}
@@ -1159,6 +1205,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
protected void collectInterTypeMungers(List collector) {
for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
ResolvedType superType = (ResolvedType) iter.next();
if (superType == null) {
throw new BCException("UnexpectedProblem: a supertype in the hierarchy for " + this.getName() + " is null");
}
superType.collectInterTypeMungers(collector);
}
@@ -1478,6 +1527,22 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
//??? returning too soon
private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) {
ResolvedMember sig = munger.getSignature();
ResolvedType declaringAspectType = munger.getAspectType();
// if (declaringAspectType.isRawType()) declaringAspectType = declaringAspectType.getGenericType();
// if (declaringAspectType.isGenericType()) {
//
// ResolvedType genericOnType = getWorld().resolve(sig.getDeclaringType()).getGenericType();
// ConcreteTypeMunger ctm = munger.parameterizedFor(discoverActualOccurrenceOfTypeInHierarchy(genericOnType));
// sig = ctm.getSignature(); // possible sig change when type
// }
// if (munger.getMunger().hasTypeVariableAliases()) {
// ResolvedType genericOnType =
// getWorld().resolve(sig.getDeclaringType()).getGenericType();
// ConcreteTypeMunger ctm =
// munger.parameterizedFor(discoverActualOccurrenceOfTypeInHierarchy(genericOnType));
// sig = ctm.getSignature(); // possible sig change when type parameters filled in
// }
while (existingMembers.hasNext()) {
ResolvedMember existingMember = (ResolvedMember)existingMembers.next();
@@ -1506,12 +1571,34 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
// FIXME this whole method seems very hokey - unaware of covariance/varargs/bridging - it
// could do with a rewrite !
boolean sameReturnTypes = (existingMember.getReturnType().equals(sig.getReturnType()));
if (sameReturnTypes)
getWorld().getMessageHandler().handleMessage(
MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
existingMember),
munger.getSourceLocation())
);
if (sameReturnTypes) {
// pr206732 - if the existingMember is due to a previous application of this same ITD (which can
// happen if this is a binary type being brought in from the aspectpath). The 'better' fix is
// to recognize it is from the aspectpath at a higher level and dont do this, but that is rather
// more work.
boolean isDuplicateOfPreviousITD = false;
ResolvedType declaringRt = existingMember.getDeclaringType().resolve(world);
WeaverStateInfo wsi = declaringRt.getWeaverState();
if (wsi!=null) {
List mungersAffectingThisType = wsi.getTypeMungers(declaringRt);
if (mungersAffectingThisType!=null) {
for (Iterator iterator = mungersAffectingThisType.iterator(); iterator.hasNext() && !isDuplicateOfPreviousITD;) {
ConcreteTypeMunger ctMunger = (ConcreteTypeMunger) iterator.next();
// relatively crude check - is the ITD for the same as the existingmember and does it come from the same aspect
if (ctMunger.getSignature().equals(existingMember) && ctMunger.aspectType.equals(munger.getAspectType())) {
isDuplicateOfPreviousITD=true;
}
}
}
}
if (!isDuplicateOfPreviousITD) {
getWorld().getMessageHandler().handleMessage(
MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
existingMember),
munger.getSourceLocation())
);
}
}
}
} else if (isDuplicateMemberWithinTargetType(existingMember,this,sig)) {
getWorld().getMessageHandler().handleMessage(
@@ -2042,7 +2129,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
for (int i = 0; i < typeParameters.length; i++) {
UnresolvedType aType = (ResolvedType)typeParameters[i];
ResolvedType aType = (ResolvedType)typeParameters[i];
if (aType.isTypeVariableReference() &&
// assume the worst - if its definetly not a type declared one, it could be anything
((TypeVariableReference)aType).getTypeVariable().getDeclaringElementKind()!=TypeVariable.TYPE) {

+ 16
- 0
weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java Прегледај датотеку

@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.bridge.ISourceLocation;
@@ -68,6 +69,17 @@ public abstract class ResolvedTypeMunger {
if (declaringType.isRawType()) throw new IllegalStateException("Use generic type, not raw type");
if (declaringType.isParameterizedType()) throw new IllegalStateException("Use generic type, not parameterized type");
}
// boolean aChangeOccurred = false;
//
// UnresolvedType rt = signature.getReturnType();
// if (rt.isParameterizedType() || rt.isGenericType()) {rt = rt.getRawType();aChangeOccurred=true;}
// UnresolvedType[] pt = signature.getParameterTypes();
// for (int i = 0; i < pt.length; i++) {
// if (pt[i].isParameterizedType() || pt[i].isGenericType()) { pt[i] = pt[i].getRawType();aChangeOccurred=true;}
// }
// if (aChangeOccurred) {
// this.signature = new ResolvedMemberImpl(signature.getKind(),signature.getDeclaringType(),signature.getModifiers(),rt,signature.getName(),pt,signature.getExceptions());
// }
}
public void setSourceLocation(ISourceLocation isl) {
@@ -424,5 +436,9 @@ public abstract class ResolvedTypeMunger {
public boolean existsToSupportShadowMunging() {
return false;
}

public ResolvedTypeMunger parameterizeWith(Map m, World w) {
throw new BCException("Dont call parameterizeWith() on a type munger of this kind: "+this.getClass());
}
}

+ 36
- 2
weaver/src/org/aspectj/weaver/Shadow.java Прегледај датотеку

@@ -44,7 +44,7 @@ import org.aspectj.weaver.bcel.BcelAdvice;
public abstract class Shadow {

// every Shadow has a unique id, doesn't matter if it wraps...
private static int nextShadowID = 100; // easier to spot than zero.
private static int nextShadowID = 100; // easier to spot than zero. // OPTIMIZE is this a bug? static?
private final Kind kind;
private final Member signature;
@@ -187,6 +187,18 @@ public abstract class Shadow {
return getSignature()
.getParameterTypes().length;
}
/**
* Return name of the argument at position 'i' at this shadow. This does not
* make sense for all shadows - but can be useful in the case of, for example,
* method-execution.
* @return null if it cannot be determined
*/
public String getArgName(int i,World w) {
String [] names = getSignature().getParameterNames(w);
if (names==null || i>=names.length) return null;
return names[i];
}
public abstract UnresolvedType getEnclosingType();

@@ -732,7 +744,29 @@ public abstract class Shadow {
}
public String toResolvedString(World world) {
return getKind() + "(" + world.resolve(getSignature()).toGenericString() + ")";
StringBuffer sb = new StringBuffer();
sb.append(getKind());
sb.append("(");
Member m = getSignature();
if (m==null) {
sb.append("<<missing signature>>");
} else {
ResolvedMember rm = world.resolve(m);
if (rm==null) {
sb.append("<<unresolvableMember:").append(m).append(">>");
} else {
String genString = rm.toGenericString();
if (genString==null) {
sb.append("<<unableToGetGenericStringFor:").append(rm).append(">>");
} else {
sb.append(genString);
}
}
}
sb.append(")");
return sb.toString();
// was: return getKind() + "(" + world.resolve(getSignature()).toGenericString() + ")";
}

/**

+ 3
- 4
weaver/src/org/aspectj/weaver/ShadowMunger.java Прегледај датотеку

@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/


package org.aspectj.weaver;

import java.io.File;
@@ -42,10 +41,9 @@ import org.aspectj.weaver.patterns.Pointcut;
* which may modify state.
* Then implement is called.
*/

public abstract class ShadowMunger implements PartialOrder.PartialComparable, IHasPosition {
protected Pointcut pointcut;
protected Pointcut pointcut;
// these three fields hold the source location of this munger
protected int start, end;
protected ISourceContext sourceContext;
@@ -62,6 +60,7 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH
this.end = end;
this.sourceContext = sourceContext;
}

public abstract ShadowMunger concretize(ResolvedType fromType, World world, PerClause clause);


+ 2
- 3
weaver/src/org/aspectj/weaver/TypeFactory.java Прегледај датотеку

@@ -102,8 +102,8 @@ public class TypeFactory {
// (see pr122458) It is possible for a parameterized type to have *no* type parameters visible in its signature.
// This happens for an inner type of a parameterized type which simply inherits the type parameters
// of its parent. In this case it is parameterized but theres no < in the signature.
int startOfParams = signature.indexOf('<');
if (startOfParams==-1) {
// Should be an inner type of a parameterized type - could assert there is a '$' in the signature....
String signatureErasure = "L" + signature.substring(1);
@@ -123,7 +123,7 @@ public class TypeFactory {
// the type parameters of interest are only those that apply to the 'last type' in the signature
// if the signature is 'PMyInterface<String>$MyOtherType;' then there are none...
String lastType = null;
int nestedTypePosition = signature.indexOf("$");
int nestedTypePosition = signature.indexOf("$", endOfParams); // don't look for $ INSIDE the parameters
if (nestedTypePosition!=-1) lastType = signature.substring(nestedTypePosition+1);
else lastType = new String(signature);
startOfParams = lastType.indexOf("<");
@@ -132,7 +132,6 @@ public class TypeFactory {
if (startOfParams!=-1) {
typeParams = createTypeParams(lastType.substring(startOfParams +1, endOfParams));
}
return new UnresolvedType(signature,signatureErasure,typeParams);
}
// can't replace above with convertSigToType - leads to stackoverflow

+ 1
- 1
weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java Прегледај датотеку

@@ -70,7 +70,7 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T

public UnresolvedType parameterize(Map typeBindings) {
UnresolvedType ut = (UnresolvedType) typeBindings.get(getName());
if (ut!=null) return ut;
if (ut!=null) return world.resolve(ut);
return this;
}

+ 9
- 6
weaver/src/org/aspectj/weaver/UnresolvedType.java Прегледај датотеку

@@ -26,7 +26,7 @@ import org.aspectj.weaver.tools.Traceable;

/**
* A UnresolvedType represents a type to the weaver. It has a basic signature that knows
* nothing about type variables, type parameters, etc.. TypeXs are resolved in some World
* nothing about type variables, type parameters, etc.. UnresolvedTypes are resolved in some World
* (a repository of types). When a UnresolvedType is resolved it turns into a
* ResolvedType which may be a primitive type, an array type or a ReferenceType.
* ReferenceTypes may refer to simple, generic, parameterized or type-variable
@@ -121,8 +121,8 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
// this doesn't belong here and will get moved to ResolvedType later in the refactoring
public static final String MISSING_NAME = "@missing@";

// OPTIMIZE I dont think you can ask something unresolved what kind of type it is, how can it always know? Push down into resolvedtype
// that will force references to resolvedtypes to be correct rather than relying on unresolvedtypes to answer questions
protected TypeKind typeKind = TypeKind.SIMPLE; // what kind of type am I?

/**
@@ -217,6 +217,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
* that are type variable references are replaced by their matching type variable
* binding.
*/
// OPTIMIZE methods like this just allow callers to be lazy and not ensure they are working with the right (resolved) subtype
public UnresolvedType parameterize(Map typeBindings) {
throw new UnsupportedOperationException("unable to parameterize unresolved type: " + signature);
}
@@ -308,6 +309,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
* @param name the java language type name in question.
* @return a type object representing that java language type.
*/
// OPTIMIZE change users of this to use forSignature, especially for simple cases
public static UnresolvedType forName(String name) {
return forSignature(nameToSignature(name));
}
@@ -464,7 +466,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {

/**
* Returns the name of this type in java language form (e.g. java.lang.Thread or boolean[]).
* This produces a more esthetically pleasing string than {@link java.lang.Class#getName()}.
* This produces a more aesthetically pleasing string than {@link java.lang.Class#getName()}.
*
* @return the java language name of this type.
*/
@@ -664,7 +666,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {

// ---- helpers
public static String signatureToName(String signature) {
private static String signatureToName(String signature) {
switch (signature.charAt(0)) {
case 'B': return "byte";
case 'C': return "char";
@@ -856,7 +858,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
}
public UnresolvedType[] getTypeParameters() {
return typeParameters == null ? new UnresolvedType[0] : typeParameters;
return typeParameters == null ? UnresolvedType.NONE : typeParameters;
}
/**
@@ -905,6 +907,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
* from a generic method/ctor rather than a type variable from a generic type.
* Only subclasses know the answer...
*/
// OPTIMIZE don't allow this to be called, the caller must have a resolved entity
public boolean isParameterizedWithAMemberTypeVariable() {
throw new RuntimeException("I dont know - you should ask a resolved version of me: "+this);
}

+ 4
- 0
weaver/src/org/aspectj/weaver/WeaverMessages.java Прегледај датотеку

@@ -146,6 +146,10 @@ public class WeaverMessages {
public static final String INCORRECT_TARGET_FOR_DECLARE_ANNOTATION = "incorrectTargetForDeclareAnnotation";
public static final String NO_MATCH_BECAUSE_SOURCE_RETENTION = "noMatchBecauseSourceRetention";
// Annotation Value messages
public static final String INVALID_ANNOTATION_VALUE = "invalidAnnotationValue";
public static final String UNKNOWN_ANNOTATION_VALUE = "unknownAnnotationValue";
// < Java5 messages
public static final String ATANNOTATION_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "atannotationNeedsJava5";
public static final String ATWITHIN_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "atwithinNeedsJava5";

+ 0
- 84
weaver/src/org/aspectj/weaver/WeaverMetrics.java Прегледај датотеку

@@ -1,84 +0,0 @@
/* *******************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andy Clement initial implementation
* ******************************************************************/
package org.aspectj.weaver;

import org.aspectj.util.FuzzyBoolean;


/**
* Records stats about the weaver. Information like 'how many types are dismissed during fast match' that
* may be useful for trying to tune pointcuts. Not publicised.
*/
public class WeaverMetrics {
// Level 1 of matching is at the type level, which types can be dismissed?
public static int fastMatchOnTypeAttempted = 0;
public static int fastMatchOnTypeTrue = 0;
public static int fastMatchOnTypeFalse = 0;

// Level 2 of matching is fast matching on the shadows in the remaining types
public static int fastMatchOnShadowsAttempted = 0;
public static int fastMatchOnShadowsTrue = 0;
public static int fastMatchOnShadowsFalse = 0;
// Level 3 of matching is slow matching on the shadows (more shadows than were fast matched on!)
public static int matchTrue = 0;
public static int matchAttempted = 0;


public static void reset() {

fastMatchOnShadowsAttempted = 0;
fastMatchOnShadowsTrue = 0;
fastMatchOnShadowsFalse = 0;

fastMatchOnTypeAttempted = 0;
fastMatchOnTypeTrue = 0;
fastMatchOnTypeFalse = 0;
matchTrue = 0;
matchAttempted = 0;
}

public static void dumpInfo() {
System.err.println("Match summary:");
int fastMatchOnTypeMaybe = (fastMatchOnTypeAttempted-fastMatchOnTypeTrue-fastMatchOnTypeFalse);
System.err.print("At the type level, we attempted #"+fastMatchOnTypeAttempted+" fast matches:");
System.err.println(" YES/NO/MAYBE = "+fastMatchOnTypeTrue+"/"+fastMatchOnTypeFalse+"/"+fastMatchOnTypeMaybe);
int fastMatchMaybe = (fastMatchOnShadowsAttempted-fastMatchOnShadowsFalse-fastMatchOnShadowsTrue);
System.err.print("Within those #"+(fastMatchOnTypeTrue+fastMatchOnTypeMaybe)+" possible types, ");
System.err.print("we fast matched on #"+fastMatchOnShadowsAttempted+" shadows:");
System.err.println(" YES/NO/MAYBE = "+fastMatchOnShadowsTrue+"/"+fastMatchOnShadowsFalse+"/"+fastMatchMaybe);
System.err.println("Shadow (non-fast) matches attempted #"+matchAttempted+" of which "+matchTrue+" successful");
}

public static void recordFastMatchTypeResult(FuzzyBoolean fb) {
fastMatchOnTypeAttempted++;
if (fb.alwaysTrue()) fastMatchOnTypeTrue++;
if (fb.alwaysFalse()) fastMatchOnTypeFalse++;
}
public static void recordFastMatchResult(FuzzyBoolean fb) {
fastMatchOnShadowsAttempted++;
if (fb.alwaysTrue()) fastMatchOnShadowsTrue++;
if (fb.alwaysFalse()) fastMatchOnShadowsFalse++;
}
public static void recordMatchResult(boolean b) {
matchAttempted++;
if (b) matchTrue++;
}

}

+ 1
- 1
weaver/src/org/aspectj/weaver/WeaverStateInfo.java Прегледај датотеку

@@ -139,7 +139,7 @@ public class WeaverStateInfo {
readAnyReweavableData(wsi,s);
return wsi;
}
throw new RuntimeException("bad WeaverState.Kind: " + b);
throw new RuntimeException("bad WeaverState.Kind: " + b+". File was :"+(context==null?"unknown":context.makeSourceLocation(0,0).toString()));
}

+ 66
- 11
weaver/src/org/aspectj/weaver/World.java Прегледај датотеку

@@ -17,13 +17,17 @@ package org.aspectj.weaver;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.WeakHashMap;

import org.aspectj.asm.IHierarchy;
import org.aspectj.bridge.IMessageHandler;
@@ -38,9 +42,9 @@ import org.aspectj.weaver.patterns.DeclarePrecedence;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate;
import org.aspectj.weaver.tools.PointcutDesignatorHandler;
import org.aspectj.weaver.tools.Trace;
import org.aspectj.weaver.tools.TraceFactory;
import java.util.*;

/**
* A World is a collection of known types and crosscutting members.
@@ -58,6 +62,9 @@ public abstract class World implements Dump.INode {
/** The heart of the world, a map from type signatures to resolved types */
protected TypeMap typeMap = new TypeMap(this); // Signature to ResolvedType

/** New pointcut designators this world supports */
private Set pointcutDesignators;

// see pr145963
/** Should we create the hierarchy for binary classes and aspects*/
public static boolean createInjarHierarchy = true;
@@ -111,6 +118,7 @@ public abstract class World implements Dump.INode {
private boolean runMinimalMemory = false;
private boolean shouldPipelineCompilation = true;
protected boolean bcelRepositoryCaching = xsetBCEL_REPOSITORY_CACHING_DEFAULT.equalsIgnoreCase("true");
private boolean goforit = false; // TODO better name
private boolean completeBinaryTypes = false;
public boolean forDEBUG_structuralChangesCode = false;
public boolean forDEBUG_bridgingCode = false;
@@ -265,7 +273,7 @@ public abstract class World implements Dump.INode {
if (ty.isArray()) {
ResolvedType componentType = resolve(ty.getComponentType(),allowMissing);
//String brackets = signature.substring(0,signature.lastIndexOf("[")+1);
ret = new ResolvedType.Array(signature, "["+componentType.getErasureSignature(),
ret = new ArrayReferenceType(signature, "["+componentType.getErasureSignature(),
this,
componentType);
} else {
@@ -788,6 +796,8 @@ public abstract class World implements Dump.INode {
public Properties getExtraConfiguration() {
return extraConfiguration;
}
public final static String xsetWEAVE_JAVA_PACKAGES = "weaveJavaPackages"; // default false - controls LTW
public final static String xsetWEAVE_JAVAX_PACKAGES = "weaveJavaxPackages"; // default false - controls LTW
public final static String xsetCAPTURE_ALL_CONTEXT = "captureAllContext"; // default false
public final static String xsetACTIVATE_LIGHTWEIGHT_DELEGATES = "activateLightweightDelegates"; // default true
public final static String xsetRUN_MINIMAL_MEMORY ="runMinimalMemory"; // default true
@@ -799,6 +809,7 @@ public abstract class World implements Dump.INode {
public final static String xsetCOMPLETE_BINARY_TYPES = "completeBinaryTypes";
public final static String xsetCOMPLETE_BINARY_TYPES_DEFAULT = "false";
public final static String xsetBCEL_REPOSITORY_CACHING_DEFAULT = "true";
public final static String xsetGO_FOR_IT = "goforit";
public boolean isInJava5Mode() {
return behaveInJava5Way;
@@ -817,7 +828,6 @@ public abstract class World implements Dump.INode {
public boolean isJoinpointArrayConstructionEnabled() {
return optionalJoinpoint_ArrayConstruction;
}

public boolean isJoinpointSynchronizationEnabled() {
return optionalJoinpoint_Synchronization;
}
@@ -856,7 +866,7 @@ public abstract class World implements Dump.INode {
private Map /* String -> ResolvedType */ tMap = new HashMap();
// Map of types that may be ejected from the cache if we need space
private Map expendableMap = new SoftHashMap();
private Map expendableMap = Collections.synchronizedMap(new WeakHashMap());//new SoftHashMap();
public static class SoftHashMap extends AbstractMap {
private Map map;
@@ -1020,16 +1030,32 @@ public abstract class World implements Dump.INode {
String key = (String) iter.next();
ResolvedType type = (ResolvedType)tMap.get(key);
if (type==null) continue;//throw new RuntimeException("Unexpected!! "+key);
if (type.isAspect() ) continue;
if (type.isAspect() || (type.getSuperclass()!=null && type.getSuperclass().isAspect())) continue;
if (type.equals(UnresolvedType.OBJECT)) continue;
if (type.isPrimitiveType()) continue;
List typeMungers = type.getInterTypeMungers();
if (typeMungers==null || typeMungers.size()==0) {
// demote - we can recover this
tMap.remove(key);
// didnt achieve anything...
// // force the data out of memory - this may not happen if a bcel object type was loaded for
// // something not necessarily being woven as that will never go through the lifecycle states
// ReferenceTypeDelegate delly = ((ReferenceType)type).getDelegate();
// if (delly instanceof BcelObjectType) {
// ((BcelObjectType)delly).weavingCompleted();
// // that shouldnt be weavingCompleted, but it will do for now...
// }
// extreme demotion if you dont use these next two lines!
// if (memoryProfiling) expendableMap.put(key,new SoftReference(type,rq));
// else expendableMap.put(key,new SoftReference(type));
if (policy==USE_WEAK_REFS) {
if (memoryProfiling) expendableMap.put(key,new WeakReference(type,rq));
else expendableMap.put(key,new WeakReference(type));
} else if (policy==USE_SOFT_REFS) {
if (memoryProfiling) expendableMap.put(key,new SoftReference(type,rq));
else expendableMap.put(key,new SoftReference(type));
} else {
expendableMap.put(key,type);
}
count++;
}
}
@@ -1140,11 +1166,11 @@ public abstract class World implements Dump.INode {
public int hardSize() {
return tMap.size();
}
}
}
public void demote() {
typeMap.demote();
}
}
/** Reference types we don't intend to weave may be ejected from
* the cache if we need the space.
@@ -1157,7 +1183,6 @@ public abstract class World implements Dump.INode {
(!type.isPrimitiveType())
);
}

/**
* This class is used to compute and store precedence relationships between
@@ -1290,6 +1315,10 @@ public abstract class World implements Dump.INode {
if (!bcelRepositoryCaching) {
getMessageHandler().handleMessage(MessageUtil.info("[bcelRepositoryCaching=false] AspectJ will not use a bcel cache for class information"));
}

s = p.getProperty(xsetGO_FOR_IT,"false");
goforit = s.equalsIgnoreCase("true");
s = p.getProperty(xsetPIPELINE_COMPILATION,xsetPIPELINE_COMPILATION_DEFAULT);
shouldPipelineCompilation = s.equalsIgnoreCase("true");
@@ -1321,6 +1350,11 @@ public abstract class World implements Dump.INode {
ensureAdvancedConfigurationProcessed();
return runMinimalMemory;
}

public boolean shouldGoForIt() {
ensureAdvancedConfigurationProcessed();
return goforit;
}
public boolean shouldPipelineCompilation() {
ensureAdvancedConfigurationProcessed();
@@ -1353,4 +1387,25 @@ public abstract class World implements Dump.INode {
public boolean isASMAround() {
return isASMAround;
}
//
// public ResolvedType[] getAllTypes() {
// return typeMap.getAllTypes();
// }

/**
* Register a new pointcut designator handler with the world - this can be used by any pointcut parsers attached
* to the world.
*
* @param designatorHandler handler for the new pointcut
*/
public void registerPointcutHandler(PointcutDesignatorHandler designatorHandler) {
if (pointcutDesignators == null) pointcutDesignators = new HashSet();
pointcutDesignators.add(designatorHandler);
}
public Set getRegisteredPointcutHandlers() {
if (pointcutDesignators == null) return Collections.EMPTY_SET;
return pointcutDesignators;
}
}

+ 2
- 1
weaver/src/org/aspectj/weaver/XlintDefault.properties Прегледај датотеку

@@ -41,4 +41,5 @@ cantFindTypeAffectingJPMatch = warning
unorderedAdviceAtShadow=ignore
swallowedExceptionInCatchBlock=ignore
calculatingSerialVersionUID=ignore
advisingSynchronizedMethods=warning
advisingSynchronizedMethods=warning
mustWeaveXmlDefinedAspects=warning

+ 6
- 6
weaver/src/org/aspectj/weaver/ast/Not.java Прегледај датотеку

@@ -15,11 +15,11 @@ package org.aspectj.weaver.ast;


public class Not extends Test {
Test body;
Test test;

public Not(Test left) {
public Not(Test test) {
super();
this.body = left;
this.test = test;
}

public void accept(ITestVisitor v) {
@@ -27,17 +27,17 @@ public class Not extends Test {
}
public Test getBody() {
return body;
return test;
}
public String toString() {
return "!" + body;
return "!" + test;
}

public boolean equals(Object other) {
if (other instanceof Not) {
Not o = (Not) other;
return o.body.equals(body);
return o.test.equals(test);
} else {
return false;
}

+ 5
- 6
weaver/src/org/aspectj/weaver/ast/Var.java Прегледај датотеку

@@ -15,21 +15,20 @@ package org.aspectj.weaver.ast;

import org.aspectj.weaver.ResolvedType;


public class Var extends Expr {
ResolvedType type;
ResolvedType variableType;

public Var(ResolvedType type) {
public Var(ResolvedType variableType) {
super();
this.type = type;
this.variableType = variableType;
}
public ResolvedType getType() {
return type;
return variableType;
}

public String toString() {
return "(Var " + type + ")";
return "(Var " + variableType + ")";
}
public void accept(IExprVisitor v) {

weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java → weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java Прегледај датотеку

@@ -1,5 +1,5 @@
/* *******************************************************************
* Copyright (c) 2005 IBM
* Copyright (c) 2005-2008 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
@@ -10,7 +10,6 @@
* Andy Clement initial implementation
* ******************************************************************/


package org.aspectj.weaver.bcel;

import org.aspectj.apache.bcel.Constants;
@@ -26,149 +25,119 @@ import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.Shadow.Kind;


/**
* Represents access to an annotation on an element, relating to some 'kinded' pointcut.
* Depending on the kind of pointcut the element might be a field or a method or a ...
* Represents access to an annotation on an element, relating to some kinded pointcut.
* Depending on the kind of pointcut the element might be a field or a method and the code
* generators in here can retrieve the annotation from the element.
*/
public class KindedAnnotationAccessVar extends BcelVar {
public class AnnotationAccessVar extends BcelVar {

private Kind kind; // What kind of shadow are we at?
private UnresolvedType containingType; // The type upon which we want to ask for 'member'
private Member member; // For method call/execution and field get/set contains the member that has the annotation
private Kind kind; // What kind of shadow are we at?
private UnresolvedType containingType; // The type upon which we want to ask for 'member'
private Member member; // Holds the member that has the annotations (for method/field join points)
public KindedAnnotationAccessVar(Kind kind, ResolvedType type,UnresolvedType theTargetIsStoredHere,Member sig) {
super(type,0);
public AnnotationAccessVar(Kind kind, ResolvedType annotationType, UnresolvedType theTargetIsStoredHere, Member sig) {
super(annotationType,0);
this.kind = kind;
this.containingType = theTargetIsStoredHere;
this.member = sig;
}

public String toString() {
return "KindedAnnotationAccessVar(" + getType() +")";
return "AnnotationAccessVar(" + getType() +")";
}

public Instruction createLoad(InstructionFactory fact) {
throw new RuntimeException("unimplemented");
throw new IllegalStateException("unimplemented");
}
public Instruction createStore(InstructionFactory fact) {
throw new RuntimeException("unimplemented");
throw new IllegalStateException("unimplemented");
}

public InstructionList createCopyFrom(InstructionFactory fact, int oldSlot) {
throw new RuntimeException("unimplemented");
throw new IllegalStateException("unimplemented");
}
public void appendLoad(InstructionList il, InstructionFactory fact) {
il.append(createLoadInstructions(getType(), fact));
}

// FIXME asc Refactor all this stuff - there is a lot of commonality
public InstructionList createLoadInstructions(ResolvedType toType, InstructionFactory fact) {
// FIXME asc Decide on whether we ought to build an exception handler for the NoSuchMethodException that can be thrown
// by getDeclaredMethod()... right now we don't but no-one seems to care...
// LocalVariableGen var_ex = mg.addLocalVariable("ex",Type.getType("Ljava.io.IOException;"),null,null);
// int var_ex_slot = var_ex.getIndex();
//
// InstructionHandle handler = il.append(new ASTORE(var_ex_slot));
// var_ex.setStart(handler);
// var_ex.setEnd(il.append(InstructionConstants.RETURN));
//
// mg.addExceptionHandler(try_start, try_end, handler,
// new ObjectType("java.io.IOException"));
public void appendLoadAndConvert(InstructionList il, InstructionFactory fact, ResolvedType toType) {
il.append(createLoadInstructions(toType, fact));
}

public void insertLoad(InstructionList il, InstructionFactory fact) {
il.insert(createLoadInstructions(getType(), fact));
}

private InstructionList createLoadInstructions(ResolvedType toType, InstructionFactory fact) {
InstructionList il = new InstructionList();
Type jlClass = BcelWorld.makeBcelType(UnresolvedType.JAVA_LANG_CLASS);

Type jlString = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.String;"));
Type jlClassArray = BcelWorld.makeBcelType(UnresolvedType.forSignature("[Ljava.lang.Class;"));
Type jlClassArray = BcelWorld.makeBcelType(UnresolvedType.forSignature("[Ljava.lang.Class;"));
Type jlaAnnotation = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.annotation.Annotation;"));

Instruction pushConstant = fact.createConstant(new ObjectType(toType.getName()));
if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution ||
kind==Shadow.PreInitialization || kind==Shadow.Initialization ||
kind==Shadow.ConstructorCall || kind==Shadow.ConstructorExecution ||
kind==Shadow.AdviceExecution ||
// annotations for fieldset/fieldget when an ITD is involved are stored against a METHOD
((kind==Shadow.FieldGet || kind==Shadow.FieldSet) && member.getKind()==Member.METHOD)) {
((kind==Shadow.FieldGet || kind==Shadow.FieldSet) && member.getKind()==Member.METHOD)) {
Type jlrMethod = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Method;"));
// Calls getClass
// Variant (1) Use the target directly
il.append(fact.createConstant(BcelWorld.makeBcelType(containingType)));
// Variant (2) Ask the target for its class (could give a different answer at runtime)
// il.append(target.createLoad(fact));
// il.append(fact.createInvoke("java/lang/Object","getClass",jlClass,new Type[]{},Constants.INVOKEVIRTUAL));
// il.append(fact.createConstant(new ObjectType(toType.getClassName())));
if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution || kind==Shadow.AdviceExecution ||
Type[] paramTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());

il.append(fact.createConstant(BcelWorld.makeBcelType(containingType)));
if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution || kind==Shadow.AdviceExecution ||
// annotations for fieldset/fieldget when an ITD is involved are stored against a METHOD
((kind==Shadow.FieldGet || kind==Shadow.FieldSet) && member.getKind()==Member.METHOD) ||
((kind==Shadow.ConstructorCall || kind==Shadow.ConstructorExecution) && member.getKind()==Member.METHOD)) {
il.append(fact.createConstant(member.getName()));
Type[] paramTypes = null;
paramTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());
buildArray(il,fact,jlClass,paramTypes,1);
// Calls getDeclaredMethod
il.append(fact.createInvoke("java/lang/Class","getDeclaredMethod",jlrMethod,new Type[]{jlString,jlClassArray},Constants.INVOKEVIRTUAL));
// FIXME asc perf Cache the result of getDeclaredMethod() and use it
// again for other annotations on the same signature at this join point
// Calls getAnnotation
String ss = toType.getName();
il.append(fact.createConstant(new ObjectType(toType.getName())));
il.append(fact.createInvoke("java/lang/reflect/Method","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
} else { // init/preinit/ctor-call/ctor-exec
Type[] paramTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());
buildArray(il,fact,jlClass,paramTypes,1);
Type jlrCtor = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Constructor;"));
il.append(fact.createInvoke("java/lang/Class","getDeclaredConstructor",jlrCtor,new Type[]{jlClassArray},Constants.INVOKEVIRTUAL));
// !!! OPTIMIZATION: Cache the result of getDeclaredMethod() and use it
// again for other annotations on the same signature at this join point
// Calls getAnnotation
String ss = toType.getName();
il.append(fact.createConstant(new ObjectType(toType.getName())));
il.append(fact.createInvoke("java/lang/reflect/Constructor","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
}
} else if (kind == Shadow.FieldSet || kind == Shadow.FieldGet) {

il.append(fact.createConstant(member.getName()));
buildArray(il,fact,jlClass,paramTypes,1);
// OPTIMIZE cache result of getDeclaredMethod and getAnnotation? Might be able to use it again if someone else needs the same annotations?
il.append(fact.createInvoke("java/lang/Class","getDeclaredMethod",jlrMethod,new Type[]{jlString,jlClassArray},Constants.INVOKEVIRTUAL));
il.append(pushConstant);//fact.createConstant(new ObjectType(toType.getName())));
il.append(fact.createInvoke("java/lang/reflect/Method","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
} else { // init/preinit/ctor-call/ctor-exec
buildArray(il,fact,jlClass,paramTypes,1);
Type jlrCtor = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Constructor;"));
// OPTIMIZE cache result of getDeclaredConstructor and getAnnotation? Might be able to use it again if someone else needs the same annotations?
il.append(fact.createInvoke("java/lang/Class","getDeclaredConstructor",jlrCtor,new Type[]{jlClassArray},Constants.INVOKEVIRTUAL));
il.append(pushConstant);
il.append(fact.createInvoke("java/lang/reflect/Constructor","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
}
} else if (kind == Shadow.FieldSet || kind == Shadow.FieldGet) {
Type jlrField = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Field;"));
il.append(fact.createConstant(BcelWorld.makeBcelType(containingType))); // Stick the target on the stack
il.append(fact.createConstant(member.getName())); // Stick what we are after on the stack
il.append(fact.createInvoke("java/lang/Class","getDeclaredField",jlrField,new Type[]{jlString},Constants.INVOKEVIRTUAL));
String ss = toType.getName();
il.append(fact.createConstant(new ObjectType(toType.getName())));
il.append(fact.createInvoke("java/lang/reflect/Field","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
} else if (kind == Shadow.StaticInitialization || kind==Shadow.ExceptionHandler) {
il.append(pushConstant);
il.append(fact.createInvoke("java/lang/reflect/Field","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
} else if (kind == Shadow.StaticInitialization || kind==Shadow.ExceptionHandler) {
il.append(fact.createConstant(BcelWorld.makeBcelType(containingType)));
String ss = toType.getName();
il.append(fact.createConstant(new ObjectType(toType.getName())));
il.append(fact.createInvoke("java/lang/Class","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
il.append(pushConstant);
il.append(fact.createInvoke("java/lang/Class","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
} else {
throw new RuntimeException("Don't understand this kind "+kind);
throw new RuntimeException("Don't understand this kind "+kind);
}
il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
return il;
}

private void buildArray(InstructionList il, InstructionFactory fact, Type arrayElementType, Type[] arrayEntries,int dim) {
il.append(fact.createConstant(new Integer(arrayEntries==null?0:arrayEntries.length)));
il.append(fact.createConstant(Integer.valueOf(arrayEntries==null?0:arrayEntries.length)));
il.append(fact.createNewArray(arrayElementType,(short)dim));
if (arrayEntries == null) return;
for (int i = 0; i < arrayEntries.length; i++) {
il.append(InstructionFactory.createDup(1));
il.append(fact.createConstant(new Integer(i)));
il.append(fact.createConstant(Integer.valueOf(i)));
switch (arrayEntries[i].getType()) {
case Constants.T_ARRAY:
il.append(fact.createConstant(new ObjectType(arrayEntries[i].getSignature())));
@@ -188,16 +157,4 @@ public class KindedAnnotationAccessVar extends BcelVar {
}
}

public void appendLoadAndConvert(
InstructionList il,
InstructionFactory fact,
ResolvedType toType) {
il.append(createLoadInstructions(toType, fact));

}

public void insertLoad(InstructionList il, InstructionFactory fact) {
il.insert(createLoadInstructions(getType(), fact));
}

}

+ 201
- 128
weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java Прегледај датотеку

@@ -17,6 +17,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Attribute;
@@ -74,9 +75,7 @@ import org.aspectj.weaver.patterns.SimpleScope;
import org.aspectj.weaver.patterns.TypePattern;

/**
* Annotation defined aspect reader.
* <p/>
* It reads the Java 5 annotations and turns them into AjAttributes
* Annotation defined aspect reader. Reads the Java 5 annotations and turns them into AjAttributes
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
@@ -85,6 +84,7 @@ public class AtAjAttributes {
private final static List EMPTY_LIST = new ArrayList();
private final static String[] EMPTY_STRINGS = new String[0];
private final static String VALUE = "value";
private final static String ARGNAMES = "argNames";
private final static String POINTCUT = "pointcut";
private final static String THROWING = "throwing";
private final static String RETURNING = "returning";
@@ -92,8 +92,6 @@ public class AtAjAttributes {

/**
* A struct that allows to add extra arguments without always breaking the API
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
private static class AjAttributeStruct {

@@ -124,11 +122,9 @@ public class AtAjAttributes {
*/
private static class AjAttributeMethodStruct extends AjAttributeStruct {

/**
* Argument names as they appear in the SOURCE code, ordered, and lazyly populated
* Used to do formal binding
*/
// argument names used for formal binding
private String[] m_argumentNamesLazy = null;
public String unparsedArgumentNames = null; // Set only if discovered as argNames attribute of annotation

final Method method;
final BcelMethod bMethod;
@@ -141,7 +137,7 @@ public class AtAjAttributes {

public String[] getArgumentNames() {
if (m_argumentNamesLazy == null) {
m_argumentNamesLazy = getMethodArgumentNamesAsInSource(method);
m_argumentNamesLazy = getMethodArgumentNames(method,unparsedArgumentNames,this);
}
return m_argumentNamesLazy;
}
@@ -149,8 +145,6 @@ public class AtAjAttributes {

/**
* A struct when we read @AJ on field
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
private static class AjAttributeFieldStruct extends AjAttributeStruct {

@@ -184,15 +178,19 @@ public class AtAjAttributes {
* @return list of AjAttributes
*/
public static List readAj5ClassAttributes(JavaClass javaClass, ReferenceType type, ISourceContext context, IMessageHandler msgHandler, boolean isCodeStyleAspect) {
//FIXME AV - 1.5 feature limitation, kick after implemented
try {
Constant[] cpool = javaClass.getConstantPool().getConstantPool();
for (int i = 0; i < cpool.length; i++) {
Constant constant = cpool[i];
if (constant != null && constant.getTag() == Constants.CONSTANT_Utf8) {
if (!javaClass.getClassName().startsWith("org.aspectj.lang.annotation")) {
ConstantUtf8 constantUtf8 = (ConstantUtf8) constant;
if ("Lorg/aspectj/lang/annotation/DeclareAnnotation;".equals(constantUtf8.getBytes())) {
boolean ignoreThisClass = javaClass.getClassName().charAt(0)=='o' && javaClass.getClassName().startsWith("org.aspectj.lang.annotation");
if (ignoreThisClass) return EMPTY_LIST;
boolean containsPointcut = false;
boolean containsAnnotationClassReference = false;
Constant[] cpool = javaClass.getConstantPool().getConstantPool();
for (int i = 0; i < cpool.length; i++) {
Constant constant = cpool[i];
if (constant != null && constant.getTag() == Constants.CONSTANT_Utf8) {
String constantValue = ((ConstantUtf8)constant).getBytes();
if (constantValue.length()>28 && constantValue.charAt(1)=='o') {
if (constantValue.startsWith("Lorg/aspectj/lang/annotation")) {
containsAnnotationClassReference=true;
if ("Lorg/aspectj/lang/annotation/DeclareAnnotation;".equals(constantValue)) {
msgHandler.handleMessage(
new Message(
"Found @DeclareAnnotation while current release does not support it (see '" + type.getName() + "')",
@@ -202,13 +200,14 @@ public class AtAjAttributes {
)
);
}
}
if ("Lorg/aspectj/lang/annotation/Pointcut;".equals(constantValue)) {
containsPointcut=true;
}
}
}
}
} catch (Throwable t) {
;
}
if (!containsAnnotationClassReference) return EMPTY_LIST;

AjAttributeStruct struct = new AjAttributeStruct(type, context, msgHandler);
Attribute[] attributes = javaClass.getAttributes();
@@ -219,7 +218,7 @@ public class AtAjAttributes {
Attribute attribute = attributes[i];
if (acceptAttribute(attribute)) {
RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
// we don't need to look for several attribute occurence since it cannot happen as per JSR175
// we don't need to look for several attribute occurrences since it cannot happen as per JSR175
if (!isCodeStyleAspect && !javaClass.isInterface()) {
hasAtAspectAnnotation = handleAspectAnnotation(rvs, struct);
//TODO AV - if put outside the if isCodeStyleAspect then we would enable mix style
@@ -245,11 +244,10 @@ public class AtAjAttributes {
}

// the following block will not detect @Pointcut in non @Aspect types for optimization purpose
if (!hasAtAspectAnnotation) {
if (!hasAtAspectAnnotation && !containsPointcut) {
return EMPTY_LIST;
}


//FIXME AV - turn on when ajcMightHaveAspect
// if (hasAtAspectAnnotation && type.isInterface()) {
// msgHandler.handleMessage(
@@ -282,31 +280,35 @@ public class AtAjAttributes {
// we need to gather the @AJ pointcut right now and not at method level annotation extraction time
// in order to be able to resolve the pointcut references later on
// we don't need to look in super class, the pointcut reference in the grammar will do it
for (int i = 0; i < javaClass.getMethods().length; i++) {
Method method = javaClass.getMethods()[i];
if (method.getName().startsWith(NameMangler.PREFIX)) continue; // already dealt with by ajc...
//FIXME alex optimize, this method struct will gets recreated for advice extraction
AjAttributeMethodStruct mstruct = new AjAttributeMethodStruct(method, null, type, context, msgHandler);//FIXME AVASM
AjAttributeMethodStruct mstruct = null;
boolean processedPointcut = false;
Attribute[] mattributes = method.getAttributes();

for (int j = 0; j < mattributes.length; j++) {
Attribute mattribute = mattributes[j];
if (acceptAttribute(mattribute)) {
RuntimeAnnotations mrvs = (RuntimeAnnotations) mattribute;
handlePointcutAnnotation(mrvs, mstruct);
if (mstruct==null) mstruct = new AjAttributeMethodStruct(method, null, type, context, msgHandler);//FIXME AVASM
processedPointcut = handlePointcutAnnotation((RuntimeAnnotations) mattribute, mstruct);
// there can only be one RuntimeVisible bytecode attribute
break;
}
}
// FIXME asc should check we aren't adding multiple versions... will do once I get the tests passing again...
struct.ajAttributes.add(new AjAttribute.WeaverVersionInfo());
struct.ajAttributes.addAll(mstruct.ajAttributes);
if (processedPointcut) {
// FIXME asc should check we aren't adding multiple versions... will do once I get the tests passing again...
struct.ajAttributes.add(new AjAttribute.WeaverVersionInfo());
struct.ajAttributes.addAll(mstruct.ajAttributes);
}
}


// code style declare error / warning / implements / parents are field attributes
for (int i = 0; i < javaClass.getFields().length; i++) {
Field field = javaClass.getFields()[i];
Field[] fs = javaClass.getFields();
for (int i = 0; i < fs.length; i++) {
Field field = fs[i];
if (field.getName().startsWith(NameMangler.PREFIX)) continue; // already dealt with by ajc...
//FIXME alex optimize, this method struct will gets recreated for advice extraction
AjAttributeFieldStruct fstruct = new AjAttributeFieldStruct(field, null, type, context, msgHandler);
@@ -742,28 +744,27 @@ public class AtAjAttributes {
for (int i = 0; i < methods.length; i++) {
ResolvedMember method = (ResolvedMember)methods[i];
if (method.isAbstract()) {
if (defaultImplClassName == null) {
// non marker interface with no default impl provided
reportError("@DeclareParents: used with a non marker interface and no defaultImpl=\"...\" provided", struct);
return false;
}
// moved to be detected at weave time if the target doesnt implement the methods
// if (defaultImplClassName == null) {
// // non marker interface with no default impl provided
// reportError("@DeclareParents: used with a non marker interface and no defaultImpl=\"...\" provided", struct);
// return false;
// }
hasAtLeastOneMethod = true;

struct.ajAttributes.add(
new AjAttribute.TypeMunger(
new MethodDelegateTypeMunger(
method,
struct.enclosingType,
defaultImplClassName,
typePattern
)
)
);
MethodDelegateTypeMunger mdtm =
new MethodDelegateTypeMunger(
method,
struct.enclosingType,
defaultImplClassName,
typePattern
);
mdtm.setSourceLocation(struct.enclosingType.getSourceLocation());
struct.ajAttributes.add(new AjAttribute.TypeMunger(mdtm));
}
}
// successfull so far, we thus need a bcel type munger to have
// a field hosting the mixin in the target type
if (hasAtLeastOneMethod) {
if (hasAtLeastOneMethod && defaultImplClassName!=null) {
struct.ajAttributes.add(
new AjAttribute.TypeMunger(
new MethodDelegateTypeMunger.FieldHostTypeMunger(
@@ -802,6 +803,10 @@ public class AtAjAttributes {
ElementNameValuePairGen beforeAdvice = getAnnotationElement(before, VALUE);
if (beforeAdvice != null) {
// this/target/args binding
String argumentNames = getArgNamesValue(before);
if (argumentNames!=null) {
struct.unparsedArgumentNames = argumentNames;
}
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
try {
bindings = extractBindings(struct);
@@ -859,6 +864,10 @@ public class AtAjAttributes {
if (afterAdvice != null) {
// this/target/args binding
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
String argumentNames = getArgNamesValue(after);
if (argumentNames!=null) {
struct.unparsedArgumentNames = argumentNames;
}
try {
bindings = extractBindings(struct);
} catch (UnreadableDebugInfoException unreadableDebugInfoException) {
@@ -948,7 +957,10 @@ public class AtAjAttributes {
}
}
}

String argumentNames = getArgNamesValue(after);
if (argumentNames!=null) {
struct.unparsedArgumentNames = argumentNames;
}
// this/target/args binding
// exclude the return binding from the pointcut binding since it is an extraArg binding
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
@@ -1045,7 +1057,10 @@ public class AtAjAttributes {
}
}
}

String argumentNames = getArgNamesValue(after);
if (argumentNames!=null) {
struct.unparsedArgumentNames = argumentNames;
}
// this/target/args binding
// exclude the throwned binding from the pointcut binding since it is an extraArg binding
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
@@ -1106,7 +1121,11 @@ public class AtAjAttributes {
if (around != null) {
ElementNameValuePairGen aroundAdvice = getAnnotationElement(around, VALUE);
if (aroundAdvice != null) {
// this/target/args binding
// this/target/args binding
String argumentNames = getArgNamesValue(around);
if (argumentNames!=null) {
struct.unparsedArgumentNames = argumentNames;
}
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
try {
bindings = extractBindings(struct);
@@ -1154,83 +1173,93 @@ public class AtAjAttributes {
*
* @param runtimeAnnotations
* @param struct
* @return true if a pointcut was handled
*/
private static void handlePointcutAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
private static boolean handlePointcutAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
AnnotationGen pointcut = getAnnotation(runtimeAnnotations, AjcMemberMaker.POINTCUT_ANNOTATION);
if (pointcut != null) {
ElementNameValuePairGen pointcutExpr = getAnnotationElement(pointcut, VALUE);

// semantic check: the method must return void, or be "public static boolean" for if() support
if (!(Type.VOID.equals(struct.method.getReturnType())
|| (Type.BOOLEAN.equals(struct.method.getReturnType()) && struct.method.isStatic() && struct.method.isPublic()))) {
reportWarning("Found @Pointcut on a method not returning 'void' or not 'public static boolean'", struct);
;//no need to stop
}
if (pointcut==null) return false;
ElementNameValuePairGen pointcutExpr = getAnnotationElement(pointcut, VALUE);

// semantic check: the method must not throw anything
if (struct.method.getExceptionTable() != null) {
reportWarning("Found @Pointcut on a method throwing exception", struct);
;// no need to stop
}
// semantic check: the method must return void, or be "public static boolean" for if() support
if (!(Type.VOID.equals(struct.method.getReturnType())
|| (Type.BOOLEAN.equals(struct.method.getReturnType()) && struct.method.isStatic() && struct.method.isPublic()))) {
reportWarning("Found @Pointcut on a method not returning 'void' or not 'public static boolean'", struct);
;//no need to stop
}

// this/target/args binding
final IScope binding;
try {
// semantic check: the method must not throw anything
if (struct.method.getExceptionTable() != null) {
reportWarning("Found @Pointcut on a method throwing exception", struct);
;// no need to stop
}

String argumentNames = getArgNamesValue(pointcut);
if (argumentNames!=null) {
struct.unparsedArgumentNames = argumentNames;
}
// this/target/args binding
final IScope binding;
try {
if (struct.method.isAbstract()) {
binding = null;
} else {
binding = new BindingScope(
struct.enclosingType,
struct.context,
extractBindings(struct)
struct.enclosingType,
struct.context,
extractBindings(struct)
);
} catch (UnreadableDebugInfoException e) {
return;
}
}
} catch (UnreadableDebugInfoException e) {
return false;
}

UnresolvedType[] argumentTypes = new UnresolvedType[struct.method.getArgumentTypes().length];
for (int i = 0; i < argumentTypes.length; i++) {
argumentTypes[i] = UnresolvedType.forSignature(struct.method.getArgumentTypes()[i].getSignature());
}
UnresolvedType[] argumentTypes = new UnresolvedType[struct.method.getArgumentTypes().length];
for (int i = 0; i < argumentTypes.length; i++) {
argumentTypes[i] = UnresolvedType.forSignature(struct.method.getArgumentTypes()[i].getSignature());
}

Pointcut pc = null;
if (struct.method.isAbstract()) {
if ((pointcutExpr != null && isNullOrEmpty(pointcutExpr.getValue().stringifyValue()))
|| pointcutExpr == null) {
// abstract pointcut
// leave pc = null
} else {
reportError("Found defined @Pointcut on an abstract method", struct);
return;//stop
}
Pointcut pc = null;
if (struct.method.isAbstract()) {
if ((pointcutExpr != null && isNullOrEmpty(pointcutExpr.getValue().stringifyValue()))
|| pointcutExpr == null) {
// abstract pointcut
// leave pc = null
} else {
if (pointcutExpr==null || (pointcutExpr != null && isNullOrEmpty(pointcutExpr.getValue().stringifyValue()))) {
// the matches nothing pointcut (125475/125480) - perhaps not as cleanly supported as it could be.
} else {
if (pointcutExpr != null) {
// use a LazyResolvedPointcutDefinition so that the pointcut is resolved lazily
// since for it to be resolved, we will need other pointcuts to be registered as well
pc = parsePointcut(pointcutExpr.getValue().stringifyValue(), struct, true);
if (pc == null) return;//parse error
pc.setLocation(struct.context, -1, -1);//FIXME AVASM !! bMethod is null here..
} else {
reportError("Found undefined @Pointcut on a non-abstract method", struct);
return;
}
}
reportError("Found defined @Pointcut on an abstract method", struct);
return false;//stop
}
// do not resolve binding now but lazily
struct.ajAttributes.add(
new AjAttribute.PointcutDeclarationAttribute(
new LazyResolvedPointcutDefinition(
struct.enclosingType,
struct.method.getModifiers(),
struct.method.getName(),
argumentTypes,
UnresolvedType.forSignature(struct.method.getReturnType().getSignature()),
pc,//can be null for abstract pointcut
binding
)
)
);
} else {
if (pointcutExpr==null || (pointcutExpr != null && isNullOrEmpty(pointcutExpr.getValue().stringifyValue()))) {
// the matches nothing pointcut (125475/125480) - perhaps not as cleanly supported as it could be.
} else {
if (pointcutExpr != null) {
// use a LazyResolvedPointcutDefinition so that the pointcut is resolved lazily
// since for it to be resolved, we will need other pointcuts to be registered as well
pc = parsePointcut(pointcutExpr.getValue().stringifyValue(), struct, true);
if (pc == null) return false;//parse error
pc.setLocation(struct.context, -1, -1);//FIXME AVASM !! bMethod is null here..
} else {
reportError("Found undefined @Pointcut on a non-abstract method", struct);
return false;
}
}
}
// do not resolve binding now but lazily
struct.ajAttributes.add(
new AjAttribute.PointcutDeclarationAttribute(
new LazyResolvedPointcutDefinition(
struct.enclosingType,
struct.method.getModifiers(),
struct.method.getName(),
argumentTypes,
UnresolvedType.forSignature(struct.method.getReturnType().getSignature()),
pc,//can be null for abstract pointcut
binding // can be null for abstract pointcut
)
)
);
return true;
}

/**
@@ -1492,15 +1521,37 @@ public class AtAjAttributes {
}
return null;
}
/**
* Return the argNames set for an annotation or null if it is not specified.
*/
private static String getArgNamesValue(AnnotationGen anno) {
for (Iterator iterator1 = anno.getValues().iterator(); iterator1.hasNext();) {
ElementNameValuePairGen element = (ElementNameValuePairGen) iterator1.next();
if (ARGNAMES.equals(element.getNameString())) {
return element.getValue().stringifyValue();
}
}
return null;
}
private static String lastbit(String fqname) {
int i = fqname.lastIndexOf(".");
if (i==-1) return fqname; else return fqname.substring(i+1);
}

/**
* Extract the method argument names as in source from debug info
* returns an empty array upon inconsistency
* Extract the method argument names. First we try the debug info attached
* to the method (the LocalVariableTable) - if we cannot find that we look
* to use the argNames value that may have been supplied on the associated
* annotation. If that fails we just don't know and return an empty string.
*
* @param method
* @return method arg names as in source
* @param argNamesFromAnnotation
* @param methodStruct
* @return method argument names
*/
private static String[] getMethodArgumentNamesAsInSource(Method method) {
private static String[] getMethodArgumentNames(Method method, String argNamesFromAnnotation, AjAttributeMethodStruct methodStruct) {
if (method.getArgumentTypes().length == 0) {
return EMPTY_STRINGS;
}
@@ -1517,6 +1568,28 @@ public class AtAjAttributes {
}
}
}
} else {
// No debug info, do we have an annotation value we can rely on?
if (argNamesFromAnnotation!=null) {
StringTokenizer st = new StringTokenizer(argNamesFromAnnotation," ,");
List args = new ArrayList();
while (st.hasMoreTokens()) { args.add(st.nextToken());}
if (args.size()!=method.getArgumentTypes().length) {
StringBuffer shortString = new StringBuffer().append(lastbit(method.getReturnType().toString())).append(" ").append(method.getName());
if (method.getArgumentTypes().length>0) {
shortString.append("(");
for (int i =0; i<method.getArgumentTypes().length;i++) {
shortString.append(lastbit(method.getArgumentTypes()[i].toString()));
if ((i+1)<method.getArgumentTypes().length) shortString.append(",");
}
shortString.append(")");
}
reportError("argNames annotation value does not specify the right number of argument names for the method '"+shortString.toString()+"'",methodStruct);
return EMPTY_STRINGS;
}
return (String[])args.toArray(new String[]{});
}
}

if (arguments.size() != method.getArgumentTypes().length) {
@@ -1619,7 +1692,7 @@ public class AtAjAttributes {

private Pointcut m_lazyPointcut = null;

public LazyResolvedPointcutDefinition(ResolvedType declaringType, int modifiers, String name,
public LazyResolvedPointcutDefinition(UnresolvedType declaringType, int modifiers, String name,
UnresolvedType[] parameterTypes, UnresolvedType returnType,
Pointcut pointcut, IScope binding) {
super(declaringType, modifiers, name, parameterTypes, returnType, null);

+ 16
- 16
weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java Прегледај датотеку

@@ -11,14 +11,8 @@
*******************************************************************************/
package org.aspectj.weaver.bcel;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.generic.FieldInstruction;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionConstants;
@@ -26,7 +20,6 @@ import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InvokeInstruction;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjcMemberMaker;
@@ -37,6 +30,13 @@ import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.List;

/**
* Looks for all access to method or field that are not public within the body of the around advices and replace
* the invocations to a wrapper call so that the around advice can further be inlined.
@@ -257,11 +257,11 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
// flag it synthetic, AjSynthetic
method.makeSynthetic();
method.addAttribute(
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
);
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
method.addAttribute(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false),
m_aspectGen.getConstantPool()
)
@@ -318,11 +318,11 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
// flag it synthetic, AjSynthetic
method.makeSynthetic();
method.addAttribute(
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
);
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
method.addAttribute(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false),
m_aspectGen.getConstantPool()
)
@@ -380,11 +380,11 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
// flag it synthetic, AjSynthetic
method.makeSynthetic();
method.addAttribute(
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
);
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
method.addAttribute(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet, false),
m_aspectGen.getConstantPool()
)
@@ -438,11 +438,11 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
// flag it synthetic, AjSynthetic
method.makeSynthetic();
method.addAttribute(
BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
);
// flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
method.addAttribute(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet, false),
m_aspectGen.getConstantPool()
)

+ 11
- 14
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java Прегледај датотеку

@@ -67,20 +67,9 @@ public class BcelAdvice extends Advice {
Member signature,
ResolvedType concreteAspect)
{
super(attribute, pointcut, (signature==null?null:signature.slimline()));
super(attribute, pointcut,shrink(attribute.getKind(),concreteAspect,signature));// (signature==null?null:signature.slimline()));
this.concreteAspect = concreteAspect;
}

// !!! must only be used for testing
public BcelAdvice(AdviceKind kind, Pointcut pointcut, Member signature,
int extraArgumentFlags,
int start, int end, ISourceContext sourceContext, ResolvedType concreteAspect)
{
this(new AjAttribute.AdviceAttribute(kind, pointcut, extraArgumentFlags, start, end, sourceContext),
pointcut, (signature==null?null:signature.slimline()), concreteAspect);
thrownExceptions = Collections.EMPTY_LIST; //!!! interaction with unit tests
}
/**
* We don't always need to represent the signature with a heavyweight BcelMethod object - only if its around advice
* and inlining is active
@@ -105,6 +94,15 @@ public class BcelAdvice extends Advice {
}
return m;
}
// !!! must only be used for testing
public BcelAdvice(AdviceKind kind, Pointcut pointcut, Member signature,
int extraArgumentFlags,
int start, int end, ISourceContext sourceContext, ResolvedType concreteAspect)
{
this(new AjAttribute.AdviceAttribute(kind, pointcut, extraArgumentFlags, start, end, sourceContext),
pointcut, signature, concreteAspect);
thrownExceptions = Collections.EMPTY_LIST; //!!! interaction with unit tests
}

// ---- implementations of ShadowMunger's methods
@@ -211,7 +209,6 @@ public class BcelAdvice extends Advice {

if (concreteAspect.getWorld().isXnoInline()) return false;
//System.err.println("isWoven? " + ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState());
// if (BcelWorld.getBcelObjectType(concreteAspect).getJavaClass()==null) return true; // been evicted... CUSTARD
return BcelWorld.getBcelObjectType(concreteAspect).getLazyClassGen().isWoven();
}

@@ -721,7 +718,7 @@ public class BcelAdvice extends Advice {
protected void suppressLintWarnings(World inWorld) {
if (suppressedLintKinds == null) {
if (signature instanceof BcelMethod) {
this.suppressedLintKinds = Utility.getSuppressedWarnings(signature.getAnnotations(), inWorld.getLint());
this.suppressedLintKinds = Utility.getSuppressedWarnings(((BcelMethod)signature).getAnnotations(), inWorld.getLint());
} else {
this.suppressedLintKinds = Collections.EMPTY_LIST;
}

+ 55
- 25
weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java Прегледај датотеку

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

import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.Unknown;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
@@ -28,16 +27,50 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;

// this is a class o' static methods for reading attributes. It's pretty much a bridge from
// bcel to AjAttribute.
// OPTIMIZE move the contents of this class to bcel Utility
class BcelAttributes {

/**
* Process an array of Bcel attributes - looking for those with the name prefix org.aspectj.weaver. The returned
* list contains the AspectJ attributes identified and unpacked to 'AjAttribute' objects.
*/
public static List readAjAttributes(String classname,Attribute[] as, ISourceContext context,
World w,AjAttribute.WeaverVersionInfo version) {
// public static List readAjAttributes(String classname,List as, ISourceContext context,
// World w, AjAttribute.WeaverVersionInfo version) {
// List l = new ArrayList();
//
// // first pass, look for version
// List forSecondPass = new ArrayList();
// for (int i = as.size() - 1; i >= 0; i--) {
// Attribute a = (Attribute)as.get(i);
// if (a instanceof Unknown) {
// Unknown u = (Unknown) a;
// String name = u.getName();
// if (name.charAt(0)=='o') { // 'o'rg.aspectj
// if (name.startsWith(AjAttribute.AttributePrefix)) {
// if (name.endsWith(WeaverVersionInfo.AttributeName)) {
// version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,w);
// if (version.getMajorVersion() > WeaverVersionInfo.getCurrentWeaverMajorVersion()) {
// throw new BCException("Unable to continue, this version of AspectJ supports classes built with weaver version "+
// WeaverVersionInfo.toCurrentVersionString()+" but the class "+classname+" is version "+version.toString());
// }
// }
// forSecondPass.add(a);
// }
// }
// }
// }
// for (int i = forSecondPass.size()-1; i >= 0; i--) {
// Unknown a = (Unknown)forSecondPass.get(i);
// String name = a.getName();
// AjAttribute attr = AjAttribute.read(version,name,a.getBytes(),context,w);
// if (attr!=null) l.add(attr);
// }
// return l;
// }
public static List readAjAttributes(String classname, Attribute[] as, ISourceContext context, World w, AjAttribute.WeaverVersionInfo version) {
List l = new ArrayList();
// first pass, look for version
List forSecondPass = new ArrayList();
for (int i = as.length - 1; i >= 0; i--) {
@@ -45,37 +78,34 @@ class BcelAttributes {
if (a instanceof Unknown) {
Unknown u = (Unknown) a;
String name = u.getName();
if (name.charAt(0)=='o') { // 'o'rg.aspectj
if (name.charAt(0) == 'o') { // 'o'rg.aspectj
if (name.startsWith(AjAttribute.AttributePrefix)) {
if (name.endsWith(WeaverVersionInfo.AttributeName)) {
version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,w);
if (version.getMajorVersion() > WeaverVersionInfo.getCurrentWeaverMajorVersion()) {
throw new BCException("Unable to continue, this version of AspectJ supports classes built with weaver version "+
WeaverVersionInfo.toCurrentVersionString()+" but the class "+classname+" is version "+version.toString());
version = (AjAttribute.WeaverVersionInfo) AjAttribute.read(version, name, u.getBytes(), context, w);
if (version.getMajorVersion() > WeaverVersionInfo
.getCurrentWeaverMajorVersion()) {
throw new BCException(
"Unable to continue, this version of AspectJ supports classes built with weaver version "
+ WeaverVersionInfo
.toCurrentVersionString()
+ " but the class "
+ classname
+ " is version "
+ version.toString());
}
}
}
forSecondPass.add(a);
}
}
}
}
for (int i = forSecondPass.size()-1; i >= 0; i--) {
Unknown a = (Unknown)forSecondPass.get(i);
for (int i = forSecondPass.size() - 1; i >= 0; i--) {
Unknown a = (Unknown) forSecondPass.get(i);
String name = a.getName();
AjAttribute attr = AjAttribute.read(version,name,a.getBytes(),context,w);
if (attr!=null) l.add(attr);
AjAttribute attr = AjAttribute.read(version, name, a.getBytes(), context, w);
if (attr != null) l.add(attr);
}
return l;
}

public static Attribute bcelAttribute(AjAttribute a, ConstantPool pool) {
int nameIndex = pool.addUtf8(a.getNameString());
byte[] bytes = a.getBytes();
int length = bytes.length;

return new Unknown(nameIndex, length, bytes, pool);

}

}

+ 4
- 0
weaver/src/org/aspectj/weaver/bcel/BcelCflowCounterFieldAdder.java Прегледај датотеку

@@ -88,4 +88,8 @@ public class BcelCflowCounterFieldAdder extends BcelTypeMunger {
return true;
}

public String toString() {
return "(BcelTypeMunger: CflowField "+cflowCounterField.getDeclaringType().getName()+" "+cflowCounterField.getName()+")";
}

}

+ 30
- 29
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java Прегледај датотеку

@@ -80,7 +80,6 @@ import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ShadowMunger;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.WeaverMetrics;
import org.aspectj.weaver.WeaverStateInfo;
import org.aspectj.weaver.World;
import org.aspectj.weaver.patterns.DeclareAnnotation;
@@ -88,9 +87,6 @@ import org.aspectj.weaver.patterns.ExactTypePattern;
import org.aspectj.weaver.tools.Trace;
import org.aspectj.weaver.tools.TraceFactory;

import com.sun.org.apache.bcel.internal.generic.BranchInstruction;
import com.sun.org.apache.bcel.internal.generic.GOTO;
import com.sun.org.apache.bcel.internal.generic.GOTO_W;

class BcelClassWeaver implements IClassWeaver {

@@ -821,8 +817,9 @@ class BcelClassWeaver implements IClassWeaver {
if (annotationsToAdd==null) annotationsToAdd = new ArrayList();
AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation();
AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true);
annotationsToAdd.add(ag);
//CUSTARD superfluous?
//AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true);
annotationsToAdd.add(a);
mg.addAnnotation(decaM.getAnnotationX());
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod());
@@ -1002,7 +999,7 @@ class BcelClassWeaver implements IClassWeaver {
while (!worthRetrying.isEmpty() && modificationOccured) {
modificationOccured = false;
List forRemoval = new ArrayList();
for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) {
for (Iterator iter2 = worthRetrying.iterator(); iter2.hasNext();) {
DeclareAnnotation decaF = (DeclareAnnotation) iter2.next();
if (decaF.matches(itdIsActually,world)) {
LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz,fieldMunger);
@@ -1055,7 +1052,7 @@ class BcelClassWeaver implements IClassWeaver {
while (!worthRetrying.isEmpty() && modificationOccured) {
modificationOccured = false;
List forRemoval = new ArrayList();
for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) {
for (Iterator iter2 = worthRetrying.iterator(); iter2.hasNext();) {
DeclareAnnotation decaMC = (DeclareAnnotation) iter2.next();
if (decaMC.matches(unMangledInterMethod,world)) {
LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz,methodctorMunger);
@@ -1074,7 +1071,7 @@ class BcelClassWeaver implements IClassWeaver {
return isChanged;
}
private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX[] dontAddMeTwice){
private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX [] dontAddMeTwice){
for (int i = 0; i < dontAddMeTwice.length; i++){
AnnotationX ann = dontAddMeTwice[i];
if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())){
@@ -1162,7 +1159,7 @@ class BcelClassWeaver implements IClassWeaver {
}
}
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getName());
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs());
reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF);
isChanged = true;
modificationOccured = true;
@@ -1190,7 +1187,7 @@ class BcelClassWeaver implements IClassWeaver {
continue; // skip this one...
}
aBcelField.addAnnotation(decaF.getAnnotationX());
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getName());
AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs());
isChanged = true;
modificationOccured = true;
forRemoval.add(decaF);
@@ -1301,7 +1298,7 @@ class BcelClassWeaver implements IClassWeaver {
reportedProblems.add(uniqueID);
reportedProblems.add(new Integer(itdfieldsig.hashCode()*deca.hashCode()));
world.getLint().elementAlreadyAnnotated.signal(
new String[]{rm.toString(),deca.getAnnotationTypeX().toString()},
new String[]{itdfieldsig.toString(),deca.getAnnotationTypeX().toString()},
rm.getSourceLocation(),new ISourceLocation[]{deca.getSourceLocation()});
}
}
@@ -1537,10 +1534,10 @@ class BcelClassWeaver implements IClassWeaver {
// ignore
} else if (targeter instanceof LineNumberTag) {
// ignore
} else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) {
// move it...
targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof BranchInstruction) {
// } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) {
// // move it...
// targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof InstructionBranch) {
// move it
targeter.updateTarget(element, monitorExitBlockStart);
} else {
@@ -1717,10 +1714,10 @@ class BcelClassWeaver implements IClassWeaver {
// ignore
} else if (targeter instanceof LineNumberTag) {
// ignore
} else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
// move it...
targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof BranchInstruction) {
// } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
// // move it...
// targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof InstructionBranch) {
// move it
targeter.updateTarget(element, monitorExitBlockStart);
} else {
@@ -1825,9 +1822,9 @@ class BcelClassWeaver implements IClassWeaver {
// ignore
} else if (targeter instanceof LineNumberTag) {
// ignore
} else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) {
// move it...
targeter.updateTarget(element, monitorExitBlockStart);
// } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
// // move it...
// targeter.updateTarget(element, monitorExitBlockStart);
} else if (targeter instanceof InstructionBranch) {
// move it
targeter.updateTarget(element, monitorExitBlockStart);
@@ -1900,6 +1897,8 @@ class BcelClassWeaver implements IClassWeaver {
{
Instruction fresh = Utility.copyInstruction(src.getInstruction());
InstructionHandle dest;
// OPTIMIZE optimize this stuff?
if (fresh.isConstantPoolInstruction()) {
// need to reset index to go to new constant pool. This is totally
// a computation leak... we're testing this LOTS of times. Sigh.
@@ -2605,9 +2604,14 @@ class BcelClassWeaver implements IClassWeaver {
// sets of synthetics aren't join points in 1.1
return;
} else {
match(
BcelShadow.makeFieldSet(world, mg, ih, enclosingShadow),
shadowAccumulator);
// Fix for bug 172107 (similar the "get" fix for bug 109728)
BcelShadow bs=
BcelShadow.makeFieldSet(world, resolvedField, mg, ih, enclosingShadow);
String cname = fi.getClassName(cpg);
if (!resolvedField.getDeclaringType().getName().equals(cname)) {
bs.setActualTargetType(cname);
}
match(bs, shadowAccumulator);
}
}

@@ -2774,14 +2778,11 @@ class BcelClassWeaver implements IClassWeaver {
ShadowMunger munger = (ShadowMunger)i.next();
ContextToken mungerMatchToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MATCHING_POINTCUT, munger.getPointcut());
if (munger.match(shadow, world)) {
WeaverMetrics.recordMatchResult(true);// Could pass: munger
shadow.addMunger(munger);
isMatched = true;
if (shadow.getKind() == Shadow.StaticInitialization) {
clazz.warnOnAddedStaticInitializer(shadow,munger.getSourceLocation());
}
} else {
WeaverMetrics.recordMatchResult(false); // Could pass: munger
}
CompilationAndWeavingContext.leavingPhase(mungerMatchToken);
}

+ 2
- 4
weaver/src/org/aspectj/weaver/bcel/BcelField.java Прегледај датотеку

@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/


package org.aspectj.weaver.bcel;

import java.util.Collections;
@@ -36,7 +35,6 @@ import org.aspectj.weaver.World;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;


final class BcelField extends ResolvedMemberImpl {

private static int AccSynthetic = 0x1000;
@@ -56,7 +54,7 @@ final class BcelField extends ResolvedMemberImpl {
super(
FIELD,
declaringType.getResolvedTypeX(),
field.getAccessFlags(),
field.getModifiers(),
field.getName(),
field.getSignature());
this.field = field;
@@ -72,7 +70,7 @@ final class BcelField extends ResolvedMemberImpl {
* constructed at runtime (so there is no .class file to retrieve).
*/
BcelField(String declaringTypeName, Field field,World world) {
super(FIELD,UnresolvedType.forName(declaringTypeName),field.getAccessFlags(),field.getName(),field.getSignature());
super(FIELD,UnresolvedType.forName(declaringTypeName),field.getModifiers(),field.getName(),field.getSignature());
this.field = field;
this.world = world;
this.bcelObjectType = null;

+ 7
- 5
weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java Прегледај датотеку

@@ -255,11 +255,13 @@ public class BcelGenericSignatureToTypeXConverter {
ReferenceType rt = (ReferenceType) aTypeX;
TypeVariable[] typeVars = rt.getTypeVariables();
for (int i = 0; i < typeVars.length; i++) {
if (typeVars[i].getUpperBound() instanceof FTPHolder) {
Signature.FormalTypeParameter key = ((FTPHolder) typeVars[i].getUpperBound()).ftpToBeSubstituted;
typeVars[i].setUpperBound((UnresolvedType)typeVariableResolutions.get(key));
}
if (typeVars != null) {
for (int i = 0; i < typeVars.length; i++) {
if (typeVars[i].getUpperBound() instanceof FTPHolder) {
Signature.FormalTypeParameter key = ((FTPHolder) typeVars[i].getUpperBound()).ftpToBeSubstituted;
typeVars[i].setUpperBound((UnresolvedType) typeVariableResolutions.get(key));
}
}
}
}

+ 115
- 21
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java Прегледај датотеку

@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/


package org.aspectj.weaver.bcel;

import java.lang.reflect.Modifier;
@@ -19,6 +18,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.aspectj.apache.bcel.classfile.AnnotationDefault;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.ExceptionTable;
import org.aspectj.apache.bcel.classfile.GenericSignatureParser;
@@ -31,13 +31,14 @@ import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Signature;
import org.aspectj.apache.bcel.classfile.Signature.TypeVariableSignature;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.SourceLocation;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedType;
@@ -52,15 +53,14 @@ public final class BcelMethod extends ResolvedMemberImpl {

private Method method;
// private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber;
// private World world;
private BcelObjectType bcelObjectType;

public Member slimline() {
if (!bcelObjectType.getWorld().isXnoInline()) return this;
ResolvedMemberImpl mi = new ResolvedMemberImpl(kind,declaringType,modifiers,returnType,name,parameterTypes);
mi.setParameterNames(getParameterNames());
return mi;
}
// public Member slimline() {
// if (!bcelObjectType.getWorld().isXnoInline()) return this;
// ResolvedMemberImpl mi = new ResolvedMemberImpl(kind,declaringType,modifiers,returnType,name,parameterTypes);
// mi.setParameterNames(getParameterNames());
// return mi;
// }

// private AnnotationX[] annotations = null;
// private UnresolvedType genericReturnType = null;
@@ -75,6 +75,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
private static final String MAPKEY_GENERIC_PARAM_TYPES ="genericParameterTypes";
private static final String MAPKEY_ANNOTATIONS ="annotations";
private static final String MAPKEY_MD_LINE_NUMBER_ATTRIBUTE="mdLineNumberAttribute";
private AnnotationX[][] parameterAnnotations = null;

// private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
// private ShadowMunger associatedShadowMunger;
@@ -109,13 +110,12 @@ public final class BcelMethod extends ResolvedMemberImpl {
(method.getName().equals("<clinit>") ? STATIC_INITIALIZATION : METHOD),
declaringType.getResolvedTypeX(),
declaringType.isInterface()
? method.getAccessFlags() | Modifier.INTERFACE
: method.getAccessFlags(),
method.getName(),
? method.getModifiers() | Modifier.INTERFACE
: method.getModifiers(),
method.getName(),
method.getSignature());
this.method = method;
this.sourceContext = declaringType.getResolvedTypeX().getSourceContext();
//this.world = declaringType.getResolvedTypeX().getWorld();
this.bcelObjectType = declaringType;
unpackJavaAttributes();
unpackAjAttributes(bcelObjectType.getWorld());
@@ -152,6 +152,41 @@ public final class BcelMethod extends ResolvedMemberImpl {
LocalVariableTable varTable = method.getLocalVariableTable();
int len = getArity();
if (varTable == null) {
// do we have an annotation with the argNames value specified...
if (hasAnnotations()) {
AnnotationX[] axs = getAnnotations();
for (int i = 0; i < axs.length; i++) {
AnnotationX annotationX = axs[i];
String typename = annotationX.getTypeName();
if (typename.equals("org.aspectj.lang.annotation.Pointcut") ||
typename.equals("org.aspectj.lang.annotation.Before") ||
typename.equals("org.aspectj.lang.annotation.Around") ||
typename.startsWith("org.aspectj.lang.annotation.After")) {
AnnotationGen a = annotationX.getBcelAnnotation();
if (a!=null) {
List values = a.getValues();
for (Iterator iterator = values.iterator(); iterator
.hasNext();) {
ElementNameValuePairGen nvPair = (ElementNameValuePairGen) iterator.next();
if (nvPair.getNameString().equals("argNames")) {
String argNames = nvPair.getValue().stringifyValue();
StringTokenizer argNameTokenizer = new StringTokenizer(argNames," ,");
List argsList = new ArrayList();
while (argNameTokenizer.hasMoreTokens()) {
argsList.add(argNameTokenizer.nextToken());
}
int requiredCount = getParameterTypes().length;
while (argsList.size()<requiredCount) {
argsList.add("arg"+argsList.size());
}
setParameterNames((String[])argsList.toArray(new String[]{}));
return;
}
}
}
}
}
}
setParameterNames(Utility.makeArgNames(len));
} else {
UnresolvedType[] paramTypes = getParameterTypes();
@@ -228,6 +263,18 @@ public final class BcelMethod extends ResolvedMemberImpl {
return null;
}
public String getAnnotationDefaultValue() {
Attribute[] attrs = method.getAttributes();
for (int i = 0; i < attrs.length; i++) {
Attribute attribute = attrs[i];
if (attribute.getName().equals("AnnotationDefault")) {
AnnotationDefault def = (AnnotationDefault)attribute;
return def.getElementValue().stringifyValue();
}
}
return null;
}
// for testing - use with the method above
public String[] getAttributeNames(boolean onlyIncludeAjOnes) {
Attribute[] as = method.getAttributes();
@@ -304,7 +351,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
return ret;
}
public Kind getKind() {
public MemberKind getKind() {
if ((bitflags&HAS_ASSOCIATED_SHADOWMUNGER)!=0) {
return ADVICE;
} else {
@@ -313,7 +360,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
}
public boolean hasAnnotation(UnresolvedType ofType) {
ensureAnnotationTypesRetrieved();
ensureAnnotationsRetrieved();
for (Iterator iter = annotationTypes.iterator(); iter.hasNext();) {
ResolvedType aType = (ResolvedType) iter.next();
if (aType.equals(ofType)) return true;
@@ -322,7 +369,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
}
public AnnotationX[] getAnnotations() {
ensureAnnotationTypesRetrieved();
ensureAnnotationsRetrieved();
if ((bitflags&HAS_ANNOTATIONS)!=0) {
return (AnnotationX[])metaData.get(MAPKEY_ANNOTATIONS);
} else {
@@ -332,14 +379,24 @@ public final class BcelMethod extends ResolvedMemberImpl {
}
public ResolvedType[] getAnnotationTypes() {
ensureAnnotationTypesRetrieved();
ensureAnnotationsRetrieved();
ResolvedType[] ret = new ResolvedType[annotationTypes.size()];
annotationTypes.toArray(ret);
return ret;
}
public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
ensureAnnotationsRetrieved();
if ((bitflags&HAS_ANNOTATIONS)==0) return null;
AnnotationX[] annos = (AnnotationX[])metaData.get(MAPKEY_ANNOTATIONS);
for (int i=0; i<annos.length; i++) {
if (annos[i].getTypeName().equals(ofType.getName())) return annos[i];
}
return null;
}
public void addAnnotation(AnnotationX annotation) {
ensureAnnotationTypesRetrieved();
ensureAnnotationsRetrieved();
if ((bitflags&HAS_ANNOTATIONS)==0) {
AnnotationX[] ret = new AnnotationX[1];
ret[0]=annotation;
@@ -365,7 +422,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
// FIXME CUSTARD
}
private void ensureAnnotationTypesRetrieved() {
private void ensureAnnotationsRetrieved() {
if (method == null) return; // must be ok, we have evicted it
if ((bitflags&HAVE_DETERMINED_ANNOTATIONS)!=0) return;
bitflags|=HAVE_DETERMINED_ANNOTATIONS;
@@ -387,6 +444,39 @@ public final class BcelMethod extends ResolvedMemberImpl {
// }
}
private void ensureParameterAnnotationsRetrieved() {
if (method == null) return; // must be ok, we have evicted it
AnnotationGen[][] pAnns = method.getParameterAnnotations();
if (parameterAnnotationTypes==null || pAnns.length!=parameterAnnotationTypes.length) {
if (pAnns == Method.NO_PARAMETER_ANNOTATIONS) {
parameterAnnotationTypes = BcelMethod.NO_PARAMETER_ANNOTATION_TYPES;
parameterAnnotations = BcelMethod.NO_PARAMETER_ANNOTATIONXS;
} else {
AnnotationGen annos[][] = method.getParameterAnnotations();
parameterAnnotations = new AnnotationX[annos.length][];
parameterAnnotationTypes = new ResolvedType[annos.length][];
for (int i=0;i<annos.length;i++) {
parameterAnnotations[i] = new AnnotationX[annos[i].length];
parameterAnnotationTypes[i] = new ResolvedType[annos[i].length];
for (int j=0;j<annos[i].length;j++) {
parameterAnnotations[i][j] = new AnnotationX(annos[i][j],bcelObjectType.getWorld());
parameterAnnotationTypes[i][j] = bcelObjectType.getWorld().resolve(UnresolvedType.forSignature(annos[i][j].getTypeSignature()));
}
}
}
}
}

public AnnotationX[][] getParameterAnnotations() {
ensureParameterAnnotationsRetrieved();
return parameterAnnotations;
}
public ResolvedType[][] getParameterAnnotationTypes() {
ensureParameterAnnotationsRetrieved();
return parameterAnnotationTypes;
}

/**
* A method can be parameterized if it has one or more generic
@@ -406,6 +496,9 @@ public final class BcelMethod extends ResolvedMemberImpl {
// return genericParameterTypes;
}
/**
* Return the parameterized/generic return type or the normal return type if the method is not generic.
*/
public UnresolvedType getGenericReturnType() {
unpackGenericSignature();
if ((bitflags&HAS_GENERIC_RETPARAM_TYPES)==0) return getReturnType();
@@ -507,7 +600,8 @@ public final class BcelMethod extends ResolvedMemberImpl {
if (method != null) {
unpackGenericSignature();
unpackJavaAttributes();
ensureAnnotationTypesRetrieved();
ensureAnnotationsRetrieved();
ensureParameterAnnotationsRetrieved();
determineParameterNames();
// this.sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
method = null;
@@ -567,4 +661,4 @@ public final class BcelMethod extends ResolvedMemberImpl {
o.getMethod().getCode().getCodeString());
}

}
}

+ 8
- 15
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java Прегледај датотеку

@@ -31,6 +31,7 @@ import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.weaver.AbstractReferenceTypeDelegate;
import org.aspectj.weaver.AjAttribute;
@@ -148,13 +149,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
// ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.getSourceFileName());
// }
setSourcefilename(javaClass.getSourceFileName());
}
// repeat initialization
public void setJavaClass(JavaClass newclass) {
// if (this.getResolvedTypeX().isAspect())
// new RuntimeException("bcot: "+this.hashCode()+" Set javaclass for aspect").printStackTrace();
this.javaClass = newclass;
resetState();
initializeFromJavaclass();
@@ -166,7 +164,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
isAnnotation = javaClass.isAnnotation();
isAnonymous = javaClass.isAnonymous();
isNested = javaClass.isNested();
modifiers = javaClass.getAccessFlags();
modifiers = javaClass.getModifiers();
superclassName = javaClass.getSuperclassName();
className = javaClass.getClassName();
cachedGenericClassTypeSignature = null;
@@ -201,7 +199,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
ResolvedType res = getResolvedTypeX().getWorld().resolve(UnresolvedType.forSignature(superclassSignature));
return res;
}
public World getWorld() {
return getResolvedTypeX().getWorld();
}
@@ -482,7 +480,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
public LazyClassGen getLazyClassGen() {
LazyClassGen ret = lazyClassGen;
if (ret == null) {
// System.err.println("creating lazy class gen for: " + this);
//System.err.println("creating lazy class gen for: " + this);
ret = new LazyClassGen(this);
//ret.print(System.err);
//System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName );
@@ -583,8 +581,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
List values = ax.getBcelAnnotation().getValues();
for (Iterator it = values.iterator(); it.hasNext();) {
ElementNameValuePairGen element = (ElementNameValuePairGen) it.next();
ElementValueGen v = element.getValue();
retentionPolicy = v.stringifyValue();
EnumElementValueGen v = (EnumElementValueGen)element.getValue();
retentionPolicy = v.getEnumValueString();
return retentionPolicy;
}
}
@@ -619,7 +617,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
ElementValueGen[] evs = arrayValue.getElementValuesArray();
if (evs!=null) {
for (int j = 0; j < evs.length; j++) {
String targetKind = evs[j].stringifyValue();
String targetKind = ((EnumElementValueGen)evs[j]).getEnumValueString();
if (targetKind.equals("ANNOTATION_TYPE")) { targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE);
} else if (targetKind.equals("CONSTRUCTOR")) { targetKinds.add(AnnotationTargetKind.CONSTRUCTOR);
} else if (targetKind.equals("FIELD")) { targetKinds.add(AnnotationTargetKind.FIELD);
@@ -783,7 +781,6 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
public void evictWeavingState() {
// Can't chuck all this away
// if (getResolvedTypeX().isAspect()) System.err.println("Eviction of "+getResolvedTypeX().getName());
if (getResolvedTypeX().getWorld().couldIncrementalCompileFollow()) return;
if (javaClass != null) {
@@ -805,16 +802,12 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
weaverState.setReweavable(false);
weaverState.setUnwovenClassFileData(null);
}
for (int i = methods.length - 1; i >= 0; i--) { methods[i].evictWeavingState();}
for (int i = methods.length - 1; i >= 0; i--) methods[i].evictWeavingState();
for (int i = fields.length - 1; i >= 0; i--) fields[i].evictWeavingState();
// if (getResolvedTypeX().isAspect()) System.err.println("nulling jc for "+getResolvedTypeX().getName());
javaClass = null;
// setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); // bit naughty
// interfaces=null; // force reinit - may get us the right instances!
// superClass=null;
// if this is a class, make sure aspects are re-evicted if necessary
// if (!getResolvedTypeX().isAspect()) getWorld().ensureAspectsEvicted();
}
}

+ 1
- 1
weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java Прегледај датотеку

@@ -584,7 +584,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
methodGen.makeSynthetic();
}
methodGen.addAttribute(
BcelAttributes.bcelAttribute(
Utility.bcelAttribute(
new AjAttribute.AjSynthetic(),
methodGen.getEnclosingClass().getConstantPool()
)

+ 92
- 73
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java Прегледај датотеку

@@ -43,7 +43,9 @@ import org.aspectj.apache.bcel.generic.MULTIANEWARRAY;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.TargetLostException;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.AjcMemberMaker;
@@ -51,6 +53,7 @@ import org.aspectj.weaver.BCException;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.MemberImpl;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.NewConstructorTypeMunger;
import org.aspectj.weaver.NewFieldTypeMunger;
@@ -127,7 +130,6 @@ public class BcelShadow extends Shadow {
private ShadowRange range;
private final BcelWorld world;
private final LazyMethodGen enclosingMethod;
// private boolean fallsThrough; //XXX not used anymore
// SECRETAPI - for testing, this will tell us if the optimization succeeded *on the last shadow processed*
public static boolean appliedLazyTjpOptimization;
@@ -136,24 +138,15 @@ public class BcelShadow extends Shadow {
// from the signature (pr109728) (1.4 declaring type issue)
private String actualInstructionTargetType;

// ---- initialization
/**
* This generates an unassociated shadow, rooted in a particular method but not rooted
* This generates an unassociated shadow, rooted in a particular method but not rooted
* to any particular point in the code. It should be given to a rooted ShadowRange
* in the {@link ShadowRange#associateWithShadow(BcelShadow)} method.
*/
public BcelShadow(
BcelWorld world,
Kind kind,
Member signature,
LazyMethodGen enclosingMethod,
BcelShadow enclosingShadow)
{
public BcelShadow(BcelWorld world, Kind kind, Member signature, LazyMethodGen enclosingMethod, BcelShadow enclosingShadow) {
super(kind, signature, enclosingShadow);
this.world = world;
this.enclosingMethod = enclosingMethod;
// fallsThrough = kind.argsOnStack();
}

// ---- copies all state, including Shadow's mungers...
@@ -178,8 +171,6 @@ public class BcelShadow extends Shadow {
return world;
}



private void deleteNewAndDup() {
final ConstantPool cpg = getEnclosingClass().getConstantPool();
int depth = 1;
@@ -976,6 +967,7 @@ public class BcelShadow extends Shadow {
public static BcelShadow makeFieldSet(
BcelWorld world,
ResolvedMember field,
LazyMethodGen enclosingMethod,
InstructionHandle setHandle,
BcelShadow enclosingShadow)
@@ -985,9 +977,10 @@ public class BcelShadow extends Shadow {
new BcelShadow(
world,
FieldSet,
BcelWorld.makeFieldJoinPointSignature(
enclosingMethod.getEnclosingClass(),
(FieldInstruction) setHandle.getInstruction()),
field,
// BcelWorld.makeFieldJoinPointSignature(
// enclosingMethod.getEnclosingClass(),
// (FieldInstruction) setHandle.getInstruction()),
enclosingMethod,
enclosingShadow);
ShadowRange r = new ShadowRange(body);
@@ -1529,7 +1522,7 @@ public class BcelShadow extends Shadow {
}
}
protected Member getRelevantMember(Member foundMember, Member relevantMember, ResolvedType relevantType){
protected ResolvedMember getRelevantMember(ResolvedMember foundMember, Member relevantMember, ResolvedType relevantType){
if (foundMember != null){
return foundMember;
}
@@ -1567,7 +1560,7 @@ public class BcelShadow extends Shadow {
return foundMember;
}
protected ResolvedType [] getAnnotations(Member foundMember, Member relevantMember, ResolvedType relevantType){
protected ResolvedType [] getAnnotations(ResolvedMember foundMember, Member relevantMember, ResolvedType relevantType){
if (foundMember == null){
// check the ITD'd dooberries
List mungers = relevantType.resolve(world).getInterTypeMungers();
@@ -1606,27 +1599,30 @@ public class BcelShadow extends Shadow {
// by determining what "kind" of shadow we are, we can find out the
// annotations on the appropriate element (method, field, constructor, type).
// Then create one BcelVar entry in the map for each annotation, keyed by
// annotation type (UnresolvedType).
// annotation type.
// FIXME asc Refactor this code, there is duplication
ResolvedType[] annotations = null;
Member relevantMember = getSignature();
ResolvedType relevantType = relevantMember.getDeclaringType().resolve(world);
if (relevantType.isRawType() || relevantType.isParameterizedType()) relevantType = relevantType.getGenericType();
// Member relevantMember = getSignature();
Member shadowSignature = getSignature();
Member annotationHolder = getSignature();
ResolvedType relevantType = shadowSignature.getDeclaringType().resolve(world);
if (relevantType.isRawType() || relevantType.isParameterizedType()) relevantType = relevantType.getGenericType();

if (getKind() == Shadow.StaticInitialization) {
annotations = relevantType.resolve(world).getAnnotationTypes();
} else if (getKind() == Shadow.MethodCall || getKind() == Shadow.ConstructorCall) {
Member foundMember = findMethod2(relevantType.resolve(world).getDeclaredMethods(),getSignature());
annotations = getAnnotations(foundMember, relevantMember, relevantType);
relevantMember = getRelevantMember(foundMember,relevantMember,relevantType);
relevantType = relevantMember.getDeclaringType().resolve(world);
ResolvedMember foundMember = findMethod2(relevantType.resolve(world).getDeclaredMethods(),getSignature());
annotations = getAnnotations(foundMember, shadowSignature, relevantType);
annotationHolder = getRelevantMember(foundMember,shadowSignature,relevantType);
relevantType = annotationHolder.getDeclaringType().resolve(world);
} else if (getKind() == Shadow.FieldSet || getKind() == Shadow.FieldGet) {
relevantMember = findField(relevantType.getDeclaredFields(),getSignature());
annotationHolder = findField(relevantType.getDeclaredFields(),getSignature());
if (relevantMember==null) {
if (annotationHolder==null) {
// check the ITD'd dooberries
List mungers = relevantType.resolve(world).getInterTypeMungers();
for (Iterator iter = mungers.iterator(); iter.hasNext();) {
@@ -1638,21 +1634,21 @@ public class BcelShadow extends Shadow {
ResolvedMember rmm = findMethod(typeMunger.getAspectType(),ajcMethod);
if (fakerm.equals(getSignature())) {
relevantType = typeMunger.getAspectType();
relevantMember = rmm;
annotationHolder = rmm;
}
}
}
}
annotations = relevantMember.getAnnotationTypes();
annotations = ((ResolvedMember)annotationHolder).getAnnotationTypes();
} else if (getKind() == Shadow.MethodExecution || getKind() == Shadow.ConstructorExecution ||
getKind() == Shadow.AdviceExecution) {
//ResolvedMember rm[] = relevantType.getDeclaredMethods();
Member foundMember = findMethod2(relevantType.getDeclaredMethods(),getSignature());
ResolvedMember foundMember = findMethod2(relevantType.getDeclaredMethods(),getSignature());
annotations = getAnnotations(foundMember, relevantMember, relevantType);
relevantMember = foundMember;
relevantMember = getRelevantMember(foundMember, relevantMember,relevantType);
annotations = getAnnotations(foundMember, shadowSignature, relevantType);
annotationHolder = foundMember;
annotationHolder = getRelevantMember(foundMember, annotationHolder,relevantType);
} else if (getKind() == Shadow.ExceptionHandler) {
relevantType = getSignature().getParameterTypes()[0].resolve(world);
@@ -1670,7 +1666,7 @@ public class BcelShadow extends Shadow {
for (int i = 0; i < annotations.length; i++) {
ResolvedType aTX = annotations[i];
KindedAnnotationAccessVar kaav = new KindedAnnotationAccessVar(getKind(),aTX.resolve(world),relevantType,relevantMember);
AnnotationAccessVar kaav = new AnnotationAccessVar(getKind(),aTX.resolve(world),relevantType,annotationHolder);
kindedAnnotationVars.put(aTX,kaav);
}
}
@@ -1718,7 +1714,7 @@ public class BcelShadow extends Shadow {
for (int i = 0; i < annotations.length; i++) {
ResolvedType ann = annotations[i];
Kind k = Shadow.StaticInitialization;
withinAnnotationVars.put(ann,new KindedAnnotationAccessVar(k,ann,getEnclosingType(),null));
withinAnnotationVars.put(ann,new AnnotationAccessVar(k,ann,getEnclosingType(),null));
}
}
@@ -1733,7 +1729,7 @@ public class BcelShadow extends Shadow {
Kind k = (getEnclosingMethod().getMemberView().getKind()==Member.CONSTRUCTOR?
Shadow.ConstructorExecution:Shadow.MethodExecution);
withincodeAnnotationVars.put(ann,
new KindedAnnotationAccessVar(k,ann,getEnclosingType(),getEnclosingCodeSignature()));
new AnnotationAccessVar(k,ann,getEnclosingType(),getEnclosingCodeSignature()));
}
}
@@ -1767,36 +1763,49 @@ public class BcelShadow extends Shadow {
* advice specified one.
*/
public void weaveAfterReturning(BcelAdvice munger) {
List returns = findReturnInstructions();
boolean hasReturnInstructions = !returns.isEmpty();
// list of instructions that handle the actual return from the join point
InstructionList retList = new InstructionList();
// variable that holds the return value
BcelVar returnValueVar = null;
if (hasReturnInstructions) {
returnValueVar = generateReturnInstructions(returns,retList);
} else {
// we need at least one instruction, as the target for jumps
retList.append(InstructionConstants.NOP);
}

// list of instructions for dispatching to the advice itself
InstructionList advice = getAfterReturningAdviceDispatchInstructions(
munger, retList.getStart());
if (hasReturnInstructions) {
InstructionHandle gotoTarget = advice.getStart();
for (Iterator i = returns.iterator(); i.hasNext();) {
InstructionHandle ih = (InstructionHandle) i.next();
retargetReturnInstruction(munger.hasExtraParameter(), returnValueVar, gotoTarget, ih);
}
}
range.append(advice);
range.append(retList);
try {
List returns = findReturnInstructions();
boolean hasReturnInstructions = !returns.isEmpty();
// list of instructions that handle the actual return from the join point
InstructionList retList = new InstructionList();
// variable that holds the return value
BcelVar returnValueVar = null;
if (hasReturnInstructions) {
returnValueVar = generateReturnInstructions(returns,retList);
} else {
// we need at least one instruction, as the target for jumps
retList.append(InstructionConstants.NOP);
}
// list of instructions for dispatching to the advice itself
InstructionList advice = getAfterReturningAdviceDispatchInstructions(
munger, retList.getStart());
if (hasReturnInstructions) {
InstructionHandle gotoTarget = advice.getStart();
for (Iterator i = returns.iterator(); i.hasNext();) {
InstructionHandle ih = (InstructionHandle) i.next();
retargetReturnInstruction(munger.hasExtraParameter(), returnValueVar, gotoTarget, ih);
}
}
range.append(advice);
range.append(retList);
} catch (RuntimeException e) {
StringBuffer sb = new StringBuffer();
sb.append("Unexpected runtime exception occurred in BcelShadow.weaveAfterReturning()\n");
sb.append("shadow is '"+toString()+"'\n");
sb.append("method is '"+enclosingMethod+"'\n");
sb.append("enclosing shadow is '"+enclosingShadow+"'\n");
sb.append("range is '"+range+"'\n");
sb.append("munger is '"+munger+"'\n");
IMessage m = MessageUtil.abort(sb.toString(), e);
world.getMessageHandler().handleMessage(m);
throw e;
}
}

/**
@@ -2366,7 +2375,17 @@ public class BcelShadow extends Shadow {
extraParamOffset += thisJoinPointVar.getType().getSize();
}
Type[] adviceParameterTypes = adviceMethod.getArgumentTypes();
// We use the munger signature here because it allows for any parameterization of the mungers pointcut that
// may have occurred ie. if the pointcut is p(T t) in the super aspect and that has become p(Foo t) in the sub aspect
// then here the munger signature will have 'Foo' as an argument in it whilst the adviceMethod argument type will be 'Object' - since
// it represents the advice method in the superaspect which uses the erasure of the type variable p(Object t) - see pr174449.
Type[] adviceParameterTypes =
BcelWorld.makeBcelTypes(munger.getSignature().getParameterTypes());
// adviceMethod.getArgumentTypes();
adviceMethod.getArgumentTypes(); // forces initialization ... dont like this but seems to be required for some tests to pass, I think that means
// there is a LazyMethodGen method that is not correctly setup to call initialize() when it is invoked - but I dont have
// time right now to discover which
Type[] extractedMethodParameterTypes = extractedMethod.getArgumentTypes();
Type[] parameterTypes =
new Type[extractedMethodParameterTypes.length
@@ -2500,7 +2519,7 @@ public class BcelShadow extends Shadow {
// call to the extracted method.

// inlining support for code style aspects
if (!munger.getConcreteAspect().isAnnotationStyleAspect()) {
if (!munger.getDeclaringType().isAnnotationStyleAspect()) {
String proceedName =
NameMangler.proceedMethodName(munger.getSignature().getName());

@@ -3057,7 +3076,7 @@ public class BcelShadow extends Shadow {
if (munger.getConcreteAspect()!=null && munger.getConcreteAspect().isAnnotationStyleAspect()
&& munger.getDeclaringAspect()!=null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
// stick the bitflags on the stack and call the variant of linkClosureAndJoinPoint that takes an int
closureInstantiation.append(fact.createConstant(new Integer(bitflags)));
closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags)));
closureInstantiation.append(Utility.createInvoke(
getFactory(),
getWorld(),
@@ -3428,12 +3447,12 @@ public class BcelShadow extends Shadow {
if (targetVar != null && targetVar != thisVar) {
UnresolvedType targetType = getTargetType();
targetType = ensureTargetTypeIsCorrect(targetType);
// see pr109728 - this fixes the case when the declaring class is sometype 'X' but the getfield
// see pr109728,pr229910 - this fixes the case when the declaring class is sometype 'X' but the (gs)etfield
// in the bytecode refers to a subtype of 'X'. This makes sure we use the type originally
// mentioned in the fieldget instruction as the method parameter and *not* the type upon which the
// field is declared because when the instructions are extracted into the new around body,
// they will still refer to the subtype.
if (getKind()==FieldGet && getActualTargetType()!=null &&
if ((getKind()==FieldGet || getKind()==FieldSet) && getActualTargetType()!=null &&
!getActualTargetType().equals(targetType.getName())) {
targetType = UnresolvedType.forName(getActualTargetType()).resolve(world);
}

+ 69
- 13
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java Прегледај датотеку

@@ -17,6 +17,7 @@ package org.aspectj.weaver.bcel;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.apache.bcel.Constants;
@@ -332,25 +333,24 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
*/
private boolean enforceDecpRule4_compatibleReturnTypes(BcelClassWeaver weaver, ResolvedMember superMethod, LazyMethodGen subMethod) {
boolean cont = true;
String superReturnTypeSig = superMethod.getReturnType().getSignature();
String subReturnTypeSig = subMethod.getReturnType().getSignature();
superReturnTypeSig = superReturnTypeSig.replace('.','/');
subReturnTypeSig = subReturnTypeSig.replace('.','/');
if (!superReturnTypeSig.equals(subReturnTypeSig)) {
// Allow for covariance - wish I could test this (need Java5...)
String superReturnTypeSig = superMethod.getGenericReturnType().getSignature(); // eg. Pjava/util/Collection<LFoo;>
String subReturnTypeSig = subMethod.getGenericReturnTypeSignature();
superReturnTypeSig = superReturnTypeSig.replace('.', '/');
subReturnTypeSig = subReturnTypeSig.replace('.', '/');
if (!superReturnTypeSig.equals(subReturnTypeSig)) {
// Check for covariance
ResolvedType subType = weaver.getWorld().resolve(subMethod.getReturnType());
ResolvedType superType = weaver.getWorld().resolve(superMethod.getReturnType());
if (!superType.isAssignableFrom(subType)) {
ISourceLocation sloc = subMethod.getSourceLocation();
weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error(
"The return type is incompatible with "+superMethod.getDeclaringType()+"."+superMethod.getName()+superMethod.getParameterSignature(),
subMethod.getSourceLocation()));
"The return type is incompatible with " + superMethod.getDeclaringType() + "." + superMethod.getName()
+ superMethod.getParameterSignature(), subMethod.getSourceLocation()));
// this just might be a better error message...
// "The return type '"+subReturnTypeSig+"' is incompatible with the overridden method "+superMethod.getDeclaringType()+"."+
// superMethod.getName()+superMethod.getParameterSignature()+" which returns '"+superReturnTypeSig+"'",
cont=false;
}
}
}
return cont;
}
@@ -379,11 +379,14 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
}

/**
* Search the specified type for a particular method - do not use the return value in the comparison as it is not
* considered for overriding.
*/
private LazyMethodGen findMatchingMethod(LazyClassGen newParentTarget, ResolvedMember m) {
LazyMethodGen found = null;
// Search the type for methods overriding super methods (methods that come from the new parent)
// Don't use the return value in the comparison as overriding doesnt
for (Iterator i = newParentTarget.getMethodGens().iterator(); i.hasNext() && found==null;) {
List methodGens = newParentTarget.getMethodGens();
for (Iterator i = methodGens.iterator(); i.hasNext() && found == null;) {
LazyMethodGen gen = (LazyMethodGen) i.next();
if (gen.getName().equals(m.getName()) &&
gen.getParameterSignature().equals(m.getParameterSignature())) {
@@ -1088,6 +1091,27 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
clazz.addMethodGen(bridgeMethod);
}
// Unlike toString() on a member, this does not include the declaring type
private String stringifyMember(ResolvedMember member) {
StringBuffer buf = new StringBuffer();
buf.append(member.getReturnType().getName());
buf.append(' ');
buf.append(member.getName());
if (member.getKind() != Member.FIELD) {
buf.append("(");
UnresolvedType[] params = member.getParameterTypes();
if (params.length != 0) {
buf.append(params[0]);
for (int i=1, len = params.length; i < len; i++) {
buf.append(", ");
buf.append(params[i].getName());
}
}
buf.append(")");
}
return buf.toString();
}
private boolean mungeMethodDelegate(BcelClassWeaver weaver, MethodDelegateTypeMunger munger) {
ResolvedMember introduced = munger.getSignature();

@@ -1103,6 +1127,34 @@ public class BcelTypeMunger extends ConcreteTypeMunger {

boolean shouldApply = munger.matches(weaver.getLazyClassGen().getType(), aspectType);
if (shouldApply) {
// If no implementation class was specified, the intention was that the types matching the pattern
// already implemented the interface, let's check that now!
if (munger.getImplClassName()==null) {
boolean isOK = false;
List/*LazyMethodGen*/ existingMethods = gen.getMethodGens();
for (Iterator i = existingMethods.iterator(); i.hasNext() && !isOK;) {
LazyMethodGen m = (LazyMethodGen) i.next();
if (m.getName().equals(introduced.getName()) &&
m.getParameterSignature().equals(introduced.getParameterSignature()) &&
m.getReturnType().equals(introduced.getReturnType())) {
isOK = true;
}
}
if (!isOK) {
// the class does not implement this method, they needed to supply a default impl class
IMessage msg = new Message("@DeclareParents: No defaultImpl was specified but the type '"+gen.getName()+
"' does not implement the method '"+stringifyMember(introduced)+"' defined on the interface '"+introduced.getDeclaringType()+"'",
weaver.getLazyClassGen().getType().getSourceLocation(),true,new ISourceLocation[]{munger.getSourceLocation()});
weaver.getWorld().getMessageHandler().handleMessage(msg);
return false;
}
return true;
}
LazyMethodGen mg = new LazyMethodGen(
introduced.getModifiers() - Modifier.ABSTRACT,
BcelWorld.makeBcelType(introduced.getReturnType()),
@@ -1666,6 +1718,10 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
return new BcelTypeMunger(munger.parameterizedFor(target),aspectType);
}
public ConcreteTypeMunger parameterizeWith(Map m, World w) {
return new BcelTypeMunger(munger.parameterizeWith(m,w),aspectType);
}
/**
* Returns a list of type variable aliases used in this munger. For example, if the
* ITD is 'int I<A,B>.m(List<A> las,List<B> lbs) {}' then this returns a list containing

+ 59
- 15
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java Прегледај датотеку

@@ -64,25 +64,24 @@ import org.aspectj.weaver.AsmRelationshipProvider;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.CrosscuttingMembersSet;
import org.aspectj.weaver.CustomMungerFactory;
import org.aspectj.weaver.IClassFileProvider;
import org.aspectj.weaver.IWeaveRequestor;
import org.aspectj.weaver.IWeaver;
import org.aspectj.weaver.NewParentTypeMunger;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ReferenceTypeDelegate;
import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ShadowMunger;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.WeaverMetrics;
import org.aspectj.weaver.WeaverStateInfo;
import org.aspectj.weaver.World;
import org.aspectj.weaver.patterns.AndPointcut;
import org.aspectj.weaver.patterns.BindingAnnotationTypePattern;
import org.aspectj.weaver.patterns.BindingTypePattern;
import org.aspectj.weaver.patterns.CflowPointcut;
import org.aspectj.weaver.patterns.ConcreteCflowPointcut;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.DeclareParents;
@@ -113,7 +112,6 @@ public class BcelWeaver implements IWeaver {
public BcelWeaver(BcelWorld world) {
super();
if (trace.isTraceEnabled()) trace.enter("<init>",this,world);
WeaverMetrics.reset();
this.world = world;
this.xcutSet = world.getCrosscuttingMembersSet();
if (trace.isTraceEnabled()) trace.exit("<init>");
@@ -138,6 +136,7 @@ public class BcelWeaver implements IWeaver {
private List declareParentsList = null; // setup by prepareForWeave

private ZipOutputStream zipOutputStream;
private CustomMungerFactory customMungerFactory;

// ----
@@ -192,8 +191,6 @@ public class BcelWeaver implements IWeaver {
wsi.getUnwovenClassFileData(wovenJavaClass.getBytes()));
world.storeClass(unwovenJavaClass);
classType.setJavaClass(unwovenJavaClass);
if (world.isRunMinimalMemory() && world.isXnoInline())
classType.evictWeavingState(); // CUSTARD
// classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes())));
}
@@ -201,6 +198,14 @@ public class BcelWeaver implements IWeaver {
//=> mainly for nothing for LTW - pbly for something in incremental build...
xcutSet.addOrReplaceAspect(type);
if (trace.isTraceEnabled()) trace.exit("addLibraryAspect",type);
if (type.getSuperclass().isAspect()) {
// If the supertype includes ITDs and the user has not included that aspect in the aop.xml, they will
// not get picked up, which can give unusual behaviour! See bug 223094
// This change causes us to pick up the super aspect regardless of what was said in the aop.xml - giving
// predictable behaviour. If the user also supplied it, there will be no problem other than the second
// addition overriding the first
addLibraryAspect(type.getSuperclass().getName());
}
return type;
} else {
// FIXME AV - better warning upon no such aspect from aop.xml
@@ -463,7 +468,6 @@ public class BcelWeaver implements IWeaver {
if (trace.isTraceEnabled()) trace.enter("prepareForWeave",this);
needToReweaveWorld = xcutSet.hasChangedSinceLastReset();

CflowPointcut.clearCaches();
// update mungers
for (Iterator i = addedClasses.iterator(); i.hasNext(); ) {
@@ -490,6 +494,8 @@ public class BcelWeaver implements IWeaver {
typeMungerList = xcutSet.getTypeMungers();
lateTypeMungerList = xcutSet.getLateTypeMungers();
declareParentsList = xcutSet.getDeclareParents();
addCustomMungers();
// The ordering here used to be based on a string compare on toString() for the two mungers -
// that breaks for the @AJ style where advice names aren't programmatically generated. So we
@@ -521,6 +527,30 @@ public class BcelWeaver implements IWeaver {
if (trace.isTraceEnabled()) trace.exit("prepareForWeave");
}
private void addCustomMungers() {
if (customMungerFactory != null) {
for (Iterator i = addedClasses.iterator(); i.hasNext();) {
UnwovenClassFile jc = (UnwovenClassFile) i.next();
String name = jc.getClassName();
ResolvedType type = world.resolve(name);
if (type.isAspect()) {
Collection/*ShadowMunger*/ shadowMungers = customMungerFactory.createCustomShadowMungers(type);
if (shadowMungers != null) {
shadowMungerList.addAll(shadowMungers);
}
Collection/*ConcreteTypeMunger*/ typeMungers = customMungerFactory
.createCustomTypeMungers(type);
if (typeMungers != null)
typeMungerList.addAll(typeMungers);
}
}
}
}
public void setCustomMungerFactory(CustomMungerFactory factory) {
customMungerFactory = factory;
}
/*
* Rewrite all of the pointcuts in the world into their most efficient
* form for subsequent matching. Also ensure that if pc1.equals(pc2)
@@ -833,9 +863,7 @@ public class BcelWeaver implements IWeaver {
*/
private void raiseUnboundFormalError(String name, Pointcut userPointcut) {
world.showMessage(IMessage.ERROR,
WeaverMessages.format(WeaverMessages.UNBOUND_FORMAL,
name),
userPointcut.getSourceContext().makeSourceLocation(userPointcut),null);
WeaverMessages.format(WeaverMessages.UNBOUND_FORMAL,name),userPointcut.getSourceLocation(),null);
}


@@ -1037,6 +1065,17 @@ public class BcelWeaver implements IWeaver {
}
}

// Go through the types and ensure any 'damaged' during compile time are repaired prior to weaving
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
UnwovenClassFile classFile = (UnwovenClassFile)i.next();
String className = classFile.getClassName();
ResolvedType theType = world.resolve(className);
if (theType!=null) {
BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
if (classType!=null) classType.ensureDelegateConsistent();
}
}

// special case for AtAspectJMungerOnly - see #113587
if (input.isApplyAtAspectJMungersOnly()) {
ContextToken atAspectJMungersOnly = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY, "");
@@ -1345,6 +1384,10 @@ public class BcelWeaver implements IWeaver {
//clazz is null if the classfile was unchanged by weaving...
if (clazz != null) {
UnwovenClassFile[] newClasses = getClassFilesFor(clazz);
// Copy the char[] across as it means the WeaverAdapter.removeFromMap() can be fast!
if (newClasses[0].getClassName().equals(classFile.getClassName())) {
newClasses[0].setClassNameAsChars(classFile.getClassNameAsChars());
}
for (int i = 0; i < newClasses.length; i++) {
requestor.acceptResult(newClasses[i]);
}
@@ -1374,11 +1417,13 @@ public class BcelWeaver implements IWeaver {
public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) {
List childClasses = clazz.getChildClasses(world);
UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()];
ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getJavaClassBytesIncludingReweavable(world));
// APR29
ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getClassName(),clazz.getJavaClassBytesIncludingReweavable(world));
int index = 1;
for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter.next();
UnwovenClassFile childClass = new UnwovenClassFile(clazz.getFileName() + "$" + element.name, element.bytes);
// APR29
UnwovenClassFile childClass = new UnwovenClassFile(clazz.getFileName() + "$" + element.name,/*clazz.getClassName()+"$"+element.name,*/ element.bytes);
ret[index++] = childClass;
}
return ret;
@@ -1409,8 +1454,8 @@ public class BcelWeaver implements IWeaver {
boolean typeChanged = applyDeclareParents(decp,onType);
if (typeChanged) {
aParentChangeOccurred = true;
} else { // Perhaps it would have matched if a 'dec @type' had modified the type
if (!decp.getChild().isStarAnnotation()) decpToRepeat.add(decp);
} else {
decpToRepeat.add(decp);
}
}

@@ -1718,7 +1763,6 @@ public class BcelWeaver implements IWeaver {
while (iter.hasNext()) {
ShadowMunger munger = (ShadowMunger)iter.next();
FuzzyBoolean fb = munger.getPointcut().fastMatch(info);
WeaverMetrics.recordFastMatchTypeResult(fb); // Could pass: munger.getPointcut().toString(),info
if (fb.maybeTrue()) {
result.add(munger);
}

+ 4
- 62
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java Прегледај датотеку

@@ -45,13 +45,13 @@ import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository;
import org.aspectj.apache.bcel.util.Repository;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationOnTypeMunger;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.ICrossReferenceHandler;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.MemberImpl;
import org.aspectj.weaver.NewParentTypeMunger;
@@ -104,8 +104,6 @@ public class BcelWorld extends World implements Repository {
}

private static List getPathEntries(String s) {
List ret = new ArrayList();
StringTokenizer tok = new StringTokenizer(s, File.pathSeparator);
@@ -170,61 +168,6 @@ public class BcelWorld extends World implements Repository {
classPath.addPath(name, this.getMessageHandler());
}

/**
* Parse a string into advice.
*
* <blockquote><pre>
* Kind ( Id , ... ) : Pointcut -> MethodSignature
* </pre></blockquote>
*/
public Advice shadowMunger(String str, int extraFlag) {
str = str.trim();
int start = 0;
int i = str.indexOf('(');
AdviceKind kind =
AdviceKind.stringToKind(str.substring(start, i));
start = ++i;
i = str.indexOf(')', i);
String[] ids = parseIds(str.substring(start, i).trim());
//start = ++i;
i = str.indexOf(':', i);
start = ++i;
i = str.indexOf("->", i);
Pointcut pointcut = Pointcut.fromString(str.substring(start, i).trim());
Member m = MemberImpl.methodFromString(str.substring(i+2, str.length()).trim());

// now, we resolve
UnresolvedType[] types = m.getParameterTypes();
FormalBinding[] bindings = new FormalBinding[ids.length];
for (int j = 0, len = ids.length; j < len; j++) {
bindings[j] = new FormalBinding(types[j], ids[j], j, 0, 0, "fromString");
}

Pointcut p =
pointcut.resolve(new SimpleScope(this, bindings));

return new BcelAdvice(kind, p, m, extraFlag, 0, 0, null, null);
}
private String[] parseIds(String str) {
if (str.length() == 0) return ZERO_STRINGS;
List l = new ArrayList();
int start = 0;
while (true) {
int i = str.indexOf(',', start);
if (i == -1) {
l.add(str.substring(start).trim());
break;
}
l.add(str.substring(start, i).trim());
start = i+1;
}
return (String[]) l.toArray(new String[l.size()]);
}
// ---- various interactions with bcel

public static Type makeBcelType(UnresolvedType type) {
@@ -452,7 +395,7 @@ public class BcelWorld extends World implements Repository {
}

public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberImpl.Kind kind) {
public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberKind kind) {
Member ret = mg.getMemberView();
if (ret == null) {
int mods = mg.getAccessFlags();
@@ -460,7 +403,8 @@ public class BcelWorld extends World implements Repository {
mods |= Modifier.INTERFACE;
}
if (kind == null) {
if (mg.getName().equals("<init>")) {
//OPTIMIZE surely we can pass the kind in and not resort to string compares?
if (mg.getName().equals("<init>")) {
kind = Member.CONSTRUCTOR;
} else if (mg.getName().equals("<clinit>")) {
kind = Member.STATIC_INITIALIZATION;
@@ -482,12 +426,10 @@ public class BcelWorld extends World implements Repository {
}
public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg,InstructionHandle h) {
Instruction i = h.getInstruction();
return MemberImpl.monitorEnter();
}

public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg,InstructionHandle h) {
Instruction i = h.getInstruction();
return MemberImpl.monitorExit();
}

+ 47
- 47
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java Прегледај датотеку

@@ -53,7 +53,7 @@ import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.SourceLocation;
import org.aspectj.util.CollectionUtil;
import org.aspectj.util.LangUtil;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.Member;
@@ -481,17 +481,12 @@ public final class LazyClassGen {
}
// Add a weaver version attribute to the file being produced (if necessary...)
boolean hasVersionAttribute = false;
Attribute[] attrs = myGen.getAttributes();
for (int i = 0; i < attrs.length && !hasVersionAttribute; i++) {
Attribute attribute = attrs[i];
if (attribute.getName().equals("org.aspectj.weaver.WeaverVersion")) hasVersionAttribute=true;
}
if (!hasVersionAttribute)
myGen.addAttribute(BcelAttributes.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPool()));
if (!myGen.hasAttribute("org.aspectj.weaver.WeaverVersion")) {
myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPool()));
}

if (myType != null && myType.getWeaverState() != null) {
myGen.addAttribute(BcelAttributes.bcelAttribute(
myGen.addAttribute(Utility.bcelAttribute(
new AjAttribute.WeaverState(myType.getWeaverState()),
getConstantPool()));
}
@@ -505,7 +500,13 @@ public final class LazyClassGen {

addAjcInitializers();

calculateSourceDebugExtensionOffsets();
// 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430). Will be revisited when contents
// of attribute are confirmed to be correct.
boolean sourceDebugExtensionSupportSwitchedOn = false;
if (sourceDebugExtensionSupportSwitchedOn) {
calculateSourceDebugExtensionOffsets();
}
int len = methodGens.size();
myGen.setMethods(Method.NoMethods);
@@ -515,25 +516,26 @@ public final class LazyClassGen {
if (isEmptyClinit(gen)) continue;
myGen.addMethod(gen.getMethod());
}
len = fields.size();
myGen.setFields(Field.NoFields);
for (int i = 0; i < len; i++) {
BcelField gen = (BcelField) fields.get(i);
myGen.addField(gen.getField(this.constantPoolGen));
}
if (inlinedFiles.size() != 0) {
if (hasSourceDebugExtensionAttribute(myGen)) {
world.showMessage(
IMessage.WARNING,
WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()),
null,
null);

if (sourceDebugExtensionSupportSwitchedOn) {
if (inlinedFiles.size() != 0) {
if (hasSourceDebugExtensionAttribute(myGen)) {
world.showMessage(
IMessage.WARNING,
WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()),
null,
null);
}
// myGen.addAttribute(getSourceDebugExtensionAttribute());
}
// 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430). Will be revisited when contents
// of attribute are confirmed to be correct.
// myGen.addAttribute(getSourceDebugExtensionAttribute());
}
}
fixupGenericSignatureAttribute();
}
@@ -560,11 +562,7 @@ public final class LazyClassGen {
// 2. Find the old attribute
Signature sigAttr = null;
if (myType!=null) { // if null, this is a type built from scratch, it won't already have a sig attribute
Attribute[] as = myGen.getAttributes();
for (int i = 0; i < as.length; i++) {
Attribute attribute = as[i];
if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute;
}
sigAttr = (Signature) myGen.getAttribute("Signature");
}
// 3. Do we need an attribute?
@@ -632,7 +630,7 @@ public final class LazyClassGen {
// create an empty myGen so that we can give back a return value that doesn't upset the
// rest of the process.
myGen = new ClassGen(myGen.getClassName(), myGen.getSuperclassName(),
myGen.getFileName(), myGen.getAccessFlags(), myGen.getInterfaceNames());
myGen.getFileName(), myGen.getModifiers(), myGen.getInterfaceNames());
// raise an error against this compilation unit.
getWorld().showMessage(
IMessage.ERROR,
@@ -643,15 +641,16 @@ public final class LazyClassGen {
}

private static boolean hasSourceDebugExtensionAttribute(ClassGen gen) {
ConstantPool pool = gen.getConstantPool();
Attribute[] attrs = gen.getAttributes();
for (int i = 0; i < attrs.length; i++) {
if ("SourceDebugExtension"
.equals(((ConstantUtf8) pool.getConstant(attrs[i].getNameIndex())).getBytes())) {
return true;
}
}
return false;
return gen.hasAttribute("SourceDebugExtension");
// ConstantPool pool = gen.getConstantPool();
// Attribute[] attrs = gen.getAttributes();
// for (int i = 0; i < attrs.length; i++) {
// if ("SourceDebugExtension"
// .equals(((ConstantUtf8) pool.getConstant(attrs[i].getNameIndex())).getBytes())) {
// return true;
// }
// }
// return false;
}

public JavaClass getJavaClass(BcelWorld world) {
@@ -734,10 +733,10 @@ public final class LazyClassGen {

public String toShortString() {
String s =
org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getAccessFlags(), true);
org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getModifiers(), true);
if (s != "")
s += " ";
s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getAccessFlags());
s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getModifiers());
s += " ";
s += myGen.getClassName();
return s;
@@ -861,7 +860,7 @@ public final class LazyClassGen {
Type.VOID,
"<clinit>",
new Type[0],
CollectionUtil.NO_STRINGS,
LangUtil.NO_STRINGS,
this);
clinit.getBody().insert(InstructionConstants.RETURN);
methodGens.add(clinit);
@@ -878,7 +877,7 @@ public final class LazyClassGen {
Type.VOID,
NameMangler.AJC_PRE_CLINIT_NAME,
new Type[0],
CollectionUtil.NO_STRINGS,
LangUtil.NO_STRINGS,
this);
ajcClinit.getBody().insert(InstructionConstants.RETURN);
methodGens.add(ajcClinit);
@@ -1258,7 +1257,8 @@ public final class LazyClassGen {
private void makeSyntheticAndTransientIfNeeded(FieldGen field) {
if (field.getName().startsWith(NameMangler.PREFIX) &&
!field.getName().startsWith("ajc$interField$")) {
!field.getName().startsWith("ajc$interField$") &&
!field.getName().startsWith("ajc$instance$")) {
// it's an aj added field
// first do transient
if (!field.isStatic()) {
@@ -1284,9 +1284,9 @@ public final class LazyClassGen {
}
}
private boolean hasSyntheticAttribute(Attribute[] attributes) {
for (int i = 0; i < attributes.length; i++) {
if (attributes[i].getName().equals("Synthetic")) {
private boolean hasSyntheticAttribute(List attributes) {
for (int i = 0; i < attributes.size(); i++) {
if (((Attribute)attributes.get(i)).getName().equals("Synthetic")) {
return true;
}
}
@@ -1338,7 +1338,7 @@ public final class LazyClassGen {
public void forcePublic() {
myGen.setAccessFlags(Utility.makePublic(myGen.getAccessFlags()));
myGen.setModifiers(Utility.makePublic(myGen.getModifiers()));
}


+ 211
- 107
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java Прегледај датотеку

@@ -39,6 +39,7 @@ import org.aspectj.apache.bcel.generic.ClassGenException;
import org.aspectj.apache.bcel.generic.CodeExceptionGen;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionBranch;
import org.aspectj.apache.bcel.generic.InstructionComparator;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionSelect;
@@ -50,6 +51,7 @@ import org.aspectj.apache.bcel.generic.LocalVariableTag;
import org.aspectj.apache.bcel.generic.MethodGen;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.apache.bcel.generic.Tag;
import org.aspectj.apache.bcel.generic.TargetLostException;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
@@ -69,6 +71,7 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.tools.Traceable;



/**
* A LazyMethodGen should be treated as a MethodGen. It's our way of abstracting over the
* low-level Method objects. It converts through {@link MethodGen} to create
@@ -86,22 +89,25 @@ import org.aspectj.weaver.tools.Traceable;
public final class LazyMethodGen implements Traceable {
private static final int ACC_SYNTHETIC = 0x1000;
private int accessFlags;
private Type returnType;
private final String name;
private int accessFlags;
private Type returnType;
private final String name;
private Type[] argumentTypes;
//private final String[] argumentNames;
private String[] declaredExceptions;
private InstructionList body; // leaving null for abstracts
private Attribute[] attributes;
private List attributes;
private List newAnnotations;
private final LazyClassGen enclosingClass;
private BcelMethod memberView;
private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
int highestLineNumber = 0;
boolean wasNewPacked = false;

/*
* We use LineNumberTags and not Gens.
*
* This option specifies whether we let the BCEL classes create LineNumberGens and LocalVariableGens
* or if we make it create LineNumberTags and LocalVariableTags. Up until 1.5.1 we always created
* Gens - then on return from the MethodGen ctor we took them apart, reprocessed them all and
@@ -114,12 +120,7 @@ public final class LazyMethodGen implements Traceable {
* instructions it targets, it relies on the instructions targetting *it* - this reduces the amount
* of targeter manipulation we have to do.
*
* Because this *could* go wrong - it passes all our tests, but you never know, the option:
* -Xset:optimizeWithTags=false
* will turn it *OFF*
*/
public static boolean avoidUseOfBcelGenObjects = true;
public static boolean checkedXsetOption = false;

/** This is nonnull if this method is the result of an "inlining". We currently
* copy methods into other classes for around advice. We add this field so
@@ -167,7 +168,7 @@ public final class LazyMethodGen implements Traceable {
} else {
body = null;
}
this.attributes = new Attribute[0];
this.attributes = new ArrayList();
this.enclosingClass = enclosingClass;
assertGoodBody();

@@ -207,7 +208,7 @@ public final class LazyMethodGen implements Traceable {
}
this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
this.accessFlags = m.getAccessFlags();
this.accessFlags = m.getModifiers();
this.name = m.getName();

// @AJ advice are not inlined by default since requires further analysis
@@ -233,7 +234,7 @@ public final class LazyMethodGen implements Traceable {
}
//this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
this.memberView = m;
this.accessFlags = savedMethod.getAccessFlags();
this.accessFlags = savedMethod.getModifiers();
this.name = m.getName();

// @AJ advice are not inlined by default since requires further analysis
@@ -301,22 +302,15 @@ public final class LazyMethodGen implements Traceable {
private void initialize() {
if (returnType != null) return;
// Check whether we need to configure the optimization
if (!checkedXsetOption) {
Properties p = enclosingClass.getWorld().getExtraConfiguration();
if (p!=null) {
String s = p.getProperty("optimizeWithTags","true");
avoidUseOfBcelGenObjects = s.equalsIgnoreCase("true");
if (!avoidUseOfBcelGenObjects)
enclosingClass.getWorld().getMessageHandler().handleMessage(MessageUtil.info("[optimizeWithTags=false] Disabling optimization to use Tags rather than Gens"));
}
checkedXsetOption=true;
}
//System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " + savedMethod);
MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(),avoidUseOfBcelGenObjects);
MethodGen gen = null;
try {
gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(),true);
} catch (RuntimeException t) {
System.err.println(getName());
throw t;
}
this.returnType = gen.getReturnType();
this.argumentTypes = gen.getArgumentTypes();

@@ -341,13 +335,9 @@ public final class LazyMethodGen implements Traceable {

unpackHandlers(gen);
if (avoidUseOfBcelGenObjects) {
ensureAllLineNumberSetup(gen);
highestLineNumber = gen.getHighestlinenumber();
} else {
unpackLineNumbers(gen);
unpackLocals(gen);
}
ensureAllLineNumberSetup(gen);
highestLineNumber = gen.getHighestlinenumber();
}
assertGoodBody();
@@ -411,29 +401,6 @@ public final class LazyMethodGen implements Traceable {
}
}

private void unpackLineNumbers(MethodGen gen) {
LineNumberTag lr = null;
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
InstructionTargeter[] targeters = ih.getTargeters();
if (targeters != null) {
for (int i = targeters.length - 1; i >= 0; i--) {
InstructionTargeter targeter = targeters[i];
if (targeter instanceof LineNumberGen) {
LineNumberGen lng = (LineNumberGen) targeter;
lng.updateTarget(ih, null);
int lineNumber = lng.getSourceLine();
if (highestLineNumber < lineNumber) highestLineNumber = lineNumber;
lr = new LineNumberTag(lineNumber);
}
}
}
if (lr != null) {
ih.addTargeter(lr);
}
}
gen.removeLineNumbers();
}

/**
* On entry to this method we have a method whose instruction stream contains a few instructions
* that have line numbers assigned to them (LineNumberTags). The aim is to ensure every instruction
@@ -460,33 +427,6 @@ public final class LazyMethodGen implements Traceable {
}
}
}

private void unpackLocals(MethodGen gen) {
Set locals = new HashSet();
for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
InstructionTargeter[] targeters = ih.getTargeters();
List ends = new ArrayList(0);
if (targeters != null) {
for (int i = targeters.length - 1; i >= 0; i--) {
InstructionTargeter targeter = targeters[i];
if (targeter instanceof LocalVariableGen) {
LocalVariableGen lng = (LocalVariableGen) targeter;
LocalVariableTag lr = new LocalVariableTag(lng.getType().getSignature()/*BcelWorld.fromBcel(lng.getType())*/, lng.getName(), lng.getIndex(), lng.getStart().getPosition());
if (lng.getStart() == ih) {
locals.add(lr);
} else {
ends.add(lr);
}
}
}
}
for (Iterator i = locals.iterator(); i.hasNext(); ) {
ih.addTargeter((LocalVariableTag) i.next());
}
locals.removeAll(ends);
}
gen.removeLocalVariables();
}
// ===============
@@ -505,7 +445,8 @@ public final class LazyMethodGen implements Traceable {
try {
MethodGen gen = pack();
return gen.getMethod();
savedMethod = gen.getMethod();
return savedMethod;
} catch (ClassGenException e) {
enclosingClass.getBcelObjectType().getResolvedTypeX().getWorld().showMessage(
IMessage.ERROR,
@@ -522,6 +463,9 @@ public final class LazyMethodGen implements Traceable {
}
public void markAsChanged() {
if (wasNewPacked) {
throw new RuntimeException("Already packed method is being re-modified: "+getClassName()+" "+toShortString());
}
initialize();
savedMethod = null;
}
@@ -529,7 +473,8 @@ public final class LazyMethodGen implements Traceable {
// =============================

public String toString() {
WeaverVersionInfo weaverVersion = enclosingClass.getBcelObjectType().getWeaverVersionAttribute();
BcelObjectType bot = enclosingClass.getBcelObjectType();
WeaverVersionInfo weaverVersion = (bot==null?WeaverVersionInfo.CURRENT:bot.getWeaverVersionAttribute());
return toLongString(weaverVersion);
}

@@ -611,7 +556,7 @@ public final class LazyMethodGen implements Traceable {
if (enclosingClass != null && enclosingClass.getType() != null) {
context = enclosingClass.getType().getSourceContext();
}
List as = BcelAttributes.readAjAttributes(getClassName(),attributes, context,null,weaverVersion);
List as = BcelAttributes.readAjAttributes(getClassName(), (Attribute[])attributes.toArray(new Attribute[]{}), context,null,weaverVersion);
if (! as.isEmpty()) {
out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger...
}
@@ -909,6 +854,14 @@ public final class LazyMethodGen implements Traceable {
return name;
}

public String getGenericReturnTypeSignature() {
if (memberView == null) {
return getReturnType().getSignature();
} else {
return memberView.getGenericReturnType().getSignature();
}
}
public Type getReturnType() {
initialize();
return returnType;
@@ -928,7 +881,7 @@ public final class LazyMethodGen implements Traceable {
return body != null;
}

public Attribute[] getAttributes() {
public List/*Attribute*/ getAttributes() {
return attributes;
}

@@ -966,8 +919,8 @@ public final class LazyMethodGen implements Traceable {
gen.addException(declaredExceptions[i]);
}
for (int i = 0, len = attributes.length; i < len; i++) {
gen.addAttribute(attributes[i]);
for (int i = 0, len = attributes.size(); i < len; i++) {
gen.addAttribute((Attribute)attributes.get(i));
}
if (newAnnotations!=null) {
@@ -996,7 +949,16 @@ public final class LazyMethodGen implements Traceable {
}
if (hasBody()) {
packBody(gen);
if (this.enclosingClass.getWorld().shouldGoForIt()) {
if (isAdviceMethod() || getName().equals("<clinit>")) {
packBody(gen);
} else {
newPackBody(gen);
}
} else {
packBody(gen);
}
// FINISH OFF CASE/SWITCH !
gen.setMaxLocals();
gen.setMaxStack();
} else {
@@ -1109,6 +1071,108 @@ public final class LazyMethodGen implements Traceable {
}
}

/*
* Andys version
*/
public void newPackBody(MethodGen gen) {
InstructionList theBody = getBody();
InstructionHandle iHandle = theBody.getStart();

int currLine = -1;
int lineNumberOffset = (fromFilename == null) ? 0: getEnclosingClass().getSourceDebugExtensionOffset(fromFilename);
Map localVariables = new HashMap();
LinkedList exceptionList = new LinkedList();
Set forDeletion = new HashSet();
Set branchInstructions = new HashSet();
// OPTIMIZE sort out in here: getRange()/insertHandler() and type of exceptionList
while (iHandle != null) {
Instruction inst = iHandle.getInstruction();
InstructionHandle nextInst = iHandle.getNext();
// OPTIMIZE remove this instructionhandle as it now points to nowhere?
if (inst == Range.RANGEINSTRUCTION) {
Range r = Range.getRange(iHandle);
if (r instanceof ExceptionRange) {
ExceptionRange er = (ExceptionRange) r;
if (er.getStart() == iHandle) {
if (!er.isEmpty()){
// order is important, insert handlers in order of start
insertHandler(er, exceptionList);
}
}
}
forDeletion.add(iHandle);
} else {
if (inst instanceof InstructionBranch) {
branchInstructions.add(iHandle);
}

InstructionTargeter[] targeters = iHandle.getTargeters();
if (targeters != null) {
for (int k = targeters.length - 1; k >= 0; k--) {
InstructionTargeter targeter = targeters[k];
if (targeter instanceof LineNumberTag) {
int line = ((LineNumberTag)targeter).getLineNumber();
if (line != currLine) {
gen.addLineNumber(iHandle, line + lineNumberOffset);
currLine = line;
}
} else if (targeter instanceof LocalVariableTag) {
LocalVariableTag lvt = (LocalVariableTag) targeter;
LVPosition p = (LVPosition)localVariables.get(lvt);
// If we don't know about it, create a new position and store
// If we do know about it - update its end position
if (p==null) {
LVPosition newp = new LVPosition();
newp.start=newp.end=iHandle;
localVariables.put(lvt,newp);
} else {
p.end = iHandle;
}
}
}
}
}
iHandle = iHandle.getNext();
}
for (Iterator iterator = branchInstructions.iterator(); iterator.hasNext();) {
BranchHandle iBranch = (BranchHandle) iterator.next();
handleBranchInstruction(iBranch,forDeletion);
}
// now add exception handlers
for (Iterator iter = exceptionList.iterator(); iter.hasNext();) {
ExceptionRange r = (ExceptionRange) iter.next();
if (r.isEmpty()) continue;
gen.addExceptionHandler(
jumpForward(r.getRealStart(),forDeletion),
jumpForward(r.getRealEnd(),forDeletion),
jumpForward(r.getHandler(),forDeletion),
(r.getCatchType() == null)
? null
: (ObjectType) BcelWorld.makeBcelType(r.getCatchType()));
}
for (Iterator iterator = forDeletion.iterator(); iterator.hasNext();) {
try {
theBody.delete((InstructionHandle)iterator.next());
} catch (TargetLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
gen.setInstructionList(theBody);
addLocalVariables(gen,localVariables);
// JAVAC adds line number tables (with just one entry) to generated accessor methods - this
// keeps some tools that rely on finding at least some form of linenumbertable happy.
// Let's check if we have one - if we don't then let's add one.
// TODO Could be made conditional on whether line debug info is being produced
if (gen.getLineNumbers().length==0) {
gen.addLineNumber(gen.getInstructionList().getStart(),1);
}
wasNewPacked = true;
}
private void addLocalVariables(MethodGen gen, Map localVariables) {
// now add local variables
gen.removeLocalVariables();
@@ -1166,28 +1230,59 @@ public final class LazyMethodGen implements Traceable {
InstructionBranch newBranchInstruction = (InstructionBranch) newInstruction;
InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old target
// try {
// New target is in hash map
newBranchInstruction.setTarget(remap(oldTarget, map));
// } catch (NullPointerException e) {
// print();
// System.out.println("Was trying to remap " + bi);
// System.out.println("who's target was supposedly " + itarget);
// throw e;
// }
if (oldBranchInstruction instanceof InstructionSelect) {
// Either LOOKUPSWITCH or TABLESWITCH
InstructionHandle[] oldTargets = ((InstructionSelect) oldBranchInstruction).getTargets();
InstructionHandle[] newTargets = ((InstructionSelect) newBranchInstruction).getTargets();
if (oldBranchInstruction instanceof InstructionSelect) {
// Either LOOKUPSWITCH or TABLESWITCH
InstructionHandle[] oldTargets = ((InstructionSelect) oldBranchInstruction).getTargets();
InstructionHandle[] newTargets = ((InstructionSelect) newBranchInstruction).getTargets();
for (int k = oldTargets.length - 1; k >= 0; k--) {
// Update all targets
for (int k = oldTargets.length - 1; k >= 0; k--) {
// Update all targets
newTargets[k] = remap(oldTargets[k], map);
newTargets[k].addTargeter(newBranchInstruction);
}
}
}
private InstructionHandle jumpForward(InstructionHandle t,Set handlesForDeletion) {
InstructionHandle target = t;
if (handlesForDeletion.contains(target)) {
do {
target = target.getNext();
} while (handlesForDeletion.contains(target));
}
return target;
}
private void handleBranchInstruction(BranchHandle branchHandle, Set handlesForDeletion) {
InstructionBranch branchInstruction = (InstructionBranch) branchHandle.getInstruction();
InstructionHandle target = branchInstruction.getTarget(); // old target
if (handlesForDeletion.contains(target)) {
do {
target = target.getNext();
} while (handlesForDeletion.contains(target));
branchInstruction.setTarget(target);
}
if (branchInstruction instanceof InstructionSelect) {
// Either LOOKUPSWITCH or TABLESWITCH
InstructionHandle[] targets = ((InstructionSelect)branchInstruction).getTargets();
for (int k = targets.length - 1; k >= 0; k--) {
InstructionHandle oneTarget = targets[k];
if (handlesForDeletion.contains(oneTarget)) {
do {
oneTarget = oneTarget.getNext();
} while (handlesForDeletion.contains(oneTarget));
branchInstruction.setTarget(oneTarget);
oneTarget.addTargeter(branchInstruction);
}
}
}
}

private void handleRangeInstruction(InstructionHandle ih, LinkedList exnList) {
// we're a range instruction
@@ -1251,6 +1346,13 @@ public final class LazyMethodGen implements Traceable {
// curr = next;
// }
// }
private static InstructionHandle fNext(InstructionHandle ih) {
while (true) {
if (ih.getInstruction()==Range.RANGEINSTRUCTION) ih = ih.getNext();
else return ih;
}
}

private static InstructionHandle remap(InstructionHandle ih, Map map) {
while (true) {
@@ -1513,6 +1615,7 @@ public final class LazyMethodGen implements Traceable {
// ----
boolean isAdviceMethod() {
if (memberView==null) return false;
return memberView.getAssociatedShadowMunger() != null;
}
@@ -1576,10 +1679,11 @@ public final class LazyMethodGen implements Traceable {
* @param attr
*/
public void addAttribute(Attribute attr) {
Attribute[] newAttributes = new Attribute[attributes.length + 1];
System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
newAttributes[attributes.length] = attr;
attributes = newAttributes;
attributes.add(attr);
// Attribute[] newAttributes = new Attribute[attributes.length + 1];
// System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
// newAttributes[attributes.length] = attr;
// attributes = newAttributes;
}

public String toTraceString() {

+ 13
- 1
weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java Прегледај датотеку

@@ -27,6 +27,7 @@ import org.aspectj.util.FileUtil;

public class UnwovenClassFile {
protected String filename;
protected char[] charfilename;
protected byte[] bytes;
// protected JavaClass javaClass = null;
//protected byte[] writtenBytes = null;
@@ -149,9 +150,15 @@ public class UnwovenClassFile {
return true;
}

public char[] getClassNameAsChars() {
if (charfilename==null) {
charfilename = getClassName().replace('.', '/').toCharArray();
}
return charfilename;
}
public String getClassName() {
if (className == null) className = getJavaClass().getClassName();
if (className == null) className = getJavaClass().getClassName(); // OPTIMIZE quicker way to determine name??? surely?
return className;
}
@@ -184,6 +191,7 @@ public class UnwovenClassFile {
}

// record
// OPTIMIZE why is the 'short name' used here (the bit after the dollar) - seems we mess about a lot trimming it off only to put it back on!
public static class ChildClass {
public final String name;
public final byte[] bytes;
@@ -206,6 +214,10 @@ public class UnwovenClassFile {
return "(ChildClass " + name + ")";
}
}

public void setClassNameAsChars(char[] classNameAsChars) {
this.charfilename = classNameAsChars;
}
}



+ 4
- 2
weaver/src/org/aspectj/weaver/bcel/UnwovenClassFileWithThirdPartyManagedBytecode.java Прегледај датотеку

@@ -29,9 +29,11 @@ public class UnwovenClassFileWithThirdPartyManagedBytecode
byte[] getBytes();
}
public UnwovenClassFileWithThirdPartyManagedBytecode(String filename,
// OPTIMIZE make classname an input char[]
public UnwovenClassFileWithThirdPartyManagedBytecode(String filename,String classname,
IByteCodeProvider provider) {
super(filename,null);
// APR29
super(filename,classname,null);
this.provider = provider;
}

+ 37
- 61
weaver/src/org/aspectj/weaver/bcel/Utility.java Прегледај датотеку

@@ -24,9 +24,12 @@ import java.util.Hashtable;
import java.util.List;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.ClassParser;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Unknown;
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
@@ -52,6 +55,7 @@ import org.aspectj.apache.bcel.generic.SwitchBuilder;
import org.aspectj.apache.bcel.generic.TargetLostException;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.Lint;
@@ -205,12 +209,8 @@ public class Utility {
kind = Constants.INVOKEVIRTUAL;
}

return fact.createInvoke(
declaringClass.getClassName(),
newMethod.getName(),
Type.getReturnType(newMethod.getSignature()),
Type.getArgumentTypes(newMethod.getSignature()),
kind);
String sig = newMethod.getSignature();
return fact.createInvoke(declaringClass.getClassName(),newMethod.getName(),sig,kind);
}
public static byte[] stringToUTF(String s) {
@@ -541,37 +541,6 @@ public class Utility {
}
}
public static String arrayToString(int[] a) {
int len = a.length;
if (len == 0) return "[]";
StringBuffer buf = new StringBuffer("[");
buf.append(a[0]);
for (int i = 1; i < len; i++) {
buf.append(", ");
buf.append(a[i]);
}
buf.append("]");
return buf.toString();
}

/**
* replace an instruction handle with another instruction, in this case, a branch instruction.
*
* @param ih the instruction handle to replace.
* @param branchInstruction the branch instruction to replace ih with
* @param enclosingMethod where to find ih's instruction list.
*/
public static void replaceInstruction(
InstructionHandle ih,
InstructionBranch branchInstruction,
LazyMethodGen enclosingMethod)
{
InstructionList il = enclosingMethod.getBody();
InstructionHandle fresh = il.append(ih, branchInstruction);
deleteInstruction(ih, fresh, enclosingMethod);
}
public static void replaceInstruction(
InstructionHandle ih,
InstructionList replacementInstructions,
@@ -704,15 +673,14 @@ public class Utility {
// assumes that there is no already extant source line tag. Otherwise we'll have to be better.
public static void setSourceLine(InstructionHandle ih, int lineNumber) {
// OPTIMIZE LineNumberTag instances for the same line could be shared throughout a method...
ih.addTargeter(new LineNumberTag(lineNumber));
}

public static int makePublic(int i) {
return i & ~(Modifier.PROTECTED | Modifier.PRIVATE) | Modifier.PUBLIC;
}
public static int makePrivate(int i) {
return i & ~(Modifier.PROTECTED | Modifier.PUBLIC) | Modifier.PRIVATE;
}

public static BcelVar[] pushAndReturnArrayOfVars(
ResolvedType[] proceedParamTypes,
InstructionList il,
@@ -806,25 +774,33 @@ public class Utility {
}
// not yet used...
public static boolean isSimple(Method method) {
if (method.getCode()==null) return true;
if (method.getCode().getCode().length>10) return false;
InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive!
InstructionHandle InstrHandle = instrucs.getStart();
while (InstrHandle != null) {
Instruction Instr = InstrHandle.getInstruction();
int opCode = Instr.opcode;
// if current instruction is a branch instruction, see if it's a backward branch.
// if it is return immediately (can't be trivial)
if (Instr instanceof InstructionBranch) {
// InstructionBranch BI = (InstructionBranch) Instr;
if (Instr.getIndex() < 0) return false;
} else if (Instr instanceof InvokeInstruction) {
// if current instruction is an invocation, indicate that it can't be trivial
return false;
}
InstrHandle = InstrHandle.getNext();
}
return true;
}
// public static boolean isSimple(Method method) {
// if (method.getCode()==null) return true;
// if (method.getCode().getCode().length>10) return false;
// InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive!
// InstructionHandle InstrHandle = instrucs.getStart();
// while (InstrHandle != null) {
// Instruction Instr = InstrHandle.getInstruction();
// int opCode = Instr.opcode;
// // if current instruction is a branch instruction, see if it's a backward branch.
// // if it is return immediately (can't be trivial)
// if (Instr instanceof InstructionBranch) {
// // InstructionBranch BI = (InstructionBranch) Instr;
// if (Instr.getIndex() < 0) return false;
// } else if (Instr instanceof InvokeInstruction) {
// // if current instruction is an invocation, indicate that it can't be trivial
// return false;
// }
// InstrHandle = InstrHandle.getNext();
// }
// return true;
// }

public static Attribute bcelAttribute(AjAttribute a, ConstantPool pool) {
int nameIndex = pool.addUtf8(a.getNameString());
byte[] bytes = a.getBytes();
int length = bytes.length;
return new Unknown(nameIndex, length, bytes, pool);
}
}

+ 13
- 0
weaver/src/org/aspectj/weaver/loadtime/IWeavingContext.java Прегледај датотеку

@@ -14,6 +14,9 @@ package org.aspectj.weaver.loadtime;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.List;

import org.aspectj.weaver.tools.WeavingAdaptor;

/**
* This class adds support to AspectJ for an OSGi environment
@@ -73,4 +76,14 @@ public interface IWeavingContext {
*/
public boolean isLocallyDefined(String classname);

/**
* Allow custom parsing of aop.xml or alternative mechanism for providing
* Definitions
*
* @param loader
* @param adaptor
* @return List containing 0 or more Definition instances
*/
public List getDefinitions(final ClassLoader loader, WeavingAdaptor adaptor);

}

+ 3
- 1
weaver/src/org/aspectj/weaver/ltw/LTWWorld.java Прегледај датотеку

@@ -258,6 +258,8 @@ public class LTWWorld extends BcelWorld implements IReflectionWorld {
visitor.visitObject(loader.getParent());
super.accept(visitor);
}

public boolean shouldGoForIt() {
return true; // Zooooooooooom
}
}

+ 0
- 22
weaver/src/org/aspectj/weaver/ltw/LTWeaver.java Прегледај датотеку

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

import org.aspectj.weaver.IWeaver;

/**
* @author adrian
*
*/
public class LTWeaver implements IWeaver {

}

+ 18
- 2
weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java Прегледај датотеку

@@ -18,7 +18,8 @@ import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;

import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.ResolvedType;
/**
* @author colyer
*
@@ -39,6 +40,10 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
public FuzzyBoolean matches(AnnotatedElement annotated) {
return left.matches(annotated).and(right.matches(annotated));
}
public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations ) {
return left.matches(annotated,parameterAnnotations).and(right.matches(annotated,parameterAnnotations));
}

public void resolve(World world) {
left.resolve(world);
@@ -60,6 +65,7 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
AnnotationTypePattern newRight = right.parameterizeWith(typeVariableMap,w);
AndAnnotationTypePattern ret = new AndAnnotationTypePattern(newLeft,newRight);
ret.copyLocationFrom(this);
if (this.isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
return ret;
}
@@ -68,6 +74,9 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
AnnotationTypePattern.read(s,context),
AnnotationTypePattern.read(s,context));
p.readLocation(context,s);
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) {
if (s.readBoolean()) p.setForParameterAnnotationMatch();
}
return p;
}
@@ -76,18 +85,20 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
left.write(s);
right.write(s);
writeLocation(s);
s.writeBoolean(isForParameterAnnotationMatch());
}
public boolean equals(Object obj) {
if (!(obj instanceof AndAnnotationTypePattern)) return false;
AndAnnotationTypePattern other = (AndAnnotationTypePattern) obj;
return (left.equals(other.left) && right.equals(other.right));
return (left.equals(other.left) && right.equals(other.right) && left.isForParameterAnnotationMatch()==right.isForParameterAnnotationMatch());
}
public int hashCode() {
int result = 17;
result = result*37 + left.hashCode();
result = result*37 + right.hashCode();
result = result*37 + (isForParameterAnnotationMatch()?0:1);
return result;
}
@@ -108,4 +119,9 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
right.traverse(visitor,ret);
return ret;
}

public void setForParameterAnnotationMatch() {
left.setForParameterAnnotationMatch();
right.setForParameterAnnotationMatch();
}
}

+ 11
- 29
weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java Прегледај датотеку

@@ -18,6 +18,7 @@ import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;

@@ -25,6 +26,8 @@ public abstract class AnnotationTypePattern extends PatternNode {

public static final AnnotationTypePattern ANY = new AnyAnnotationTypePattern();
public static final AnnotationTypePattern ELLIPSIS = new EllipsisAnnotationTypePattern();
public static final AnnotationTypePattern[] NONE = new AnnotationTypePattern[0];
private boolean isForParameterAnnotationMatch;
/**
* TODO: write, read, equals & hashcode both in annotation hierarachy and
@@ -35,6 +38,7 @@ public abstract class AnnotationTypePattern extends PatternNode {
}
public abstract FuzzyBoolean matches(AnnotatedElement annotated);
public abstract FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations);
public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
return FuzzyBoolean.MAYBE;
@@ -84,44 +88,22 @@ public abstract class AnnotationTypePattern extends PatternNode {
throw new BCException("unknown TypePattern kind: " + key);
}

}

class AnyAnnotationTypePattern extends AnnotationTypePattern {

public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
return FuzzyBoolean.YES;
}
public FuzzyBoolean matches(AnnotatedElement annotated) {
return FuzzyBoolean.YES;
}

public void write(DataOutputStream s) throws IOException {
s.writeByte(AnnotationTypePattern.ANY_KEY);
}
public void resolve(World world) {
}
public String toString() { return "@ANY"; }
public void setForParameterAnnotationMatch() { isForParameterAnnotationMatch = true; }
public boolean isForParameterAnnotationMatch() { return isForParameterAnnotationMatch; }

public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public boolean isAny() { return true; }
public AnnotationTypePattern parameterizeWith(Map arg0,World w) {
return this;
}
}


class EllipsisAnnotationTypePattern extends AnnotationTypePattern {

public FuzzyBoolean matches(AnnotatedElement annotated) {
return FuzzyBoolean.NO;
}

public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
return FuzzyBoolean.NO;
}

public void write(DataOutputStream s) throws IOException {
s.writeByte(AnnotationTypePattern.ELLIPSIS_KEY);
}

+ 55
- 0
weaver/src/org/aspectj/weaver/patterns/AnyAnnotationTypePattern.java Прегледај датотеку

@@ -0,0 +1,55 @@
/* *******************************************************************
* Copyright (c) 2008 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors
* Andy Clement - extracted from AnnotationTypePattern
* ******************************************************************/
package org.aspectj.weaver.patterns;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Map;

import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ResolvedType;

public class AnyAnnotationTypePattern extends AnnotationTypePattern {

public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
return FuzzyBoolean.YES;
}
public FuzzyBoolean matches(AnnotatedElement annotated) {
return FuzzyBoolean.YES;
}
public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
return FuzzyBoolean.YES;
}

public void write(DataOutputStream s) throws IOException {
s.writeByte(AnnotationTypePattern.ANY_KEY);
}
public void resolve(World world) {
}
public String toString() { return "@ANY"; }

public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public boolean isAny() { return true; }
public AnnotationTypePattern parameterizeWith(Map arg0,World w) {
return this;
}
}

+ 2
- 2
weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java Прегледај датотеку

@@ -23,7 +23,7 @@ import java.util.Map;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.BetaException;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ResolvedType;
@@ -293,7 +293,7 @@ public class ArgsPointcut extends NameBindingPointcut {
}
return findResidueNoEllipsis(shadow, state, patternsWithoutEllipsis);
} else {
throw new BetaException("unimplemented");
throw new BCException("unimplemented");
}
}

+ 1
- 0
weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java Прегледај датотеку

@@ -106,6 +106,7 @@ public class BasicTokenSource implements ITokenSource {
case '@':
case '<':
case '>':
case '=':
case '?':
tokens.add(BasicToken.makeOperator(makeString(ch), i-1, i-1));
continue;

+ 2
- 2
weaver/src/org/aspectj/weaver/patterns/BindingAnnotationTypePattern.java Прегледај датотеку

@@ -33,7 +33,7 @@ public class BindingAnnotationTypePattern extends ExactAnnotationTypePattern imp
* @param annotationType
*/
public BindingAnnotationTypePattern(UnresolvedType annotationType, int index) {
super(annotationType);
super(annotationType,null);
this.formalIndex = index;
}
@@ -105,7 +105,7 @@ public class BindingAnnotationTypePattern extends ExactAnnotationTypePattern imp
public AnnotationTypePattern remapAdviceFormals(IntMap bindings) {
if (!bindings.hasKey(formalIndex)) {
return new ExactAnnotationTypePattern(annotationType);
return new ExactAnnotationTypePattern(annotationType,null);
} else {
int newFormalIndex = bindings.get(formalIndex);
return new BindingAnnotationTypePattern(annotationType, newFormalIndex);

+ 10
- 35
weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java Прегледај датотеку

@@ -50,8 +50,6 @@ public class CflowPointcut extends Pointcut {
boolean isBelow;// Is this cflowbelow?
private int[] freeVars;
private static Hashtable cflowFields = new Hashtable();
private static Hashtable cflowBelowFields = new Hashtable();
/**
* Used to indicate that we're in the context of a cflow when concretizing if's
@@ -217,7 +215,7 @@ public class CflowPointcut extends Pointcut {
if (freeVars==null || freeVars.length == 0) { // No state, so don't use a stack, use a counter.
ResolvedMember localCflowField = null;

Object field = getCflowfield(concreteEntry,concreteAspect,"counter");
Object field = getCflowfield(xcut, concreteEntry, concreteAspect, "counter");
// Check if we have already got a counter for this cflow pointcut
if (field != null) {
@@ -236,7 +234,7 @@ public class CflowPointcut extends Pointcut {
concreteAspect.crosscuttingMembers.addConcreteShadowMunger(
Advice.makeCflowEntry(world,concreteEntry,isBelow,localCflowField,freeVars==null?0:freeVars.length,innerCflowEntries,inAspect));
putCflowfield(concreteEntry,concreteAspect,localCflowField,"counter"); // Remember it
putCflowfield(xcut,concreteEntry,concreteAspect,localCflowField,"counter"); // Remember it
}
Pointcut ret = new ConcreteCflowPointcut(localCflowField, null,true);
@@ -276,7 +274,7 @@ public class CflowPointcut extends Pointcut {
slots.add(slot);
}
ResolvedMember localCflowField = null;
Object field = getCflowfield(concreteEntry,concreteAspect,"stack");
Object field = getCflowfield(xcut,concreteEntry,concreteAspect,"stack");
if (field != null) {
localCflowField = (ResolvedMember)field;
} else {
@@ -295,7 +293,7 @@ public class CflowPointcut extends Pointcut {
concreteAspect.crosscuttingMembers.addTypeMunger(
world.makeCflowStackFieldAdder(localCflowField));
putCflowfield(concreteEntry,concreteAspect,localCflowField,"stack");
putCflowfield(xcut,concreteEntry,concreteAspect,localCflowField,"stack");
}
Pointcut ret = new ConcreteCflowPointcut(localCflowField, slots,false);
ret.copyLocationFrom(this);
@@ -304,10 +302,6 @@ public class CflowPointcut extends Pointcut {
}
public static void clearCaches() {
cflowFields.clear();
cflowBelowFields.clear();
}
private String getKey(Pointcut p,ResolvedType a,String stackOrCounter) {
StringBuffer sb = new StringBuffer();
@@ -319,22 +313,22 @@ public class CflowPointcut extends Pointcut {
return sb.toString();
}
private Object getCflowfield(Pointcut pcutkey, ResolvedType concreteAspect,String stackOrCounter) {
private Object getCflowfield(CrosscuttingMembers xcut, Pointcut pcutkey, ResolvedType concreteAspect,String stackOrCounter) {
String key = getKey(pcutkey,concreteAspect,stackOrCounter);
Object o =null;
if (isBelow) o = cflowBelowFields.get(key);
else o = cflowFields.get(key);
if (isBelow) o = xcut.getCflowBelowFields().get(key);
else o = xcut.getCflowFields().get(key);
//System.err.println("Retrieving for key "+key+" returning "+o);
return o;
}
private void putCflowfield(Pointcut pcutkey,ResolvedType concreteAspect,Object o,String stackOrCounter) {
private void putCflowfield(CrosscuttingMembers xcut, Pointcut pcutkey,ResolvedType concreteAspect,Object o,String stackOrCounter) {
String key = getKey(pcutkey,concreteAspect,stackOrCounter);
//System.err.println("Storing cflow field for key"+key);
if (isBelow) {
cflowBelowFields.put(key,o);
xcut.getCflowBelowFields().put(key,o);
} else {
cflowFields.put(key,o);
xcut.getCflowFields().put(key,o);
}
}

@@ -342,23 +336,4 @@ public class CflowPointcut extends Pointcut {
return visitor.visit(this, data);
}

public static void clearCaches(ResolvedType aspectType) {
//System.err.println("Wiping entries starting "+aspectType.getName());
String key = aspectType.getName()+"::";
wipeKeys(key,cflowFields);
wipeKeys(key,cflowBelowFields);
}
private static void wipeKeys(String keyPrefix,Hashtable ht) {
Enumeration keys = ht.keys();
List forRemoval = new ArrayList();
while (keys.hasMoreElements()) {
String s = (String)keys.nextElement();
if (s.startsWith(keyPrefix)) forRemoval.add(s);
}
for (Iterator iter = forRemoval.iterator(); iter.hasNext();) {
String element = (String) iter.next();
ht.remove(element);
}
}
}

+ 165
- 28
weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java Прегледај датотеку

@@ -11,21 +11,27 @@ package org.aspectj.weaver.patterns;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.TypeVariableReference;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;

/**
* Matches an annotation of a given type
@@ -36,11 +42,21 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
protected String formalName;
protected boolean resolved = false;
private boolean bindingPattern = false;
private Map annotationValues;
/**
* @param annotationValues
*
*/
public ExactAnnotationTypePattern(UnresolvedType annotationType) {
// OPTIMIZE is annotationtype really unresolved???? surely it is resolved by now...
public ExactAnnotationTypePattern(UnresolvedType annotationType, Map annotationValues) {
this.annotationType = annotationType;
this.annotationValues = annotationValues;
this.resolved = (annotationType instanceof ResolvedType);
}
// Used when deserializing, values will be added
private ExactAnnotationTypePattern(UnresolvedType annotationType) {
this.annotationType = annotationType;
this.resolved = (annotationType instanceof ResolvedType);
}
@@ -60,9 +76,13 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
public UnresolvedType getAnnotationType() {
return annotationType;
}
public Map getAnnotationValues() {
return annotationValues;
}

public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
if (annotated.hasAnnotation(annotationType)) {
if (annotated.hasAnnotation(annotationType) && annotationValues == null) {
return FuzzyBoolean.YES;
} else {
// could be inherited, but we don't know that until we are
@@ -72,30 +92,116 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
}
public FuzzyBoolean matches(AnnotatedElement annotated) {
boolean checkSupers = false;
if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
if (annotated instanceof ResolvedType) {
checkSupers = true;
}
}
if (annotated.hasAnnotation(annotationType)) {
if (annotationType instanceof ReferenceType) {
ReferenceType rt = (ReferenceType)annotationType;
if (rt.getRetentionPolicy()!=null && rt.getRetentionPolicy().equals("SOURCE")) {
rt.getWorld().getMessageHandler().handleMessage(
MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,annotationType,annotated),getSourceLocation()));
return FuzzyBoolean.NO;
return matches(annotated,null);
}
public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
if (!isForParameterAnnotationMatch()) {
boolean checkSupers = false;
if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
if (annotated instanceof ResolvedType) {
checkSupers = true;
}
}
return FuzzyBoolean.YES;
} else if (checkSupers) {
ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass();
while (toMatchAgainst != null) {
if (toMatchAgainst.hasAnnotation(annotationType)) return FuzzyBoolean.YES;
toMatchAgainst = toMatchAgainst.getSuperclass();
if (annotated.hasAnnotation(annotationType)) {
if (annotationType instanceof ReferenceType) {
ReferenceType rt = (ReferenceType)annotationType;
if (rt.getRetentionPolicy()!=null && rt.getRetentionPolicy().equals("SOURCE")) {
rt.getWorld().getMessageHandler().handleMessage(
MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,annotationType,annotated),getSourceLocation()));
return FuzzyBoolean.NO;
}
}
// Are we also matching annotation values?
if (annotationValues!=null) {
AnnotationX theAnnotation = annotated.getAnnotationOfType(annotationType);
// Check each one
Set keys = annotationValues.keySet();
for (Iterator keyIter = keys.iterator(); keyIter.hasNext();) {
String k = (String) keyIter.next();
String v = (String)annotationValues.get(k);
if (theAnnotation.hasNamedValue(k)) {
// Simple case, value is 'name=value' and the annotation specified the same thing
if (!theAnnotation.hasNameValuePair(k,v)) {
return FuzzyBoolean.NO;
}
} else {
// Complex case, look at the default value
ResolvedMember[] ms = ((ResolvedType)annotationType).getDeclaredMethods();
boolean foundMatch = false;
for (int i=0; i<ms.length && !foundMatch;i++) {
if (ms[i].isAbstract() && ms[i].getParameterTypes().length==0 && ms[i].getName().equals(k)) {
// we might be onto something
String s= ms[i].getAnnotationDefaultValue();
if (s!=null && s.equals(v)) foundMatch=true;;
}
}
if (!foundMatch)
return FuzzyBoolean.NO;
}
}
}
return FuzzyBoolean.YES;
} else if (checkSupers) {
ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass();
while (toMatchAgainst != null) {
if (toMatchAgainst.hasAnnotation(annotationType)) {
// Are we also matching annotation values?
if (annotationValues!=null) {
AnnotationX theAnnotation = toMatchAgainst.getAnnotationOfType(annotationType);
// Check each one
Set keys = annotationValues.keySet();
for (Iterator keyIter = keys.iterator(); keyIter.hasNext();) {
String k = (String) keyIter.next();
String v = (String)annotationValues.get(k);
if (theAnnotation.hasNamedValue(k)) {
// Simple case, value is 'name=value' and the annotation specified the same thing
if (!theAnnotation.hasNameValuePair(k,v)) {
return FuzzyBoolean.NO;
}
} else {
// Complex case, look at the default value
ResolvedMember[] ms = ((ResolvedType)annotationType).getDeclaredMethods();
boolean foundMatch = false;
for (int i=0; i<ms.length && !foundMatch;i++) {
if (ms[i].isAbstract() && ms[i].getParameterTypes().length==0 && ms[i].getName().equals(k)) {
// we might be onto something
String s= ms[i].getAnnotationDefaultValue();
if (s!=null && s.equals(v)) foundMatch=true;;
}
}
if (!foundMatch)
return FuzzyBoolean.NO;
}
}
}
return FuzzyBoolean.YES;
}
toMatchAgainst = toMatchAgainst.getSuperclass();
}
}
} else {
// check parameter annotations
if (parameterAnnotations==null) return FuzzyBoolean.NO;
for (int i = 0; i < parameterAnnotations.length; i++) {
if (annotationType.equals(parameterAnnotations[i])) {
// Are we also matching annotation values?
if (annotationValues!=null) {
parameterAnnotations[i].getWorld().getMessageHandler().handleMessage(
MessageUtil.error("Compiler limitation: annotation value matching for parameter annotations not yet supported"));
return FuzzyBoolean.NO;
}
return FuzzyBoolean.YES;
}
}
}
}
return FuzzyBoolean.NO;
}
@@ -113,7 +219,9 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {

public void resolve(World world) {
if (!resolved) annotationType = annotationType.resolve(world);
if (!resolved) {
annotationType = annotationType.resolve(world);
}
resolved = true;
}

@@ -144,6 +252,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
binding.copyLocationFrom(this);
bindings.register(binding, scope);
binding.resolveBinding(scope.getWorld());
if (isForParameterAnnotationMatch()) binding.setForParameterAnnotationMatch();
return binding;
}
@@ -179,10 +288,11 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
} else if (annotationType.isParameterizedType()) {
newAnnotationType = annotationType.parameterize(typeVariableMap);
}
ExactAnnotationTypePattern ret = new ExactAnnotationTypePattern(newAnnotationType);
ExactAnnotationTypePattern ret = new ExactAnnotationTypePattern(newAnnotationType,annotationValues);
ret.formalName = formalName;
ret.bindingPattern = bindingPattern;
ret.copyLocationFrom(this);
if (isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
return ret;
}
@@ -219,10 +329,22 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
annotationType.write(s);
}
writeLocation(s);
s.writeBoolean(isForParameterAnnotationMatch());
if (annotationValues==null) {
s.writeInt(0);
} else {
s.writeInt(annotationValues.size());
Set key = annotationValues.keySet();
for (Iterator keys = key.iterator(); keys.hasNext();) {
String k = (String) keys.next();
s.writeUTF(k);
s.writeUTF((String)annotationValues.get(k));
}
}
}

public static AnnotationTypePattern read(VersionedDataInputStream s,ISourceContext context) throws IOException {
AnnotationTypePattern ret;
ExactAnnotationTypePattern ret;
byte version = s.readByte();
if (version > VERSION) {
throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
@@ -234,6 +356,21 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
ret = new ExactAnnotationTypePattern(UnresolvedType.read(s));
}
ret.readLocation(context,s);
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160) {
if (s.readBoolean()) ret.setForParameterAnnotationMatch();
}
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) {
int annotationValueCount = s.readInt();
if (annotationValueCount>0) {
Map aValues = new HashMap();
for (int i=0;i<annotationValueCount;i++) {
String key = s.readUTF();
String val = s.readUTF();
aValues.put(key,val);
}
ret.annotationValues = aValues;
}
}
return ret;
}
@@ -243,14 +380,14 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
public boolean equals(Object obj) {
if (!(obj instanceof ExactAnnotationTypePattern)) return false;
ExactAnnotationTypePattern other = (ExactAnnotationTypePattern) obj;
return (other.annotationType.equals(annotationType));
return (other.annotationType.equals(annotationType)) && isForParameterAnnotationMatch()==other.isForParameterAnnotationMatch();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return annotationType.hashCode();
return annotationType.hashCode()*37+(isForParameterAnnotationMatch()?0:1);
}
public String toString() {

+ 13
- 2
weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java Прегледај датотеку

@@ -106,7 +106,12 @@ public class ExactTypePattern extends TypePattern {
typeMatch = matchesTypeVariable((TypeVariableReferenceType)matchType);
}
annotationPattern.resolve(matchType.getWorld());
boolean annMatch = this.annotationPattern.matches(matchType).alwaysTrue();
boolean annMatch = false;
if (matchType.temporaryAnnotationTypes!=null) {
annMatch = annotationPattern.matches(matchType,matchType.temporaryAnnotationTypes).alwaysTrue();
} else {
annMatch = annotationPattern.matches(matchType).alwaysTrue();
}
return (typeMatch && annMatch);
}
@@ -125,7 +130,12 @@ public class ExactTypePattern extends TypePattern {
typeMatch = matchesTypeVariable((TypeVariableReferenceType)matchType);
}
annotationPattern.resolve(matchType.getWorld());
boolean annMatch = this.annotationPattern.matches(annotatedType).alwaysTrue();
boolean annMatch = false;
if (annotatedType.temporaryAnnotationTypes!=null) {
annMatch = annotationPattern.matches(annotatedType,annotatedType.temporaryAnnotationTypes).alwaysTrue();
} else {
annMatch = annotationPattern.matches(annotatedType).alwaysTrue();
}
return (typeMatch && annMatch);
}
@@ -134,6 +144,7 @@ public class ExactTypePattern extends TypePattern {
// true if (matchType instanceof this.type)
public FuzzyBoolean matchesInstanceof(ResolvedType matchType) {
// in our world, Object is assignable from anything
annotationPattern.resolve(matchType.getWorld());
if (type.equals(ResolvedType.OBJECT))
return FuzzyBoolean.YES.and(annotationPattern.matches(matchType));

+ 16
- 1
weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java Прегледај датотеку

@@ -16,8 +16,10 @@ import java.util.Map;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;

public class NotAnnotationTypePattern extends AnnotationTypePattern {

@@ -35,6 +37,9 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
return negatedPattern.matches(annotated).not();
}
public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
return negatedPattern.matches(annotated,parameterAnnotations).not();
}
/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolve(org.aspectj.weaver.World)
*/
@@ -56,6 +61,7 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
AnnotationTypePattern newNegatedPattern = negatedPattern.parameterizeWith(typeVariableMap,w);
NotAnnotationTypePattern ret = new NotAnnotationTypePattern(newNegatedPattern);
ret.copyLocationFrom(this);
if (this.isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
return ret;
}
@@ -66,22 +72,27 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
s.writeByte(AnnotationTypePattern.NOT);
negatedPattern.write(s);
writeLocation(s);
s.writeBoolean(isForParameterAnnotationMatch());
}

public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
AnnotationTypePattern ret = new NotAnnotationTypePattern(AnnotationTypePattern.read(s,context));
ret.readLocation(context,s);
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) {
if (s.readBoolean()) ret.setForParameterAnnotationMatch();
}
return ret;
}
public boolean equals(Object obj) {
if (!(obj instanceof NotAnnotationTypePattern)) return false;
NotAnnotationTypePattern other = (NotAnnotationTypePattern) obj;
return other.negatedPattern.equals(negatedPattern);
return other.negatedPattern.equals(negatedPattern) && other.isForParameterAnnotationMatch()==isForParameterAnnotationMatch();
}

public int hashCode() {
int result = 17 + 37*negatedPattern.hashCode();
result = 37*result +(isForParameterAnnotationMatch()?0:1);
return result;
}
@@ -102,4 +113,8 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
negatedPattern.traverse(visitor,ret);
return ret;
}

public void setForParameterAnnotationMatch() {
negatedPattern.setForParameterAnnotationMatch();
}
}

+ 18
- 1
weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java Прегледај датотеку

@@ -16,8 +16,10 @@ import java.util.Map;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;

public class OrAnnotationTypePattern extends AnnotationTypePattern {

@@ -33,6 +35,10 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
public FuzzyBoolean matches(AnnotatedElement annotated) {
return left.matches(annotated).or(right.matches(annotated));
}

public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations ) {
return left.matches(annotated,parameterAnnotations).or(right.matches(annotated,parameterAnnotations));
}
public void resolve(World world) {
left.resolve(world);
@@ -54,6 +60,7 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
AnnotationTypePattern newRight = right.parameterizeWith(typeVariableMap,w);
OrAnnotationTypePattern ret = new OrAnnotationTypePattern(newLeft,newRight);
ret.copyLocationFrom(this);
if (isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
return ret;
}

@@ -73,6 +80,9 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
AnnotationTypePattern.read(s,context),
AnnotationTypePattern.read(s,context));
p.readLocation(context,s);
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) {
if (s.readBoolean()) p.setForParameterAnnotationMatch();
}
return p;
}
@@ -81,18 +91,20 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
left.write(s);
right.write(s);
writeLocation(s);
s.writeBoolean(isForParameterAnnotationMatch());
}
public boolean equals(Object obj) {
if (!(obj instanceof OrAnnotationTypePattern)) return false;
OrAnnotationTypePattern other = (OrAnnotationTypePattern) obj;
return (left.equals(other.left) && right.equals(other.right));
return (left.equals(other.left) && right.equals(other.right)) && isForParameterAnnotationMatch()==other.isForParameterAnnotationMatch();
}
public int hashCode() {
int result = 17;
result = result*37 + left.hashCode();
result = result*37 + right.hashCode();
result = result*37 + (isForParameterAnnotationMatch()?0:1);
return result;
}
@@ -103,4 +115,9 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
public AnnotationTypePattern getLeft() { return left; }
public AnnotationTypePattern getRight() { return right; }

public void setForParameterAnnotationMatch() {
left.setForParameterAnnotationMatch();
right.setForParameterAnnotationMatch();
}

}

+ 0
- 512
weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java Прегледај датотеку

@@ -12,7 +12,6 @@
*******************************************************************************/
package org.aspectj.weaver.patterns;

import org.aspectj.weaver.Member;

/**
* A Pointcut or TypePattern visitor
@@ -93,515 +92,4 @@ public interface PatternNodeVisitor {
// Catch-all
Object visit(PatternNode node, Object data);

/**
* A sample toString like visitor that helps understanding the AST tree structure organization
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
static class DumpPointcutVisitor implements PatternNodeVisitor {

private StringBuffer sb = new StringBuffer();
public String get() {
return sb.toString();
}

private void append(Object o) {
sb.append(o.toString());
}
private void append(char c) {
sb.append(c);
}

/**
* This method helps maintaining the API and raises warning when PatternNode subclasses do not
* implement the visitor pattern
*
* @param node
* @param data
* @return
*/
public Object visit(PatternNode node, Object data) {
System.err.println("Should implement: " + node.getClass());
return null;
}

public Object visit(AnyTypePattern node, Object data) {
append('*');
return null;
}

public Object visit(NoTypePattern node, Object data) {
append(node.toString());//TODO no idea when this one is used
return null;
}

public Object visit(EllipsisTypePattern node, Object data) {
append(node.toString());
return null;
}

public Object visit(AnyWithAnnotationTypePattern node, Object data) {
node.annotationPattern.accept(this, data);
append(" *");
return null;
}

public Object visit(AnyAnnotationTypePattern node, Object data) {
//@ANY : ignore
append('*');
return null;
}

public Object visit(EllipsisAnnotationTypePattern node, Object data) {
append("..");
return null;
}

public Object visit(AndAnnotationTypePattern node, Object data) {
node.getLeft().accept(this, data);
append(' ');
node.getRight().accept(this, data);
return null;
}

public Object visit(AndPointcut node, Object data) {
append('(');
node.getLeft().accept(this, data);
append(" && ");
node.getRight().accept(this, data);
append(')');
return null;
}

public Object visit(AndTypePattern node, Object data) {
append('(');
node.getLeft().accept(this, data);
append(" && ");
node.getRight().accept(this, data);
append(')');
return null;
}

public Object visit(AnnotationPatternList node, Object data) {
AnnotationTypePattern[] annotations = node.getAnnotationPatterns();
for (int i = 0; i < annotations.length; i++) {
if (i>0) append(", ");//Note: list is ",", and is " " separated for annotations
annotations[i].accept(this, data);
}
return null;
}

public Object visit(AnnotationPointcut node, Object data) {
append("@annotation(");
node.getAnnotationTypePattern().accept(this, data);
append(')');
return null;
}

public Object visit(ArgsAnnotationPointcut node, Object data) {
append("@args(");
node.getArguments().accept(this, data);
append(')');
return null;
}

public Object visit(ArgsPointcut node, Object data) {
append("args(");
node.getArguments().accept(this, data);
append(')');
return null;
}

public Object visit(BindingAnnotationTypePattern node, Object data) {
append(node);
return null;
}

public Object visit(BindingTypePattern node, Object data) {
append(node);
return null;
}

public Object visit(CflowPointcut node, Object data) {
append(node.isCflowBelow()?"cflowbelow(":"cflow(");
node.getEntry().accept(this, data);
append(')');
return null;
}

public Object visit(ExactAnnotationTypePattern node, Object data) {
//append('@'); // since @annotation(@someAnno) cannot be parsed anymore
append(node.getAnnotationType().getName());
return null;
}

public Object visit(ExactTypePattern node, Object data) {
if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
append('(');
node.getAnnotationPattern().accept(this, data);
append(' ');
}

String typeString = node.getType().toString();
if (node.isVarArgs()) typeString = typeString.substring(0, typeString.lastIndexOf('['));//TODO AV - ugly
append(typeString);
if (node.isIncludeSubtypes()) append('+');
if (node.isVarArgs()) append("...");
if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
append(')');
}
return null;
}

public Object visit(KindedPointcut node, Object data) {
append(node.getKind().getSimpleName());
append('(');
node.getSignature().accept(this, data);
append(')');
return null;
}

public Object visit(ModifiersPattern node, Object data) {
append(node.toString());//note: node takes care of forbidden mods
return null;
}

public Object visit(NamePattern node, Object data) {
append(node.toString());
return null;
}

public Object visit(NotAnnotationTypePattern node, Object data) {
append("!");
node.getNegatedPattern().accept(this, data);
return null;
}

public Object visit(NotPointcut node, Object data) {
append("!(");
node.getNegatedPointcut().accept(this, data);
append(')');
return null;
}

public Object visit(NotTypePattern node, Object data) {
append("!(");
node.getNegatedPattern().accept(this, data);
append(')');
return null;
}

public Object visit(OrAnnotationTypePattern node, Object data) {
append('(');
node.getLeft().accept(this, data);
append(" || ");
node.getRight().accept(this, data);
append(')');
return null;
}

public Object visit(OrPointcut node, Object data) {
append('(');
node.getLeft().accept(this, data);
append(" || ");
node.getRight().accept(this, data);
append(')');
return null;
}

public Object visit(OrTypePattern node, Object data) {
append('(');
node.getLeft().accept(this, data);
append(" || ");
node.getRight().accept(this, data);
append(')');
return null;
}

public Object visit(ReferencePointcut node, Object data) {
append(node.toString());
return null;
}

public Object visit(SignaturePattern node, Object data) {
if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
node.getAnnotationPattern().accept(this, data);
append(' ');
}

if (node.getModifiers() != ModifiersPattern.ANY) {
node.getModifiers().accept(this, data);
append(' ');
}

if (node.getKind() == Member.STATIC_INITIALIZATION) {
node.getDeclaringType().accept(this, data);
} else if (node.getKind() == Member.HANDLER) {
append("handler(");
node.getParameterTypes().get(0).accept(this, data);//Note: we know we have 1 child
append(')');
} else {
if (!(node.getKind() == Member.CONSTRUCTOR)) {
node.getReturnType().accept(this, data);
append(' ');
}
if (node.getDeclaringType() != TypePattern.ANY) {
node.getDeclaringType().accept(this, data);
append('.');
}
if (node.getKind() == Member.CONSTRUCTOR) {
append("new");
} else {
node.getName().accept(this, data);
}
if (node.getKind() == Member.METHOD || node.getKind() == Member.CONSTRUCTOR) {
append('(');
node.getParameterTypes().accept(this, data);
append(')');
}
if (node.getThrowsPattern() != null) {
append(' ');
node.getThrowsPattern().accept(this, data);
}
}
return null;
}

public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
append(node.isThis() ? "@this(" : "@target(");
node.getAnnotationTypePattern().accept(this, data);
append(')');
return null;
}

public Object visit(ThisOrTargetPointcut node, Object data) {
append(node.isThis() ? "this(" : "target(");
node.getType().accept(this, data);
append(')');
return null;
}

// Note: a visitor instance is not thread safe so should not be shared
private boolean inThrowsForbidden = false;

public Object visit(ThrowsPattern node, Object data) {
if (node == ThrowsPattern.ANY) return null;

append("throws ");
node.getRequired().accept(this, data);
if (node.getForbidden().size() > 0) {
// a hack since throws !(A, B) cannot be parsed
try {
inThrowsForbidden = true;
node.getForbidden().accept(this, data);
} finally {
inThrowsForbidden = false;
}
}
return null;
}

public Object visit(TypePatternList node, Object data) {
if (node.getTypePatterns().length == 0) return null;

TypePattern[] typePatterns = node.getTypePatterns();
for (int i = 0; i < typePatterns.length; i++) {
TypePattern typePattern = typePatterns[i];
if (i > 0) append(", ");
if (inThrowsForbidden) append('!');
typePattern.accept(this, data);
}
return null;
}

public Object visit(WildAnnotationTypePattern node, Object data) {
append("@(");
node.getTypePattern().accept(this, data);
append(')');
return null;
}

public Object visit(WildTypePattern node, Object data) {
if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
append('(');
node.getAnnotationPattern().accept(this, data);
append(' ');
}
NamePattern[] namePatterns = node.getNamePatterns();
for (int i=0; i < namePatterns.length; i++) {
if (namePatterns[i] == null) {
append('.');//FIXME mh, error prone, can't we have a nullNamePattern ?
} else {
if (i > 0) append('.');
namePatterns[i].accept(this, data);
}
}
if (node.isIncludeSubtypes()) append('+');
if (node.isVarArgs()) append("...");
if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
append(')');
}
return null;
}

public Object visit(WithinAnnotationPointcut node, Object data) {
append("@within(");
node.getAnnotationTypePattern().accept(this, data);
append(')');
return null;
}

public Object visit(WithinCodeAnnotationPointcut node, Object data) {
append("@withincode(");
node.getAnnotationTypePattern().accept(this, data);
append(')');
return null;
}

public Object visit(WithinPointcut node, Object data) {
append("within(");
node.getTypePattern().accept(this, data);
append(')');
return null;
}

public Object visit(WithincodePointcut node, Object data) {
append("withincode(");
node.getSignature().accept(this, data);
append(')');
return null;
}

public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
append("");//TODO shouldn't that be a "false" ?
return null;
}


//-------------- perX

public Object visit(PerCflow node, Object data) {
append(node);
return null;
}

public Object visit(PerFromSuper node, Object data) {
append(node);
return null;
}

public Object visit(PerObject node, Object data) {
append(node);
return null;
}

public Object visit(PerSingleton node, Object data) {
append(node);
return null;
}

public Object visit(PerTypeWithin node, Object data) {
append(node);
return null;
}

// ------------- declare X

public Object visit(DeclareAnnotation node, Object data) {
append(node);
return null;
}

public Object visit(DeclareErrorOrWarning node, Object data) {
append(node);
return null;
}

public Object visit(DeclareParents node, Object data) {
append(node);
return null;
}

public Object visit(DeclarePrecedence node, Object data) {
append(node);
return null;
}

public Object visit(DeclareSoft node, Object data) {
append(node);
return null;
}

// ----------- misc

public Object visit(ConcreteCflowPointcut node, Object data) {
append(node);
return null;
}

public Object visit(HandlerPointcut node, Object data) {
append(node);
return null;
}

public Object visit(IfPointcut node, Object data) {
append(node);
return null;
}
public Object visit(TypeVariablePattern node, Object data) {
append(node);
return null;
}
public Object visit(TypeVariablePatternList node, Object data) {
append(node);
return null;
}

public Object visit(HasMemberTypePattern node, Object data) {
append(node);
return null;
}

public static void check(String s) {
check(Pointcut.fromString(s), false);
}

public static void check(PatternNode pc, boolean isTypePattern) {
DumpPointcutVisitor v1 = new DumpPointcutVisitor();
pc.accept(v1, null);

DumpPointcutVisitor v2 = new DumpPointcutVisitor();
final PatternNode pc2;
if (isTypePattern) {
pc2 = new PatternParser(v1.get()).parseTypePattern();
} else {
pc2 = Pointcut.fromString(v1.get());
}
pc2.accept(v2, null);

// at second parsing, the String form stay stable when parsed and parsed again
if (! v1.get().equals(v2.get())) {
throw new ParserException("Unstable back parsing for '"+pc+"', got '" + v1.get() + "' and '" + v2.get() + "'", null);
}
}

public static void main(String args[]) throws Throwable {
String[] s = new String[]{
//"@args(Foo, Goo, *, .., Moo)",
//"execution(* *())",
//"call(* *(int, Integer...))",
//"staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
"(if(true) && set(int BaseApp.i))"

};
for (int i = 0; i < s.length; i++) {
check(s[i]);
}
}

}

}

+ 150
- 36
weaver/src/org/aspectj/weaver/patterns/PatternParser.java Прегледај датотеку

@@ -17,11 +17,14 @@ package org.aspectj.weaver.patterns;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
@@ -42,6 +45,8 @@ public class PatternParser {
/** extension handlers used in weaver tools API only */
private Set pointcutDesignatorHandlers = Collections.EMPTY_SET;
private ReflectionWorld world;
private AnnotationTypePattern[] parameterAnnotationTypePatterns;

/**
* Constructor for PatternParser.
@@ -213,7 +218,7 @@ public class PatternParser {
*/
eat(":");
allowHasTypePatterns = true;
TypePattern p = parseTypePattern(false);
TypePattern p = parseTypePattern(false,false);
allowHasTypePatterns = false;
IToken t = tokenSource.next();
if (!(t.getString().equals("extends") || t.getString().equals("implements"))) {
@@ -336,7 +341,7 @@ public class PatternParser {
AnnotationTypePattern.ANY));
} else if (kind.equals("handler")) {
eat("(");
TypePattern typePat = parseTypePattern(false);
TypePattern typePat = parseTypePattern(false,false);
eat(")");
p = new HandlerPointcut(typePat);
} else if (kind.equals("lock") || kind.equals("unlock")) {
@@ -348,7 +353,7 @@ public class PatternParser {
p = new KindedPointcut(Shadow.Initialization, sig);
} else if (kind.equals("staticinitialization")) {
eat("(");
TypePattern typePat = parseTypePattern(false);
TypePattern typePat = parseTypePattern(false,false);
eat(")");
p = new KindedPointcut(Shadow.StaticInitialization,
new SignaturePattern(Member.STATIC_INITIALIZATION, ModifiersPattern.ANY,
@@ -522,7 +527,7 @@ public class PatternParser {
*/
private Pointcut parseArgsPointcut() {
//parseIdentifier();
TypePatternList arguments = parseArgumentsPattern();
TypePatternList arguments = parseArgumentsPattern(false);
return new ArgsPointcut(arguments);
}
@@ -553,7 +558,7 @@ public class PatternParser {
throw new ParserException("(",tokenSource.peek(-1));
}

TypePatternList arguments = parseArgumentsPattern();
TypePatternList arguments = parseArgumentsPattern(false);
return new ReferencePointcut(onType, simpleName, arguments);
}
@@ -652,41 +657,62 @@ public class PatternParser {
}
public TypePattern parseTypePattern() {
return parseTypePattern(false);
return parseTypePattern(false,false);
}
public TypePattern parseTypePattern(boolean insideTypeParameters) {
TypePattern p = parseAtomicTypePattern(insideTypeParameters);
public TypePattern parseTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) {
TypePattern p = parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible);
if (maybeEat("&&")) {
p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters));
p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters,parameterAnnotationsPossible));
}
if (maybeEat("||")) {
p = new OrTypePattern(p, parseTypePattern(insideTypeParameters));
p = new OrTypePattern(p, parseTypePattern(insideTypeParameters,parameterAnnotationsPossible));
}
return p;
}
private TypePattern parseNotOrTypePattern(boolean insideTypeParameters) {
TypePattern p = parseAtomicTypePattern(insideTypeParameters);
private TypePattern parseNotOrTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) {
TypePattern p = parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible);
if (maybeEat("&&")) {
p = new AndTypePattern(p, parseTypePattern(insideTypeParameters));
p = new AndTypePattern(p, parseTypePattern(insideTypeParameters,parameterAnnotationsPossible));
}
return p;
}
private TypePattern parseAtomicTypePattern(boolean insideTypeParameters) {
AnnotationTypePattern ap = maybeParseAnnotationPattern();
// Need to differentiate in here between two kinds of annotation pattern - depending on where the ( is
private TypePattern parseAtomicTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) {
AnnotationTypePattern ap = maybeParseAnnotationPattern(); // might be parameter annotation pattern or type annotation pattern
if (maybeEat("!")) {
//int startPos = tokenSource.peek(-1).getStart();
//??? we lose source location for true start of !type
TypePattern p = new NotTypePattern(parseAtomicTypePattern(insideTypeParameters));
p = setAnnotationPatternForTypePattern(p,ap);
// An annotation, if processed, is outside of the Not - so here we have to build
// an And pattern containing the annotation and the not as left and right children
// *unless* the annotation pattern was just 'Any' then we can skip building the
// And and just return the Not directly (pr228980)
TypePattern p = null;
TypePattern tp = parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible);
if (!(ap instanceof AnyAnnotationTypePattern)) {
p = new NotTypePattern(tp);
p = new AndTypePattern(setAnnotationPatternForTypePattern(TypePattern.ANY,ap,false),p);
} else {
p = new NotTypePattern(tp);
}
return p;
}
if (maybeEat("(")) {
TypePattern p = parseTypePattern(insideTypeParameters);
p = setAnnotationPatternForTypePattern(p,ap);
TypePattern p = parseTypePattern(insideTypeParameters,false);
if ((p instanceof NotTypePattern) && !(ap instanceof AnyAnnotationTypePattern)) {
// dont set the annotation on it, we don't want the annotation to be
// considered as part of the not, it is outside the not (pr228980)
TypePattern tp = setAnnotationPatternForTypePattern(TypePattern.ANY, ap, parameterAnnotationsPossible);
p = new AndTypePattern(tp,p);
} else {
p = setAnnotationPatternForTypePattern(p,ap,parameterAnnotationsPossible);
}
eat(")");
boolean isVarArgs = maybeEat("...");
if (isVarArgs) p.setIsVarArgs(isVarArgs);
@@ -697,13 +723,15 @@ public class PatternParser {
int startPos = tokenSource.peek().getStart();
TypePattern p = parseSingleTypePattern(insideTypeParameters);
int endPos = tokenSource.peek(-1).getEnd();
p = setAnnotationPatternForTypePattern(p,ap);
p = setAnnotationPatternForTypePattern(p,ap,false);
p.setLocation(sourceContext, startPos, endPos);
return p;
}
private TypePattern setAnnotationPatternForTypePattern(TypePattern t, AnnotationTypePattern ap) {

private TypePattern setAnnotationPatternForTypePattern(TypePattern t, AnnotationTypePattern ap,boolean parameterAnnotationsPattern) {
TypePattern ret = t;
if (parameterAnnotationsPattern) ap.setForParameterAnnotationMatch();
if (ap != AnnotationTypePattern.ANY) {
if (t == TypePattern.ANY) {
ret = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0,false,null);
@@ -730,8 +758,10 @@ public class PatternParser {
return ret;
}

// PVAL cope with annotation values at other places in this code
public AnnotationTypePattern maybeParseSingleAnnotationPattern() {
AnnotationTypePattern ret = null;
Map values = null;
// LALR(2) - fix by making "!@" a single token
int startIndex = tokenSource.getIndex();
if (maybeEat("!")) {
@@ -743,7 +773,13 @@ public class PatternParser {
return ret;
} else {
TypePattern p = parseSingleTypePattern();
ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p));
if (maybeEatAdjacent("(")) {
values = parseAnnotationValues();
eat(")");
ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p,values));
} else {
ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p));
}
return ret;
}
} else {
@@ -759,7 +795,13 @@ public class PatternParser {
return ret;
} else {
TypePattern p = parseSingleTypePattern();
ret = new WildAnnotationTypePattern(p);
if (maybeEatAdjacent("(")) {
values = parseAnnotationValues();
eat(")");
ret = new WildAnnotationTypePattern(p,values);
} else {
ret = new WildAnnotationTypePattern(p);
}
return ret;
}
} else {
@@ -768,6 +810,35 @@ public class PatternParser {
}
}
// Parse annotation values. In an expression in @A(a=b,c=d) this method will be
// parsing the a=b,c=d.)
public Map/*String,String*/ parseAnnotationValues() {
Map values = new HashMap();
boolean seenDefaultValue = false;
do {
String possibleKeyString = parseAnnotationNameValuePattern();
if (possibleKeyString==null) {
throw new ParserException("expecting simple literal ",tokenSource.peek(-1));
}
// did they specify just a single entry 'v' or a keyvalue pair 'k=v'
if (maybeEat("=")) {
// it was a key!
String valueString = parseAnnotationNameValuePattern();
if (valueString==null) {
throw new ParserException("expecting simple literal ",tokenSource.peek(-1));
}
values.put(possibleKeyString,valueString);
} else {
if (seenDefaultValue) {
throw new ParserException("cannot specify two default values",tokenSource.peek(-1));
}
seenDefaultValue = true;
values.put("value",possibleKeyString);
}
} while (maybeEat(",")); // keep going whilst there are ','
return values;
}
public TypePattern parseSingleTypePattern() {
return parseSingleTypePattern(false);
}
@@ -836,11 +907,11 @@ public class PatternParser {
TypePattern[] additionalInterfaceBounds = new TypePattern[0];
TypePattern lowerBound = null;
if (maybeEatIdentifier("extends")) {
upperBound = parseTypePattern(false);
upperBound = parseTypePattern(false,false);
additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds();
}
if (maybeEatIdentifier("super")) {
lowerBound = parseTypePattern(false);
lowerBound = parseTypePattern(false,false);
}
int endPos = tokenSource.peek(-1).getEnd();
return new WildTypePattern(names,false,0,endPos,false,null,upperBound,additionalInterfaceBounds,lowerBound);
@@ -903,7 +974,7 @@ public class PatternParser {
annotationName.append(parseIdentifier());
}
UnresolvedType type = UnresolvedType.forName(annotationName.toString());
p = new ExactAnnotationTypePattern(type);
p = new ExactAnnotationTypePattern(type,null);
return p;
}

@@ -1018,6 +1089,36 @@ public class PatternParser {
return names;
}
// supported form 'a.b.c.d' or just 'a'
public String parseAnnotationNameValuePattern() {
StringBuffer buf = new StringBuffer();
IToken tok;
int startPos = tokenSource.peek().getStart();
boolean dotOK = false;
int depth = 0;
while (true) {
tok = tokenSource.peek();
// keep going until we hit ')' or '=' or ','
if (tok.getString()==")" && depth==0) break;
if (tok.getString()=="=" && depth==0) break;
if (tok.getString()=="," && depth==0) break;
// keep track of nested brackets
if (tok.getString()=="(") depth++;
if (tok.getString()==")") depth--;
if (tok.getString()=="{") depth++;
if (tok.getString()=="}") depth--;

if (tok.getString()=="." && !dotOK) {
throw new ParserException("dot not expected",tok);
}
buf.append(tok.getString());
tokenSource.next();
dotOK=true;
}
if (buf.length()==0) return null;
else return buf.toString();
}
public NamePattern parseNamePattern() {
@@ -1098,19 +1199,21 @@ public class PatternParser {
}
}
public TypePatternList parseArgumentsPattern() {
public TypePatternList parseArgumentsPattern(boolean parameterAnnotationsPossible) {
List patterns = new ArrayList();
eat("(");
// ()
if (maybeEat(")")) {
return new TypePatternList();
}
do {
if (maybeEat(".")) {
if (maybeEat(".")) { // ..
eat(".");
patterns.add(TypePattern.ELLIPSIS);
} else {
patterns.add(parseTypePattern());
} else {
patterns.add(parseTypePattern(false,parameterAnnotationsPossible));
}
} while (maybeEat(","));
eat(")");
@@ -1162,11 +1265,11 @@ public class PatternParser {
int startPos = tokenSource.peek().getStart();
AnnotationTypePattern annotationPattern = maybeParseAnnotationPattern();
ModifiersPattern modifiers = parseModifiersPattern();
TypePattern returnType = parseTypePattern(false);
TypePattern returnType = parseTypePattern(false,false);
TypePattern declaringType;
NamePattern name = null;
Member.Kind kind;
MemberKind kind;
// here we can check for 'new'
if (maybeEatNew(returnType)) {
kind = Member.CONSTRUCTOR;
@@ -1180,7 +1283,7 @@ public class PatternParser {
} else {
kind = Member.METHOD;
IToken nameToken = tokenSource.peek();
declaringType = parseTypePattern(false);
declaringType = parseTypePattern(false,false);
if (maybeEat(".")) {
nameToken = tokenSource.peek();
name = parseNamePattern();
@@ -1201,8 +1304,8 @@ public class PatternParser {
}
}
TypePatternList parameterTypes = parseArgumentsPattern();
TypePatternList parameterTypes = parseArgumentsPattern(true);
ThrowsPattern throwsPattern = parseOptionalThrowsPattern();
SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType, name, parameterTypes, throwsPattern, annotationPattern);
int endPos = tokenSource.peek(-1).getEnd();
@@ -1304,7 +1407,7 @@ public class PatternParser {
if (!maybeEat("<")) return null;
List typePats = new ArrayList();
do {
TypePattern tp = parseTypePattern(true);
TypePattern tp = parseTypePattern(true,false);
typePats.add(tp);
} while(maybeEat(","));
eat(">");
@@ -1430,6 +1533,17 @@ public class PatternParser {
}
}
public boolean maybeEatAdjacent(String token) {
IToken next = tokenSource.peek();
if (next.getString() == token) {
if (isAdjacent(tokenSource.peek(-1),next)) {
tokenSource.next();
return true;
}
}
return false;
}
public boolean maybeEat(String token) {
IToken next = tokenSource.peek();
if (next.getString() == token) {

+ 0
- 2
weaver/src/org/aspectj/weaver/patterns/PointcutRewriter.java Прегледај датотеку

@@ -168,8 +168,6 @@ public class PointcutRewriter {
// A && (B || C) => (A && B) || (A && C)
// (A || B) && C => (A && C) || (B && C)
// is this next one optimal??
// (A || B) && (C || D) => (¬A && B && ¬C && D) || (B && C) || (A && ¬C && D) || (A && ¬B && C)
private Pointcut pullUpDisjunctions(Pointcut pc) {
if (isNot(pc)) {
NotPointcut npc = (NotPointcut)pc;

+ 41
- 15
weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java Прегледај датотеку

@@ -32,9 +32,11 @@ import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjcMemberMaker;
import org.aspectj.weaver.AnnotationTargetKind;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.Constants;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.JoinPointSignature;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.NewFieldTypeMunger;
@@ -43,11 +45,10 @@ import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;
import org.aspectj.weaver.bcel.BcelTypeMunger;


public class SignaturePattern extends PatternNode {
private Member.Kind kind;
private MemberKind kind;
private ModifiersPattern modifiers;
private TypePattern returnType;
private TypePattern declaringType;
@@ -57,7 +58,7 @@ public class SignaturePattern extends PatternNode {
private AnnotationTypePattern annotationPattern;
private transient int hashcode = -1;
public SignaturePattern(Member.Kind kind, ModifiersPattern modifiers,
public SignaturePattern(MemberKind kind, ModifiersPattern modifiers,
TypePattern returnType, TypePattern declaringType,
NamePattern name, TypePatternList parameterTypes,
ThrowsPattern throwsPattern,
@@ -84,7 +85,7 @@ public class SignaturePattern extends PatternNode {
}
if (parameterTypes != null) {
parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false);
checkForIncorrectTargetKind(parameterTypes,scope,false);
checkForIncorrectTargetKind(parameterTypes,scope,false,true);
}
if (throwsPattern != null) {
throwsPattern = throwsPattern.resolveBindings(scope, bindings);
@@ -100,11 +101,15 @@ public class SignaturePattern extends PatternNode {
hashcode =-1;
return this;
}
private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) {
checkForIncorrectTargetKind(patternNode, scope, targetsOtherThanTypeAllowed, false);
}
// bug 115252 - adding an xlint warning if the annnotation target type is
// wrong. This logic, or similar, may have to be applied elsewhere in the case
// of pointcuts which don't go through SignaturePattern.resolveBindings(..)
private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) {
private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
// return if we're not in java5 mode, if the unmatchedTargetKind Xlint
// warning has been turned off, or if the patternNode is *
if (!scope.getWorld().isInJava5Mode()
@@ -125,7 +130,7 @@ public class SignaturePattern extends PatternNode {
reportUnmatchedTargetKindMessage(targetKinds,patternNode,scope,false);
}
} else {
TypePatternVisitor visitor = new TypePatternVisitor(scope,targetsOtherThanTypeAllowed);
TypePatternVisitor visitor = new TypePatternVisitor(scope,targetsOtherThanTypeAllowed,parameterTargettingAnnotationsAllowed);
patternNode.traverse(visitor,null);
if (visitor.containedIncorrectTargetKind()) {
Set keys = visitor.getIncorrectTargetKinds().keySet();
@@ -171,14 +176,17 @@ public class SignaturePattern extends PatternNode {
private IScope scope;
private Map incorrectTargetKinds /* PatternNode -> AnnotationTargetKind[] */ = new HashMap();
private boolean targetsOtherThanTypeAllowed;
private boolean parameterTargettingAnnotationsAllowed;

/**
* @param requiredTarget - the signature pattern Kind
* @param scope
* @param parameterTargettingAnnotationsAllowed
*/
public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed) {
public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
this.scope = scope;
this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed;
this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed;
}
public Object visit(WildAnnotationTypePattern node, Object data) {
@@ -196,7 +204,9 @@ public class SignaturePattern extends PatternNode {
if (targetKinds == null) return data;
List incorrectTargets = new ArrayList();
for (int i = 0; i < targetKinds.length; i++) {
if (targetKinds[i].getName().equals(kind.getName())) {
if (targetKinds[i].getName().equals(kind.getName()) ||
(targetKinds[i].getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())
) {
return data;
}
incorrectTargets.add(targetKinds[i]);
@@ -207,13 +217,20 @@ public class SignaturePattern extends PatternNode {
} else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
if (targetKinds == null) return data;
// exception here is if parameter annotations are allowed
if (parameterTargettingAnnotationsAllowed) {
for (int i = 0; i < targetKinds.length; i++) {
AnnotationTargetKind annotationTargetKind = targetKinds[i];
if (annotationTargetKind.getName().equals("PARAMETER") && node.isForParameterAnnotationMatch()) return data;
}
}
incorrectTargetKinds.put(node,targetKinds);
}
return data;
}
public Object visit(ExactTypePattern node, Object data) {
ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()));
ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()),null);
eatp.accept(this,data);
return data;
}
@@ -382,9 +399,11 @@ public class SignaturePattern extends PatternNode {
}
if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) return FuzzyBoolean.NO;
ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes());
if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC).alwaysTrue()) {
ResolvedType[][] parameterAnnotationTypes = aMethod.getParameterAnnotationTypes();
if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null;
if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
// It could still be a match based on the generic sig parameter types of a parameterized type
if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) {
if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()),TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
return FuzzyBoolean.MAYBE;
// It could STILL be a match based on the erasure of the parameter types??
// to be determined via test cases...
@@ -398,6 +417,8 @@ public class SignaturePattern extends PatternNode {
return FuzzyBoolean.YES;
}


/**
* match on declaring type, parameter types, throws types
*/
@@ -406,7 +427,12 @@ public class SignaturePattern extends PatternNode {

if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length)) return FuzzyBoolean.NO;
ResolvedType[] resolvedParameters = world.resolve(aConstructor.getParameterTypes());
if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC).alwaysTrue()) {
ResolvedType[][] parameterAnnotationTypes = aConstructor.getParameterAnnotationTypes();

if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null;

if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
// It could still be a match based on the generic sig parameter types of a parameterized type
if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) {
return FuzzyBoolean.MAYBE;
@@ -474,7 +500,7 @@ public class SignaturePattern extends PatternNode {
ResolvedMember [] mems = member.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include supers with getInterTypeMungersIncludingSupers?
List mungers = member.getDeclaringType().resolve(world).getInterTypeMungers();
for (Iterator iter = mungers.iterator(); iter.hasNext();) {
BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) iter.next();
if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
ResolvedMember fakerm = typeMunger.getSignature();
ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm,typeMunger.getAspectType());
@@ -571,7 +597,7 @@ public class SignaturePattern extends PatternNode {
public NamePattern getName() { return name; }
public TypePattern getDeclaringType() { return declaringType; }
public Member.Kind getKind() {
public MemberKind getKind() {
return kind;
}
@@ -657,7 +683,7 @@ public class SignaturePattern extends PatternNode {
}

public static SignaturePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
Member.Kind kind = Member.Kind.read(s);
MemberKind kind = MemberKind.read(s);
ModifiersPattern modifiers = ModifiersPattern.read(s);
TypePattern returnType = TypePattern.read(s, context);
TypePattern declaringType = TypePattern.read(s, context);

+ 13
- 2
weaver/src/org/aspectj/weaver/patterns/TypePattern.java Прегледај датотеку

@@ -158,7 +158,11 @@ public abstract class TypePattern extends PatternNode {
if (type.isTypeVariableReference()) {
typesIterator = ((TypeVariableReference)type).getTypeVariable().getFirstBound().resolve(type.getWorld()).getDirectSupertypes();
} else {
typesIterator = type.getDirectSupertypes();
// pr223605
if (type.isRawType()) {
type = type.getGenericType();
}
typesIterator = type.getDirectSupertypes();
}
// FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh
@@ -467,9 +471,16 @@ class AnyWithAnnotationTypePattern extends TypePattern {

protected boolean matchesExactly(ResolvedType type) {
annotationPattern.resolve(type.getWorld());
return annotationPattern.matches(type).alwaysTrue();
boolean b = false;
if (type.temporaryAnnotationTypes!=null) {
b = annotationPattern.matches(type,type.temporaryAnnotationTypes).alwaysTrue();
} else {
b = annotationPattern.matches(type).alwaysTrue();
}
return b;
}
protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
annotationPattern.resolve(type.getWorld());
return annotationPattern.matches(annotatedType).alwaysTrue();

+ 23
- 3
weaver/src/org/aspectj/weaver/patterns/TypePatternList.java Прегледај датотеку

@@ -87,6 +87,9 @@ public class TypePatternList extends PatternNode {
return (size() -ellipsisCount) <= numParams;
}
}
public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind) {
return matches(types,kind,null);
}
//XXX shares much code with WildTypePattern and with NamePattern
/**
@@ -99,7 +102,7 @@ public class TypePatternList extends PatternNode {
*
* This method will never return FuzzyBoolean.NEVER
*/
public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind) {
public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind, ResolvedType[][] parameterAnnotations) {
int nameLength = types.length;
int patternLength = typePatterns.length;
@@ -110,7 +113,16 @@ public class TypePatternList extends PatternNode {
if (nameLength != patternLength) return FuzzyBoolean.NO;
FuzzyBoolean finalReturn = FuzzyBoolean.YES;
while (patternIndex < patternLength) {
FuzzyBoolean ret = typePatterns[patternIndex++].matches(types[nameIndex++], kind);
ResolvedType t = types[nameIndex];
FuzzyBoolean ret = null;
try {
if (parameterAnnotations!=null) t.temporaryAnnotationTypes = parameterAnnotations[nameIndex];
ret = typePatterns[patternIndex].matches(t,kind);
} finally {
t.temporaryAnnotationTypes=null;
}
patternIndex++;
nameIndex++;
if (ret == FuzzyBoolean.NO) return ret;
if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
}
@@ -123,7 +135,15 @@ public class TypePatternList extends PatternNode {
if (p == TypePattern.ELLIPSIS) {
nameIndex = nameLength - (patternLength-patternIndex);
} else {
FuzzyBoolean ret = p.matches(types[nameIndex++], kind);
ResolvedType t = types[nameIndex];
FuzzyBoolean ret = null;
try {
if (parameterAnnotations!=null) t.temporaryAnnotationTypes = parameterAnnotations[nameIndex];
ret = p.matches(t, kind);
} finally {
t.temporaryAnnotationTypes=null;
}
nameIndex++;
if (ret == FuzzyBoolean.NO) return ret;
if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
}

+ 213
- 13
weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java Прегледај датотеку

@@ -11,7 +11,10 @@ package org.aspectj.weaver.patterns;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.MessageUtil;
@@ -19,10 +22,12 @@ import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;

/**
* @author colyer
@@ -34,6 +39,7 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {

private TypePattern typePattern;
private boolean resolved = false;
Map annotationValues;
/**
*
@@ -43,26 +49,189 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
this.typePattern = typePattern;
this.setLocation(typePattern.getSourceContext(), typePattern.start, typePattern.end);
}
public WildAnnotationTypePattern(TypePattern typePattern, Map annotationValues) {
super();
this.typePattern = typePattern;
this.annotationValues = annotationValues;
// PVAL make the location be from start of type pattern to end of values
this.setLocation(typePattern.getSourceContext(), typePattern.start, typePattern.end);
}

public TypePattern getTypePattern() {
return typePattern;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.patterns.AnnotationTypePattern#matches(org.aspectj.weaver.AnnotatedElement)
*/
public FuzzyBoolean matches(AnnotatedElement annotated) {
return matches(annotated,null);
}

/**
* Resolve any annotation values specified, checking they are all well formed (valid names, valid values)
* @param annotationType the annotation type for which the values have been specified
* @param scope the scope within which to resolve type references (eg. Color.GREEN)
*/
protected void resolveAnnotationValues(ResolvedType annotationType, IScope scope) {
if (annotationValues == null) return;
// Check any values specified are OK:
// - the value names are for valid annotation fields
// - the specified values are of the correct type
// - for enums, check the specified values can be resolved in the specified scope
Set keys = annotationValues.keySet();
ResolvedMember[] ms = annotationType.getDeclaredMethods();
for (Iterator kIter = keys.iterator(); kIter.hasNext();) {
String k = (String) kIter.next();
String v = (String) annotationValues.get(k);
boolean validKey = false;
for (int i = 0; i < ms.length; i++) {
ResolvedMember resolvedMember = ms[i];
if (resolvedMember.getName().equals(k) && resolvedMember.isAbstract()) {
validKey = true;
ResolvedType t = resolvedMember.getReturnType().resolve(scope.getWorld());
if (t.isEnum()) {
// value must be an enum reference X.Y
int pos = v.lastIndexOf(".");
if (pos == -1) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"enum"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
} else {
String typename = v.substring(0,pos);
ResolvedType rt = scope.lookupType(typename, this).resolve(scope.getWorld());
v = rt.getSignature()+v.substring(pos+1); // from 'Color.RED' to 'Lp/Color;RED'
annotationValues.put(k,v);
}
} else if (t.isPrimitiveType()) {
if (t.getSignature()=="I") {
try {
int value = Integer.parseInt(v);
annotationValues.put(k,Integer.toString(value));
} catch (NumberFormatException nfe) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"int"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
}
} else if (t.getSignature()=="F") {
try {
float value = Float.parseFloat(v);
annotationValues.put(k,Float.toString(value));
} catch (NumberFormatException nfe) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"float"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
}

} else if (t.getSignature()=="Z") {
if (v.equalsIgnoreCase("true") || v.equalsIgnoreCase("false")) {
// is it ok !
} else {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"boolean"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
}
} else if (t.getSignature()=="S") {
try {
short value = Short.parseShort(v);
annotationValues.put(k,Short.toString(value));
} catch (NumberFormatException nfe) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"short"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
}
} else if (t.getSignature()=="J") {
try {
long value = Long.parseLong(v);
annotationValues.put(k,Long.toString(value));
} catch (NumberFormatException nfe) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"long"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
}
} else if (t.getSignature()=="D") {
try {
double value = Double.parseDouble(v);
annotationValues.put(k,Double.toString(value));
} catch (NumberFormatException nfe) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"double"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
}
} else if (t.getSignature()=="B") {
try {
byte value = Byte.parseByte(v);
annotationValues.put(k,Byte.toString(value));
} catch (NumberFormatException nfe) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"byte"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
}
} else if (t.getSignature()=="C") {
if (v.length()!=3) { // '?'
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"char"),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
} else {
annotationValues.put(k,v.substring(1,2));
}
} else {
throw new RuntimeException("Not implemented for "+t);
}
} else if (t.equals(ResolvedType.JAVA_LANG_STRING)) {
// nothing to do, it will be OK
} else {
throw new RuntimeException("Compiler limitation: annotation value support not implemented for type "+t);
}
}
}
if (!validKey) {
IMessage m = MessageUtil.error(
WeaverMessages.format(WeaverMessages.UNKNOWN_ANNOTATION_VALUE,annotationType,k),
getSourceLocation());
scope.getWorld().getMessageHandler().handleMessage(m);
}
}
}




public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
if (!resolved) {
throw new IllegalStateException("Can't match on an unresolved annotation type pattern");
}
// matches if the type of any of the annotations on the AnnotatedElement is
// matched by the typePattern.
ResolvedType[] annTypes = annotated.getAnnotationTypes();

if (annTypes!=null && annTypes.length!=0) {
for (int i = 0; i < annTypes.length; i++) {
if (typePattern.matches(annTypes[i],TypePattern.STATIC).alwaysTrue()) {
return FuzzyBoolean.YES;
if (annotationValues!=null) {
// PVAL improve this restriction, would allow '*(value=Color.RED)'
throw new IllegalStateException("Cannot use annotationvalues with a wild annotation pattern");
}
if (isForParameterAnnotationMatch()) {
if (parameterAnnotations!=null && parameterAnnotations.length!=0) {
for (int i = 0; i < parameterAnnotations.length; i++) {
if (typePattern.matches(parameterAnnotations[i],TypePattern.STATIC).alwaysTrue()) {
return FuzzyBoolean.YES;
}
}
}
} else {
// matches if the type of any of the annotations on the AnnotatedElement is
// matched by the typePattern.
ResolvedType[] annTypes = annotated.getAnnotationTypes();
if (annTypes!=null && annTypes.length!=0) {
for (int i = 0; i < annTypes.length; i++) {
if (typePattern.matches(annTypes[i],TypePattern.STATIC).alwaysTrue()) {
return FuzzyBoolean.YES;
}
}
}
}
@@ -100,8 +269,11 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
scope.getWorld().getMessageHandler().handleMessage(m);
resolved = false;
}
ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(et.getExactType().resolve(scope.getWorld()));
ResolvedType annotationType = et.getExactType().resolve(scope.getWorld());
resolveAnnotationValues(annotationType,scope);
ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(annotationType,annotationValues);
eatp.copyLocationFrom(this);
if (isForParameterAnnotationMatch()) eatp.setForParameterAnnotationMatch();
return eatp;
} else {
return this;
@@ -124,10 +296,23 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
s.writeByte(VERSION);
typePattern.write(s);
writeLocation(s);
s.writeBoolean(isForParameterAnnotationMatch());
// PVAL
if (annotationValues==null) {
s.writeInt(0);
} else {
s.writeInt(annotationValues.size());
Set key = annotationValues.keySet();
for (Iterator keys = key.iterator(); keys.hasNext();) {
String k = (String) keys.next();
s.writeUTF(k);
s.writeUTF((String)annotationValues.get(k));
}
}
}

public static AnnotationTypePattern read(VersionedDataInputStream s,ISourceContext context) throws IOException {
AnnotationTypePattern ret;
WildAnnotationTypePattern ret;
byte version = s.readByte();
if (version > VERSION) {
throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
@@ -135,6 +320,21 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
TypePattern t = TypePattern.read(s,context);
ret = new WildAnnotationTypePattern(t);
ret.readLocation(context,s);
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) {
if (s.readBoolean()) ret.setForParameterAnnotationMatch();
}
if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) {
int annotationValueCount = s.readInt();
if (annotationValueCount>0) {
Map aValues = new HashMap();
for (int i=0;i<annotationValueCount;i++) {
String key = s.readUTF();
String val = s.readUTF();
aValues.put(key,val);
}
ret.annotationValues = aValues;
}
}
return ret;
}

@@ -144,14 +344,14 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
public boolean equals(Object obj) {
if (!(obj instanceof WildAnnotationTypePattern)) return false;
WildAnnotationTypePattern other = (WildAnnotationTypePattern) obj;
return other.typePattern.equals(typePattern);
return other.typePattern.equals(typePattern) && this.isForParameterAnnotationMatch()==other.isForParameterAnnotationMatch();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return 17 + 37*typePattern.hashCode();
return (17 + 37*typePattern.hashCode())*37+(isForParameterAnnotationMatch()?0:1);
}
/* (non-Javadoc)

+ 3
- 3
weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java Прегледај датотеку

@@ -236,8 +236,8 @@ public class WildTypePattern extends TypePattern {
return matchesExactlyByName(targetTypeName,type.isAnonymous(),type.isNested()) &&
matchesParameters(type,STATIC) &&
matchesBounds(type,STATIC) &&
annotationPattern.matches(annotatedType).alwaysTrue();
matchesBounds(type,STATIC) &&
annotationPattern.matches(annotatedType,type.temporaryAnnotationTypes).alwaysTrue();
}
@@ -644,7 +644,7 @@ public class WildTypePattern extends TypePattern {
if (dim == 0 && !isVarArgs && upperBound == null && lowerBound == null && (additionalInterfaceBounds == null || additionalInterfaceBounds.length==0)) { // pr72531
return TypePattern.ANY; //??? loses source location
}
} else {
} else if (!isVarArgs){
annotationPattern = annotationPattern.resolveBindings(scope,bindings,allowBinding);
AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annotationPattern);
ret.setLocation(sourceContext,start,end);

+ 0
- 40
weaver/src/org/aspectj/weaver/raw types.txt Прегледај датотеку

@@ -1,40 +0,0 @@

Current situation with respect to raw types...

* We can create an unresolved type (typeKind = SIMPLE) by
UnresolvedType.forSignature or forName
* We can create an unresolved type (typeKind = RAW) by calling
UnresolvedType.forRawTypeName
This method is called by...
BcelWorld.addSourceObjectType when types in jar files or on the classpath are added to
the weaver for processing. If the JavaClass is determined to be generic then a raw
UnresolvedType is built and a ReferenceType constructed from that. A BcelObjectType is
built using the Resolved raw type (and when it's generic signature is unpacked later that will
be swapped out for the generic type). Then a generic type is created, the delegates of
the generic and raw types are set to point to the BcelObjectType, and the generic type
of the raw type is set to point to the generic type. The raw type is explicitly added into
the typeMap.
EclipseFactory.addSourceTypeBinding when adding a binding for a generic type during
completeTypeBindings. This is put into the world by calling world.lookupOrCreateName.
Then a generic type is created and the raw type's generic type is set to refer to it.
EclipseFactory.fromBinding when processing a RawTypeBinding. A later call to resolve
is responsible for adding this to the type map.
* World.resolve processing works as follows:

in resolveObjectType, if the typeKind of the UnresolvedType is neither parameterized
nor generic, then a new ReferenceType is created using the rawTypeSignature of the
unresolved type. Then the delegate is created, and if this turns out to be generic then a
generic type is also built and set as the generic type of the reference type (but nothing
sets the type of the reference type to raw???).
in resolveTheGenericType the rawTypeSignature is looked up in the typeMap. If it
is not found, then a new UnresolvedType is created forSignature, resolved (see above),
and put in the type map. The generic type is then created and set as the generic type
of the raw type.

+ 7
- 0
weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java Прегледај датотеку

@@ -14,7 +14,9 @@ package org.aspectj.weaver.reflect;
import java.lang.reflect.Member;
import java.util.Set;

import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;

/**
@@ -30,8 +32,13 @@ public interface AnnotationFinder {
Object getAnnotation(ResolvedType annotationType, Object onObject);
Object getAnnotationFromMember(ResolvedType annotationType, Member aMember);
public AnnotationX getAnnotationOfType(UnresolvedType ofType,Member onMember);
public String getAnnotationDefaultValue(Member onMember);
Object getAnnotationFromClass(ResolvedType annotationType, Class aClass);
Set/*ResolvedType*/ getAnnotations(Member onMember);
ResolvedType[][] getParameterAnnotationTypes(Member onMember);
}

+ 10
- 7
weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java Прегледај датотеку

@@ -215,11 +215,12 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
public ResolvedMember[] getDeclaredFields() {
if (fields == null) {
Field[] reflectFields = this.myClass.getDeclaredFields();
this.fields = new ResolvedMember[reflectFields.length];
ResolvedMember[] rFields = new ResolvedMember[reflectFields.length];
for (int i = 0; i < reflectFields.length; i++) {
this.fields[i] =
rFields[i] =
ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectFields[i], world);
}
this.fields = rFields;
}
return fields;
}
@@ -230,11 +231,12 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
public ResolvedType[] getDeclaredInterfaces() {
if (interfaces == null) {
Class[] reflectInterfaces = this.myClass.getInterfaces();
this.interfaces = new ResolvedType[reflectInterfaces.length];
ResolvedType[] rInterfaces = new ResolvedType[reflectInterfaces.length];
for (int i = 0; i < reflectInterfaces.length; i++) {
this.interfaces[i] = ReflectionBasedReferenceTypeDelegateFactory
rInterfaces[i] = ReflectionBasedReferenceTypeDelegateFactory
.resolveTypeInWorld(reflectInterfaces[i],world);
}
this.interfaces = rInterfaces;
}
return interfaces;
}
@@ -246,15 +248,16 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
if (methods == null) {
Method[] reflectMethods = this.myClass.getDeclaredMethods();
Constructor[] reflectCons = this.myClass.getDeclaredConstructors();
this.methods = new ResolvedMember[reflectMethods.length + reflectCons.length];
ResolvedMember[] rMethods = new ResolvedMember[reflectMethods.length + reflectCons.length];
for (int i = 0; i < reflectMethods.length; i++) {
this.methods[i] =
rMethods[i] =
ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectMethods[i], world);
}
for (int i = 0; i < reflectCons.length; i++) {
this.methods[i + reflectMethods.length] =
rMethods[i + reflectMethods.length] =
ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectCons[i], world);
}
this.methods = rMethods;
}
return methods;
}

+ 32
- 4
weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java Прегледај датотеку

@@ -12,12 +12,16 @@
package org.aspectj.weaver.reflect;

import java.lang.reflect.Member;
import java.util.Iterator;

import org.aspectj.weaver.AnnotationX;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;


/**
* Subtype of ResolvedMemberImpl used in reflection world.
* Knows how to get annotations from a java.lang.reflect.Member
@@ -39,7 +43,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
* @param name
* @param parameterTypes
*/
public ReflectionBasedResolvedMemberImpl(Kind kind,
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers,
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes,
@@ -57,7 +61,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
* @param parameterTypes
* @param checkedExceptions
*/
public ReflectionBasedResolvedMemberImpl(Kind kind,
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers,
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions,
@@ -77,7 +81,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
* @param checkedExceptions
* @param backingGenericMember
*/
public ReflectionBasedResolvedMemberImpl(Kind kind,
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers,
UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes,
@@ -96,7 +100,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
* @param name
* @param signature
*/
public ReflectionBasedResolvedMemberImpl(Kind kind,
public ReflectionBasedResolvedMemberImpl(MemberKind kind,
UnresolvedType declaringType, int modifiers, String name,
String signature, Member reflectMember) {
super(kind, declaringType, modifiers, name, signature);
@@ -169,6 +173,30 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
return super.getAnnotationTypes();
}
public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
unpackAnnotations();
if (annotationFinder==null) return null;
for (Iterator iterator = annotationTypes.iterator(); iterator.hasNext();) {
ResolvedType type = (ResolvedType) iterator.next();
if (type.getSignature().equals(ofType.getSignature())) {
return annotationFinder.getAnnotationOfType(ofType, reflectMember);
}
}
return null;
}

public String getAnnotationDefaultValue() {
if (annotationFinder==null) return null;
return annotationFinder.getAnnotationDefaultValue(reflectMember);
}

public ResolvedType[][] getParameterAnnotationTypes() {
if (parameterAnnotationTypes==null && annotationFinder!=null) {
parameterAnnotationTypes = annotationFinder.getParameterAnnotationTypes(reflectMember);
}
return parameterAnnotationTypes;
}
private void unpackAnnotations() {
if (annotationTypes == null && annotationFinder != null) {
annotationTypes = annotationFinder.getAnnotations(reflectMember);

+ 1
- 1
weaver/src/org/aspectj/weaver/tools/CommonsTraceFactory.java Прегледај датотеку

@@ -11,7 +11,7 @@
package org.aspectj.weaver.tools;

import org.apache.commons.logging.LogFactory;
//OPTIMIZE move out of main weaver for now?
public class CommonsTraceFactory extends TraceFactory {

private LogFactory logFactory = LogFactory.getFactory();

+ 2
- 1
weaver/src/org/aspectj/weaver/tools/FuzzyBoolean.java Прегледај датотеку

@@ -12,7 +12,8 @@

package org.aspectj.weaver.tools;

/** This class implements a boolean that includes a "maybe"
/**
* This class implements a boolean that includes a "maybe"
*/
public class FuzzyBoolean {

+ 1
- 0
weaver/src/org/aspectj/weaver/tools/PointcutParser.java Прегледај датотеку

@@ -260,6 +260,7 @@ public class PointcutParser {
*/
public void registerPointcutDesignatorHandler(PointcutDesignatorHandler designatorHandler) {
this.pointcutDesignators.add(designatorHandler);
if (world != null) world.registerPointcutHandler(designatorHandler);
}
/**

+ 41
- 28
weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java Прегледај датотеку

@@ -26,6 +26,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

@@ -46,12 +47,14 @@ import org.aspectj.util.LangUtil;
import org.aspectj.weaver.IClassFileProvider;
import org.aspectj.weaver.IWeaveRequestor;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.World;
import org.aspectj.weaver.bcel.BcelObjectType;
import org.aspectj.weaver.bcel.BcelWeaver;
import org.aspectj.weaver.bcel.BcelWorld;
import org.aspectj.weaver.bcel.UnwovenClassFile;
import org.aspectj.weaver.bcel.Utility;

// OPTIMIZE add guards for all the debug/info/etc
/**
* This adaptor allows the AspectJ compiler to be embedded in an existing
* system to facilitate load-time weaving. It provides an interface for a
@@ -86,6 +89,12 @@ public class WeavingAdaptor implements IMessageContext {
protected Map generatedClasses = new HashMap(); /* String -> UnwovenClassFile */
protected BcelObjectType delegateForCurrentClass; // lazily initialized, should be used to prevent parsing bytecode multiple times

private int weavingSpecialTypes = 0;
private static final int INITIALIZED = 0x1;
private static final int WEAVE_JAVA_PACKAGE = 0x2;
private static final int WEAVE_JAVAX_PACKAGE= 0x4;
private static Trace trace = TraceFactory.getTraceFactory().getTrace(WeavingAdaptor.class);

protected WeavingAdaptor () {
@@ -128,7 +137,7 @@ public class WeavingAdaptor implements IMessageContext {
URL[] urls = ((URLClassLoader)loader).getURLs();
list.addAll(0,FileUtil.makeClasspath(urls));
}
else {
else {
warn("cannot determine classpath");
}
}
@@ -157,7 +166,6 @@ public class WeavingAdaptor implements IMessageContext {
private void init(List classPath, List aspectPath) {
abortOnError = true;
createMessageHandler();
info("using classpath: " + classPath);
info("using aspectpath: " + aspectPath);
@@ -227,7 +235,7 @@ public class WeavingAdaptor implements IMessageContext {
weaver.addLibraryJarFile(libFile);
}
catch (IOException ex) {
warn("bad library: '" + libFile + "'");
warn("bad library: '" + libFile + "'");
}
}

@@ -235,10 +243,11 @@ public class WeavingAdaptor implements IMessageContext {
* Weave a class using aspects previously supplied to the adaptor.
* @param name the name of the class
* @param bytes the class bytes
* @param mustWeave if true then this class *must* get woven (used for concrete aspects generated from XML)
* @return the woven bytes
* @exception IOException weave failed
*/
public byte[] weaveClass (String name, byte[] bytes) throws IOException {
public byte[] weaveClass (String name, byte[] bytes,boolean mustWeave) throws IOException {
if (trace.isTraceEnabled()) trace.enter("weaveClass",this,new Object[] {name, bytes});

if (!enabled) {
@@ -259,6 +268,11 @@ public class WeavingAdaptor implements IMessageContext {
debug("weaving '" + name + "'");
bytes = getWovenBytes(name, bytes);
} else if (shouldWeaveAnnotationStyleAspect(name, bytes)) {
if (mustWeave) {
if (bcelWorld.getLint().mustWeaveXmlDefinedAspects.isEnabled()) {
bcelWorld.getLint().mustWeaveXmlDefinedAspects.signal(name,null);
}
}
// an @AspectJ aspect needs to be at least munged by the aspectOf munger
debug("weaving '" + name + "'");
bytes = getAtAspectJAspectBytes(name, bytes);
@@ -294,10 +308,25 @@ public class WeavingAdaptor implements IMessageContext {
}

private boolean shouldWeaveName (String name) {
if ((weavingSpecialTypes&INITIALIZED)==0) {
weavingSpecialTypes|=INITIALIZED;
// initialize it
Properties p = weaver.getWorld().getExtraConfiguration();
if (p!=null) {
boolean b = p.getProperty(World.xsetWEAVE_JAVA_PACKAGES,"false").equalsIgnoreCase("true");
if (b) {
weavingSpecialTypes|=WEAVE_JAVA_PACKAGE;
}
b = p.getProperty(World.xsetWEAVE_JAVAX_PACKAGES,"false").equalsIgnoreCase("true");
if (b) {
weavingSpecialTypes|=WEAVE_JAVAX_PACKAGE;
}
}
}
boolean should =
!((name.startsWith("org.aspectj.")
|| name.startsWith("java.")
|| name.startsWith("javax."))
!(name.startsWith("org.aspectj.")
|| (name.startsWith("java.") && (weavingSpecialTypes&WEAVE_JAVA_PACKAGE)==0)
|| (name.startsWith("javax.") && (weavingSpecialTypes&WEAVE_JAVAX_PACKAGE)==0)
//|| name.startsWith("$Proxy")//JDK proxies//FIXME AV is that 1.3 proxy ? fe. ataspect.$Proxy0 is a java5 proxy...
|| name.startsWith("sun.reflect."));//JDK reflect
return should;
@@ -319,25 +348,9 @@ public class WeavingAdaptor implements IMessageContext {
}
return (delegateForCurrentClass.isAnnotationStyleAspect());
}

// private boolean asmCheckAnnotationStyleAspect(byte[] bytes) {
// IsAtAspectAnnotationVisitor detector = new IsAtAspectAnnotationVisitor();
//
// ClassReader cr = new ClassReader(bytes);
// try {
// cr.accept(detector, true);//, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES);
// } catch (Exception spe) {
// // if anything goes wrong, e.g., an NPE, then assume it's NOT an @AspectJ aspect...
// System.err.println("Unexpected problem parsing bytes to discover @Aspect annotation");
// spe.printStackTrace();
// return false;
// }
//
// return detector.isAspect();
// }
protected void ensureDelegateInitialized(String name,byte[] bytes) {
if (delegateForCurrentClass==null)
if (delegateForCurrentClass==null) // OPTIMIZE better job here?
delegateForCurrentClass = ((BcelWorld)weaver.getWorld()).addSourceObjectType(Utility.makeJavaClass(name, bytes));
}

@@ -396,10 +409,10 @@ public class WeavingAdaptor implements IMessageContext {
info("adding aspect library: '" + aspectLibrary + "'");
weaver.addLibraryJarFile(aspectLibrary);
} catch (IOException ex) {
error("exception adding aspect library: '" + ex + "'");
error("exception adding aspect library: '" + ex + "'");
}
} else {
error("bad aspect library: '" + aspectLibrary + "'");
error("bad aspect library: '" + aspectLibrary + "'");
}
}
@@ -470,7 +483,7 @@ public class WeavingAdaptor implements IMessageContext {
os.close();
}
catch (IOException ex) {
warn("unable to dump class " + name + " in directory " + dirName,ex);
warn("unable to dump class " + name + " in directory " + dirName,ex);
}
}

@@ -649,7 +662,7 @@ public class WeavingAdaptor implements IMessageContext {
private class WeavingClassFileProvider implements IClassFileProvider {

private UnwovenClassFile unwovenClass;
private List unwovenClasses = new ArrayList(); /* List<UnovenClassFile> */
private List unwovenClasses = new ArrayList(); /* List<UnwovenClassFile> */
private UnwovenClassFile wovenClass;
private boolean isApplyAtAspectJMungersOnly = false;


+ 0
- 6
weaver/src/org/aspectj/weaver/tools/package.html Прегледај датотеку

@@ -1,6 +0,0 @@
<html>
<body>
Provides a set of interfaces for third-parties wishing to integrate
AspectJ weaving capabilities into their environments.
</body>
</html>

+ 4
- 0
weaver/src/org/aspectj/weaver/weaver-messages.properties Прегледај датотеку

@@ -157,6 +157,10 @@ referenceToNonAnnotationType=Type referred to is not an annotation type: {0}
bindingNonRuntimeRetentionAnnotation=Annotation type {0} does not have runtime retention
noMatchBecauseSourceRetention=Failing match because annotation ''{0}'' on type ''{1}'' has SOURCE retention. Matching allowed when RetentionPolicy is CLASS or RUNTIME

# Annotation value
invalidAnnotationValue=Invalid annotation value ''{0}'', expected {1} value
unknownAnnotationValue=The annotation ''{0}'' does not define a value named ''{1}''

# Generics
cantDecpMultipleParameterizations=Cannot declare parent {0} onto type {1} since it already has {2} in its hierarchy
noParameterizedTypePatternInHandler=a parameterized type pattern may not be used in a handler pointcut expression

+ 14
- 14
weaver/testsrc/org/aspectj/weaver/MemberTestCase.java Прегледај датотеку

@@ -29,10 +29,10 @@ public class MemberTestCase extends TestCase {
}

public void testMethodConstruction() {
Member s = MemberImpl.methodFromString("void Foo.goo(int)");
Member s = TestUtils.methodFromString("void Foo.goo(int)");
Member t = MemberImpl.method(UnresolvedType.forName("Foo"), 0, "goo", "(I)V");
Member u = MemberImpl.methodFromString("void Foo1.goo(int)");
Member v = MemberImpl.methodFromString("int Foo.goo(int)");
Member u = TestUtils.methodFromString("void Foo1.goo(int)");
Member v = TestUtils.methodFromString("int Foo.goo(int)");

TestUtil.assertCommutativeEquals(s, s, true);
TestUtil.assertCommutativeEquals(t, t, true);
@@ -45,10 +45,10 @@ public class MemberTestCase extends TestCase {
TestUtil.assertCommutativeEquals(t, v, false);
TestUtil.assertCommutativeEquals(u, v, false);

s = MemberImpl.fieldFromString("int Foo.goo");
s = TestUtils.fieldFromString("int Foo.goo");
t = MemberImpl.field("Foo", 0, "goo", "I");
u = MemberImpl.fieldFromString("int Foo.goo1");
v = MemberImpl.fieldFromString("long Foo.goo");
u = TestUtils.fieldFromString("int Foo.goo1");
v = TestUtils.fieldFromString("long Foo.goo");

TestUtil.assertCommutativeEquals(s, s, true);
TestUtil.assertCommutativeEquals(t, t, true);
@@ -64,7 +64,7 @@ public class MemberTestCase extends TestCase {


public void testMethodContents() {
Member m = MemberImpl.methodFromString("void Foo.goo(int)");
Member m = TestUtils.methodFromString("void Foo.goo(int)");
kindTest(m, Member.METHOD);
declaringTypeTest(m, "Foo");
nameTest(m, "goo");
@@ -75,7 +75,7 @@ public class MemberTestCase extends TestCase {
isConstructorTest(m, false);
isStaticTest(m, false);

m = MemberImpl.methodFromString("interface java.lang.Object java.util.Iterator.next()");
m = TestUtils.methodFromString("interface java.lang.Object java.util.Iterator.next()");
kindTest(m, Member.METHOD);
declaringTypeTest(m, "java.util.Iterator");
nameTest(m, "next");
@@ -86,7 +86,7 @@ public class MemberTestCase extends TestCase {
isConstructorTest(m, false);
isStaticTest(m, false);

m = MemberImpl.methodFromString("void Foo.<init>(int, java.lang.Object)");
m = TestUtils.methodFromString("void Foo.<init>(int, java.lang.Object)");
kindTest(m, Member.CONSTRUCTOR);
declaringTypeTest(m, "Foo");
nameTest(m, "<init>");
@@ -97,7 +97,7 @@ public class MemberTestCase extends TestCase {
isConstructorTest(m, true);
isStaticTest(m, false);

m = MemberImpl.methodFromString("private double Foo.sqrt(double)");
m = TestUtils.methodFromString("private double Foo.sqrt(double)");
kindTest(m, Member.METHOD);
declaringTypeTest(m, "Foo");
nameTest(m, "sqrt");
@@ -108,7 +108,7 @@ public class MemberTestCase extends TestCase {
isConstructorTest(m, false);
isStaticTest(m, false);

m = MemberImpl.methodFromString("static int java.lang.Math.max(int, int)");
m = TestUtils.methodFromString("static int java.lang.Math.max(int, int)");
kindTest(m, Member.METHOD);
declaringTypeTest(m, "java.lang.Math");
nameTest(m, "max");
@@ -121,7 +121,7 @@ public class MemberTestCase extends TestCase {
}

public void testFieldContents() {
Member m = MemberImpl.fieldFromString("int Foo.goo");
Member m = TestUtils.fieldFromString("int Foo.goo");
kindTest(m, Member.FIELD);
declaringTypeTest(m, "Foo");
nameTest(m, "goo");
@@ -132,7 +132,7 @@ public class MemberTestCase extends TestCase {
isConstructorTest(m, false);
isStaticTest(m, false);

m = MemberImpl.fieldFromString("static java.util.Iterator goo.Bar.i");
m = TestUtils.fieldFromString("static java.util.Iterator goo.Bar.i");
kindTest(m, Member.FIELD);
declaringTypeTest(m, "goo.Bar");
nameTest(m, "i");
@@ -168,7 +168,7 @@ public class MemberTestCase extends TestCase {
private void declaringTypeTest(Member m, String declaringName) {
assertEquals(m + " declared in", UnresolvedType.forName(declaringName), m.getDeclaringType());
}
private void kindTest(Member m, MemberImpl.Kind kind) {
private void kindTest(Member m, MemberKind kind) {
assertEquals(m + " kind", kind, m.getKind());
}

+ 162
- 0
weaver/testsrc/org/aspectj/weaver/TestUtils.java Прегледај датотеку

@@ -0,0 +1,162 @@
/* *******************************************************************
* Copyright (c) 2008 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andy Clement initial implementation
* ******************************************************************/
package org.aspectj.weaver;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.aspectj.weaver.bcel.BcelAdvice;
import org.aspectj.weaver.patterns.FormalBinding;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.SimpleScope;


public class TestUtils {
private static final String[] ZERO_STRINGS = new String[0];

/**
* Build a member from a string representation:
* <blockquote><pre>
* static? TypeName TypeName.Id
* </pre></blockquote>
*/
public static MemberImpl fieldFromString(String str) {
str = str.trim();
final int len = str.length();
int i = 0;
int mods = 0;
if (str.startsWith("static", i)) {
mods = Modifier.STATIC;
i += 6;
while (Character.isWhitespace(str.charAt(i))) i++;
}
int start = i;
while (! Character.isWhitespace(str.charAt(i))) i++;
UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i));

start = i;
i = str.lastIndexOf('.');
UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
start = ++i;
String name = str.substring(start, len).trim();
return new MemberImpl(
Member.FIELD,
declaringTy,
mods,
retTy,
name,
UnresolvedType.NONE);
}

/**
* Build a member from a string representation:
* <blockquote><pre>
* (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
* </pre></blockquote>
*/
public static Member methodFromString(String str) {
str = str.trim();
// final int len = str.length();
int i = 0;

int mods = 0;
if (str.startsWith("static", i)) {
mods = Modifier.STATIC;
i += 6;
} else if (str.startsWith("interface", i)) {
mods = Modifier.INTERFACE;
i += 9;
} else if (str.startsWith("private", i)) {
mods = Modifier.PRIVATE;
i += 7;
}
while (Character.isWhitespace(str.charAt(i))) i++;
int start = i;
while (! Character.isWhitespace(str.charAt(i))) i++;
UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i));

start = i;
i = str.indexOf('(', i);
i = str.lastIndexOf('.', i);
UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
start = ++i;
i = str.indexOf('(', i);
String name = str.substring(start, i).trim();
start = ++i;
i = str.indexOf(')', i);
String[] paramTypeNames = parseIds(str.substring(start, i).trim());

return MemberImpl.method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames));
}

private static String[] parseIds(String str) {
if (str.length() == 0) return ZERO_STRINGS;
List l = new ArrayList();
int start = 0;
while (true) {
int i = str.indexOf(',', start);
if (i == -1) {
l.add(str.substring(start).trim());
break;
}
l.add(str.substring(start, i).trim());
start = i+1;
}
return (String[]) l.toArray(new String[l.size()]);
}

/**
* Moved from BcelWorld to here
*
* Parse a string into advice.
*
* <blockquote><pre>
* Kind ( Id , ... ) : Pointcut -> MethodSignature
* </pre></blockquote>
*/
public static Advice shadowMunger(World w,String str, int extraFlag) {
str = str.trim();
int start = 0;
int i = str.indexOf('(');
AdviceKind kind =
AdviceKind.stringToKind(str.substring(start, i));
start = ++i;
i = str.indexOf(')', i);
String[] ids = parseIds(str.substring(start, i).trim());
//start = ++i;
i = str.indexOf(':', i);
start = ++i;
i = str.indexOf("->", i);
Pointcut pointcut = Pointcut.fromString(str.substring(start, i).trim());
Member m = TestUtils.methodFromString(str.substring(i+2, str.length()).trim());

// now, we resolve
UnresolvedType[] types = m.getParameterTypes();
FormalBinding[] bindings = new FormalBinding[ids.length];
for (int j = 0, len = ids.length; j < len; j++) {
bindings[j] = new FormalBinding(types[j], ids[j], j, 0, 0, "fromString");
}

Pointcut p =
pointcut.resolve(new SimpleScope(w, bindings));

return new BcelAdvice(kind, p, m, extraFlag, 0, 0, null, null);
}
}

+ 23
- 0
weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java Прегледај датотеку

@@ -122,6 +122,29 @@ public class TypeXTestCase extends TestCase {
}
}
public void testTypeFactoryForParameterizedTypes() {
if (LangUtil.is15VMOrGreater()) { // no funny types pre 1.5
UnresolvedType enumOfSimpleType =
TypeFactory.createTypeFromSignature("Pjava/lang/Enum<Ljava/lang/String;>;");
assertEquals(1, enumOfSimpleType.getTypeParameters().length);
UnresolvedType enumOfNestedType =
TypeFactory.createTypeFromSignature("Pjava/lang/Enum<Ljavax/jws/soap/SOAPBinding$ParameterStyle;>;");
assertEquals(1, enumOfNestedType.getTypeParameters().length);

// is this signature right?
UnresolvedType nestedTypeOfParameterized =
TypeFactory.createTypeFromSignature("PMyInterface<Ljava/lang/String;>$MyOtherType;");
assertEquals(0, nestedTypeOfParameterized.getTypeParameters().length);
// how about this one? is this valid?
UnresolvedType doublyNestedTypeSignatures =
TypeFactory.createTypeFromSignature("PMyInterface<Ljava/lang/String;Ljava/lang/String;>$MyOtherType<Ljava/lang/Object;>;");
assertEquals(1, doublyNestedTypeSignatures.getTypeParameters().length);
}
}
private void checkTX(UnresolvedType tx,boolean shouldBeParameterized,int numberOfTypeParameters) {
assertTrue("Expected parameterization flag to be "+shouldBeParameterized,tx.isParameterizedType()==shouldBeParameterized);
if (numberOfTypeParameters==0) {

+ 1
- 1
weaver/testsrc/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java Прегледај датотеку

@@ -33,7 +33,7 @@ public class AfterThrowingWeaveTestCase extends WeaveTestCase {
BcelWorld world = new BcelWorld();
ShadowMunger myMunger =
world.shadowMunger("afterThrowing(): get(* *.out) -> static void Aspect.ajc_afterThrowing_field_get(java.lang.Throwable)",
TestUtils.shadowMunger(world,"afterThrowing(): get(* *.out) -> static void Aspect.ajc_afterThrowing_field_get(java.lang.Throwable)",
Advice.ExtraArgument);
ShadowMunger cm = myMunger.concretize(ResolvedType.MISSING, world, null);


+ 7
- 6
weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java Прегледај датотеку

@@ -19,6 +19,7 @@ import java.util.Arrays;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.MemberImpl;
import org.aspectj.weaver.TestUtils;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;

@@ -46,7 +47,7 @@ public class TjpWeaveTestCase extends WeaveTestCase {
BcelAdvice munger = new BcelAdvice(
AdviceKind.stringToKind("before"),
makePointcutAll(),
MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"),
TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"),
Advice.ThisJoinPointStaticPart, -1, -1, null, null);
weaveTest("HelloWorld", "StaticTjpBeforeHelloWorld", munger);
@@ -57,7 +58,7 @@ public class TjpWeaveTestCase extends WeaveTestCase {
BcelAdvice munger = new BcelAdvice(
AdviceKind.stringToKind("before"),
makePointcutAll(),
MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"),
TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"),
Advice.ThisEnclosingJoinPointStaticPart, -1, -1, null, null);
weaveTest("HelloWorld", "StaticEnclosingTjpBeforeHelloWorld", munger);
@@ -68,7 +69,7 @@ public class TjpWeaveTestCase extends WeaveTestCase {
BcelAdvice munger = new BcelAdvice(
AdviceKind.stringToKind("before"),
makePointcutAll(),
MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint)"),
TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint)"),
Advice.ThisJoinPoint, -1, -1, null, null);
weaveTest("HelloWorld", "TjpBeforeHelloWorld", munger);
@@ -78,7 +79,7 @@ public class TjpWeaveTestCase extends WeaveTestCase {
BcelAdvice munger = new BcelAdvice(
AdviceKind.stringToKind("around"),
makePointcutAll(),
MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
TestUtils.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, null);
weaveTest("HelloWorld", "TjpAroundHelloWorld", munger);
@@ -90,14 +91,14 @@ public class TjpWeaveTestCase extends WeaveTestCase {
BcelAdvice munger1 = new BcelAdvice(
AdviceKind.stringToKind("around"),
makePointcutAll(),
MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
TestUtils.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null,
rtx);
BcelAdvice munger2 = new BcelAdvice(
AdviceKind.stringToKind("around"),
makePointcutAll(),
MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
TestUtils.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null,
rtx);

+ 1
- 1
weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java Прегледај датотеку

@@ -189,7 +189,7 @@ public abstract class WeaveTestCase extends TestCase {

protected ShadowMunger makeConcreteAdvice(String mungerString, int extraArgFlag, PerClause perClause) {
Advice myMunger =
world.shadowMunger(mungerString, extraArgFlag);
TestUtils.shadowMunger(world,mungerString, extraArgFlag);
// PerSingleton s = new PerSingleton();
// s.concretize(world.resolve("Aspect"));

+ 0
- 0
weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java Прегледај датотеку


Неке датотеке нису приказане због велике количине промена

Loading…
Откажи
Сачувај