Переглянути джерело

246125: the SPLIT

tags/V1_6_3rc1
aclement 15 роки тому
джерело
коміт
eb5b285778
100 змінених файлів з 20316 додано та 0 видалено
  1. 158
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AbstractAnnotationAJ.java
  2. 128
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java
  3. 444
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Advice.java
  4. 117
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AdviceKind.java
  5. 699
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AjAttribute.java
  6. 621
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AjcMemberMaker.java
  7. 21
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AnnotatedElement.java
  8. 102
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AnnotationAJ.java
  9. 35
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AnnotationAnnotationValue.java
  10. 47
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AnnotationNameValuePair.java
  11. 57
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AnnotationOnTypeMunger.java
  12. 51
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AnnotationTargetKind.java
  13. 72
    0
      org.aspectj.matcher/src/org/aspectj/weaver/AnnotationValue.java
  14. 57
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ArrayAnnotationValue.java
  15. 196
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ArrayReferenceType.java
  16. 58
    0
      org.aspectj.matcher/src/org/aspectj/weaver/BCException.java
  17. 58
    0
      org.aspectj.matcher/src/org/aspectj/weaver/BindingScope.java
  18. 334
    0
      org.aspectj.matcher/src/org/aspectj/weaver/BoundedReferenceType.java
  19. 151
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Checker.java
  20. 31
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ClassAnnotationValue.java
  21. 144
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ConcreteTypeMunger.java
  22. 30
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Constants.java
  23. 533
    0
      org.aspectj.matcher/src/org/aspectj/weaver/CrosscuttingMembers.java
  24. 305
    0
      org.aspectj.matcher/src/org/aspectj/weaver/CrosscuttingMembersSet.java
  25. 58
    0
      org.aspectj.matcher/src/org/aspectj/weaver/CustomMungerFactory.java
  26. 506
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Dump.java
  27. 37
    0
      org.aspectj.matcher/src/org/aspectj/weaver/EnumAnnotationValue.java
  28. 30
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ExposeTypeMunger.java
  29. 158
    0
      org.aspectj.matcher/src/org/aspectj/weaver/GeneratedReferenceTypeDelegate.java
  30. 43
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IClassFileProvider.java
  31. 29
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IClassWeaver.java
  32. 23
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ICrossReferenceHandler.java
  33. 16
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IEclipseSourceContext.java
  34. 33
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IHasPosition.java
  35. 21
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IHasSourceLocation.java
  36. 23
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ISourceContext.java
  37. 26
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IUnwovenClassFile.java
  38. 38
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IWeaveRequestor.java
  39. 44
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IWeavingSupport.java
  40. 147
    0
      org.aspectj.matcher/src/org/aspectj/weaver/IntMap.java
  41. 264
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Iterators.java
  42. 409
    0
      org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignature.java
  43. 251
    0
      org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignatureIterator.java
  44. 315
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Lint.java
  45. 47
    0
      org.aspectj.matcher/src/org/aspectj/weaver/LintMessage.java
  46. 102
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Member.java
  47. 565
    0
      org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java
  48. 37
    0
      org.aspectj.matcher/src/org/aspectj/weaver/MemberKind.java
  49. 202
    0
      org.aspectj.matcher/src/org/aspectj/weaver/MethodDelegateTypeMunger.java
  50. 212
    0
      org.aspectj.matcher/src/org/aspectj/weaver/MissingResolvedTypeWithKnownSignature.java
  51. 334
    0
      org.aspectj.matcher/src/org/aspectj/weaver/NameMangler.java
  52. 144
    0
      org.aspectj.matcher/src/org/aspectj/weaver/NewConstructorTypeMunger.java
  53. 124
    0
      org.aspectj.matcher/src/org/aspectj/weaver/NewFieldTypeMunger.java
  54. 146
    0
      org.aspectj.matcher/src/org/aspectj/weaver/NewMethodTypeMunger.java
  55. 51
    0
      org.aspectj.matcher/src/org/aspectj/weaver/NewParentTypeMunger.java
  56. 91
    0
      org.aspectj.matcher/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java
  57. 81
    0
      org.aspectj.matcher/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java
  58. 80
    0
      org.aspectj.matcher/src/org/aspectj/weaver/PoliceExtensionUse.java
  59. 32
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Position.java
  60. 69
    0
      org.aspectj.matcher/src/org/aspectj/weaver/PrivilegedAccessMunger.java
  61. 810
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java
  62. 105
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ReferenceTypeDelegate.java
  63. 191
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
  64. 1156
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMemberImpl.java
  65. 165
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ResolvedPointcutDefinition.java
  66. 2201
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
  67. 446
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ResolvedTypeMunger.java
  68. 666
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Shadow.java
  69. 191
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ShadowMunger.java
  70. 246
    0
      org.aspectj.matcher/src/org/aspectj/weaver/SignatureUtils.java
  71. 82
    0
      org.aspectj.matcher/src/org/aspectj/weaver/SimpleAnnotationValue.java
  72. 109
    0
      org.aspectj.matcher/src/org/aspectj/weaver/SourceContextImpl.java
  73. 153
    0
      org.aspectj.matcher/src/org/aspectj/weaver/StandardAnnotation.java
  74. 56
    0
      org.aspectj.matcher/src/org/aspectj/weaver/StaticJoinPointFactory.java
  75. 35
    0
      org.aspectj.matcher/src/org/aspectj/weaver/TemporaryTypeMunger.java
  76. 293
    0
      org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java
  77. 372
    0
      org.aspectj.matcher/src/org/aspectj/weaver/TypeVariable.java
  78. 23
    0
      org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableDeclaringElement.java
  79. 22
    0
      org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReference.java
  80. 146
    0
      org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.java
  81. 914
    0
      org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java
  82. 102
    0
      org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java
  83. 43
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Utils.java
  84. 32
    0
      org.aspectj.matcher/src/org/aspectj/weaver/VersionedDataInputStream.java
  85. 63
    0
      org.aspectj.matcher/src/org/aspectj/weaver/WeakClassLoaderReference.java
  86. 210
    0
      org.aspectj.matcher/src/org/aspectj/weaver/WeaverMessages.java
  87. 476
    0
      org.aspectj.matcher/src/org/aspectj/weaver/WeaverStateInfo.java
  88. 69
    0
      org.aspectj.matcher/src/org/aspectj/weaver/WildcardedUnresolvedType.java
  89. 1286
    0
      org.aspectj.matcher/src/org/aspectj/weaver/World.java
  90. 47
    0
      org.aspectj.matcher/src/org/aspectj/weaver/XlintDefault.properties
  91. 22
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/ASTNode.java
  92. 51
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/And.java
  93. 41
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/Call.java
  94. 48
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/CallExpr.java
  95. 34
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/Expr.java
  96. 44
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/FieldGet.java
  97. 47
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/FieldGetCall.java
  98. 59
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/HasAnnotation.java
  99. 23
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/IExprVisitor.java
  100. 0
    0
      org.aspectj.matcher/src/org/aspectj/weaver/ast/ITestVisitor.java

+ 158
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AbstractAnnotationAJ.java Переглянути файл

@@ -0,0 +1,158 @@
/* *******************************************************************
* 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
*
* ******************************************************************/
package org.aspectj.weaver;

import java.util.Collections;
import java.util.Iterator;
import java.util.Set;

public abstract class AbstractAnnotationAJ implements AnnotationAJ {

protected final ResolvedType type;

private Set supportedTargets = null; // @target meta annotation

public AbstractAnnotationAJ(ResolvedType type) {
this.type = type;
}

/**
* {@inheritDoc}
*/
public final ResolvedType getType() {
return type;
}

/**
* {@inheritDoc}
*/
public final String getTypeSignature() {
return type.getSignature();
}

/**
* {@inheritDoc}
*/
public final String getTypeName() {
return type.getName();
}

/**
* {@inheritDoc}
*/
public final boolean allowedOnAnnotationType() {
ensureAtTargetInitialized();
if (supportedTargets.isEmpty()) {
return true;
}
return supportedTargets.contains("ANNOTATION_TYPE");
}

/**
* {@inheritDoc}
*/
public final boolean allowedOnField() {
ensureAtTargetInitialized();
if (supportedTargets.isEmpty()) {
return true;
}
return supportedTargets.contains("FIELD");
}

/**
* {@inheritDoc}
*/
public final boolean allowedOnRegularType() {
ensureAtTargetInitialized();
if (supportedTargets.isEmpty()) {
return true;
}
return supportedTargets.contains("TYPE");
}

/**
* {@inheritDoc}
*/
public final void ensureAtTargetInitialized() {
if (supportedTargets == null) {
AnnotationAJ atTargetAnnotation = retrieveAnnotationOnAnnotation(UnresolvedType.AT_TARGET);
if (atTargetAnnotation == null) {
supportedTargets = Collections.EMPTY_SET;
} else {
supportedTargets = atTargetAnnotation.getTargets();
}
}
}

/**
* {@inheritDoc}
*/
public final String getValidTargets() {
StringBuffer sb = new StringBuffer();
sb.append("{");
for (Iterator iter = supportedTargets.iterator(); iter.hasNext();) {
String evalue = (String) iter.next();
sb.append(evalue);
if (iter.hasNext()) {
sb.append(",");
}
}
sb.append("}");
return sb.toString();
}

/**
* {@inheritDoc}
*/
public final boolean specifiesTarget() {
ensureAtTargetInitialized();
return !supportedTargets.isEmpty();
}

/**
* Helper method to retrieve an annotation on an annotation e.g. retrieveAnnotationOnAnnotation(UnresolvedType.AT_TARGET)
*/
private final AnnotationAJ retrieveAnnotationOnAnnotation(UnresolvedType requiredAnnotationSignature) {
AnnotationAJ[] annos = type.getAnnotations();
for (int i = 0; i < annos.length; i++) {
AnnotationAJ a = annos[i];
if (a.getTypeSignature().equals(requiredAnnotationSignature.getSignature())) {
return annos[i];
}
}
return null;
}

/**
* {@inheritDoc}
*/
public abstract boolean isRuntimeVisible();

/**
* {@inheritDoc}
*/
public abstract Set getTargets();

/**
* {@inheritDoc}
*/
public abstract boolean hasNameValuePair(String name, String value);

/**
* {@inheritDoc}
*/
public abstract boolean hasNamedValue(String name);

/**
* {@inheritDoc}
*/
public abstract String stringify();

}

+ 128
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java Переглянути файл

@@ -0,0 +1,128 @@
/* *******************************************************************
* Copyright (c) 2002 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:
* PARC initial implementation
* Andy Clement - June 2005 - separated out from ResolvedType
* ******************************************************************/
package org.aspectj.weaver;

import java.util.ArrayList;
import java.util.List;

import org.aspectj.bridge.ISourceLocation;
import org.aspectj.util.GenericSignature;
import org.aspectj.util.GenericSignatureParser;
import org.aspectj.util.GenericSignature.ClassSignature;

public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDelegate {

private String sourcefilename = UNKNOWN_SOURCE_FILE;
private ISourceContext sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;

protected boolean exposedToWeaver;
protected ReferenceType resolvedTypeX;
protected ClassSignature cachedGenericClassTypeSignature;

// Happens to match Bcel javaClass default of '<Unknown>'
public final static String UNKNOWN_SOURCE_FILE = "<Unknown>";

public AbstractReferenceTypeDelegate(ReferenceType resolvedTypeX, boolean exposedToWeaver) {
this.resolvedTypeX = resolvedTypeX;
this.exposedToWeaver = exposedToWeaver;
}

public final boolean isClass() {
return !isAspect() && !isInterface();
}

/**
* Designed to be overriden by EclipseType to disable collection of shadow mungers during pre-weave compilation phase
*/
public boolean doesNotExposeShadowMungers() {
return false;
}

public boolean isExposedToWeaver() {
return exposedToWeaver;
}

public ReferenceType getResolvedTypeX() {
return resolvedTypeX;
}

public final String getSourcefilename() {
return sourcefilename;
}

public final void setSourcefilename(String sourceFileName) {
sourcefilename = sourceFileName;
if (sourceFileName != null && sourceFileName.equals(AbstractReferenceTypeDelegate.UNKNOWN_SOURCE_FILE)) {
sourcefilename = "Type '" + getResolvedTypeX().getName() + "' (no debug info available)";
} else {
String pname = getResolvedTypeX().getPackageName();
if (pname != null) {
sourcefilename = pname.replace('.', '/') + '/' + sourceFileName;
}
}
if (sourcefilename != null && sourceContext instanceof SourceContextImpl) {
((SourceContextImpl) sourceContext).setSourceFileName(sourcefilename);
}
}

public ISourceLocation getSourceLocation() {
return getSourceContext().makeSourceLocation(0, 0);
}

public ISourceContext getSourceContext() {
return sourceContext;
}

public void setSourceContext(ISourceContext isc) {
sourceContext = isc;
}

public GenericSignature.ClassSignature getGenericClassTypeSignature() {
if (cachedGenericClassTypeSignature == null) {
String sig = getDeclaredGenericSignature();
if (sig != null) {
GenericSignatureParser parser = new GenericSignatureParser();
cachedGenericClassTypeSignature = parser.parseAsClassSignature(sig);
}
}
return cachedGenericClassTypeSignature;
}

protected GenericSignature.FormalTypeParameter[] getFormalTypeParametersFromOuterClass() {
List typeParameters = new ArrayList();
ReferenceType outer = (ReferenceType) getOuterClass();
ReferenceTypeDelegate outerDelegate = outer.getDelegate();
AbstractReferenceTypeDelegate outerObjectType = (AbstractReferenceTypeDelegate) outerDelegate;
if (outerObjectType.isNested()) {
GenericSignature.FormalTypeParameter[] parentParams = outerObjectType.getFormalTypeParametersFromOuterClass();
for (int i = 0; i < parentParams.length; i++) {
typeParameters.add(parentParams[i]);
}
}
GenericSignature.ClassSignature outerSig = outerObjectType.getGenericClassTypeSignature();
if (outerSig != null) {
for (int i = 0; i < outerSig.formalTypeParameters.length; i++) {
typeParameters.add(outerSig.formalTypeParameters[i]);
}
}

GenericSignature.FormalTypeParameter[] ret = new GenericSignature.FormalTypeParameter[typeParameters.size()];
typeParameters.toArray(ret);
return ret;
}

public boolean copySourceContext() {
return true;
}

}

+ 444
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Advice.java Переглянути файл

@@ -0,0 +1,444 @@
/* *******************************************************************
* 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.util.Collections;
import java.util.List;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.patterns.AndPointcut;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.TypePattern;

public abstract class Advice extends ShadowMunger {

protected AjAttribute.AdviceAttribute attribute; // the pointcut field is
// ignored

protected AdviceKind kind; // alias of attribute.getKind()
protected Member signature;
protected boolean hasMatchedAtLeastOnce = false;

// not necessarily declaring aspect, this is a semantics change from 1.0
protected ResolvedType concreteAspect; // null until after concretize

protected List innerCflowEntries = Collections.EMPTY_LIST; // just for
// cflow*Entry
// kinds
protected int nFreeVars; // just for cflow*Entry kinds

protected TypePattern exceptionType; // just for Softener kind

// if we are parameterized, these type may be different to the advice
// signature types
protected UnresolvedType[] bindingParameterTypes;

protected List/* Lint.Kind */suppressedLintKinds = null; // based on
// annotations on
// this advice

public ISourceLocation lastReportedMonitorExitJoinpointLocation = null;

public static Advice makeCflowEntry(World world, Pointcut entry, boolean isBelow, Member stackField, int nFreeVars,
List innerCflowEntries, ResolvedType inAspect) {
Advice ret = world.createAdviceMunger(isBelow ? AdviceKind.CflowBelowEntry : AdviceKind.CflowEntry, entry, stackField, 0,
entry);
// 0);
ret.innerCflowEntries = innerCflowEntries;
ret.nFreeVars = nFreeVars;
ret.concreteAspect = inAspect;
return ret;
}

public static Advice makePerCflowEntry(World world, Pointcut entry, boolean isBelow, Member stackField, ResolvedType inAspect,
List innerCflowEntries) {
Advice ret = world.createAdviceMunger(isBelow ? AdviceKind.PerCflowBelowEntry : AdviceKind.PerCflowEntry, entry,
stackField, 0, entry);
ret.innerCflowEntries = innerCflowEntries;
ret.concreteAspect = inAspect;
return ret;
}

public static Advice makePerObjectEntry(World world, Pointcut entry, boolean isThis, ResolvedType inAspect) {
Advice ret = world.createAdviceMunger(isThis ? AdviceKind.PerThisEntry : AdviceKind.PerTargetEntry, entry, null, 0, entry);

ret.concreteAspect = inAspect;
return ret;
}

// PTWIMPL per type within entry advice is what initializes the aspect
// instance in the matched type
public static Advice makePerTypeWithinEntry(World world, Pointcut p, ResolvedType inAspect) {
Advice ret = world.createAdviceMunger(AdviceKind.PerTypeWithinEntry, p, null, 0, p);
ret.concreteAspect = inAspect;
return ret;
}

public static Advice makeSoftener(World world, Pointcut entry, TypePattern exceptionType, ResolvedType inAspect,
IHasSourceLocation loc) {
Advice ret = world.createAdviceMunger(AdviceKind.Softener, entry, null, 0, loc);

ret.exceptionType = exceptionType;
ret.concreteAspect = inAspect;
// System.out.println("made ret: " + ret + " with " + exceptionType);
return ret;
}

public Advice(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature) {
super(pointcut, attribute.getStart(), attribute.getEnd(), attribute.getSourceContext());
this.attribute = attribute;
kind = attribute.getKind(); // alias
this.signature = signature;
if (signature != null) {
bindingParameterTypes = signature.getParameterTypes();
} else {
bindingParameterTypes = new UnresolvedType[0];
}
}

public boolean match(Shadow shadow, World world) {
if (super.match(shadow, world)) {
if (shadow.getKind() == Shadow.ExceptionHandler) {
if (kind.isAfter() || kind == AdviceKind.Around) {
world.showMessage(IMessage.WARNING, WeaverMessages.format(WeaverMessages.ONLY_BEFORE_ON_HANDLER),
getSourceLocation(), shadow.getSourceLocation());
return false;
}
}
if (shadow.getKind() == Shadow.SynchronizationLock || shadow.getKind() == Shadow.SynchronizationUnlock) {
if (kind == AdviceKind.Around
// Don't work, see comments in SynchronizationTests
// && attribute.getProceedCallSignatures()!=null
// && attribute.getProceedCallSignatures().length!=0
) {
world.showMessage(IMessage.WARNING, WeaverMessages.format(WeaverMessages.NO_AROUND_ON_SYNCHRONIZATION),
getSourceLocation(), shadow.getSourceLocation());
return false;
}
}

if (hasExtraParameter() && kind == AdviceKind.AfterReturning) {
ResolvedType resolvedExtraParameterType = getExtraParameterType().resolve(world);
ResolvedType shadowReturnType = shadow.getReturnType().resolve(world);
boolean matches = (resolvedExtraParameterType.isConvertableFrom(shadowReturnType) && shadow.getKind()
.hasReturnValue());
if (matches && resolvedExtraParameterType.isParameterizedType()) {
maybeIssueUncheckedMatchWarning(resolvedExtraParameterType, shadowReturnType, shadow, world);
}
return matches;
} else if (hasExtraParameter() && kind == AdviceKind.AfterThrowing) { // pr119749
ResolvedType exceptionType = getExtraParameterType().resolve(world);
if (!exceptionType.isCheckedException())
return true;
UnresolvedType[] shadowThrows = shadow.getSignature().getExceptions(world);
boolean matches = false;
for (int i = 0; i < shadowThrows.length && !matches; i++) {
ResolvedType type = shadowThrows[i].resolve(world);
if (exceptionType.isAssignableFrom(type))
matches = true;
}
return matches;
} else if (kind == AdviceKind.PerTargetEntry) {
return shadow.hasTarget();
} else if (kind == AdviceKind.PerThisEntry) {
return shadow.hasThis();
} else if (kind == AdviceKind.Around) {
if (shadow.getKind() == Shadow.PreInitialization) {
world.showMessage(IMessage.WARNING, WeaverMessages.format(WeaverMessages.AROUND_ON_PREINIT),
getSourceLocation(), shadow.getSourceLocation());
return false;
} else if (shadow.getKind() == Shadow.Initialization) {
world.showMessage(IMessage.WARNING, WeaverMessages.format(WeaverMessages.AROUND_ON_INIT), getSourceLocation(),
shadow.getSourceLocation());
return false;
} else if (shadow.getKind() == Shadow.StaticInitialization
&& shadow.getEnclosingType().resolve(world).isInterface()) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.AROUND_ON_INTERFACE_STATICINIT, shadow
.getEnclosingType().getName()), getSourceLocation(), shadow.getSourceLocation());
return false;
} else {
// System.err.println(getSignature().getReturnType() +
// " from " + shadow.getReturnType());
if (getSignature().getReturnType() == ResolvedType.VOID) {
if (shadow.getReturnType() != ResolvedType.VOID) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.NON_VOID_RETURN, shadow),
getSourceLocation(), shadow.getSourceLocation());
return false;
}
} else if (getSignature().getReturnType().equals(UnresolvedType.OBJECT)) {
return true;
} else {
ResolvedType shadowReturnType = shadow.getReturnType().resolve(world);
ResolvedType adviceReturnType = getSignature().getGenericReturnType().resolve(world);

if (shadowReturnType.isParameterizedType() && adviceReturnType.isRawType()) { // Set
// <
// Integer
// >
// and
// Set
ResolvedType shadowReturnGenericType = shadowReturnType.getGenericType(); // Set
ResolvedType adviceReturnGenericType = adviceReturnType.getGenericType(); // Set
if (shadowReturnGenericType.isAssignableFrom(adviceReturnGenericType)
&& world.getLint().uncheckedAdviceConversion.isEnabled()) {
world.getLint().uncheckedAdviceConversion.signal(new String[] { shadow.toString(),
shadowReturnType.getName(), adviceReturnType.getName() }, shadow.getSourceLocation(),
new ISourceLocation[] { getSourceLocation() });
}
} else if (!shadowReturnType.isAssignableFrom(adviceReturnType)) {
// System.err.println(this + ", " + sourceContext +
// ", " + start);
world.showMessage(IMessage.ERROR, WeaverMessages
.format(WeaverMessages.INCOMPATIBLE_RETURN_TYPE, shadow), getSourceLocation(), shadow
.getSourceLocation());
return false;
}
}
}
}
return true;
} else {
return false;
}
}

/**
* In after returning advice if we are binding the extra parameter to a parameterized type we may not be able to do a type-safe
* conversion.
*
* @param resolvedExtraParameterType the type in the after returning declaration
* @param shadowReturnType the type at the shadow
* @param world
*/
private void maybeIssueUncheckedMatchWarning(ResolvedType afterReturningType, ResolvedType shadowReturnType, Shadow shadow,
World world) {
boolean inDoubt = !afterReturningType.isAssignableFrom(shadowReturnType);
if (inDoubt && world.getLint().uncheckedArgument.isEnabled()) {
String uncheckedMatchWith = afterReturningType.getSimpleBaseName();
if (shadowReturnType.isParameterizedType() && (shadowReturnType.getRawType() == afterReturningType.getRawType())) {
uncheckedMatchWith = shadowReturnType.getSimpleName();
}
if (!Utils.isSuppressing(getSignature().getAnnotations(), "uncheckedArgument")) {
world.getLint().uncheckedArgument.signal(new String[] { afterReturningType.getSimpleName(), uncheckedMatchWith,
afterReturningType.getSimpleBaseName(), shadow.toResolvedString(world) }, getSourceLocation(),
new ISourceLocation[] { shadow.getSourceLocation() });
}
}
}

// ----

public AdviceKind getKind() {
return kind;
}

public Member getSignature() {
return signature;
}

public boolean hasExtraParameter() {
return (getExtraParameterFlags() & ExtraArgument) != 0;
}

protected int getExtraParameterFlags() {
return attribute.getExtraParameterFlags();
}

protected int getExtraParameterCount() {
return countOnes(getExtraParameterFlags() & ParameterMask);
}

public UnresolvedType[] getBindingParameterTypes() {
return bindingParameterTypes;
}

public void setBindingParameterTypes(UnresolvedType[] types) {
bindingParameterTypes = types;
}

public static int countOnes(int bits) {
int ret = 0;
while (bits != 0) {
if ((bits & 1) != 0)
ret += 1;
bits = bits >> 1;
}
return ret;
}

public int getBaseParameterCount() {
return getSignature().getParameterTypes().length - getExtraParameterCount();
}

public String[] getBaseParameterNames(World world) {
String[] allNames = getSignature().getParameterNames(world);
int extras = getExtraParameterCount();
if (extras == 0)
return allNames;
String[] result = new String[getBaseParameterCount()];
for (int i = 0; i < result.length; i++) {
result[i] = allNames[i];
}
return result;
}

public UnresolvedType getExtraParameterType() {
if (!hasExtraParameter())
return ResolvedType.MISSING;
if (signature instanceof ResolvedMember) {
if (getConcreteAspect().isAnnotationStyleAspect()) {
// bug 122742 - if we're an annotation style aspect then one
// of the extra parameters could be JoinPoint which we want
// to ignore
int baseParmCnt = getBaseParameterCount();
UnresolvedType[] genericParameterTypes = ((ResolvedMember) signature).getGenericParameterTypes();
while ((baseParmCnt + 1 < genericParameterTypes.length)
&& (genericParameterTypes[baseParmCnt].equals(AjcMemberMaker.TYPEX_JOINPOINT)
|| genericParameterTypes[baseParmCnt].equals(AjcMemberMaker.TYPEX_STATICJOINPOINT) || genericParameterTypes[baseParmCnt]
.equals(AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT))) {
baseParmCnt++;
}
return ((ResolvedMember) signature).getGenericParameterTypes()[baseParmCnt];
}
return ((ResolvedMember) signature).getGenericParameterTypes()[getBaseParameterCount()];
} else {
return signature.getParameterTypes()[getBaseParameterCount()];
}
}

public UnresolvedType getDeclaringAspect() {
return getOriginalSignature().getDeclaringType();
}

protected Member getOriginalSignature() {
return signature;
}

protected String extraParametersToString() {
if (getExtraParameterFlags() == 0) {
return "";
} else {
return "(extraFlags: " + getExtraParameterFlags() + ")";
}
}

public Pointcut getPointcut() {
return pointcut;
}

// ----

/**
* @param fromType is guaranteed to be a non-abstract aspect
* @param clause has been concretized at a higher level
*/
public ShadowMunger concretize(ResolvedType fromType, World world, PerClause clause) {
// assert !fromType.isAbstract();
Pointcut p = pointcut.concretize(fromType, getDeclaringType(), signature.getArity(), this);
if (clause != null) {
Pointcut oldP = p;
p = new AndPointcut(clause, p);
p.copyLocationFrom(oldP);
p.state = Pointcut.CONCRETE;

// FIXME ? ATAJ copy unbound bindings to ignore
p.m_ignoreUnboundBindingForNames = oldP.m_ignoreUnboundBindingForNames;
}

Advice munger = world.getWeavingSupport().createAdviceMunger(attribute, p, signature);
munger.concreteAspect = fromType;
munger.bindingParameterTypes = bindingParameterTypes;
munger.setDeclaringType(getDeclaringType());
// System.err.println("concretizing here " + p + " with clause " +
// clause);
return munger;
}

// ---- from object

public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("(").append(getKind()).append(extraParametersToString());
sb.append(": ").append(pointcut).append("->").append(signature).append(")");
return sb.toString();
// return "("
// + getKind()
// + extraParametersToString()
// + ": "
// + pointcut
// + "->"
// + signature
// + ")";
}

// XXX this perhaps ought to take account of the other fields in advice ...
public boolean equals(Object other) {
if (!(other instanceof Advice))
return false;
Advice o = (Advice) other;
return o.kind.equals(kind) && ((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut))
&& ((o.signature == null) ? (signature == null) : o.signature.equals(signature));
// && (AsmManager.getDefault().getHandleProvider().dependsOnLocation() ? ((o.getSourceLocation() == null) ?
// (getSourceLocation() == null)
// : o.getSourceLocation().equals(getSourceLocation()))
// : true) // pr134471 - remove when handles are improved
// // to be independent of location
// ;

}

private volatile int hashCode = 0;

public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37 * result + kind.hashCode();
result = 37 * result + ((pointcut == null) ? 0 : pointcut.hashCode());
result = 37 * result + ((signature == null) ? 0 : signature.hashCode());
hashCode = result;
}
return hashCode;
}

// ---- fields

public static final int ExtraArgument = 1;
public static final int ThisJoinPoint = 2;
public static final int ThisJoinPointStaticPart = 4;
public static final int ThisEnclosingJoinPointStaticPart = 8;
public static final int ParameterMask = 0xf;

public static final int CanInline = 0x40;

// for testing only
public void setLexicalPosition(int lexicalPosition) {
start = lexicalPosition;
}

public ResolvedType getConcreteAspect() {
return concreteAspect;
}

public boolean hasMatchedSomething() {
return hasMatchedAtLeastOnce;
}

public void setHasMatchedSomething(boolean hasMatchedSomething) {
hasMatchedAtLeastOnce = hasMatchedSomething;
}

public abstract boolean hasDynamicTests();

}

+ 117
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AdviceKind.java Переглянути файл

@@ -0,0 +1,117 @@
/* *******************************************************************
* 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.IOException;

import org.aspectj.util.TypeSafeEnum;

/**
* 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;
this.isAfter = isAfter;
this.isCflow = isCflow;
}
public static AdviceKind read(VersionedDataInputStream s) throws IOException {
int key = s.readByte();
switch(key) {
case 1: return Before;
case 2: return After;
case 3: return AfterThrowing;
case 4: return AfterReturning;
case 5: return Around;
case 6: return CflowEntry;
case 7: return CflowBelowEntry;

case 8: return InterInitializer;
case 9: return PerCflowEntry;
case 10: return PerCflowBelowEntry;
case 11: return PerThisEntry;
case 12: return PerTargetEntry;

case 13: return Softener;
case 14: return PerTypeWithinEntry;
}
throw new RuntimeException("unimplemented kind: " + key);
}
public static final AdviceKind Before = new AdviceKind("before", 1, 0, false, false);
public static final AdviceKind After = new AdviceKind("after", 2, 0, true, false);
public static final AdviceKind AfterThrowing = new AdviceKind("afterThrowing", 3, 0, true, false);
public static final AdviceKind AfterReturning = new AdviceKind("afterReturning", 4, 0, true, false);
public static final AdviceKind Around = new AdviceKind("around", 5, 0, false, false);
// these kinds can't be declared, but are used by the weaver
public static final AdviceKind CflowEntry = new AdviceKind("cflowEntry", 6, 1, false, true);
public static final AdviceKind CflowBelowEntry = new AdviceKind("cflowBelowEntry", 7, -1, false, true); //XXX resolve precednece with the below
public static final AdviceKind InterInitializer = new AdviceKind("interInitializer", 8, -2, false, false);

public static final AdviceKind PerCflowEntry = new AdviceKind("perCflowEntry", 9, 1, false, true);
public static final AdviceKind PerCflowBelowEntry = new AdviceKind("perCflowBelowEntry", 10, -1, false, true);

public static final AdviceKind PerThisEntry = new AdviceKind("perThisEntry", 11, 1, false, false);
public static final AdviceKind PerTargetEntry = new AdviceKind("perTargetEntry", 12, 1, false, false);

public static final AdviceKind Softener = new AdviceKind("softener", 13, 1, false, false);
// PTWIMPL Advice representing when aspect should be initialized
public static final AdviceKind PerTypeWithinEntry = new AdviceKind("perTypeWithinEntry",14,1,false,false);

public static AdviceKind stringToKind(String s) {
if (s.equals(Before.getName())) return Before;
if (s.equals(After.getName())) return After;
if (s.equals(AfterThrowing.getName())) return AfterThrowing;
if (s.equals(AfterReturning.getName())) return AfterReturning;
if (s.equals(Around.getName())) return Around;
throw new IllegalArgumentException("unknown kind: " + "\"" + s + "\"");
}

public boolean isAfter() {
return this.isAfter;
}
public boolean isCflow() {
return this.isCflow;
}

public int getPrecedence() {
return precedence;
}

public boolean isPerEntry() {
return
this == PerCflowEntry || this == PerCflowBelowEntry ||
this == PerThisEntry || this == PerTargetEntry ||
this == PerTypeWithinEntry; // PTWIMPL Allow for PTW case
}
public boolean isPerObjectEntry() {
return this == PerThisEntry || this == PerTargetEntry;
}

}

+ 699
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AjAttribute.java Переглянути файл

@@ -0,0 +1,699 @@
/* *******************************************************************
* 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;

import org.aspectj.bridge.MessageUtil;
import org.aspectj.bridge.Version;
import org.aspectj.util.FileUtil;
import org.aspectj.weaver.patterns.Declare;
import org.aspectj.weaver.patterns.IScope;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;

/**
* These attributes are written to and read from .class files (see the JVM
* spec).
*
* <p>
* Each member or type can have a number of AjAttributes. Each such attribute is
* in 1-1 correspondence with an Unknown bcel attribute. Creating one of these
* does NOTHING to the underlying thing, so if you really want to add an
* attribute to a particular thing, well, you'd better actually do that.
*
* @author Erik Hilsdale
* @author Jim Hugunin
*/
public abstract class AjAttribute {

public static final String AttributePrefix = "org.aspectj.weaver";

protected abstract void write(DataOutputStream s) throws IOException;

public abstract String getNameString();

public char[] getNameChars() {
return getNameString().toCharArray();
}

/**
* Just writes the contents
*/
public byte[] getBytes() {
try {
ByteArrayOutputStream b0 = new ByteArrayOutputStream();
DataOutputStream s0 = new DataOutputStream(b0);
write(s0);
return b0.toByteArray();
} catch (IOException e) {
// shouldn't happen with ByteArrayOutputStreams
throw new RuntimeException("sanity check");
}
}

/**
* Writes the full attribute, i.e. name_index, length, and contents
*/
public byte[] getAllBytes(short nameIndex) {
try {
byte[] bytes = getBytes();

ByteArrayOutputStream b0 = new ByteArrayOutputStream();
DataOutputStream s0 = new DataOutputStream(b0);

s0.writeShort(nameIndex);
s0.writeInt(bytes.length);
s0.write(bytes);
return b0.toByteArray();
} catch (IOException e) {
// shouldn't happen with ByteArrayOutputStreams
throw new RuntimeException("sanity check");
}
}

public static AjAttribute read(AjAttribute.WeaverVersionInfo v, String name, byte[] bytes, ISourceContext context, World w) {
try {
if (bytes == null)
bytes = new byte[0];
VersionedDataInputStream s = new VersionedDataInputStream(new ByteArrayInputStream(bytes));
s.setVersion(v);
if (name.equals(Aspect.AttributeName)) {
return new Aspect(PerClause.readPerClause(s, context));
} else if (name.equals(MethodDeclarationLineNumberAttribute.AttributeName)) {
return MethodDeclarationLineNumberAttribute.read(s);
} else if (name.equals(WeaverState.AttributeName)) {
return new WeaverState(WeaverStateInfo.read(s, context));
} else if (name.equals(WeaverVersionInfo.AttributeName)) {
return WeaverVersionInfo.read(s);
} else if (name.equals(AdviceAttribute.AttributeName)) {
AdviceAttribute aa = AdviceAttribute.read(s, context);
aa.getPointcut().check(context, w);
return aa;
} else if (name.equals(PointcutDeclarationAttribute.AttributeName)) {
PointcutDeclarationAttribute pda = new PointcutDeclarationAttribute(ResolvedPointcutDefinition.read(s, context));
pda.pointcutDef.getPointcut().check(context, w);
return pda;
} else if (name.equals(TypeMunger.AttributeName)) {
return new TypeMunger(ResolvedTypeMunger.read(s, context));
} else if (name.equals(AjSynthetic.AttributeName)) {
return new AjSynthetic();
} else if (name.equals(DeclareAttribute.AttributeName)) {
return new DeclareAttribute(Declare.read(s, context));
} else if (name.equals(PrivilegedAttribute.AttributeName)) {
return PrivilegedAttribute.read(s, context);
} else if (name.equals(SourceContextAttribute.AttributeName)) {
return SourceContextAttribute.read(s);
} else if (name.equals(EffectiveSignatureAttribute.AttributeName)) {
return EffectiveSignatureAttribute.read(s, context);
} else {
// We have to tell the user about this...
if (w == null || w.getMessageHandler() == null)
throw new BCException("unknown attribute" + name);
w.getMessageHandler().handleMessage(MessageUtil.warn("unknown attribute encountered " + name));
return null;
}
} catch (BCException e) {
throw new BCException("malformed " + name + " attribute (length:" + bytes.length + ")" + e);
} catch (IOException e) {
throw new BCException("malformed " + name + " attribute (length:" + bytes.length + ")" + e);
}
}

// ----

/**
* Synthetic members should have NO advice put on them or on their contents.
* This attribute is currently unused as we consider all members starting
* with NameMangler.PREFIX to automatically be synthetic. As we use this we
* might find that we want multiple kinds of synthetic. In particular, if we
* want to treat the call to a synthetic getter (say, of an introduced
* field) as a field reference itself, then a method might want a particular
* kind of AjSynthetic attribute that also includes a signature of what it
* stands for.
*/
public static class AjSynthetic extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.AjSynthetic";

public String getNameString() {
return AttributeName;
}

// private ResolvedTypeMunger munger;
public AjSynthetic() {
}

public void write(DataOutputStream s) throws IOException {
}
}

public static class TypeMunger extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.TypeMunger";

public String getNameString() {
return AttributeName;
}

private final ResolvedTypeMunger munger;

public TypeMunger(ResolvedTypeMunger munger) {
this.munger = munger;
}

public void write(DataOutputStream s) throws IOException {
munger.write(s);
}

public ConcreteTypeMunger reify(World world, ResolvedType aspectType) {
return world.getWeavingSupport().concreteTypeMunger(munger, aspectType);
}
}

public static class WeaverState extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.WeaverState";

public String getNameString() {
return AttributeName;
}

private final WeaverStateInfo kind;

public WeaverState(WeaverStateInfo kind) {
this.kind = kind;
}

public void write(DataOutputStream s) throws IOException {
kind.write(s);
}

public WeaverStateInfo reify() {
return kind;
}
}

public static class WeaverVersionInfo extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.WeaverVersion";

// If you change the format of an AspectJ class file, you have two
// options:
// - changing the minor version means you have not added anything that
// prevents
// previous versions of the weaver from operating (e.g.
// MethodDeclarationLineNumber attribute)
// - changing the major version means you have added something that
// prevents previous
// versions of the weaver from operating correctly.
//
// The user will get a warning for any org.aspectj.weaver attributes the
// weaver does
// not recognize.

// When we don't know ... (i.e. pre 1.2.1)
public final static short WEAVER_VERSION_MAJOR_UNKNOWN = 0;
public final static short WEAVER_VERSION_MINOR_UNKNOWN = 0;

// These are the weaver major/minor numbers for AspectJ 1.2.1
public final static short WEAVER_VERSION_MAJOR_AJ121 = 1;
public final static short WEAVER_VERSION_MINOR_AJ121 = 0;

// These are the weaver major/minor numbers for AspectJ 1.5.0
public final static short WEAVER_VERSION_MAJOR_AJ150M4 = 3;
public final static short WEAVER_VERSION_MAJOR_AJ150 = 2;
public final static short WEAVER_VERSION_MINOR_AJ150 = 0;

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

// These are the weaver major/minor numbers for AspectJ 1.6.1
public final static short WEAVER_VERSION_MAJOR_AJ161 = 6; // annotation
// value
// binding
public final static short WEAVER_VERSION_MINOR_AJ161 = 0;

// These are the weaver major/minor versions for *this* weaver
private final static short CURRENT_VERSION_MAJOR = WEAVER_VERSION_MAJOR_AJ161;
private final static short CURRENT_VERSION_MINOR = WEAVER_VERSION_MINOR_AJ161;

public final static WeaverVersionInfo UNKNOWN = new WeaverVersionInfo(WEAVER_VERSION_MAJOR_UNKNOWN,
WEAVER_VERSION_MINOR_UNKNOWN);
public final static WeaverVersionInfo CURRENT = new WeaverVersionInfo(CURRENT_VERSION_MAJOR, CURRENT_VERSION_MINOR);

// These are the versions read in from a particular class file.
private final short major_version;
private final short minor_version;

private long buildstamp = Version.NOTIME;

public String getNameString() {
return AttributeName;
}

// Default ctor uses the current version numbers
public WeaverVersionInfo() {
major_version = CURRENT_VERSION_MAJOR;
minor_version = CURRENT_VERSION_MINOR;
}

public WeaverVersionInfo(short major, short minor) {
major_version = major;
minor_version = minor;
}

public void write(DataOutputStream s) throws IOException {
s.writeShort(CURRENT_VERSION_MAJOR);
s.writeShort(CURRENT_VERSION_MINOR);
s.writeLong(Version.getTime()); // build used to construct the
// class...
}

public static WeaverVersionInfo read(VersionedDataInputStream s) throws IOException {
short major = s.readShort();
short minor = s.readShort();
WeaverVersionInfo wvi = new WeaverVersionInfo(major, minor);
if (s.getMajorVersion() >= WEAVER_VERSION_MAJOR_AJ150M4) {
long stamp = 0;
try {
stamp = s.readLong();
wvi.setBuildstamp(stamp);
} catch (EOFException eof) {
// didnt find that build stamp - its not the end of the
// world
}
}
return wvi;
}

public short getMajorVersion() {
return major_version;
}

public short getMinorVersion() {
return minor_version;
}

public static short getCurrentWeaverMajorVersion() {
return CURRENT_VERSION_MAJOR;
}

public static short getCurrentWeaverMinorVersion() {
return CURRENT_VERSION_MINOR;
}

public void setBuildstamp(long stamp) {
buildstamp = stamp;
}

public long getBuildstamp() {
return buildstamp;
}

public String toString() {
return major_version + "." + minor_version;
}

public static String toCurrentVersionString() {
return CURRENT_VERSION_MAJOR + "." + CURRENT_VERSION_MINOR;
}

}

public static class SourceContextAttribute extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.SourceContext";

public String getNameString() {
return AttributeName;
}

private final String sourceFileName;
private final int[] lineBreaks;

public SourceContextAttribute(String sourceFileName, int[] lineBreaks) {
this.sourceFileName = sourceFileName;
this.lineBreaks = lineBreaks;
}

public void write(DataOutputStream s) throws IOException {
s.writeUTF(sourceFileName);
FileUtil.writeIntArray(lineBreaks, s);
}

public static SourceContextAttribute read(VersionedDataInputStream s) throws IOException {
return new SourceContextAttribute(s.readUTF(), FileUtil.readIntArray(s));
}

public int[] getLineBreaks() {
return lineBreaks;
}

public String getSourceFileName() {
return sourceFileName;
}
}

public static class MethodDeclarationLineNumberAttribute extends AjAttribute {

public static final String AttributeName = "org.aspectj.weaver.MethodDeclarationLineNumber";

public String getNameString() {
return AttributeName;
}

private final int lineNumber;

// AV: added in 1.5 M3 thus handling cases where we don't have that
// information
private final int offset;

public MethodDeclarationLineNumberAttribute(int line, int offset) {
lineNumber = line;
this.offset = offset;
}

public int getLineNumber() {
return lineNumber;
}

public int getOffset() {
return offset;
}

public void write(DataOutputStream s) throws IOException {
s.writeInt(lineNumber);
s.writeInt(offset);
}

public static MethodDeclarationLineNumberAttribute read(VersionedDataInputStream s) throws IOException {
int line = s.readInt();
int offset = 0;
if (s.available() > 0) {
offset = s.readInt();
}
return new MethodDeclarationLineNumberAttribute(line, offset);
}

public String toString() {
return AttributeName + ": " + lineNumber + ":" + offset;
}
}

public static class PointcutDeclarationAttribute extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.PointcutDeclaration";

public String getNameString() {
return AttributeName;
}

private final ResolvedPointcutDefinition pointcutDef;

public PointcutDeclarationAttribute(ResolvedPointcutDefinition pointcutDef) {
this.pointcutDef = pointcutDef;
}

public void write(DataOutputStream s) throws IOException {
pointcutDef.write(s);
}

public ResolvedPointcutDefinition reify() {
return pointcutDef;
}
}

public static class DeclareAttribute extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.Declare";

public String getNameString() {
return AttributeName;
}

private final Declare declare;

public DeclareAttribute(Declare declare) {
this.declare = declare;
}

public void write(DataOutputStream s) throws IOException {
declare.write(s);
}

public Declare getDeclare() {
return declare;
}
}

public static class AdviceAttribute extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.Advice";

public String getNameString() {
return AttributeName;
}

private final AdviceKind kind;
private final Pointcut pointcut;
private final int extraParameterFlags;
private final int start;
private final int end;
private final ISourceContext sourceContext;

// these are only used by around advice
private boolean proceedInInners;
private ResolvedMember[] proceedCallSignatures; // size == # of proceed
// calls in body
private boolean[] formalsUnchangedToProceed; // size == formals.size
private UnresolvedType[] declaredExceptions;

/**
* @param lexicalPosition must be greater than the lexicalPosition of
* any advice declared before this one in an aspect,
* otherwise, it can be any value.
*/
public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags, int start, int end,
ISourceContext sourceContext) {
this.kind = kind;
this.pointcut = pointcut;
extraParameterFlags = extraArgumentFlags;
this.start = start;
this.end = end;
this.sourceContext = sourceContext;

// XXX put this back when testing works better (or fails better)
// if (kind == AdviceKind.Around) throw new
// IllegalArgumentException("not for around");
}

public AdviceAttribute(AdviceKind kind, Pointcut pointcut, int extraArgumentFlags, int start, int end,
ISourceContext sourceContext, boolean proceedInInners, ResolvedMember[] proceedCallSignatures,
boolean[] formalsUnchangedToProceed, UnresolvedType[] declaredExceptions) {
this.kind = kind;
this.pointcut = pointcut;
extraParameterFlags = extraArgumentFlags;
this.start = start;
this.end = end;
this.sourceContext = sourceContext;

if (kind != AdviceKind.Around)
throw new IllegalArgumentException("only for around");

this.proceedInInners = proceedInInners;
this.proceedCallSignatures = proceedCallSignatures;
this.formalsUnchangedToProceed = formalsUnchangedToProceed;
this.declaredExceptions = declaredExceptions;
}

public static AdviceAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException {
AdviceKind kind = AdviceKind.read(s);
if (kind == AdviceKind.Around) {
return new AdviceAttribute(kind, Pointcut.read(s, context), s.readByte(), s.readInt(), s.readInt(), context, s
.readBoolean(), ResolvedMemberImpl.readResolvedMemberArray(s, context), FileUtil.readBooleanArray(s),
UnresolvedType.readArray(s));
} else {
return new AdviceAttribute(kind, Pointcut.read(s, context), s.readByte(), s.readInt(), s.readInt(), context);
}
}

public void write(DataOutputStream s) throws IOException {
kind.write(s);
pointcut.write(s);
s.writeByte(extraParameterFlags);
s.writeInt(start);
s.writeInt(end);

if (kind == AdviceKind.Around) {
s.writeBoolean(proceedInInners);
ResolvedMemberImpl.writeArray(proceedCallSignatures, s);
FileUtil.writeBooleanArray(formalsUnchangedToProceed, s);
UnresolvedType.writeArray(declaredExceptions, s);
}
}

public Advice reify(Member signature, World world) {
return world.getWeavingSupport().createAdviceMunger(this, pointcut, signature);
}

public String toString() {
return "AdviceAttribute(" + kind + ", " + pointcut + ", " + extraParameterFlags + ", " + start + ")";
}

public int getExtraParameterFlags() {
return extraParameterFlags;
}

public AdviceKind getKind() {
return kind;
}

public Pointcut getPointcut() {
return pointcut;
}

public UnresolvedType[] getDeclaredExceptions() {
return declaredExceptions;
}

public boolean[] getFormalsUnchangedToProceed() {
return formalsUnchangedToProceed;
}

public ResolvedMember[] getProceedCallSignatures() {
return proceedCallSignatures;
}

public boolean isProceedInInners() {
return proceedInInners;
}

public int getEnd() {
return end;
}

public ISourceContext getSourceContext() {
return sourceContext;
}

public int getStart() {
return start;
}

}

public static class Aspect extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.Aspect";

public String getNameString() {
return AttributeName;
}

private final PerClause perClause;
private IScope resolutionScope;

public Aspect(PerClause perClause) {
this.perClause = perClause;
}

public PerClause reify(ResolvedType inAspect) {
// XXXperClause.concretize(inAspect);
return perClause;
}

public PerClause reifyFromAtAspectJ(ResolvedType inAspect) {
perClause.resolve(resolutionScope);
return perClause;
}

public void write(DataOutputStream s) throws IOException {
perClause.write(s);
}

public void setResolutionScope(IScope binding) {
resolutionScope = binding;
}
}

public static class PrivilegedAttribute extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.Privileged";

public String getNameString() {
return AttributeName;
}

private final ResolvedMember[] accessedMembers;

public PrivilegedAttribute(ResolvedMember[] accessedMembers) {
this.accessedMembers = accessedMembers;
}

public void write(DataOutputStream s) throws IOException {
ResolvedMemberImpl.writeArray(accessedMembers, s);
}

public ResolvedMember[] getAccessedMembers() {
return accessedMembers;
}

public static PrivilegedAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException {
return new PrivilegedAttribute(ResolvedMemberImpl.readResolvedMemberArray(s, context));
}
}

public static class EffectiveSignatureAttribute extends AjAttribute {
public static final String AttributeName = "org.aspectj.weaver.EffectiveSignature";

public String getNameString() {
return AttributeName;
}

private final ResolvedMember effectiveSignature;
private final Shadow.Kind shadowKind;
private final boolean weaveBody;

public EffectiveSignatureAttribute(ResolvedMember effectiveSignature, Shadow.Kind shadowKind, boolean weaveBody) {
this.effectiveSignature = effectiveSignature;
this.shadowKind = shadowKind;
this.weaveBody = weaveBody;
}

public void write(DataOutputStream s) throws IOException {
effectiveSignature.write(s);
shadowKind.write(s);
s.writeBoolean(weaveBody);
}

public static EffectiveSignatureAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException {
return new EffectiveSignatureAttribute(ResolvedMemberImpl.readResolvedMember(s, context), Shadow.Kind.read(s), s
.readBoolean());
}

public ResolvedMember getEffectiveSignature() {
return effectiveSignature;
}

public String toString() {
return "EffectiveSignatureAttribute(" + effectiveSignature + ", " + shadowKind + ")";
}

public Shadow.Kind getShadowKind() {
return shadowKind;
}

public boolean isWeaveBody() {
return weaveBody;
}

}

}

+ 621
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AjcMemberMaker.java Переглянути файл

@@ -0,0 +1,621 @@
/* *******************************************************************
* 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.lang.reflect.Modifier;

//import org.aspectj.weaver.ResolvedType.Name;

public class AjcMemberMaker {
private static final int PUBLIC_STATIC_FINAL = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;

private static final int PRIVATE_STATIC = Modifier.PRIVATE | Modifier.STATIC;

private static final int PUBLIC_STATIC = Modifier.PUBLIC | Modifier.STATIC;

private static final int BRIDGE = 0x0040;

private static final int VISIBILITY = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;

public static final UnresolvedType CFLOW_STACK_TYPE = UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE);
public static final UnresolvedType AROUND_CLOSURE_TYPE = UnresolvedType
.forSignature("Lorg/aspectj/runtime/internal/AroundClosure;");

public static final UnresolvedType CONVERSIONS_TYPE = UnresolvedType.forSignature("Lorg/aspectj/runtime/internal/Conversions;");

public static final UnresolvedType NO_ASPECT_BOUND_EXCEPTION = UnresolvedType
.forSignature("Lorg/aspectj/lang/NoAspectBoundException;");

public static ResolvedMember ajcPreClinitMethod(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.METHOD, declaringType, PRIVATE_STATIC, NameMangler.AJC_PRE_CLINIT_NAME, "()V");
}

public static ResolvedMember ajcPostClinitMethod(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.METHOD, declaringType, PRIVATE_STATIC, NameMangler.AJC_POST_CLINIT_NAME, "()V");
}

public static Member noAspectBoundExceptionInit() {
return new ResolvedMemberImpl(Member.METHOD, NO_ASPECT_BOUND_EXCEPTION, Modifier.PUBLIC, "<init>", "()V");
}

public static Member noAspectBoundExceptionInit2() {
return new ResolvedMemberImpl(Member.METHOD, NO_ASPECT_BOUND_EXCEPTION, Modifier.PUBLIC, "<init>",
"(Ljava/lang/String;Ljava/lang/Throwable;)V");
}

public static Member noAspectBoundExceptionInitWithCause() {
return new ResolvedMemberImpl(Member.METHOD, NO_ASPECT_BOUND_EXCEPTION, Modifier.PUBLIC, "<init>",
"(Ljava/lang/String;Ljava/lang/Throwable;)V");
}

public static ResolvedMember perCflowPush(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, NameMangler.PERCFLOW_PUSH_METHOD, "()V");
}

public static ResolvedMember perCflowField(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.FIELD, declaringType, PUBLIC_STATIC_FINAL, NameMangler.PERCFLOW_FIELD_NAME,
CFLOW_STACK_TYPE.getSignature());
}

public static ResolvedMember perSingletonField(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.FIELD, declaringType, PUBLIC_STATIC_FINAL, NameMangler.PERSINGLETON_FIELD_NAME,
declaringType.getSignature());
}

public static ResolvedMember initFailureCauseField(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.FIELD, declaringType, PRIVATE_STATIC, NameMangler.INITFAILURECAUSE_FIELD_NAME,
UnresolvedType.THROWABLE.getSignature());
}

public static ResolvedMember perObjectField(UnresolvedType declaringType, ResolvedType aspectType) {
int modifiers = Modifier.PRIVATE;
if (!UnresolvedType.SERIALIZABLE.resolve(aspectType.getWorld()).isAssignableFrom(aspectType)) {
modifiers |= Modifier.TRANSIENT;
}
return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, aspectType, NameMangler
.perObjectInterfaceField(aspectType), UnresolvedType.NONE);
}

// PTWIMPL ResolvedMember for aspect instance field, declared in matched type
public static ResolvedMember perTypeWithinField(UnresolvedType declaringType, ResolvedType aspectType) {
int modifiers = Modifier.PRIVATE | Modifier.STATIC;
if (!isSerializableAspect(aspectType)) {
modifiers |= Modifier.TRANSIENT;
}
return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, aspectType, NameMangler
.perTypeWithinFieldForTarget(aspectType), UnresolvedType.NONE);
}

// PTWIMPL ResolvedMember for type instance field, declared in aspect
// (holds typename for which aspect instance exists)
public static ResolvedMember perTypeWithinWithinTypeField(UnresolvedType declaringType, ResolvedType aspectType) {
int modifiers = Modifier.PRIVATE;
if (!isSerializableAspect(aspectType)) {
modifiers |= Modifier.TRANSIENT;
}
return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, UnresolvedType.JAVA_LANG_STRING,
NameMangler.PERTYPEWITHIN_WITHINTYPEFIELD, UnresolvedType.NONE);
}

private static boolean isSerializableAspect(ResolvedType aspectType) {
return UnresolvedType.SERIALIZABLE.resolve(aspectType.getWorld()).isAssignableFrom(aspectType);
}

public static ResolvedMember perObjectBind(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, NameMangler.PEROBJECT_BIND_METHOD,
"(Ljava/lang/Object;)V");
}

// PTWIMPL ResolvedMember for getInstance() method, declared in aspect
public static ResolvedMember perTypeWithinGetInstance(UnresolvedType declaringType) {
// private static a.X ajc$getInstance(java.lang.Class)
ResolvedMemberImpl rm = new ResolvedMemberImpl(Member.METHOD, declaringType, PRIVATE_STATIC, declaringType, // return value
NameMangler.PERTYPEWITHIN_GETINSTANCE_METHOD, new UnresolvedType[] { UnresolvedType.JAVA_LANG_CLASS });
return rm;
}

// PTWIMPL ResolvedMember for getWithinTypeName() method
public static ResolvedMember perTypeWithinGetWithinTypeNameMethod(UnresolvedType declaringType, boolean inJava5Mode) {
// public String getWithinTypeName()
ResolvedMemberImpl rm = new ResolvedMemberImpl(Member.METHOD, declaringType, Modifier.PUBLIC,
UnresolvedType.JAVA_LANG_STRING, // return value
NameMangler.PERTYPEWITHIN_GETWITHINTYPENAME_METHOD, UnresolvedType.NONE);
return rm;
}

public static ResolvedMember perTypeWithinCreateAspectInstance(UnresolvedType declaringType) {
// public static a.X ajc$createAspectInstance(java.lang.String)
ResolvedMemberImpl rm = new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, declaringType, // return value
NameMangler.PERTYPEWITHIN_CREATEASPECTINSTANCE_METHOD, new UnresolvedType[] { UnresolvedType
.forSignature("Ljava/lang/String;") }, new UnresolvedType[] {});
return rm;
}

public static UnresolvedType perObjectInterfaceType(UnresolvedType aspectType) {
return UnresolvedType.forName(aspectType.getName() + "$ajcMightHaveAspect");
}

public static ResolvedMember perObjectInterfaceGet(UnresolvedType aspectType) {
return new ResolvedMemberImpl(Member.METHOD, perObjectInterfaceType(aspectType), Modifier.PUBLIC | Modifier.ABSTRACT,
NameMangler.perObjectInterfaceGet(aspectType), "()" + aspectType.getSignature());
}

public static ResolvedMember perObjectInterfaceSet(UnresolvedType aspectType) {
return new ResolvedMemberImpl(Member.METHOD, perObjectInterfaceType(aspectType), Modifier.PUBLIC | Modifier.ABSTRACT,
NameMangler.perObjectInterfaceSet(aspectType), "(" + aspectType.getSignature() + ")V");
}

// PTWIMPL ResolvedMember for localAspectOf() method, declared in matched type
public static ResolvedMember perTypeWithinLocalAspectOf(UnresolvedType shadowType, UnresolvedType aspectType) {
return new ResolvedMemberImpl(Member.METHOD, shadowType,// perTypeWithinInterfaceType(aspectType),
Modifier.PUBLIC | Modifier.STATIC, NameMangler.perTypeWithinLocalAspectOf(aspectType), "()"
+ aspectType.getSignature());
}

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

public static ResolvedMember perSingletonHasAspectMethod(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "hasAspect", "()Z");
}

public static ResolvedMember perCflowAspectOfMethod(UnresolvedType declaringType) {
return perSingletonAspectOfMethod(declaringType);
}

public static ResolvedMember perCflowHasAspectMethod(UnresolvedType declaringType) {
return perSingletonHasAspectMethod(declaringType);
}

public static ResolvedMember perObjectAspectOfMethod(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "aspectOf", "(Ljava/lang/Object;)"
+ declaringType.getSignature());
}

public static ResolvedMember perObjectHasAspectMethod(UnresolvedType declaringType) {
return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "hasAspect", "(Ljava/lang/Object;)Z");
}

// PTWIMPL ResolvedMember for aspectOf(), declared in aspect
public static ResolvedMember perTypeWithinAspectOfMethod(UnresolvedType declaringType, boolean inJava5Mode) {
UnresolvedType parameterType = null;
if (inJava5Mode) {
parameterType = UnresolvedType.forRawTypeName("java.lang.Class");
} else {
parameterType = UnresolvedType.forSignature("Ljava/lang/Class;");
}
return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, declaringType, "aspectOf",
new UnresolvedType[] { parameterType });
// return new ResolvedMemberImpl(Member.METHOD,
// declaringType, PUBLIC_STATIC, "aspectOf",
// "(Ljava/lang/Class;)" + declaringType.getSignature());
}

/*
* public static ResolvedMember perTypeWithinGetWithinTypeMethod(UnresolvedType declaringType, boolean inJava5Mode) {
* UnresolvedType returnType = null; if (inJava5Mode) { returnType = UnresolvedType.forRawTypeName("java.lang.Class"); } else {
* returnType = UnresolvedType.forSignature("Ljava/lang/Class;"); } return new
* ResolvedMemberImpl(Member.METHOD,declaringType,Modifier.PUBLIC,ResolvedType.JAVA_LANG_STRING,"getWithinType",new
* UnresolvedType[]{}); }
*/

// PTWIMPL ResolvedMember for hasAspect(), declared in aspect
public static ResolvedMember perTypeWithinHasAspectMethod(UnresolvedType declaringType, boolean inJava5Mode) {
UnresolvedType parameterType = null;
if (inJava5Mode) {
parameterType = UnresolvedType.forRawTypeName("java.lang.Class");
} else {
parameterType = UnresolvedType.forSignature("Ljava/lang/Class;");
}
return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, ResolvedType.BOOLEAN, "hasAspect",
new UnresolvedType[] { parameterType });
// return new ResolvedMemberImpl(Member.METHOD,
// declaringType, PUBLIC_STATIC, "hasAspect",
// "(Ljava/lang/Class;)Z");
}

// -- privileged accessors

public static ResolvedMember privilegedAccessMethodForMethod(UnresolvedType aspectType, ResolvedMember method) {
return new ResolvedMemberImpl(Member.METHOD, method.getDeclaringType(), Modifier.PUBLIC
| (method.isStatic() ? Modifier.STATIC : 0), method.getReturnType(), NameMangler.privilegedAccessMethodForMethod(
method.getName(), method.getDeclaringType(), aspectType), method.getParameterTypes(), method.getExceptions());
}

public static ResolvedMember privilegedAccessMethodForFieldGet(UnresolvedType aspectType, Member field) {
String sig;
if (field.isStatic()) {
sig = "()" + field.getReturnType().getSignature();
} else {
sig = "(" + field.getDeclaringType().getSignature() + ")" + field.getReturnType().getSignature();
}

return new ResolvedMemberImpl(Member.METHOD, field.getDeclaringType(), PUBLIC_STATIC, // Modifier.PUBLIC | (field.isStatic()
// ? Modifier.STATIC : 0),
NameMangler.privilegedAccessMethodForFieldGet(field.getName(), field.getDeclaringType(), aspectType), sig);
}

public static ResolvedMember privilegedAccessMethodForFieldSet(UnresolvedType aspectType, Member field) {
String sig;
if (field.isStatic()) {
sig = "(" + field.getReturnType().getSignature() + ")V";
} else {
sig = "(" + field.getDeclaringType().getSignature() + field.getReturnType().getSignature() + ")V";
}

return new ResolvedMemberImpl(Member.METHOD, field.getDeclaringType(), PUBLIC_STATIC, // Modifier.PUBLIC | (field.isStatic()
// ? Modifier.STATIC : 0),
NameMangler.privilegedAccessMethodForFieldSet(field.getName(), field.getDeclaringType(), aspectType), sig);
}

// --- inline accessors
// ??? can eclipse handle a transform this weird without putting synthetics into the mix
public static ResolvedMember superAccessMethod(UnresolvedType baseType, ResolvedMember method) {
return new ResolvedMemberImpl(Member.METHOD, baseType, Modifier.PUBLIC, method.getReturnType(), NameMangler
.superDispatchMethod(baseType, method.getName()), method.getParameterTypes(), method.getExceptions());
}

public static ResolvedMember inlineAccessMethodForMethod(UnresolvedType aspectType, ResolvedMember method) {
UnresolvedType[] paramTypes = method.getParameterTypes();
if (!method.isStatic()) {
paramTypes = UnresolvedType.insert(method.getDeclaringType(), paramTypes);
}
return new ResolvedMemberImpl(Member.METHOD, aspectType,
PUBLIC_STATIC, // ??? what about privileged and super access
// ???Modifier.PUBLIC | (method.isStatic() ? Modifier.STATIC : 0),
method.getReturnType(),

NameMangler.inlineAccessMethodForMethod(method.getName(), method.getDeclaringType(), aspectType), paramTypes,
method.getExceptions());
}

public static ResolvedMember inlineAccessMethodForFieldGet(UnresolvedType aspectType, Member field) {
String sig;
if (field.isStatic()) {
sig = "()" + field.getReturnType().getSignature();
} else {
sig = "(" + field.getDeclaringType().getSignature() + ")" + field.getReturnType().getSignature();
}

return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, // Modifier.PUBLIC | (field.isStatic() ?
// Modifier.STATIC : 0),
NameMangler.inlineAccessMethodForFieldGet(field.getName(), field.getDeclaringType(), aspectType), sig);
}

public static ResolvedMember inlineAccessMethodForFieldSet(UnresolvedType aspectType, Member field) {
String sig;
if (field.isStatic()) {
sig = "(" + field.getReturnType().getSignature() + ")V";
} else {
sig = "(" + field.getDeclaringType().getSignature() + field.getReturnType().getSignature() + ")V";
}

return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, // Modifier.PUBLIC | (field.isStatic() ?
// Modifier.STATIC : 0),
NameMangler.inlineAccessMethodForFieldSet(field.getName(), field.getDeclaringType(), aspectType), sig);
}

// --- runtimeLibrary api stuff

public static Member cflowStackPeekInstance() {
return new MemberImpl(Member.METHOD, CFLOW_STACK_TYPE, 0, "peekInstance", "()Ljava/lang/Object;");
}

public static Member cflowStackPushInstance() {
return new MemberImpl(Member.METHOD, CFLOW_STACK_TYPE, 0, "pushInstance", "(Ljava/lang/Object;)V");
}

public static Member cflowStackIsValid() {
return new MemberImpl(Member.METHOD, CFLOW_STACK_TYPE, 0, "isValid", "()Z");
}

public static Member cflowStackInit() {
return new MemberImpl(Member.CONSTRUCTOR, CFLOW_STACK_TYPE, 0, "<init>", "()V");
}

public static Member aroundClosurePreInitializationField() {
return new MemberImpl(Member.FIELD, AROUND_CLOSURE_TYPE, 0, "preInitializationState", "[Ljava/lang/Object;");
}

public static Member aroundClosurePreInitializationGetter() {
return new MemberImpl(Member.METHOD, AROUND_CLOSURE_TYPE, 0, "getPreInitializationState", "()[Ljava/lang/Object;");
}

public static ResolvedMember preIntroducedConstructor(UnresolvedType aspectType, UnresolvedType targetType,
UnresolvedType[] paramTypes) {
return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC_FINAL, UnresolvedType.OBJECTARRAY, NameMangler
.preIntroducedConstructor(aspectType, targetType), paramTypes);
}

public static ResolvedMember postIntroducedConstructor(UnresolvedType aspectType, UnresolvedType targetType,
UnresolvedType[] paramTypes) {
return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC_FINAL, ResolvedType.VOID, NameMangler
.postIntroducedConstructor(aspectType, targetType), UnresolvedType.insert(targetType, paramTypes));
}

public static ResolvedMember itdAtDeclareParentsField(ResolvedType targetType, UnresolvedType itdType, UnresolvedType aspectType) {
return new ResolvedMemberImpl(Member.FIELD, targetType, Modifier.PRIVATE, itdType, NameMangler.itdAtDeclareParentsField(
aspectType, itdType), null);
}

public static ResolvedMember interConstructor(ResolvedType targetType, ResolvedMember constructor, UnresolvedType aspectType) {
//
// ResolvedType targetType,
// UnresolvedType[] argTypes,
// int modifiers)
// {
ResolvedMember ret = new ResolvedMemberImpl(Member.CONSTRUCTOR, targetType, Modifier.PUBLIC, ResolvedType.VOID, "<init>",
constructor.getParameterTypes(), constructor.getExceptions());
// System.out.println("ret: " + ret + " mods: " + Modifier.toString(modifiers));
if (Modifier.isPublic(constructor.getModifiers()))
return ret;
while (true) {
ret = addCookieTo(ret, aspectType);
if (targetType.lookupMemberNoSupers(ret) == null)
return ret;
}
}

public static ResolvedMember interFieldInitializer(ResolvedMember field, UnresolvedType aspectType) {
return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, NameMangler.interFieldInitializer(aspectType, field
.getDeclaringType(), field.getName()), field.isStatic() ? "()V" : "(" + field.getDeclaringType().getSignature()
+ ")V");
}

/**
* Makes public and non-final
*/
private static int makePublicNonFinal(int modifiers) {
return (modifiers & ~VISIBILITY & ~Modifier.FINAL) | Modifier.PUBLIC;
}

/**
* This static method goes on the aspect that declares the inter-type field
*/
public static ResolvedMember interFieldSetDispatcher(ResolvedMember field, UnresolvedType aspectType) {
ResolvedMember rm = new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, ResolvedType.VOID, NameMangler
.interFieldSetDispatcher(aspectType, field.getDeclaringType(), field.getName()),
field.isStatic() ? new UnresolvedType[] { field.getReturnType() } : new UnresolvedType[] {
field.getDeclaringType(), field.getReturnType() });
rm.setTypeVariables(field.getTypeVariables());
return rm;
}

/**
* This static method goes on the aspect that declares the inter-type field
*/
public static ResolvedMember interFieldGetDispatcher(ResolvedMember field, UnresolvedType aspectType) {
ResolvedMember rm = new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, field.getReturnType(), NameMangler
.interFieldGetDispatcher(aspectType, field.getDeclaringType(), field.getName()),
field.isStatic() ? UnresolvedType.NONE : new UnresolvedType[] { field.getDeclaringType() }, UnresolvedType.NONE);
rm.setTypeVariables(field.getTypeVariables());
return rm;
}

// private static int makeFieldModifiers(int declaredModifiers) {
// int ret = Modifier.PUBLIC;
// if (Modifier.isTransient(declaredModifiers)) ret |= Modifier.TRANSIENT;
// if (Modifier.isVolatile(declaredModifiers)) ret |= Modifier.VOLATILE;
// return ret;
// }

/**
* This field goes on the class the field is declared onto
*/
public static ResolvedMember interFieldClassField(ResolvedMember field, UnresolvedType aspectType) {
return new ResolvedMemberImpl(Member.FIELD, field.getDeclaringType(), makePublicNonFinal(field.getModifiers()), field
.getReturnType(), NameMangler.interFieldClassField(field.getModifiers(), aspectType, field.getDeclaringType(),
field.getName()), UnresolvedType.NONE, UnresolvedType.NONE);
}

/**
* This field goes on top-most implementers of the interface the field is declared onto
*/
public static ResolvedMember interFieldInterfaceField(ResolvedMember field, UnresolvedType onClass, UnresolvedType aspectType) {
return new ResolvedMemberImpl(Member.FIELD, onClass, makePublicNonFinal(field.getModifiers()), field.getReturnType(),
NameMangler.interFieldInterfaceField(aspectType, field.getDeclaringType(), field.getName()), UnresolvedType.NONE,
UnresolvedType.NONE);
}

/**
* This instance method goes on the interface the field is declared onto as well as its top-most implementors
*/
public static ResolvedMember interFieldInterfaceSetter(ResolvedMember field, ResolvedType onType, UnresolvedType aspectType) {
int modifiers = Modifier.PUBLIC;
if (onType.isInterface())
modifiers |= Modifier.ABSTRACT;
ResolvedMember rm = new ResolvedMemberImpl(Member.METHOD, onType, modifiers, ResolvedType.VOID, NameMangler
.interFieldInterfaceSetter(aspectType, field.getDeclaringType(), field.getName()), new UnresolvedType[] { field
.getReturnType() }, UnresolvedType.NONE);
rm.setTypeVariables(field.getTypeVariables());
return rm;
}

/**
* This instance method goes on the interface the field is declared onto as well as its top-most implementors
*/
public static ResolvedMember interFieldInterfaceGetter(ResolvedMember field, ResolvedType onType, UnresolvedType aspectType) {
int modifiers = Modifier.PUBLIC;
if (onType.isInterface())
modifiers |= Modifier.ABSTRACT;
ResolvedMember rm = new ResolvedMemberImpl(Member.METHOD, onType, modifiers, field.getReturnType(), NameMangler
.interFieldInterfaceGetter(aspectType, field.getDeclaringType(), field.getName()), UnresolvedType.NONE,
UnresolvedType.NONE);
rm.setTypeVariables(field.getTypeVariables());
return rm;
}

/**
* This method goes on the target type of the inter-type method. (and possibly the topmost-implementors, if the target type is
* an interface). The implementation will call the interMethodDispatch method on the aspect.
*/
public static ResolvedMember interMethod(ResolvedMember meth, UnresolvedType aspectType, boolean onInterface) {
if (Modifier.isPublic(meth.getModifiers()) && !onInterface)
return meth;

int modifiers = makePublicNonFinal(meth.getModifiers());
if (onInterface)
modifiers |= Modifier.ABSTRACT;

ResolvedMemberImpl rmi = new ResolvedMemberImpl(Member.METHOD, meth.getDeclaringType(), modifiers, meth.getReturnType(),
NameMangler.interMethod(meth.getModifiers(), aspectType, meth.getDeclaringType(), meth.getName()), meth
.getParameterTypes(), meth.getExceptions());
rmi.setTypeVariables(meth.getTypeVariables());
return rmi;
}

/**
* This method goes on the target type of the inter-type method. (and possibly the topmost-implementors, if the target type is
* an interface). The implementation will call the interMethodDispatch method on the aspect.
*/
public static ResolvedMember interMethodBridger(ResolvedMember meth, UnresolvedType aspectType, boolean onInterface) {
// if (Modifier.isPublic(meth.getModifiers()) && !onInterface)
// return meth;

int modifiers = makePublicNonFinal(meth.getModifiers()) | BRIDGE;
if (onInterface)
modifiers |= Modifier.ABSTRACT;

ResolvedMemberImpl rmi = new ResolvedMemberImpl(Member.METHOD, meth.getDeclaringType(), modifiers, meth.getReturnType(),
NameMangler.interMethod(meth.getModifiers(), aspectType, meth.getDeclaringType(), meth.getName()), meth
.getParameterTypes(), meth.getExceptions());
rmi.setTypeVariables(meth.getTypeVariables());
return rmi;
}

/**
* Sometimes the intertyped method requires a bridge method alongside it. For example if the method 'N SomeI<N>.m()' is put onto
* an interface 'interface I<N extends Number>' and then a concrete implementation is 'class C implements I<Float>' then the ITD
* on the interface will be 'Number m()', whereas the ITD on the 'topmostimplementor' will be 'Float m()'. A bridge method needs
* to be created in the topmostimplementor 'Number m()' that delegates to 'Float m()'
*/
public static ResolvedMember bridgerToInterMethod(ResolvedMember meth, UnresolvedType aspectType) {

int modifiers = makePublicNonFinal(meth.getModifiers());

ResolvedMemberImpl rmi = new ResolvedMemberImpl(Member.METHOD, aspectType, modifiers, meth.getReturnType(), NameMangler
.interMethod(meth.getModifiers(), aspectType, meth.getDeclaringType(), meth.getName()), meth.getParameterTypes(),
meth.getExceptions());
rmi.setTypeVariables(meth.getTypeVariables());
return rmi;
}

/**
* This static method goes on the declaring aspect of the inter-type method. The implementation calls the interMethodBody()
* method on the aspect.
*/
public static ResolvedMember interMethodDispatcher(ResolvedMember meth, UnresolvedType aspectType) {
UnresolvedType[] paramTypes = meth.getParameterTypes();
if (!meth.isStatic()) {
paramTypes = UnresolvedType.insert(meth.getDeclaringType(), paramTypes);
}

ResolvedMemberImpl rmi = new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, meth.getReturnType(), NameMangler
.interMethodDispatcher(aspectType, meth.getDeclaringType(), meth.getName()), paramTypes, meth.getExceptions());

rmi.setTypeVariables(meth.getTypeVariables());

return rmi;
}

/**
* This method goes on the declaring aspect of the inter-type method. It contains the real body of the ITD method.
*/
public static ResolvedMember interMethodBody(ResolvedMember meth, UnresolvedType aspectType) {
UnresolvedType[] paramTypes = meth.getParameterTypes();
if (!meth.isStatic()) {
paramTypes = UnresolvedType.insert(meth.getDeclaringType(), paramTypes);
}

int modifiers = PUBLIC_STATIC;
if (Modifier.isStrict(meth.getModifiers())) {
modifiers |= Modifier.STRICT;
}

ResolvedMemberImpl rmi = new ResolvedMemberImpl(Member.METHOD, aspectType, modifiers, meth.getReturnType(), NameMangler
.interMethodBody(aspectType, meth.getDeclaringType(), meth.getName()), paramTypes, meth.getExceptions());
rmi.setTypeVariables(meth.getTypeVariables());
return rmi;
}

private static ResolvedMember addCookieTo(ResolvedMember ret, UnresolvedType aspectType) {
UnresolvedType[] params = ret.getParameterTypes();

UnresolvedType[] freshParams = UnresolvedType.add(params, aspectType);
return new ResolvedMemberImpl(ret.getKind(), ret.getDeclaringType(), ret.getModifiers(), ret.getReturnType(),
ret.getName(), freshParams, ret.getExceptions());
}

public static ResolvedMember toObjectConversionMethod(UnresolvedType fromType) {
if (fromType.isPrimitiveType()) {
String name = fromType.toString() + "Object";
return new ResolvedMemberImpl(Member.METHOD, CONVERSIONS_TYPE, PUBLIC_STATIC, UnresolvedType.OBJECT, name,
new UnresolvedType[] { fromType }, UnresolvedType.NONE);
} else {
return null;
}
}

public static Member interfaceConstructor(ResolvedType resolvedTypeX) {
// AMC next two lines should not be needed when sig for generic type is changed
ResolvedType declaringType = resolvedTypeX;
if (declaringType.isRawType())
declaringType = declaringType.getGenericType();
return new ResolvedMemberImpl(Member.CONSTRUCTOR, declaringType, Modifier.PUBLIC, "<init>", "()V");
}

// -- common types we use. Note: Java 5 dependand types are refered to as String
public final static UnresolvedType ASPECT_ANNOTATION = UnresolvedType.forSignature("Lorg/aspectj/lang/annotation/Aspect;");

public final static UnresolvedType BEFORE_ANNOTATION = UnresolvedType.forSignature("Lorg/aspectj/lang/annotation/Before;");

public final static UnresolvedType AROUND_ANNOTATION = UnresolvedType.forSignature("Lorg/aspectj/lang/annotation/Around;");

public final static UnresolvedType AFTERRETURNING_ANNOTATION = UnresolvedType
.forSignature("Lorg/aspectj/lang/annotation/AfterReturning;");

public final static UnresolvedType AFTERTHROWING_ANNOTATION = UnresolvedType
.forSignature("Lorg/aspectj/lang/annotation/AfterThrowing;");

public final static UnresolvedType AFTER_ANNOTATION = UnresolvedType.forSignature("Lorg/aspectj/lang/annotation/After;");

public final static UnresolvedType POINTCUT_ANNOTATION = UnresolvedType.forSignature("Lorg/aspectj/lang/annotation/Pointcut;");

public final static UnresolvedType DECLAREERROR_ANNOTATION = UnresolvedType
.forSignature("Lorg/aspectj/lang/annotation/DeclareError;");

public final static UnresolvedType DECLAREWARNING_ANNOTATION = UnresolvedType
.forSignature("Lorg/aspectj/lang/annotation/DeclareWarning;");

public final static UnresolvedType DECLAREPRECEDENCE_ANNOTATION = UnresolvedType
.forSignature("Lorg/aspectj/lang/annotation/DeclarePrecedence;");

// public final static UnresolvedType DECLAREIMPLEMENTS_ANNOTATION =
// UnresolvedType.forSignature("Lorg/aspectj/lang/annotation/DeclareImplements;");

public final static UnresolvedType DECLAREPARENTS_ANNOTATION = UnresolvedType
.forSignature("Lorg/aspectj/lang/annotation/DeclareParents;");

public final static UnresolvedType TYPEX_JOINPOINT = UnresolvedType.forSignature("Lorg/aspectj/lang/JoinPoint;");

public final static UnresolvedType TYPEX_PROCEEDINGJOINPOINT = UnresolvedType
.forSignature("Lorg/aspectj/lang/ProceedingJoinPoint;");

public final static UnresolvedType TYPEX_STATICJOINPOINT = UnresolvedType
.forSignature("Lorg/aspectj/lang/JoinPoint$StaticPart;");

public final static UnresolvedType TYPEX_ENCLOSINGSTATICJOINPOINT = UnresolvedType
.forSignature("Lorg/aspectj/lang/JoinPoint$EnclosingStaticPart;");

}

+ 21
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AnnotatedElement.java Переглянути файл

@@ -0,0 +1,21 @@
/* *******************************************************************
* Copyright (c) 2004 IBM Corporation.
* 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
*
* ******************************************************************/
package org.aspectj.weaver;

/**
* Represents any element that may have annotations
*/
public interface AnnotatedElement {
boolean hasAnnotation(UnresolvedType ofType);

ResolvedType[] getAnnotationTypes();

AnnotationAJ getAnnotationOfType(UnresolvedType ofType);
}

+ 102
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AnnotationAJ.java Переглянути файл

@@ -0,0 +1,102 @@
/* *******************************************************************
* Copyright (c) 2006-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
*
* ******************************************************************/
package org.aspectj.weaver;

import java.util.Set;

/**
* Simple representation of an annotation that the weaver can work with.
*
* @author AndyClement
*/
public interface AnnotationAJ {

public static final AnnotationAJ[] EMPTY_ARRAY = new AnnotationAJ[0];

/**
* @return the signature for the annotation type, eg. Lcom/foo/MyAnno;
*/
public String getTypeSignature();

/**
* @return the type name for the annotation, eg. com.foo.MyAnno
*/
public String getTypeName();

/**
* @return the type of the annotation
*/
public ResolvedType getType();

/**
* return true if this annotation can target an annotation type
*/
public boolean allowedOnAnnotationType();

/**
* @return true if this annotation can be put on a field
*/
public boolean allowedOnField();

/**
* @return true if this annotation can target a 'regular' type. A 'regular' type is enum/class/interface - it is *not*
* annotation.
*/
public boolean allowedOnRegularType();

/**
* @return for the @target annotation, this will return a set of the element-types it can be applied to. For other annotations ,
* it returns the empty set.
*/
public Set getTargets();

/**
* @param name the name of the value
* @return true if there is a value with that name
*/
public boolean hasNamedValue(String name);

/**
* @param name the name of the annotation field
* @param value the value of the annotation field
* @return true if there is a value with the specified name and value
*/
public boolean hasNameValuePair(String name, String value);

/**
* @return String representation of the valid targets for this annotation, eg. "{TYPE,FIELD}"
*/
public String getValidTargets();

/**
* @return String form of the annotation and any values, eg. @Foo(a=b,c=d)
*/
public String stringify();

/**
* @return true if this annotation is marked with @target
*/
public boolean specifiesTarget();

/**
* @return true if the annotation is marked for runtime visibility
*/
public boolean isRuntimeVisible();

/**
* Determine the string representation of the value of a field. For example in @SuppressAjWarnings({"adviceDidNotMatch"})
* the return value for getStringFormOfValue("value") would be "[adviceDidNotMatch]".
*
* @param name the name of the annotation field being looked up
* @return string representation of the value of that field, may be null if no such field set
*/
public String getStringFormOfValue(String name);

}

+ 35
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AnnotationAnnotationValue.java Переглянути файл

@@ -0,0 +1,35 @@
/* *******************************************************************
* Copyright (c) 2006 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 IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;

public class AnnotationAnnotationValue extends AnnotationValue {

private AnnotationAJ value;
public AnnotationAnnotationValue(AnnotationAJ value) {
super(AnnotationValue.ANNOTATION);
this.value = value;
}
public AnnotationAJ getAnnotation() {
return value;
}
public String stringify() {
return value.stringify();
}
public String toString() {
return value.toString();
}

}

+ 47
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AnnotationNameValuePair.java Переглянути файл

@@ -0,0 +1,47 @@
/* *******************************************************************
* Copyright (c) 2006 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 IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;

public class AnnotationNameValuePair {
private String name;
private AnnotationValue val;

public AnnotationNameValuePair(String name,AnnotationValue val) {
this.name = name;
this.val = val;
}
public String getName() {
return name;
}
public AnnotationValue getValue() {
return val;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(name+"="+val.toString());
return sb.toString();
}

public String stringify() {
StringBuffer sb = new StringBuffer();
if (!name.equals("value")) {
sb.append(name+"=");
}
sb.append(val.stringify());
return sb.toString();
}
}

+ 57
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AnnotationOnTypeMunger.java Переглянути файл

@@ -0,0 +1,57 @@
/* *******************************************************************
* Copyright (c) 2005 IBM
* 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.io.DataOutputStream;
import java.io.IOException;

/**
* Represents adding an annotation to a type
*/
public class AnnotationOnTypeMunger extends ResolvedTypeMunger {
AnnotationAJ newAnnotation;

public AnnotationOnTypeMunger(AnnotationAJ anno) {
super(AnnotationOnType, null);
newAnnotation = anno;
}

public void write(DataOutputStream s) throws IOException {
throw new RuntimeException("unimplemented");
}

public AnnotationAJ getNewAnnotation() {
return newAnnotation;
}

public boolean equals(Object other) {
if (!(other instanceof AnnotationOnTypeMunger))
return false;
AnnotationOnTypeMunger o = (AnnotationOnTypeMunger) other;
// TODO does not check equality of annotation values
return newAnnotation.getTypeSignature().equals(
o.newAnnotation.getTypeSignature());
}

private volatile int hashCode = 0;

public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37 * result + newAnnotation.getTypeSignature().hashCode();
hashCode = result;
}
return hashCode;
}

}

+ 51
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AnnotationTargetKind.java Переглянути файл

@@ -0,0 +1,51 @@
/********************************************************************
* 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:
* Helen Hawkins - Initial implementation
*******************************************************************/
package org.aspectj.weaver;

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

import org.aspectj.util.TypeSafeEnum;

/**
* A TypeSafeEnum similar to the Java5 ElementType Enum
*/
public class AnnotationTargetKind extends TypeSafeEnum {

public AnnotationTargetKind(String name, int key) {
super(name, key);
}
public static AnnotationTargetKind read(DataInputStream s) throws IOException {
int key = s.readByte();
switch(key) {
case 1: return ANNOTATION_TYPE;
case 2: return CONSTRUCTOR;
case 3: return FIELD;
case 4: return LOCAL_VARIABLE;
case 5: return METHOD;
case 6: return PACKAGE;
case 7: return PARAMETER;
case 8: return TYPE;
}
throw new BCException("weird annotation target kind " + key);
}

public static final AnnotationTargetKind ANNOTATION_TYPE = new AnnotationTargetKind("ANNOTATION_TYPE", 1);
public static final AnnotationTargetKind CONSTRUCTOR = new AnnotationTargetKind("CONSTRUCTOR", 2);
public static final AnnotationTargetKind FIELD = new AnnotationTargetKind("FIELD", 3);
public static final AnnotationTargetKind LOCAL_VARIABLE = new AnnotationTargetKind("LOCAL_VARIABLE", 4);
public static final AnnotationTargetKind METHOD = new AnnotationTargetKind("METHOD", 5);
public static final AnnotationTargetKind PACKAGE = new AnnotationTargetKind("PACKAGE", 6);
public static final AnnotationTargetKind PARAMETER = new AnnotationTargetKind("PARAMETER", 7);
public static final AnnotationTargetKind TYPE = new AnnotationTargetKind("TYPE", 8);

}

+ 72
- 0
org.aspectj.matcher/src/org/aspectj/weaver/AnnotationValue.java Переглянути файл

@@ -0,0 +1,72 @@
/* *******************************************************************
* Copyright (c) 2006 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 IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;


public abstract class AnnotationValue {
protected int valueKind;

public static final int STRING = 's';
public static final int ENUM_CONSTANT = 'e';
public static final int CLASS = 'c';
public static final int ANNOTATION = '@';
public static final int ARRAY = '[';
public static final int PRIMITIVE_INT = 'I';
public static final int PRIMITIVE_BYTE = 'B';
public static final int PRIMITIVE_CHAR = 'C';
public static final int PRIMITIVE_DOUBLE = 'D';
public static final int PRIMITIVE_FLOAT = 'F';
public static final int PRIMITIVE_LONG = 'J';
public static final int PRIMITIVE_SHORT = 'S';
public static final int PRIMITIVE_BOOLEAN= 'Z';

public abstract String stringify();
public AnnotationValue(int kind) {
valueKind = kind;
}
public static String whatKindIsThis(int kind) {
switch (kind) {
case PRIMITIVE_BYTE: // byte
return "byte";
case PRIMITIVE_CHAR: // char
return "char";
case PRIMITIVE_DOUBLE: // double
return "double";
case PRIMITIVE_FLOAT: // float
return "float";
case PRIMITIVE_INT: // int
return "int";
case PRIMITIVE_LONG: // long
return "long";
case PRIMITIVE_SHORT: // short
return "short";
case PRIMITIVE_BOOLEAN: // boolean
return "boolean";
case 's': // String
return "string";
case 'e': // Enum constant
return "enum";
case 'c': // Class
return "class";
case '@': // Annotation
return "annotation";
case '[': // Array
return "array";
default:
throw new RuntimeException("Dont know what this is : "+kind);
}
}
}

+ 57
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ArrayAnnotationValue.java Переглянути файл

@@ -0,0 +1,57 @@
/* *******************************************************************
* Copyright (c) 2006 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 IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;

public class ArrayAnnotationValue extends AnnotationValue {

private AnnotationValue[] values;
public ArrayAnnotationValue() {
super(AnnotationValue.ARRAY);
}
public void setValues(AnnotationValue[] values) {
this.values = values;
}
public ArrayAnnotationValue(AnnotationValue[] values) {
super(AnnotationValue.ARRAY);
this.values = values;
}
public AnnotationValue[] getValues() {
return values;
}
public String stringify() {
StringBuffer sb = new StringBuffer();
sb.append("[");
for (int i = 0; i < values.length; i++) {
sb.append(values[i].stringify());
if (i+1<values.length) sb.append(",");
}
sb.append("]");
return sb.toString();
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("{");
for (int i = 0; i < values.length; i++) {
sb.append(values[i].toString());
if ((i+1)<values.length) sb.append(",");
}
sb.append("}");
return sb.toString();
}

}

+ 196
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ArrayReferenceType.java Переглянути файл

@@ -0,0 +1,196 @@
/* *******************************************************************
* 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 final 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 AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
return null;
}

public AnnotationAJ[] getAnnotations() {
return AnnotationAJ.EMPTY_ARRAY;
}

public ResolvedType[] getAnnotationTypes() {
return ResolvedType.NONE;
}

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;
}
}

+ 58
- 0
org.aspectj.matcher/src/org/aspectj/weaver/BCException.java Переглянути файл

@@ -0,0 +1,58 @@
/* *******************************************************************
* 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.PrintStream;
import java.io.PrintWriter;

import org.aspectj.bridge.context.CompilationAndWeavingContext;

/**
* Exception to use inside the bcweaver.
*/
public class BCException extends RuntimeException {
Throwable thrown;
public BCException() {
super();
}

public BCException(String s) {
super(s + "\n" + CompilationAndWeavingContext.getCurrentContext());
}
public BCException(String s, Throwable thrown) {
this(s);
this.thrown = thrown;
}
public void printStackTrace() {
printStackTrace(System.err);
}
public void printStackTrace(PrintStream s) {
printStackTrace(new PrintWriter(s));
}
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
if (null != thrown) {
s.print("Caused by: ");
s.print(thrown.getClass().getName());
String message = thrown.getMessage();
if (null != message) {
s.print(": ");
s.print(message);
}
s.println();
thrown.printStackTrace(s);
}
}

}

+ 58
- 0
org.aspectj.matcher/src/org/aspectj/weaver/BindingScope.java Переглянути файл

@@ -0,0 +1,58 @@
/* *******************************************************************
* Copyright (c) 2006-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
*
* ******************************************************************/
package org.aspectj.weaver;

import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.patterns.FormalBinding;
import org.aspectj.weaver.patterns.SimpleScope;

/**
* BindingScope that knows the enclosingType, which is needed for pointcut reference resolution
*
* @author Alexandre Vasseur
*/
public class BindingScope extends SimpleScope {
private final ResolvedType m_enclosingType;
private final ISourceContext m_sourceContext;

public BindingScope(ResolvedType type, ISourceContext sourceContext, FormalBinding[] bindings) {
super(type.getWorld(), bindings);
m_enclosingType = type;
m_sourceContext = sourceContext;
}

public ResolvedType getEnclosingType() {
return m_enclosingType;
}

public ISourceLocation makeSourceLocation(IHasPosition location) {
return m_sourceContext.makeSourceLocation(location);
}

public UnresolvedType lookupType(String name, IHasPosition location) {
// bug 126560
if (m_enclosingType != null) {
// add the package we're in to the list of imported
// prefixes so that we can find types in the same package
String pkgName = m_enclosingType.getPackageName();
if (pkgName != null && !pkgName.equals("")) {
String[] currentImports = getImportedPrefixes();
String[] newImports = new String[currentImports.length + 1];
for (int i = 0; i < currentImports.length; i++) {
newImports[i] = currentImports[i];
}
newImports[currentImports.length] = pkgName.concat(".");
setImportedPrefixes(newImports);
}
}
return super.lookupType(name, location);
}

}

+ 334
- 0
org.aspectj.matcher/src/org/aspectj/weaver/BoundedReferenceType.java Переглянути файл

@@ -0,0 +1,334 @@
/* *******************************************************************
* 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;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;

import org.aspectj.weaver.patterns.PerClause;

/**
* A BoundedReferenceType is the result of a generics wildcard expression ?
* extends String, ? super Foo etc..
*
* The "signature" for a bounded reference type follows the generic signature
* specification in section 4.4 of JVM spec: *,+,- plus signature strings.
*
* The bound may be a type variable (e.g. ? super T)
*/
public class BoundedReferenceType extends ReferenceType {

private ResolvedType lowerBound;

private ResolvedType upperBound;

protected ReferenceType[] additionalInterfaceBounds = new ReferenceType[0];

protected boolean isExtends = true;

protected boolean isSuper = false;

public UnresolvedType getUpperBound() {
return upperBound;
}

public UnresolvedType getLowerBound() {
return lowerBound;
}

public BoundedReferenceType(ReferenceType aBound, boolean isExtends,
World world) {
super((isExtends ? "+" : "-") + aBound.signature,
aBound.signatureErasure, world);
this.isExtends = isExtends;
this.isSuper = !isExtends;
if (isExtends) {
upperBound = aBound;
} else {
lowerBound = aBound;
upperBound = world.resolve(UnresolvedType.OBJECT);
}
setDelegate(new ReferenceTypeReferenceTypeDelegate(
(ReferenceType) getUpperBound()));
}

public BoundedReferenceType(ReferenceType aBound, boolean isExtends,
World world, ReferenceType[] additionalInterfaces) {
this(aBound, isExtends, world);
this.additionalInterfaceBounds = additionalInterfaces;
}

public ReferenceType[] getAdditionalBounds() {
return additionalInterfaceBounds;
}

public UnresolvedType parameterize(Map typeBindings) {
ReferenceType[] parameterizedAdditionalInterfaces = new ReferenceType[additionalInterfaceBounds == null ? 0
: additionalInterfaceBounds.length];
for (int i = 0; i < parameterizedAdditionalInterfaces.length; i++) {
parameterizedAdditionalInterfaces[i] = (ReferenceType) additionalInterfaceBounds[i]
.parameterize(typeBindings);
}
if (isExtends) {
return new BoundedReferenceType((ReferenceType) getUpperBound()
.parameterize(typeBindings), isExtends, world,
parameterizedAdditionalInterfaces);
} else {
return new BoundedReferenceType((ReferenceType) getLowerBound()
.parameterize(typeBindings), isExtends, world,
parameterizedAdditionalInterfaces);
}
}

/**
* only for use when resolving GenericsWildcardTypeX or a
* TypeVariableReferenceType
*/
protected BoundedReferenceType(String sig, String sigErasure, World world) {
super(sig, sigErasure, world);
upperBound = world.resolve(UnresolvedType.OBJECT);
setDelegate(new ReferenceTypeReferenceTypeDelegate(
(ReferenceType) getUpperBound()));
}

public ReferenceType[] getInterfaceBounds() {
return additionalInterfaceBounds;
}

public boolean hasLowerBound() {
return getLowerBound() != null;
}

public boolean isExtends() {
return (isExtends && !getUpperBound().getSignature().equals(
"Ljava/lang/Object;"));
}

public boolean isSuper() {
return isSuper;
}

public boolean alwaysMatches(ResolvedType aCandidateType) {
if (isExtends()) {
// aCandidateType must be a subtype of upperBound
return ((ReferenceType) getUpperBound())
.isAssignableFrom(aCandidateType);
} else if (isSuper()) {
// aCandidateType must be a supertype of lowerBound
return aCandidateType
.isAssignableFrom((ReferenceType) getLowerBound());
} else {
return true; // straight '?'
}
}

// this "maybe matches" that
public boolean canBeCoercedTo(ResolvedType aCandidateType) {
if (alwaysMatches(aCandidateType))
return true;
if (aCandidateType.isGenericWildcard()) {
BoundedReferenceType boundedRT = (BoundedReferenceType) aCandidateType;
ResolvedType myUpperBound = (ResolvedType) getUpperBound();
ResolvedType myLowerBound = (ResolvedType) getLowerBound();
if (isExtends()) {
if (boundedRT.isExtends()) {
return myUpperBound
.isAssignableFrom((ResolvedType) boundedRT
.getUpperBound());
} else if (boundedRT.isSuper()) {
return myUpperBound == boundedRT.getLowerBound();
} else {
return true; // it's '?'
}
} else if (isSuper()) {
if (boundedRT.isSuper()) {
return ((ResolvedType) boundedRT.getLowerBound())
.isAssignableFrom(myLowerBound);
} else if (boundedRT.isExtends()) {
return myLowerBound == boundedRT.getUpperBound();
} else {
return true;
}
} else {
return true;
}
} else {
return false;
}
}

public String getSimpleName() {
if (!isExtends() && !isSuper())
return "?";
if (isExtends()) {
return ("? extends " + getUpperBound().getSimpleName());
} else {
return ("? super " + getLowerBound().getSimpleName());
}
}

// override to include additional interface bounds...
public ResolvedType[] getDeclaredInterfaces() {
ResolvedType[] interfaces = super.getDeclaredInterfaces();
if (additionalInterfaceBounds.length > 0) {
ResolvedType[] allInterfaces = new ResolvedType[interfaces.length
+ additionalInterfaceBounds.length];
System
.arraycopy(interfaces, 0, allInterfaces, 0,
interfaces.length);
System.arraycopy(additionalInterfaceBounds, 0, allInterfaces,
interfaces.length, additionalInterfaceBounds.length);
return allInterfaces;
} else {
return interfaces;
}
}

public boolean isGenericWildcard() {
return true;
}

protected static class ReferenceTypeReferenceTypeDelegate extends
AbstractReferenceTypeDelegate {

public ReferenceTypeReferenceTypeDelegate(ReferenceType backing) {
super(backing, false);
}

public void addAnnotation(AnnotationAJ annotationX) {
throw new UnsupportedOperationException(
"What on earth do you think you are doing???");
}

public boolean isAspect() {
return resolvedTypeX.isAspect();
}

public boolean isAnnotationStyleAspect() {
return resolvedTypeX.isAnnotationStyleAspect();
}

public boolean isInterface() {
return resolvedTypeX.isInterface();
}

public boolean isEnum() {
return resolvedTypeX.isEnum();
}

public boolean isAnnotation() {
return resolvedTypeX.isAnnotation();
}

public boolean isAnnotationWithRuntimeRetention() {
return resolvedTypeX.isAnnotationWithRuntimeRetention();
}

public boolean isAnonymous() {
return resolvedTypeX.isAnonymous();
}

public boolean isNested() {
return resolvedTypeX.isNested();
}

public ResolvedType getOuterClass() {
return resolvedTypeX.getOuterClass();
}

public String getRetentionPolicy() {
return resolvedTypeX.getRetentionPolicy();
}

public boolean canAnnotationTargetType() {
return resolvedTypeX.canAnnotationTargetType();
}

public AnnotationTargetKind[] getAnnotationTargetKinds() {
return resolvedTypeX.getAnnotationTargetKinds();
}

public boolean isGeneric() {
return resolvedTypeX.isGenericType();
}

public String getDeclaredGenericSignature() {
return resolvedTypeX.getDeclaredGenericSignature();
}

public boolean hasAnnotation(UnresolvedType ofType) {
return resolvedTypeX.hasAnnotation(ofType);
}

public AnnotationAJ[] getAnnotations() {
return resolvedTypeX.getAnnotations();
}

public ResolvedType[] getAnnotationTypes() {
return resolvedTypeX.getAnnotationTypes();
}

public ResolvedMember[] getDeclaredFields() {
return resolvedTypeX.getDeclaredFields();
}

public ResolvedType[] getDeclaredInterfaces() {
return resolvedTypeX.getDeclaredInterfaces();
}

public ResolvedMember[] getDeclaredMethods() {
return resolvedTypeX.getDeclaredMethods();
}

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

public PerClause getPerClause() {
return resolvedTypeX.getPerClause();
}

public Collection getDeclares() {
return resolvedTypeX.getDeclares();
}

public Collection getTypeMungers() {
return resolvedTypeX.getTypeMungers();
}

public Collection getPrivilegedAccesses() {
return Collections.EMPTY_LIST;
}

public int getModifiers() {
return resolvedTypeX.getModifiers();
}

public ResolvedType getSuperclass() {
return resolvedTypeX.getSuperclass();
}

public WeaverStateInfo getWeaverState() {
return null;
}

public TypeVariable[] getTypeVariables() {
return resolvedTypeX.getTypeVariables();
}

public void ensureDelegateConsistent() {
resolvedTypeX.getDelegate().ensureDelegateConsistent();
}

}
}

+ 151
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Checker.java Переглянути файл

@@ -0,0 +1,151 @@
/* *******************************************************************
* 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.util.Collection;
import java.util.Collections;
import java.util.Map;

import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;

/**
* Representation of a shadow munger for a declare error or warning declaration.
*
* @author Andy Clement
*/
public class Checker extends ShadowMunger {

private final String message;
private final boolean isError; // if not error then it is a warning
private volatile int hashCode = -1;

/**
* Create a Checker for a deow.
*
* @param deow the declare error or warning for which to create the checker munger
*/
public Checker(DeclareErrorOrWarning deow) {
super(deow.getPointcut(), deow.getStart(), deow.getEnd(), deow.getSourceContext());
this.message = deow.getMessage();
this.isError = deow.isError();
}

/**
* Only used when filling in a parameterized Checker.
*
* @param pc the pointcut
* @param start the start
* @param end the end
* @param context the source context
* @param message the message string
* @param isError whether it is an error or just a warning
*/
private Checker(Pointcut pc, int start, int end, ISourceContext context, String message, boolean isError) {
super(pc, start, end, context);
this.message = message;
this.isError = isError;
}

public boolean isError() {
return isError;
}

/**
* Not supported for a Checker
*/
public void specializeOn(Shadow shadow) {
throw new RuntimeException("illegal state");
}

/**
* Not supported for a Checker
*/
public void implementOn(Shadow shadow) {
throw new RuntimeException("illegal state");
}

/**
* Determine if the Checker matches at a shadow. If it does then we can immediately report the message. There (currently) can
* never be a non-statically determinable match.
*
* @param shadow the shadow which to match against
* @param world the world through which to access message handlers
*/
public boolean match(Shadow shadow, World world) {
if (super.match(shadow, world)) {
world.reportCheckerMatch(this, shadow);
}
return false;
}

// FIXME what the hell?
public int compareTo(Object other) {
return 0;
}

// FIXME Alex: ATAJ is that ok in all cases ?
/**
* Default to true
*
* @return
*/
public boolean mustCheckExceptions() {
return true;
}

public Collection getThrownExceptions() {
return Collections.EMPTY_LIST;
}

// FIXME this perhaps ought to take account of the other fields in advice ...
public boolean equals(Object other) {
if (!(other instanceof Checker)) {
return false;
}
Checker o = (Checker) other;
return o.isError == isError && ((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut));
}

public int hashCode() {
if (hashCode == -1) {
int result = 17;
result = 37 * result + (isError ? 1 : 0);
result = 37 * result + ((pointcut == null) ? 0 : pointcut.hashCode());
hashCode = result;
}
return hashCode;
}

public ShadowMunger parameterizeWith(ResolvedType declaringType, Map typeVariableMap) {
Checker ret = new Checker(this.pointcut.parameterizeWith(typeVariableMap, declaringType.getWorld()), this.start, this.end,
this.sourceContext, this.message, this.isError);
return ret;
}

/**
* Concretize this Checker by concretizing the pointcut.
*
*/
public ShadowMunger concretize(ResolvedType theAspect, World world, PerClause clause) {
this.pointcut = this.pointcut.concretize(theAspect, getDeclaringType(), 0, this);
this.hashCode = -1;
return this;
}

public String getMessage() {
return this.message;
}

}

+ 31
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ClassAnnotationValue.java Переглянути файл

@@ -0,0 +1,31 @@
/* *******************************************************************
* Copyright (c) 2006 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 IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;

public class ClassAnnotationValue extends AnnotationValue {

private String signature;
public ClassAnnotationValue(String sig) {
super(AnnotationValue.CLASS);
this.signature = sig;
}
public String stringify() {
return signature;
}
public String toString() {
return signature;
}

}

+ 144
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ConcreteTypeMunger.java Переглянути файл

@@ -0,0 +1,144 @@
/* *******************************************************************
* 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.util.Map;

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

public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparable {
protected ResolvedTypeMunger munger;
protected ResolvedType aspectType;

public ConcreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) {
this.munger = munger;
this.aspectType = aspectType;
}

// An EclipseTypeMunger and a BcelTypeMunger may say TRUE for equivalentTo()...
// public boolean equivalentTo(Object other) {
// if (! (other instanceof ConcreteTypeMunger)) return false;
// ConcreteTypeMunger o = (ConcreteTypeMunger) other;
// return ((o.getMunger() == null) ? (getMunger() == null) : o.getMunger().equals(getMunger()))
// && ((o.getAspectType() == null) ? (getAspectType() == null) : o.getAspectType().equals(getAspectType()));
// }

// public abstract boolean munge(LazyClassGen gen);

/**
* returns null for mungers that are used internally, but were not part of a declared thing in source code.
*/
public ResolvedTypeMunger getMunger() {
return munger;
}

public ResolvedType getAspectType() {
return aspectType;
}

public ResolvedMember getSignature() {
return munger.getSignature();
}

public World getWorld() {
return aspectType.getWorld();
}

public ISourceLocation getSourceLocation() {
if (munger == null)
return null;
return munger.getSourceLocation(); // XXX
}

public boolean matches(ResolvedType onType) {
if (munger == null)
throw new RuntimeException("huh: " + this);
return munger.matches(onType, aspectType);
}

public ResolvedMember getMatchingSyntheticMember(Member member) {
return munger.getMatchingSyntheticMember(member, aspectType);
}

public int compareTo(Object other) {
ConcreteTypeMunger o = (ConcreteTypeMunger) other;

ResolvedType otherAspect = o.aspectType;

if (aspectType.equals(otherAspect)) {
return getSignature().getStart() < o.getSignature().getStart() ? -1 : +1;
} else if (aspectType.isAssignableFrom(o.aspectType)) {
return +1;
} else if (o.aspectType.isAssignableFrom(aspectType)) {
return -1;
} else {
return 0;
}
}

public int fallbackCompareTo(Object other) {
// ConcreteTypeMunger o = (ConcreteTypeMunger) other;
return 0;
}

/**
* returns true if the ITD target type used type variables, for example I<T>. When they are specified like this, the ITDs
* 'share' type variables with the generic type. Usually this method is called because we need to know whether to tailor the
* munger for addition to a particular type. For example: <code>
* interface I<T> {}
*
* aspect X implements I<String> {
* List<T> I<T>.foo { return null; }
* }
* </code> In this case the munger matches X but it matches with the form <code>
* List<String> foo() { return null; }
* </code>
*/
public boolean isTargetTypeParameterized() {
if (munger == null)
return false;
return munger.sharesTypeVariablesWithGenericType();
}

/**
* For an ITD made on a generic type that shares type variables with that target type, this method will tailor the ITD for a
* particular usage of the generic type - either in its raw or parameterized form.
*/
public abstract ConcreteTypeMunger parameterizedFor(ResolvedType targetType);

public boolean isLateMunger() {
if (munger == null)
return false;
return munger.isLateMunger();
}

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

/**
* Some type mungers are created purely to help with the implementation of shadow mungers. For example to support the cflow()
* pointcut we create a new cflow field in the aspect, and that is added via a BcelCflowCounterFieldAdder.
*
* During compilation we need to compare sets of type mungers, and if some only come into existence after the 'shadowy' type
* things have been processed, we need to ignore them during the comparison.
*
* Returning true from this method indicates the type munger exists to support 'shadowy' stuff - and so can be ignored in some
* comparison.
*/
public boolean existsToSupportShadowMunging() {
if (munger != null) {
return munger.existsToSupportShadowMunging();
}
return false;
}
}

+ 30
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Constants.java Переглянути файл

@@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2004 IBM
* 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 API and implementation
*******************************************************************************/
package org.aspectj.weaver;

/**
* Some useful weaver constants.
*
* Current uses:
* 1. Holds values that are necessary for working with 1.5 code but
* which don't exist in a 1.4 world.
*/
public interface Constants {

public final static int ACC_BRIDGE = 0x0040;
public final static int ACC_VARARGS = 0x0080;
public final static String RUNTIME_LEVEL_12 = "1.2";
public final static String RUNTIME_LEVEL_15 = "1.5";
// Default for 1.5.0
public final static String RUNTIME_LEVEL_DEFAULT = RUNTIME_LEVEL_15;
}

+ 533
- 0
org.aspectj.matcher/src/org/aspectj/weaver/CrosscuttingMembers.java Переглянути файл

@@ -0,0 +1,533 @@
/* *******************************************************************
* 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.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.patterns.Declare;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
import org.aspectj.weaver.patterns.DeclareParents;
import org.aspectj.weaver.patterns.DeclarePrecedence;
import org.aspectj.weaver.patterns.DeclareSoft;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.PointcutRewriter;

/**
* This holds on to all members that have an invasive effect outside of there
* own compilation unit. These members need to be all gathered up and in a world
* before any weaving can take place.
*
* They are also important in the compilation process and need to be gathered up
* before the inter-type declaration weaving stage (unsurprisingly).
*
* All members are concrete.
*
* @author Jim Hugunin
*/
public class CrosscuttingMembers {
private final ResolvedType inAspect;
private final World world;

private PerClause perClause;

private List shadowMungers = new ArrayList(4);
private List typeMungers = new ArrayList(4);
private List lateTypeMungers = new ArrayList(0);

private List declareParents = new ArrayList(4);
private List declareSofts = new ArrayList(0);
private List declareDominates = new ArrayList(4);

// These are like declare parents type mungers
private List declareAnnotationsOnType = new ArrayList();
private List declareAnnotationsOnField = new ArrayList();
private List declareAnnotationsOnMethods = new ArrayList(); // includes
// ctors

private boolean shouldConcretizeIfNeeded = true;

public CrosscuttingMembers(ResolvedType inAspect, boolean shouldConcretizeIfNeeded) {
this.inAspect = inAspect;
world = inAspect.getWorld();
this.shouldConcretizeIfNeeded = shouldConcretizeIfNeeded;
}

private final Hashtable cflowFields = new Hashtable();
private final Hashtable cflowBelowFields = new Hashtable();

// public void addConcreteShadowMungers(Collection c) {
// shadowMungers.addAll(c);
// }

public void addConcreteShadowMunger(ShadowMunger m) {
// assert m is concrete
shadowMungers.add(m);
}

public void addShadowMungers(Collection c) {
for (Iterator i = c.iterator(); i.hasNext();) {
addShadowMunger((ShadowMunger) i.next());
}
}

private void addShadowMunger(ShadowMunger m) {
if (inAspect.isAbstract())
return; // we don't do mungers for abstract aspects
addConcreteShadowMunger(m.concretize(inAspect, world, perClause));
}

public void addTypeMungers(Collection c) {
typeMungers.addAll(c);
}

public void addTypeMunger(ConcreteTypeMunger m) {
if (m == null)
throw new Error("FIXME AV - should not happen or what ?");// return;
// //???
typeMungers.add(m);
}

public void addLateTypeMungers(Collection c) {
lateTypeMungers.addAll(c);
}

public void addLateTypeMunger(ConcreteTypeMunger m) {
lateTypeMungers.add(m);
}

public void addDeclares(Collection c) {
for (Iterator i = c.iterator(); i.hasNext();) {
addDeclare((Declare) i.next());
}
}

public void addDeclare(Declare declare) {
// this is not extensible, oh well
if (declare instanceof DeclareErrorOrWarning) {
ShadowMunger m = new Checker((DeclareErrorOrWarning) declare);
m.setDeclaringType(declare.getDeclaringType());
addShadowMunger(m);
} else if (declare instanceof DeclarePrecedence) {
declareDominates.add(declare);
} else if (declare instanceof DeclareParents) {
DeclareParents dp = (DeclareParents) declare;
exposeTypes(dp.getParents().getExactTypes());
declareParents.add(dp);
} else if (declare instanceof DeclareSoft) {
DeclareSoft d = (DeclareSoft) declare;
// Ordered so that during concretization we can check the related
// munger
ShadowMunger m = Advice.makeSoftener(world, d.getPointcut(), d.getException(), inAspect, d);
m.setDeclaringType(d.getDeclaringType());
Pointcut concretePointcut = d.getPointcut().concretize(inAspect, d.getDeclaringType(), 0, m);
m.pointcut = concretePointcut;
declareSofts.add(new DeclareSoft(d.getException(), concretePointcut));
addConcreteShadowMunger(m);
} else if (declare instanceof DeclareAnnotation) {
// FIXME asc perf Possible Improvement. Investigate why this is
// called twice in a weave ?
DeclareAnnotation da = (DeclareAnnotation) declare;
if (da.getAspect() == null)
da.setAspect(inAspect);
if (da.isDeclareAtType()) {
declareAnnotationsOnType.add(da);
} else if (da.isDeclareAtField()) {
declareAnnotationsOnField.add(da);
} else if (da.isDeclareAtMethod() || da.isDeclareAtConstuctor()) {
declareAnnotationsOnMethods.add(da);
}
} else {
throw new RuntimeException("unimplemented");
}
}

public void exposeTypes(Collection typesToExpose) {
for (Iterator i = typesToExpose.iterator(); i.hasNext();) {
exposeType((UnresolvedType) i.next());
}
}

public void exposeType(UnresolvedType typeToExpose) {
if (ResolvedType.isMissing(typeToExpose))
return;
if (typeToExpose.isParameterizedType() || typeToExpose.isRawType()) {
if (typeToExpose instanceof ResolvedType) {
typeToExpose = ((ResolvedType) typeToExpose).getGenericType();
} else {
typeToExpose = UnresolvedType.forSignature(typeToExpose.getErasureSignature());
}
}
// Check we haven't already got a munger for this:
String signatureToLookFor = typeToExpose.getSignature();
for (Iterator iterator = typeMungers.iterator(); iterator.hasNext();) {
ConcreteTypeMunger cTM = (ConcreteTypeMunger) iterator.next();
ResolvedTypeMunger rTM = cTM.getMunger();
if (rTM != null && rTM instanceof ExposeTypeMunger) {
String exposedType = ((ExposeTypeMunger) rTM).getExposedTypeSignature();
if (exposedType.equals(signatureToLookFor))
return; // dont need to bother
}
}
addTypeMunger(world.getWeavingSupport().concreteTypeMunger(new ExposeTypeMunger(typeToExpose), inAspect));
// ResolvedMember member = new ResolvedMemberImpl(
// Member.STATIC_INITIALIZATION, typeToExpose, 0, ResolvedType.VOID,
// "<clinit>", UnresolvedType.NONE);
// addTypeMunger(world.concreteTypeMunger(
// new PrivilegedAccessMunger(member), inAspect));
}

public void addPrivilegedAccesses(Collection accessedMembers) {
for (Iterator i = accessedMembers.iterator(); i.hasNext();) {
addPrivilegedAccess((ResolvedMember) i.next());
}
}

private void addPrivilegedAccess(ResolvedMember member) {
// System.err.println("add priv access: " + member);
addTypeMunger(world.getWeavingSupport().concreteTypeMunger(new PrivilegedAccessMunger(member), inAspect));
}

public Collection getCflowEntries() {
ArrayList ret = new ArrayList();
for (Iterator i = shadowMungers.iterator(); i.hasNext();) {
ShadowMunger m = (ShadowMunger) i.next();
if (m instanceof Advice) {
Advice a = (Advice) m;
if (a.getKind().isCflow()) {
ret.add(a);
}
}
}
return ret;
}

/**
* Updates the records if something has changed. This is called at most
* twice, firstly whilst collecting ITDs and declares. At this point the
* CrosscuttingMembers we're comparing ourselves with doesn't know about
* shadowmungers. Therefore a straight comparison with the existing list of
* shadowmungers would return that something has changed even though it
* might not have, so in this first round we ignore the shadowMungers. The
* second time this is called is whilst we're preparing to weave. At this
* point we know everything in the system and so we're able to compare the
* shadowMunger list. (see bug 129163)
*
* @param other
* @param careAboutShadowMungers
* @return true if something has changed since the last time this method was
* called, false otherwise
*/
public boolean replaceWith(CrosscuttingMembers other, boolean careAboutShadowMungers) {
boolean changed = false;

if (careAboutShadowMungers) {
if (perClause == null || !perClause.equals(other.perClause)) {
changed = true;
perClause = other.perClause;
}
}

// XXX all of the below should be set equality rather than list equality
// System.err.println("old: " + shadowMungers + " new: " +
// other.shadowMungers);

if (careAboutShadowMungers) {
// bug 129163: use set equality rather than list equality
Set theseShadowMungers = new HashSet();
Set theseInlinedAroundMungers = new HashSet();
for (Iterator iter = shadowMungers.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
if (munger instanceof Advice) {
Advice adviceMunger = (Advice) munger;
// bug 154054: if we're around advice that has been inlined
// then we need to do more checking than existing equals
// methods allow
if (!world.isXnoInline() && adviceMunger.getKind().equals(AdviceKind.Around)) {
theseInlinedAroundMungers.add(adviceMunger);
} else {
theseShadowMungers.add(adviceMunger);
}
} else {
theseShadowMungers.add(munger);
}
}
Set tempSet = new HashSet();
tempSet.addAll(other.shadowMungers);
Set otherShadowMungers = new HashSet();
Set otherInlinedAroundMungers = new HashSet();
for (Iterator iter = tempSet.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
if (munger instanceof Advice) {
Advice adviceMunger = (Advice) munger;
// bug 154054: if we're around advice that has been inlined
// then we need to do more checking than existing equals
// methods allow
if (!world.isXnoInline() && adviceMunger.getKind().equals(AdviceKind.Around)) {
otherInlinedAroundMungers.add(rewritePointcutInMunger(adviceMunger));
} else {
otherShadowMungers.add(rewritePointcutInMunger(adviceMunger));
}
} else {
otherShadowMungers.add(rewritePointcutInMunger(munger));
}
}
if (!theseShadowMungers.equals(otherShadowMungers)) {
changed = true;
}
if (!equivalent(theseInlinedAroundMungers, otherInlinedAroundMungers)) {
changed = true;
}

// bug 158573 - if there are no changes then preserve whether
// or not a particular shadowMunger has matched something.
if (!changed) {
for (Iterator iter = shadowMungers.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
int i = other.shadowMungers.indexOf(munger);
ShadowMunger otherMunger = (ShadowMunger) other.shadowMungers.get(i);
if (munger instanceof Advice) {
((Advice) otherMunger).setHasMatchedSomething(((Advice) munger).hasMatchedSomething());
}
}
}
// replace the existing list of shadowmungers with the
// new ones in case anything like the sourcelocation has
// changed, however, don't want this flagged as a change
// which will force a full build - bug 134541
shadowMungers = other.shadowMungers;
}

// bug 129163: use set equality rather than list equality and
// if we dont care about shadow mungers then ignore those
// typeMungers which are created to help with the implementation
// of shadowMungers
Set theseTypeMungers = new HashSet();
Set otherTypeMungers = new HashSet();
if (!careAboutShadowMungers) {
for (Iterator iter = typeMungers.iterator(); iter.hasNext();) {
Object o = iter.next();
if (o instanceof ConcreteTypeMunger) {
ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) o;
if (!typeMunger.existsToSupportShadowMunging()) {
theseTypeMungers.add(typeMunger);
}
} else {
theseTypeMungers.add(o);
}
}

for (Iterator iter = other.typeMungers.iterator(); iter.hasNext();) {
Object o = iter.next();
if (o instanceof ConcreteTypeMunger) {
ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) o;
if (!typeMunger.existsToSupportShadowMunging()) {
otherTypeMungers.add(typeMunger);
}
} else {
otherTypeMungers.add(o);
}
}
} else {
theseTypeMungers.addAll(typeMungers);
otherTypeMungers.addAll(other.typeMungers);
}

// initial go at equivalence logic rather than set compare (see
// pr133532)
// if (theseTypeMungers.size()!=otherTypeMungers.size()) {
// changed = true;
// typeMungers = other.typeMungers;
// } else {
// boolean foundInequality=false;
// for (Iterator iter = theseTypeMungers.iterator(); iter.hasNext() &&
// !foundInequality;) {
// Object thisOne = (Object) iter.next();
// boolean foundInOtherSet = false;
// for (Iterator iterator = otherTypeMungers.iterator();
// iterator.hasNext();) {
// Object otherOne = (Object) iterator.next();
// if (thisOne instanceof ConcreteTypeMunger && otherOne instanceof
// ConcreteTypeMunger) {
// if (((ConcreteTypeMunger)thisOne).equivalentTo(otherOne)) {
// foundInOtherSet=true;
// } else if (thisOne.equals(otherOne)) {
// foundInOtherSet=true;
// }
// } else {
// if (thisOne.equals(otherOne)) {
// foundInOtherSet=true;
// }
// }
// }
// if (!foundInOtherSet) foundInequality=true;
// }
// if (foundInequality) {
// changed = true;
// typeMungers = other.typeMungers;
// // } else {
// // typeMungers = other.typeMungers;
// }
// }
if (!theseTypeMungers.equals(otherTypeMungers)) {
changed = true;
typeMungers = other.typeMungers;
}

if (!lateTypeMungers.equals(other.lateTypeMungers)) {
changed = true;
lateTypeMungers = other.lateTypeMungers;
}

if (!declareDominates.equals(other.declareDominates)) {
changed = true;
declareDominates = other.declareDominates;
}

if (!declareParents.equals(other.declareParents)) {
changed = true;
declareParents = other.declareParents;
}

if (!declareSofts.equals(other.declareSofts)) {
changed = true;
declareSofts = other.declareSofts;
}

// DECAT for when attempting to replace an aspect
if (!declareAnnotationsOnType.equals(other.declareAnnotationsOnType)) {
changed = true;
declareAnnotationsOnType = other.declareAnnotationsOnType;
}

if (!declareAnnotationsOnField.equals(other.declareAnnotationsOnField)) {
changed = true;
declareAnnotationsOnField = other.declareAnnotationsOnField;
}

if (!declareAnnotationsOnMethods.equals(other.declareAnnotationsOnMethods)) {
changed = true;
declareAnnotationsOnMethods = other.declareAnnotationsOnMethods;
}

return changed;
}

private boolean equivalent(Set theseInlinedAroundMungers, Set otherInlinedAroundMungers) {
if (theseInlinedAroundMungers.size() != otherInlinedAroundMungers.size()) {
return false;
}
for (Iterator iter = theseInlinedAroundMungers.iterator(); iter.hasNext();) {
Advice thisAdvice = (Advice) iter.next();
boolean foundIt = false;
for (Iterator iterator = otherInlinedAroundMungers.iterator(); iterator.hasNext();) {
Advice otherAdvice = (Advice) iterator.next();
if (thisAdvice.equals(otherAdvice)) {
if (thisAdvice.getSignature() instanceof ResolvedMemberImpl) {
if (((ResolvedMemberImpl) thisAdvice.getSignature()).isEquivalentTo(otherAdvice.getSignature())) {
foundIt = true;
continue;
}
}
return false;
}
}
if (!foundIt) {
return false;
}
}
return true;
}

private ShadowMunger rewritePointcutInMunger(ShadowMunger munger) {
PointcutRewriter pr = new PointcutRewriter();
Pointcut p = munger.getPointcut();
Pointcut newP = pr.rewrite(p);
if (p.m_ignoreUnboundBindingForNames.length != 0) {// *sigh* dirty fix
// for dirty hacky
// implementation
// pr149305
newP.m_ignoreUnboundBindingForNames = p.m_ignoreUnboundBindingForNames;
}
munger.setPointcut(newP);
return munger;
}

public void setPerClause(PerClause perClause) {
if (shouldConcretizeIfNeeded) {
this.perClause = perClause.concretize(inAspect);
} else {
this.perClause = perClause;
}
}

public List getDeclareDominates() {
return declareDominates;
}

public List getDeclareParents() {
return declareParents;
}

public List getDeclareSofts() {
return declareSofts;
}

public List getShadowMungers() {
return shadowMungers;
}

public List getTypeMungers() {
return typeMungers;
}

public List getLateTypeMungers() {
return lateTypeMungers;
}

public List getDeclareAnnotationOnTypes() {
return declareAnnotationsOnType;
}

public List getDeclareAnnotationOnFields() {
return declareAnnotationsOnField;
}

/**
* includes declare @method and @constructor
*/
public List getDeclareAnnotationOnMethods() {
return declareAnnotationsOnMethods;
}

public Map getCflowBelowFields() {
return cflowBelowFields;
}

public Map getCflowFields() {
return cflowFields;
}

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

}

+ 305
- 0
org.aspectj.matcher/src/org/aspectj/weaver/CrosscuttingMembersSet.java Переглянути файл

@@ -0,0 +1,305 @@
/* *******************************************************************
* 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.util.ArrayList;
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.weaver.patterns.DeclareParents;
import org.aspectj.weaver.patterns.IVerificationRequired;
import org.aspectj.weaver.tools.Trace;
import org.aspectj.weaver.tools.TraceFactory;

/**
* This holds on to all CrosscuttingMembers for a world. It handles management of change.
*
* @author Jim Hugunin
*/
public class CrosscuttingMembersSet {
// FIXME AV - ? we may need a sequencedHashMap there to ensure source based precedence for @AJ advice
private final Map /* ResolvedType (the aspect) > CrosscuttingMembers */members = new HashMap();

private List shadowMungers = null;
private List typeMungers = null;
private List lateTypeMungers = null;
private List declareSofts = null;
private List declareParents = null;
private List declareAnnotationOnTypes = null;
private List declareAnnotationOnFields = null;
private List declareAnnotationOnMethods = null; // includes ctors
private List declareDominates = null;
private boolean changedSinceLastReset = false;

private List /* IVerificationRequired */verificationList = null; // List of things to be verified once the type system is
// 'complete'

private static Trace trace = TraceFactory.getTraceFactory().getTrace(CrosscuttingMembersSet.class);

public CrosscuttingMembersSet(World world) {
trace.enter("<init>", this, world);

trace.exit("<init>");
}

public boolean addOrReplaceAspect(ResolvedType aspectType) {
return addOrReplaceAspect(aspectType, true);
}

/**
* @return whether or not that was a change to the global signature XXX for efficiency we will need a richer representation than
* this
*/
public boolean addOrReplaceAspect(ResolvedType aspectType, boolean inWeavingPhase) {
trace.enter("addOrReplaceAspect", this, new Object[] { aspectType, new Boolean(inWeavingPhase) });

boolean change = false;
CrosscuttingMembers xcut = (CrosscuttingMembers) members.get(aspectType);
if (xcut == null) {
members.put(aspectType, aspectType.collectCrosscuttingMembers(inWeavingPhase));
clearCaches();
change = true;
} else {
if (xcut.replaceWith(aspectType.collectCrosscuttingMembers(inWeavingPhase), inWeavingPhase)) {
clearCaches();
change = true;
} else {
if (inWeavingPhase) {
// bug 134541 - even though we haven't changed we may have updated the
// sourcelocation for the shadowMunger which we need to pick up
shadowMungers = null;
}
change = false;
}
}
if (aspectType.isAbstract()) {
// we might have sub-aspects that need to re-collect their crosscutting members from us
boolean ancestorChange = addOrReplaceDescendantsOf(aspectType, inWeavingPhase);
change = change || ancestorChange;
}
changedSinceLastReset = changedSinceLastReset || change;

trace.exit("addOrReplaceAspect", change);
return change;
}

private boolean addOrReplaceDescendantsOf(ResolvedType aspectType, boolean inWeavePhase) {
// System.err.println("Looking at descendants of "+aspectType.getName());
Set knownAspects = members.keySet();
Set toBeReplaced = new HashSet();
for (Iterator it = knownAspects.iterator(); it.hasNext();) {
ResolvedType candidateDescendant = (ResolvedType) it.next();
if ((candidateDescendant != aspectType) && (aspectType.isAssignableFrom(candidateDescendant))) {
toBeReplaced.add(candidateDescendant);
}
}
boolean change = false;
for (Iterator it = toBeReplaced.iterator(); it.hasNext();) {
ResolvedType next = (ResolvedType) it.next();
boolean thisChange = addOrReplaceAspect(next, inWeavePhase);
change = change || thisChange;
}
return change;
}

public void addAdviceLikeDeclares(ResolvedType aspectType) {
CrosscuttingMembers xcut = (CrosscuttingMembers) members.get(aspectType);
xcut.addDeclares(aspectType.collectDeclares(true));
}

public boolean deleteAspect(UnresolvedType aspectType) {
boolean isAspect = members.remove(aspectType) != null;
clearCaches();
return isAspect;
}

public boolean containsAspect(UnresolvedType aspectType) {
return members.containsKey(aspectType);
}

// XXX only for testing
public void addFixedCrosscuttingMembers(ResolvedType aspectType) {
members.put(aspectType, aspectType.crosscuttingMembers);
clearCaches();
}

private void clearCaches() {
shadowMungers = null;
typeMungers = null;
lateTypeMungers = null;
declareSofts = null;
declareParents = null;
declareAnnotationOnFields = null;
declareAnnotationOnMethods = null;
declareAnnotationOnTypes = null;
declareDominates = null;
}

public List getShadowMungers() {
if (shadowMungers == null) {
ArrayList ret = new ArrayList();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getShadowMungers());
}
shadowMungers = ret;
}
return shadowMungers;
}

public List getTypeMungers() {
if (typeMungers == null) {
ArrayList ret = new ArrayList();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getTypeMungers());
}
typeMungers = ret;
}
return typeMungers;
}

public List getLateTypeMungers() {
if (lateTypeMungers == null) {
ArrayList ret = new ArrayList();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getLateTypeMungers());
}
lateTypeMungers = ret;
}
return lateTypeMungers;
}

public List getDeclareSofts() {
if (declareSofts == null) {
Set ret = new HashSet();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getDeclareSofts());
}
declareSofts = new ArrayList();
declareSofts.addAll(ret);
}
return declareSofts;
}

public List getDeclareParents() {
if (declareParents == null) {
Set ret = new HashSet();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getDeclareParents());
}
declareParents = new ArrayList();
declareParents.addAll(ret);
}
return declareParents;
}

// DECAT Merge multiple together
public List getDeclareAnnotationOnTypes() {
if (declareAnnotationOnTypes == null) {
Set ret = new HashSet();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getDeclareAnnotationOnTypes());
}
declareAnnotationOnTypes = new ArrayList();
declareAnnotationOnTypes.addAll(ret);
}
return declareAnnotationOnTypes;
}

public List getDeclareAnnotationOnFields() {
if (declareAnnotationOnFields == null) {
Set ret = new HashSet();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getDeclareAnnotationOnFields());
}
declareAnnotationOnFields = new ArrayList();
declareAnnotationOnFields.addAll(ret);
}
return declareAnnotationOnFields;
}

/**
* Return an amalgamation of the declare @method/@constructor statements.
*/
public List getDeclareAnnotationOnMethods() {
if (declareAnnotationOnMethods == null) {
Set ret = new HashSet();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getDeclareAnnotationOnMethods());
}
declareAnnotationOnMethods = new ArrayList();
declareAnnotationOnMethods.addAll(ret);
}
return declareAnnotationOnMethods;
}

public List getDeclareDominates() {
if (declareDominates == null) {
ArrayList ret = new ArrayList();
for (Iterator i = members.values().iterator(); i.hasNext();) {
ret.addAll(((CrosscuttingMembers) i.next()).getDeclareDominates());
}
declareDominates = ret;
}
return declareDominates;
}

public ResolvedType findAspectDeclaringParents(DeclareParents p) {
Set keys = this.members.keySet();
for (Iterator iter = keys.iterator(); iter.hasNext();) {
ResolvedType element = (ResolvedType) iter.next();
for (Iterator i = ((CrosscuttingMembers) members.get(element)).getDeclareParents().iterator(); i.hasNext();) {
DeclareParents dp = (DeclareParents) i.next();
if (dp.equals(p))
return element;
}
}
return null;
}

public void reset() {
verificationList = null;
changedSinceLastReset = false;
}

public boolean hasChangedSinceLastReset() {
return changedSinceLastReset;
}

/**
* Record something that needs verifying when we believe the type system is complete. Used for things that can't be verified as
* we go along - for example some recursive type variable references (pr133307)
*/
public void recordNecessaryCheck(IVerificationRequired verification) {
if (verificationList == null)
verificationList = new ArrayList();
verificationList.add(verification);
}

/**
* Called when type bindings are complete - calls all registered verification objects in turn.
*/
public void verify() {
if (verificationList == null)
return;
for (Iterator iter = verificationList.iterator(); iter.hasNext();) {
IVerificationRequired element = (IVerificationRequired) iter.next();
element.verify();
}
verificationList = null;
}

}

+ 58
- 0
org.aspectj.matcher/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();
}

+ 506
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Dump.java Переглянути файл

@@ -0,0 +1,506 @@
/* *******************************************************************
* Copyright (c) 2004 IBM Corporation
* 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:
* Matthew Webster
* ******************************************************************/
package org.aspectj.weaver;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
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.bridge.IMessage;
import org.aspectj.bridge.IMessageHolder;
import org.aspectj.bridge.Version;
import org.aspectj.weaver.tools.Trace;
import org.aspectj.weaver.tools.TraceFactory;
import org.aspectj.weaver.tools.Traceable;

/**
* @author websterm
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class Dump {

public final static String DUMP_CONDITION_PROPERTY = "org.aspectj.weaver.Dump.condition";
public final static String DUMP_DIRECTORY_PROPERTY = "org.aspectj.dump.directory";

/* Format for unique filename based on date & time */
private static final String FILENAME_PREFIX = "ajcore";
// private static final DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
// private static final DateFormat timeFormat = new SimpleDateFormat("HHmmss.SSS");
private static final String FILENAME_SUFFIX = "txt";
public static final String UNKNOWN_FILENAME = "Unknown";
public static final String DUMP_EXCLUDED = "Excluded";
public static final String NULL_OR_EMPTY = "Empty";
private static Class exceptionClass;
private static IMessage.Kind conditionKind = IMessage.ABORT;
private static File directory = new File(".");

private String reason;
private String fileName;
private PrintStream print;
private static String[] savedCommandLine;
private static List savedFullClasspath;
private static IMessageHolder savedMessageHolder;
private static Map nodes = new WeakHashMap();
private static String lastDumpFileName = UNKNOWN_FILENAME;
private static boolean preserveOnNextReset = false;
private static Trace trace = TraceFactory.getTraceFactory().getTrace(Dump.class);
/**
* for testing only, so that we can verify dump contents
* after compilation has completely finished
*/
public static void preserveOnNextReset() {
preserveOnNextReset = true;
}
public static void reset() {
if (preserveOnNextReset) {
preserveOnNextReset = false;
return;
}
else {
nodes.clear();
savedMessageHolder = null;
}
}
/*
* Dump methods
*/
public static String dump (String reason) {
String fileName = UNKNOWN_FILENAME;
Dump dump = null;
try {
dump = new Dump(reason);
fileName = dump.getFileName();
dump.dumpDefault();
}
finally {
if (dump != null) dump.close();
}
return fileName;
}
public static String dumpWithException (Throwable th) {
return dumpWithException(savedMessageHolder,th);
}
public static String dumpWithException (IMessageHolder messageHolder, Throwable th) {
if (trace.isTraceEnabled()) trace.enter("dumpWithException",null,new Object[] {messageHolder, th});

String fileName = UNKNOWN_FILENAME;
Dump dump = null;
try {
dump = new Dump(th.getClass().getName());
fileName = dump.getFileName();
dump.dumpException(messageHolder,th);
}
finally {
if (dump != null) dump.close();
}
if (trace.isTraceEnabled()) trace.exit("dumpWithException",fileName);
return fileName;
}

public static String dumpOnExit () {
return dumpOnExit(savedMessageHolder, false);
}

public static String dumpOnExit (IMessageHolder messageHolder, boolean reset) {
if (trace.isTraceEnabled()) trace.enter("dumpOnExit",null,messageHolder);
String fileName = UNKNOWN_FILENAME;
if (!shouldDumpOnExit(messageHolder)) {
fileName = DUMP_EXCLUDED;
}
else {
Dump dump = null;
try {
dump = new Dump(conditionKind.toString());
fileName = dump.getFileName();
dump.dumpDefault(messageHolder);
}
finally {
if (dump != null) dump.close();
}
}
if (reset) messageHolder.clearMessages();

if (trace.isTraceEnabled()) trace.exit("dumpOnExit",fileName);
return fileName;
}

private static boolean shouldDumpOnExit (IMessageHolder messageHolder) {
if (trace.isTraceEnabled()) trace.enter("shouldDumpOnExit",null,messageHolder);
if (trace.isTraceEnabled()) trace.event("shouldDumpOnExit",null,conditionKind);
boolean result = (messageHolder == null) || messageHolder.hasAnyMessage(conditionKind,true);
if (trace.isTraceEnabled()) trace.exit("shouldDumpOnExit",result);
return result;
}

/*
* Dump configuration
*/
public static void setDumpOnException (boolean b) {
if (b) {
exceptionClass = java.lang.Throwable.class;
}
else {
exceptionClass = null;
}
}
public static boolean setDumpDirectory (String directoryName) {
if (trace.isTraceEnabled()) trace.enter("setDumpDirectory",null,directoryName);
boolean success = false;

File newDirectory = new File(directoryName);
if (newDirectory.exists()) {
directory = newDirectory;
success = true;
}
if (trace.isTraceEnabled()) trace.exit("setDumpDirectory",success);
return success;
}
public static boolean getDumpOnException () {
return (exceptionClass != null);
}

public static boolean setDumpOnExit (IMessage.Kind condition) {
if (trace.isTraceEnabled()) trace.event("setDumpOnExit",null,condition);

conditionKind = condition;
return true;
}

public static boolean setDumpOnExit (String condition) {
for (Iterator i = IMessage.KINDS.iterator(); i.hasNext();) {
IMessage.Kind kind = (IMessage.Kind)i.next();
if (kind.toString().equals(condition)) {
return setDumpOnExit(kind);
}
}
return false;
}
public static IMessage.Kind getDumpOnExit () {
return conditionKind;
}
public static String getLastDumpFileName () {
return lastDumpFileName;
}

/*
* Dump registration
*/
public static void saveCommandLine (String[] args) {
savedCommandLine = new String[args.length];
System.arraycopy(args,0,savedCommandLine,0,args.length);
}

public static void saveFullClasspath (List list) {
savedFullClasspath = list;
}

public static void saveMessageHolder (IMessageHolder holder) {
savedMessageHolder = holder;
}

public static void registerNode (Class module, INode newNode) {
if (trace.isTraceEnabled()) trace.enter("registerNode",null,new Object[] { module, newNode} );

nodes.put(newNode,new WeakReference(newNode));

if (trace.isTraceEnabled()) trace.exit("registerNode",nodes.size());
}
/*
* Dump methods
*/
private Dump (String reason) {
if (trace.isTraceEnabled()) trace.enter("<init>",this,reason);

this.reason = reason;
openDump();
dumpAspectJProperties();
dumpDumpConfiguration();
if (trace.isTraceEnabled()) trace.exit("<init>",this);
}

public String getFileName() {
return fileName;
}
private void dumpDefault () {
dumpDefault(savedMessageHolder);
}
private void dumpDefault (IMessageHolder holder) {
dumpSytemProperties();
dumpCommandLine();
dumpFullClasspath();
dumpCompilerMessages(holder);
dumpNodes();
}

private void dumpNodes() {

/*
* Dump registered nodes
*/
IVisitor dumpVisitor = new IVisitor() {

public void visitObject (Object obj) {
println(formatObj(obj));
}

public void visitList (List list) {
println(list);
}
};
Set keys = nodes.keySet();
for (Iterator i = keys.iterator(); i.hasNext();) {
Object module = i.next();
// INode dumpNode = (INode)nodes.get(module);
INode dumpNode = (INode)module;
println("---- " + formatObj(dumpNode) + " ----");
try {
dumpNode.accept(dumpVisitor);
}
catch (Exception ex) {
trace.error(formatObj(dumpNode).toString(),ex);
}
}
}
private void dumpException (IMessageHolder messageHolder, Throwable th) {
println("---- Exception Information ---");
println(th);
dumpDefault(messageHolder);
}
private void dumpAspectJProperties () {
println("---- AspectJ Properties ---");
println("AspectJ Compiler " + Version.text + " built on " + Version.time_text);
}
private void dumpDumpConfiguration () {
println("---- Dump Properties ---");
println("Dump file: " + fileName);
println("Dump reason: " + reason);
println("Dump on exception: " + (exceptionClass != null));
println("Dump at exit condition: " + conditionKind);
}
private void dumpFullClasspath () {
println("---- Full Classpath ---");
if (savedFullClasspath != null && savedFullClasspath.size() > 0) {
for (Iterator iter = savedFullClasspath.iterator(); iter.hasNext(); ) {
String fileName = (String)iter.next();
File file = new File(fileName);
println(file);
}
}
else {
println(NULL_OR_EMPTY);
}
}
private void dumpSytemProperties () {
println("---- System Properties ---");
Properties props = System.getProperties();
println(props);
}
private void dumpCommandLine () {
println("---- Command Line ---");
println(savedCommandLine);
}
private void dumpCompilerMessages (IMessageHolder messageHolder) {
println("---- Compiler Messages ---");
if (messageHolder != null) for (Iterator i = messageHolder.getUnmodifiableListView().iterator(); i.hasNext(); ) {
IMessage message = (IMessage)i.next();
println(message.toString());
}
else {
println(NULL_OR_EMPTY);
}
}

/*
* Dump output
*/
private void openDump () {
if (print != null) return;
Date now = new Date();
fileName = FILENAME_PREFIX + "."
+ new SimpleDateFormat("yyyyMMdd").format(now) + "."
+ new SimpleDateFormat("HHmmss.SSS").format(now) + "."
+ FILENAME_SUFFIX;
try {
File file = new File(directory,fileName);
print = new PrintStream(new FileOutputStream(file),true);
trace.info("Dumping to " + file.getAbsolutePath());
}
catch (Exception ex) {
print = System.err;
trace.info("Dumping to stderr");
fileName = UNKNOWN_FILENAME;
}
lastDumpFileName = fileName;
}
public void close () {
print.close();
}
private void println (Object obj) {
print.println(obj);
}
private void println (Object[] array) {
if (array == null) {
println(NULL_OR_EMPTY);
return;
}
for (int i = 0; i < array.length; i++) {
print.println(array[i]);
}
}
private void println (Properties props) {
Iterator iter = props.keySet().iterator();
while (iter.hasNext()) {
String key = (String)iter.next();
String value = props.getProperty(key);
print.println(key + "=" + value);
}
}
private void println (Throwable th) {
th.printStackTrace(print);
}
private void println (File file) {
print.print(file.getAbsolutePath());
if (!file.exists()) {
println("(missing)");
}
else if (file.isDirectory()) {
int count = file.listFiles().length;
println("(" + count + " entries)");
}
else {
println("(" + file.length() + " bytes)");
}
}
private void println (List list) {
if (list == null || list.isEmpty()) println(NULL_OR_EMPTY);
else for (Iterator i = list.iterator(); i.hasNext();) {
Object o = i.next();
if (o instanceof Exception) {
println((Exception)o);
} else {
println(o.toString());
}
}
}
private static Object formatObj(Object obj) {
/* These classes have a safe implementation of toString() */
if (obj == null
|| obj instanceof String
|| obj instanceof Number
|| obj instanceof Boolean
|| obj instanceof Exception
|| obj instanceof Character
|| obj instanceof Class
|| obj instanceof File
|| obj instanceof StringBuffer
|| obj instanceof URL
) return obj;
else try {
/* Classes can provide an alternative implementation of toString() */
if (obj instanceof Traceable) {
Traceable t = (Traceable)obj;
return t.toTraceString();
}
/* Use classname@hashcode */
else return obj.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(obj));
/* Object.hashCode() can be override and may thow an exception */
} catch (Exception ex) {
return obj.getClass().getName() + "@FFFFFFFF";
}
}
static {
String exceptionName = System.getProperty("org.aspectj.weaver.Dump.exception","true");
if (!exceptionName.equals("false")) setDumpOnException(true);
String conditionName = System.getProperty(DUMP_CONDITION_PROPERTY);
if (conditionName != null) setDumpOnExit(conditionName);
String directoryName = System.getProperty(DUMP_DIRECTORY_PROPERTY);
if (directoryName != null) setDumpDirectory(directoryName);
}

public interface INode {
public void accept (IVisitor visior);
}

public interface IVisitor {
public void visitObject (Object s);
public void visitList (List list);
}

}

+ 37
- 0
org.aspectj.matcher/src/org/aspectj/weaver/EnumAnnotationValue.java Переглянути файл

@@ -0,0 +1,37 @@
/* *******************************************************************
* Copyright (c) 2006 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 IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;

public class EnumAnnotationValue extends AnnotationValue {

private String type;
private String value;
public EnumAnnotationValue(String type,String value) {
super(AnnotationValue.ENUM_CONSTANT);
this.type = type;
this.value = value;
}
public String getType() {
return type;
}
public String stringify() {
return value;
}
public String toString() {
return value;
}

}

+ 30
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ExposeTypeMunger.java Переглянути файл

@@ -0,0 +1,30 @@
/* *******************************************************************
* 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:
* Andy Clement, IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;

/**
* Special kind of privileged access munger which exposes a type to be public.
*/
public class ExposeTypeMunger extends PrivilegedAccessMunger {

public ExposeTypeMunger(UnresolvedType typeToExpose) {
super(new ResolvedMemberImpl(Member.STATIC_INITIALIZATION, typeToExpose, 0, ResolvedType.VOID, "<clinit>", UnresolvedType.NONE));
}

public String toString() {
return "ExposeTypeMunger("+getSignature().getDeclaringType().getName()+")";
}

public String getExposedTypeSignature() {
return getSignature().getDeclaringType().getSignature();
}
}

+ 158
- 0
org.aspectj.matcher/src/org/aspectj/weaver/GeneratedReferenceTypeDelegate.java Переглянути файл

@@ -0,0 +1,158 @@
/* *******************************************************************
* 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://eclipse.org/legal/epl-v10.html
*
* ******************************************************************/
package org.aspectj.weaver;

import java.util.Collection;

import org.aspectj.weaver.patterns.PerClause;

/**
* A delegate that can sit in the ReferenceType instance created for an aspect generated from aop.xml. Only answers the minimal set
* of information required as the type is processed.
*
* @author Andy Clement
*/
public class GeneratedReferenceTypeDelegate extends AbstractReferenceTypeDelegate {

private ResolvedType superclass;

public GeneratedReferenceTypeDelegate(ReferenceType backing) {
super(backing, false);
}

public void addAnnotation(AnnotationAJ annotationX) {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isAspect() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isAnnotationStyleAspect() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isInterface() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isEnum() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isAnnotation() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isAnnotationWithRuntimeRetention() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isAnonymous() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isNested() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public ResolvedType getOuterClass() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public String getRetentionPolicy() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean canAnnotationTargetType() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public AnnotationTargetKind[] getAnnotationTargetKinds() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean isGeneric() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public String getDeclaredGenericSignature() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public boolean hasAnnotation(UnresolvedType ofType) {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public AnnotationAJ[] getAnnotations() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public ResolvedType[] getAnnotationTypes() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public ResolvedMember[] getDeclaredFields() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public ResolvedType[] getDeclaredInterfaces() {
return ResolvedType.NONE;
}

public ResolvedMember[] getDeclaredMethods() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public ResolvedMember[] getDeclaredPointcuts() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public PerClause getPerClause() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public Collection getDeclares() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public Collection getTypeMungers() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public Collection getPrivilegedAccesses() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public int getModifiers() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public void setSuperclass(ResolvedType superclass) {
this.superclass = superclass;
}

public ResolvedType getSuperclass() {
return this.superclass;
}

public WeaverStateInfo getWeaverState() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public TypeVariable[] getTypeVariables() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

public void ensureDelegateConsistent() {
throw new UnsupportedOperationException("Not supported for GeneratedReferenceTypeDelegate");
}

}

+ 43
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IClassFileProvider.java Переглянути файл

@@ -0,0 +1,43 @@
/*******************************************************************************
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.weaver;

import java.util.Iterator;

/**
* @author colyer
*
* Clients implementing the IClassFileProvider can have a set of class files under
* their control woven by a weaver, by calling the weave(IClassFileProvider source) method.
* The contract is that a call to getRequestor().acceptResult() is providing a result for
* the class file most recently returned from the getClassFileIterator().
*/
public interface IClassFileProvider {
/**
* Answer an iterator that can be used to iterate over a set of UnwovenClassFiles to
* be woven. During a weave, this method may be called multiple times.
* @return iterator over UnwovenClassFiles.
*/
Iterator getClassFileIterator();
/**
* The client to which the woven results should be returned.
*/
IWeaveRequestor getRequestor();

/**
* @return true if weaver should only do some internal munging as the one needed
* for @AspectJ aspectOf methods creation
*/
boolean isApplyAtAspectJMungersOnly();

}

+ 29
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IClassWeaver.java Переглянути файл

@@ -0,0 +1,29 @@
/* *******************************************************************
* 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;

/**
* An IClassWeaver is initialized with a class (a type, really, but let's ignore that for now)
* and a world, and has one method that actually weaves the contents of the world into the class
* implementation.
*/

public interface IClassWeaver {
/** perform the weaving.
*
* @return <code>true</code> if the class is changed by the weaving, <code>false</code> otherwise.
*/
boolean weave();
}

+ 23
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ICrossReferenceHandler.java Переглянути файл

@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2000, 2003 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.weaver;

import org.aspectj.bridge.ISourceLocation;

/**
* Clients can pass a single cross-reference handler to the weaver on construction of a BcelWorld. Any cross-references detected
* during munging will be notified to the handler.
*/
public interface ICrossReferenceHandler {

void addCrossReference(ISourceLocation from, ISourceLocation to, String kind, boolean runtimeTest);

}

+ 16
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IEclipseSourceContext.java Переглянути файл

@@ -0,0 +1,16 @@
/********************************************************************
* Copyright (c) 2006 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: IBM Corporation - initial API and implementation
* Helen Hawkins - iniital version
*******************************************************************/
package org.aspectj.weaver;


public interface IEclipseSourceContext extends ISourceContext {
public void removeUnnecessaryProblems(Member method, int problemLineNumber);
}

+ 33
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IHasPosition.java Переглянути файл

@@ -0,0 +1,33 @@
/* *******************************************************************
* 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;

public interface IHasPosition {
/**
* The starting index of this location in the character stream.
*/
int getStart();
/**
* The ending index of this location in the character stream
*
* This points to the last character in this token.
*
* If a location truly had no contents, then start == end + 1. We don't recommend this.
*/
int getEnd();
//
// String getFileName();

}

+ 21
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IHasSourceLocation.java Переглянути файл

@@ -0,0 +1,21 @@
/* *******************************************************************
* 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 org.aspectj.bridge.ISourceLocation;

public interface IHasSourceLocation extends IHasPosition {
ISourceContext getSourceContext();
ISourceLocation getSourceLocation();
}

+ 23
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ISourceContext.java Переглянути файл

@@ -0,0 +1,23 @@
/* *******************************************************************
* 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 org.aspectj.bridge.ISourceLocation;

public interface ISourceContext {
public ISourceLocation makeSourceLocation(IHasPosition position);
public ISourceLocation makeSourceLocation(int line, int offset);
public int getOffset();
public void tidy();
}

+ 26
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IUnwovenClassFile.java Переглянути файл

@@ -0,0 +1,26 @@
/* *******************************************************************
* 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
*
* ******************************************************************/
package org.aspectj.weaver;

/**
* History: 246125
* @author Andy Clement
*/
public interface IUnwovenClassFile {

String getFilename();

String getClassName();

byte[] getBytes();

char[] getClassNameAsChars();

}

+ 38
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IWeaveRequestor.java Переглянути файл

@@ -0,0 +1,38 @@
/*******************************************************************************
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.weaver;


/**
* @author colyer
*
* This interface is implemented by clients driving weaving through the IClassFileProvider interface. It is used by the
* weaver to return woven class file results back to the client. The client can correlate weave results with inputs since it
* knows the last UnwovenClassFile returned by its iterator.
*/
public interface IWeaveRequestor {

/*
* A class file resulting from a weave (yes, even though the type name says "unwoven"...).
*/
void acceptResult(IUnwovenClassFile result);

// various notifications to the requestor about our progress...
void processingReweavableState();

void addingTypeMungers();

void weavingAspects();

void weavingClasses();

void weaveCompleted();
}

+ 44
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IWeavingSupport.java Переглянути файл

@@ -0,0 +1,44 @@
/* *******************************************************************
* 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 org.aspectj.weaver.ast.Var;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;

/**
* Encapsulates operations that a world will need to support if it is actually going to modify bytecode rather than just match
* against it. {@see BcelWeavingSupport}
*
* @author Andy Clement
*/
public interface IWeavingSupport {

public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature);

public abstract ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField);

public abstract ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField);

/**
* Register a munger for perclause @AJ aspect so that we add aspectOf(..) to them as needed
*
* @see org.aspectj.weaver.bcel.BcelWorld#makePerClauseAspect(ResolvedType, org.aspectj.weaver.patterns.PerClause.Kind)
*/
public abstract ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind);

public abstract ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType);

public ConcreteTypeMunger createAccessForInlineMunger(ResolvedType inAspect);

public Var makeCflowAccessVar(ResolvedType formalType, Member cflowField, int arrayIndex);
}

+ 147
- 0
org.aspectj.matcher/src/org/aspectj/weaver/IntMap.java Переглянути файл

@@ -0,0 +1,147 @@
/* *******************************************************************
* 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.util.ArrayList;
import java.util.List;

public class IntMap {
// public static final IntMap EMPTY = new IntMap(0) {
// public boolean directlyInAdvice() { return true; }
// public ShadowMunger getEnclosingAdvice() { return null; } //XXX possible
// };

// XXX begin hack to avoid a signature refactoring in Pointcut
private ResolvedType concreteAspect;
private ShadowMunger enclosingAdvice;
private List/* ResolvedPointcutDefinition */enclosingDefinition = new ArrayList();

public void pushEnclosingDefinition(ResolvedPointcutDefinition def) {
enclosingDefinition.add(def);
}

public void popEnclosingDefinitition() {
enclosingDefinition.remove(enclosingDefinition.size() - 1);
}

public ResolvedPointcutDefinition peekEnclosingDefinition() {
if (enclosingDefinition.size() == 0)
return null;
return (ResolvedPointcutDefinition) enclosingDefinition.get(enclosingDefinition.size() - 1);
}

public boolean directlyInAdvice() {
return enclosingDefinition.isEmpty();
}

public ShadowMunger getEnclosingAdvice() {
return enclosingAdvice;
}

public void setEnclosingAdvice(ShadowMunger advice) {
this.enclosingAdvice = advice;
}

public Member getAdviceSignature() {
if (enclosingAdvice instanceof Advice)
return ((Advice) enclosingAdvice).getSignature();
else
return null;
}

public ResolvedType getConcreteAspect() {
return concreteAspect;
}

public void setConcreteAspect(ResolvedType concreteAspect) {
this.concreteAspect = concreteAspect;
}

public void copyContext(IntMap bindings) {
this.enclosingAdvice = bindings.enclosingAdvice;
this.enclosingDefinition = bindings.enclosingDefinition;
this.concreteAspect = bindings.concreteAspect;
}

// XXX end hack to avoid a signature refactoring in Pointcut

private static final int MISSING = -1;

private int[] map;

private IntMap(int[] map) {
this.map = map;
}

public IntMap() {
map = new int[0];
}

public IntMap(int initialCapacity) {
map = new int[initialCapacity];
for (int i = 0; i < initialCapacity; i++) {
map[i] = MISSING;
}
}

public void put(int key, int val) {
/* assert (val >= 0 && key >= 0) */
if (key >= map.length) {
int[] tmp = new int[key * 2 + 1]; // ??? better expansion function
System.arraycopy(map, 0, tmp, 0, map.length);
for (int i = map.length, len = tmp.length; i < len; i++)
tmp[i] = MISSING;
map = tmp;
}
map[key] = val;
}

public int get(int key) {
return map[key];
}

public boolean hasKey(int key) {
return (key < map.length && map[key] != MISSING);
}

// ---- factory methods

public static IntMap idMap(int size) {
int[] map = new int[size];
for (int i = 0; i < size; i++) {
map[i] = i;
}
return new IntMap(map);
}

// ---- from object

public String toString() {
StringBuffer buf = new StringBuffer("[");
boolean seenFirst = false;
for (int i = 0, len = map.length; i < len; i++) {
if (map[i] != MISSING) {
if (seenFirst) {
buf.append(", ");
}
seenFirst = true;
buf.append(i);
buf.append(" -> ");
buf.append(map[i]);
}
}
buf.append("]");
return buf.toString();
}

}

+ 264
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Iterators.java Переглянути файл

@@ -0,0 +1,264 @@
/* *******************************************************************
* 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.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;

public final class Iterators {

/**
* Private constructor, nobody should ever make one of these
*/
private Iterators() {
}

/**
* A getter represents a mapping function from Object to Iterator
*/
public interface Getter {
Iterator get(Object target);
}

/**
* A filter represents a mapping function from Iterator to Iterator
*/
public interface Filter {
Iterator filter(Iterator in);
}

/**
* Create a new filter F that, when wrapped around another iterator I, creates a new iterator I' that will return only those
* values of I that have not yet been returned by I', discarding duplicates.
*/
public static Filter dupFilter() {
return new Filter() {
final Set seen = new HashSet(); // should have weak ptrs?

public Iterator filter(final Iterator in) {
return new Iterator() {
boolean fresh = false;
Object peek;

public boolean hasNext() {
if (fresh)
return true;
while (true) {
if (!in.hasNext())
return false;
peek = in.next();
if (!seen.contains(peek)) {
return fresh = true;
} else {
peek = null; // garbage collection
}
}
}

public Object next() {
if (!hasNext())
throw new NoSuchElementException();
Object ret = peek;
peek = null;
fresh = false;
return ret;
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}

/**
* Creates an iterator that will return the elements of a specified array, in order. Like Arrays.asList(o).iterator(), without
* all that pesky safety.
*/

public static Iterator array(final Object[] o) {
return new Iterator() {
int i = 0;
int len = (o == null) ? 0 : o.length;

public boolean hasNext() {
return i < len;
}

public Object next() {
if (i < len) {
return o[i++];
} else {
throw new NoSuchElementException();
}
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}

/**
* creates an iterator I based on a base iterator A and a getter G. I returns, in order, forall (i in I), G(i).
*/
public static Iterator mapOver(final Iterator a, final Getter g) {
return new Iterator() {
Iterator delegate = new Iterator() {
public boolean hasNext() {
if (!a.hasNext())
return false;
Object o = a.next();
delegate = append1(g.get(o), this);
return delegate.hasNext();
}

public Object next() {
if (!hasNext())
throw new UnsupportedOperationException();
return delegate.next();
}

public void remove() {
throw new UnsupportedOperationException();
}
};

public boolean hasNext() {
return delegate.hasNext();
}

public Object next() {
return delegate.next();
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}

/**
* creates an iterator I based on a base iterator A and a getter G. I returns, in order, forall (i in I) i :: forall (i' in
* g(i)) recur(i', g)
*/
public static Iterator recur(final Object a, final Getter g) {
return new Iterator() {
Iterator delegate = one(a);

public boolean hasNext() {
return delegate.hasNext();
}

public Object next() {
Object next = delegate.next();
delegate = append(g.get(next), delegate);
return next;
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}

/**
* creates an iterator I based on base iterators A and B. Returns the elements returned by A followed by those returned by B. If
* B is empty, simply returns A, and if A is empty, simply returns B. Do NOT USE if b.hasNext() is not idempotent.
*/
public static Iterator append(final Iterator a, final Iterator b) {
if (!b.hasNext())
return a;
return append1(a, b);
}

/**
* creates an iterator I based on base iterators A and B. Returns the elements returned by A followed by those returned by B. If
* A is empty, simply returns B. Guaranteed not to call B.hasNext() until A is empty.
*/
public static Iterator append1(final Iterator a, final Iterator b) {
if (!a.hasNext())
return b;
return new Iterator() {
public boolean hasNext() {
return a.hasNext() || b.hasNext();
}

public Object next() {
if (a.hasNext())
return a.next();
if (b.hasNext())
return b.next();
throw new NoSuchElementException();
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}

/**
* creates an iterator I based on a base iterator A and an object O. Returns the elements returned by A, followed by O.
*/
public static Iterator snoc(final Iterator first, final Object last) {
return new Iterator() {
Object last1 = last;

public boolean hasNext() {
return first.hasNext() || last1 != null;
}

public Object next() {
if (first.hasNext())
return first.next();
else if (last1 == null)
throw new NoSuchElementException();
Object ret = last1;
last1 = null;
return ret;
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}

/**
* creates an iterator I based on an object O. Returns O, once.
*/
public static Iterator one(final Object it) {
return new Iterator() {
boolean avail = true;

public boolean hasNext() {
return avail;
}

public Object next() {
if (!avail)
throw new NoSuchElementException();
avail = false;
return it;
}

public void remove() {
throw new UnsupportedOperationException();
}
};
}
}

+ 409
- 0
org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignature.java Переглянути файл

@@ -0,0 +1,409 @@
/* *******************************************************************
* 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;

import java.io.DataOutputStream;
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;

/**
* @author colyer Instances of this class are created by
* ResolvedMember.getSignatures() when collating all of the signatures
* for a member. We need to create entries in the set for the "gaps" in
* the hierarchy. For example:
*
* class A { void foo(); }
*
* class B extends A {}
*
* Join Point : call(* B.foo())
*
* has signatures:
*
* B.foo() AND A.foo() B.foo() will be created as a
* ResolvedMemberWithSubstituteDeclaringType
*
* Oh for a JDK 1.4 dynamic proxy.... we have to run on 1.3 :(
*/
public class JoinPointSignature implements ResolvedMember {

private ResolvedMember realMember;
private ResolvedType substituteDeclaringType;

public JoinPointSignature(ResolvedMember backing, ResolvedType aType) {
this.realMember = backing;
this.substituteDeclaringType = aType;
}

public UnresolvedType getDeclaringType() {
return substituteDeclaringType;
}

public int getModifiers(World world) {
return realMember.getModifiers(world);
}

public int getModifiers() {
return realMember.getModifiers();
}

public UnresolvedType[] getExceptions(World world) {
return realMember.getExceptions(world);
}

public UnresolvedType[] getExceptions() {
return realMember.getExceptions();
}

public ShadowMunger getAssociatedShadowMunger() {
return realMember.getAssociatedShadowMunger();
}

public boolean isAjSynthetic() {
return realMember.isAjSynthetic();
}

public boolean hasAnnotations() {
return realMember.hasAnnotations();
}

public boolean hasAnnotation(UnresolvedType ofType) {
return realMember.hasAnnotation(ofType);
}

public ResolvedType[] getAnnotationTypes() {
return realMember.getAnnotationTypes();
}

public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
return realMember.getAnnotationOfType(ofType);
}

public void setAnnotationTypes(UnresolvedType[] annotationtypes) {
realMember.setAnnotationTypes(annotationtypes);
}

public void addAnnotation(AnnotationAJ annotation) {
realMember.addAnnotation(annotation);
}

public boolean isBridgeMethod() {
return realMember.isBridgeMethod();
}

public boolean isVarargsMethod() {
return realMember.isVarargsMethod();
}

public boolean isSynthetic() {
return realMember.isSynthetic();
}

public void write(DataOutputStream s) throws IOException {
realMember.write(s);
}

public ISourceContext getSourceContext(World world) {
return realMember.getSourceContext(world);
}

public String[] getParameterNames() {
return realMember.getParameterNames();
}

public void setParameterNames(String[] names) {
realMember.setParameterNames(names);
}

public String[] getParameterNames(World world) {
return realMember.getParameterNames(world);
}

public EffectiveSignatureAttribute getEffectiveSignature() {
return realMember.getEffectiveSignature();
}

public ISourceLocation getSourceLocation() {
return realMember.getSourceLocation();
}

public int getEnd() {
return realMember.getEnd();
}

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

public int getStart() {
return realMember.getStart();
}

public void setPosition(int sourceStart, int sourceEnd) {
realMember.setPosition(sourceStart, sourceEnd);
}

public void setSourceContext(ISourceContext sourceContext) {
realMember.setSourceContext(sourceContext);
}

public boolean isAbstract() {
return realMember.isAbstract();
}

public boolean isPublic() {
return realMember.isPublic();
}

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

public boolean isNative() {
return realMember.isNative();
}

public boolean isDefault() {
return realMember.isDefault();
}

public boolean isVisible(ResolvedType fromType) {
return realMember.isVisible(fromType);
}

public void setCheckedExceptions(UnresolvedType[] checkedExceptions) {
realMember.setCheckedExceptions(checkedExceptions);
}

public void setAnnotatedElsewhere(boolean b) {
realMember.setAnnotatedElsewhere(b);
}

public boolean isAnnotatedElsewhere() {
return realMember.isAnnotatedElsewhere();
}

public UnresolvedType getGenericReturnType() {
return realMember.getGenericReturnType();
}

public UnresolvedType[] getGenericParameterTypes() {
return realMember.getGenericParameterTypes();
}

public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized) {
return realMember.parameterizedWith(typeParameters, newDeclaringType,
isParameterized);
}

public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized, List aliases) {
return realMember.parameterizedWith(typeParameters, newDeclaringType,
isParameterized, aliases);
}

public void setTypeVariables(TypeVariable[] types) {
realMember.setTypeVariables(types);
}

public TypeVariable[] getTypeVariables() {
return realMember.getTypeVariables();
}

public TypeVariable getTypeVariableNamed(String name) {
return realMember.getTypeVariableNamed(name);
}

public boolean matches(ResolvedMember aCandidateMatch) {
return realMember.matches(aCandidateMatch);
}

public ResolvedMember resolve(World world) {
return realMember.resolve(world);
}

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

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

public UnresolvedType getReturnType() {
return realMember.getReturnType();
}

public UnresolvedType getType() {
return realMember.getType();
}

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

public UnresolvedType[] getParameterTypes() {
return realMember.getParameterTypes();
}

public AnnotationAJ[][] getParameterAnnotations() {
return realMember.getParameterAnnotations();
}

public ResolvedType[][] getParameterAnnotationTypes() {
return realMember.getParameterAnnotationTypes();
}

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

public int getArity() {
return realMember.getArity();
}

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

public boolean isCompatibleWith(Member am) {
return realMember.isCompatibleWith(am);
}

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

public boolean isInterface() {
return realMember.isInterface();
}

public boolean isPrivate() {
return realMember.isPrivate();
}

public boolean canBeParameterized() {
return realMember.canBeParameterized();
}

public AnnotationAJ[] getAnnotations() {
return realMember.getAnnotations();
}

public Collection getDeclaringTypes(World world) {
throw new UnsupportedOperationException(
"Adrian doesn't think you should be calling this...");
}

public Iterator getJoinPointSignatures(World world) {
return realMember.getJoinPointSignatures(world);
}

public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(getReturnType().getName());
buf.append(' ');
buf.append(getDeclaringType().getName());
buf.append('.');
buf.append(getName());
if (getKind() != FIELD) {
buf.append("(");
UnresolvedType[] parameterTypes = getParameterTypes();
if (parameterTypes.length != 0) {
buf.append(parameterTypes[0]);
for (int i = 1, len = parameterTypes.length; i < len; i++) {
buf.append(", ");
buf.append(parameterTypes[i].getName());
}
}
buf.append(")");
}
return buf.toString();
}

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

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

public void resetName(String newName) {
realMember.resetName(newName);
}

public void resetKind(MemberKind newKind) {
realMember.resetKind(newKind);
}

public void resetModifiers(int newModifiers) {
realMember.resetModifiers(newModifiers);
}

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

public boolean equals(Object obj) {
if (!(obj instanceof JoinPointSignature))
return false;
JoinPointSignature other = (JoinPointSignature) obj;
if (!realMember.equals(other.realMember))
return false;
if (!substituteDeclaringType.equals(other.substituteDeclaringType))
return false;
return true;
}

public int hashCode() {
return 17 + (37 * realMember.hashCode())
+ (37 * substituteDeclaringType.hashCode());
}

public boolean hasBackingGenericMember() {
return realMember.hasBackingGenericMember();
}

public ResolvedMember getBackingGenericMember() {
return realMember.getBackingGenericMember();
}

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

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

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

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

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

+ 251
- 0
org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignatureIterator.java Переглянути файл

@@ -0,0 +1,251 @@
/* *******************************************************************
* 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;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

/**
* Iterates over the signatures of a join point, calculating new signatures
* lazily to minimize processing and to avoid unneccessary "can't find type"
* errors. Iterator can be cached and reused by calling the "reset" method
* between iterations.
*/
public class JoinPointSignatureIterator implements Iterator {
private Member signaturesOfMember;
private ResolvedMember firstDefiningMember;
ResolvedType firstDefiningType;
private World world;
private List /*JoinPointSignature*/ discoveredSignatures = new ArrayList();
private List additionalSignatures = Collections.EMPTY_LIST;
private Iterator discoveredSignaturesIterator = null;
private Iterator superTypeIterator = null;
private Set visitedSuperTypes = new HashSet();
private List /*SearchPair*/ yetToBeProcessedSuperMembers = null;//new ArrayList();
private boolean iteratingOverDiscoveredSignatures = true;
private boolean couldBeFurtherAsYetUndiscoveredSignatures = true;
/**
*
*/
public JoinPointSignatureIterator(Member joinPointSignature, World inAWorld) {
this.signaturesOfMember = joinPointSignature;
this.world = inAWorld;
addSignaturesUpToFirstDefiningMember();
if (!shouldWalkUpHierarchy()) couldBeFurtherAsYetUndiscoveredSignatures = false;
}

public void reset() {
discoveredSignaturesIterator = discoveredSignatures.iterator();
additionalSignatures.clear();
iteratingOverDiscoveredSignatures = true;
}
/* (non-Javadoc)
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
if (iteratingOverDiscoveredSignatures && discoveredSignaturesIterator.hasNext()) {
return true;
} else if (couldBeFurtherAsYetUndiscoveredSignatures) {
if (additionalSignatures.size() > 0) return true;
else return findSignaturesFromSupertypes();
} else {
return false;
}
}

/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Object next() {
if (iteratingOverDiscoveredSignatures && discoveredSignaturesIterator.hasNext()) {
return discoveredSignaturesIterator.next();
} else {
if (additionalSignatures.size() > 0) {
return additionalSignatures.remove(0);
}
}
throw new NoSuchElementException();
}

/* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
public void remove() {
throw new UnsupportedOperationException("can't remove from JoinPointSignatureIterator");
}
private void addSignaturesUpToFirstDefiningMember() {
// Walk up hierarchy creating one member for each type up to and including the
// first defining type
ResolvedType originalDeclaringType = signaturesOfMember.getDeclaringType().resolve(world);
if (world.isJoinpointArrayConstructionEnabled() && originalDeclaringType.isArray()) { // Aha, this must be the array constructor call join point - a 'special'...
Member m = signaturesOfMember;
ResolvedMember rm = new ResolvedMemberImpl(m.getKind(),m.getDeclaringType(),m.getModifiers(),m.getReturnType(),m.getName(),m.getParameterTypes());
discoveredSignatures.add(new JoinPointSignature(rm,originalDeclaringType));
couldBeFurtherAsYetUndiscoveredSignatures = false;
return;
}

firstDefiningMember = signaturesOfMember.resolve(world);
if (firstDefiningMember == null) {
couldBeFurtherAsYetUndiscoveredSignatures = false;
return;
}
// declaringType can be unresolved if we matched a synthetic member generated by Aj...
// should be fixed elsewhere but add this resolve call on the end for now so that we can
// focus on one problem at a time...
firstDefiningType = firstDefiningMember.getDeclaringType().resolve(world);
if (firstDefiningType != originalDeclaringType) {
if (signaturesOfMember.getKind() == Member.CONSTRUCTOR) {
return;
}
}

List declaringTypes = new ArrayList();
accumulateTypesInBetween(originalDeclaringType,
firstDefiningType,
declaringTypes);
for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
ResolvedType declaringType = (ResolvedType) iter.next();
ResolvedMember member = ((ResolvedMemberImpl)firstDefiningMember).withSubstituteDeclaringType(declaringType);
discoveredSignatures.add(member);
}
}
/**
* Build a list containing every type between subtype and supertype, inclusively.
*/
private void accumulateTypesInBetween(ResolvedType subType, ResolvedType superType, List types) {
types.add(subType);
if (subType == superType) {
return;
} else {
for (Iterator iter = subType.getDirectSupertypes(); iter.hasNext();) {
ResolvedType parent = (ResolvedType) iter.next();
if (superType.isAssignableFrom(parent,true)) {
accumulateTypesInBetween(parent, superType,types);
}
}
}
}
private boolean shouldWalkUpHierarchy() {
if (signaturesOfMember.getKind() == Member.CONSTRUCTOR) return false;
if (signaturesOfMember.getKind() == Member.FIELD) return false;
if (signaturesOfMember.isStatic()) return false;
return true;
}
private boolean findSignaturesFromSupertypes() {
iteratingOverDiscoveredSignatures = false;
if (superTypeIterator == null) {
superTypeIterator = firstDefiningType.getDirectSupertypes();
}
if (superTypeIterator.hasNext()) {
ResolvedType superType = (ResolvedType) superTypeIterator.next();
if (visitedSuperTypes.contains(superType)) {
return findSignaturesFromSupertypes();
} else {
// we haven't looked in this type yet
visitedSuperTypes.add(superType);
if (superType.isMissing()) {
// issue a warning, stop looking for join point signatures in this line
warnOnMissingType(superType);
return findSignaturesFromSupertypes();
}
ResolvedMemberImpl foundMember = (ResolvedMemberImpl) superType.lookupResolvedMember(firstDefiningMember,true);
if (foundMember != null && isVisibleTo(firstDefiningMember,foundMember)) {
List declaringTypes = new ArrayList();
// declaring type can be unresolved if the member can from an ITD...
ResolvedType resolvedDeclaringType = foundMember.getDeclaringType().resolve(world);
accumulateTypesInBetween(superType, resolvedDeclaringType, declaringTypes);
for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
ResolvedType declaringType = (ResolvedType) iter.next();
ResolvedMember member = foundMember.withSubstituteDeclaringType(declaringType);
discoveredSignatures.add(member); // for next time we are reset
if (additionalSignatures==Collections.EMPTY_LIST) additionalSignatures=new ArrayList();
additionalSignatures.add(member); // for this time
}
// if this was a parameterized type, look in the generic type that backs it too
if (superType.isParameterizedType() && (foundMember.backingGenericMember != null)) {
ResolvedMember member =new JoinPointSignature(foundMember.backingGenericMember,foundMember.declaringType.resolve(world));
discoveredSignatures.add(member); // for next time we are reset
if (additionalSignatures==Collections.EMPTY_LIST) additionalSignatures=new ArrayList();
additionalSignatures.add(member); // for this time
}
if (yetToBeProcessedSuperMembers==null) yetToBeProcessedSuperMembers=new ArrayList();
yetToBeProcessedSuperMembers.add(new SearchPair(foundMember,superType));
return true;
} else {
return findSignaturesFromSupertypes();
}
}
}
if (yetToBeProcessedSuperMembers!=null && !yetToBeProcessedSuperMembers.isEmpty()) {
SearchPair nextUp = (SearchPair) yetToBeProcessedSuperMembers.remove(0);
firstDefiningType = nextUp.type;
firstDefiningMember = nextUp.member;
superTypeIterator = null;
return findSignaturesFromSupertypes();
}
couldBeFurtherAsYetUndiscoveredSignatures = false;
return false;
}
/**
* Returns true if the parent member is visible to the child member
* In the same declaring type this is always true, otherwise if parent is private
* it is false.
* @param childMember
* @param parentMember
* @return
*/
private boolean isVisibleTo(ResolvedMember childMember, ResolvedMember parentMember) {
if (childMember.getDeclaringType().equals(parentMember.getDeclaringType())) return true;
if (Modifier.isPrivate(parentMember.getModifiers())) {
return false;
} else {
return true;
}
}
private void warnOnMissingType(ResolvedType missing) {
if (missing instanceof MissingResolvedTypeWithKnownSignature) {
// which it should be...
MissingResolvedTypeWithKnownSignature mrt = (MissingResolvedTypeWithKnownSignature) missing;
mrt.raiseWarningOnJoinPointSignature(signaturesOfMember.toString());
}
}
private static class SearchPair {
public ResolvedMember member;
public ResolvedType type;
public SearchPair(ResolvedMember member, ResolvedType type) {
this.member = member;
this.type = type;
}
}

}

+ 315
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Lint.java Переглянути файл

@@ -0,0 +1,315 @@
/* *******************************************************************
* 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.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.tools.Trace;
import org.aspectj.weaver.tools.TraceFactory;

public class Lint {
/* private */Map kinds = new HashMap();
/* private */World world;

public final Kind invalidAbsoluteTypeName = new Kind("invalidAbsoluteTypeName", "no match for this type name: {0}");

public final Kind invalidWildcardTypeName = new Kind("invalidWildcardTypeName", "no match for this type pattern: {0}");

public final Kind unresolvableMember = new Kind("unresolvableMember", "can not resolve this member: {0}");

public final Kind typeNotExposedToWeaver = new Kind("typeNotExposedToWeaver",
"this affected type is not exposed to the weaver: {0}");

public final Kind shadowNotInStructure = new Kind("shadowNotInStructure",
"the shadow for this join point is not exposed in the structure model: {0}");

public final Kind unmatchedSuperTypeInCall = new Kind("unmatchedSuperTypeInCall",
"does not match because declaring type is {0}, if match desired use target({1})");

public final Kind unmatchedTargetKind = new Kind("unmatchedTargetKind", "does not match because annotation {0} has @Target{1}");

public final Kind canNotImplementLazyTjp = new Kind("canNotImplementLazyTjp",
"can not implement lazyTjp on this joinpoint {0} because around advice is used");

public final Kind multipleAdviceStoppingLazyTjp = new Kind("multipleAdviceStoppingLazyTjp",
"can not implement lazyTjp at joinpoint {0} because of advice conflicts, see secondary locations to find conflicting advice");

public final Kind needsSerialVersionUIDField = new Kind("needsSerialVersionUIDField",
"serialVersionUID of type {0} needs to be set because of {1}");

public final Kind serialVersionUIDBroken = new Kind("brokeSerialVersionCompatibility",
"serialVersionUID of type {0} is broken because of added field {1}");

public final Kind noInterfaceCtorJoinpoint = new Kind("noInterfaceCtorJoinpoint",
"no interface constructor-execution join point - use {0}+ for implementing classes");

public final Kind noJoinpointsForBridgeMethods = new Kind(
"noJoinpointsForBridgeMethods",
"pointcut did not match on the method call to a bridge method. Bridge methods are generated by the compiler and have no join points");

public final Kind enumAsTargetForDecpIgnored = new Kind("enumAsTargetForDecpIgnored",
"enum type {0} matches a declare parents type pattern but is being ignored");

public final Kind annotationAsTargetForDecpIgnored = new Kind("annotationAsTargetForDecpIgnored",
"annotation type {0} matches a declare parents type pattern but is being ignored");

public final Kind cantMatchArrayTypeOnVarargs = new Kind("cantMatchArrayTypeOnVarargs",
"an array type as the last parameter in a signature does not match on the varargs declared method: {0}");

public final Kind adviceDidNotMatch = new Kind("adviceDidNotMatch", "advice defined in {0} has not been applied");

public final Kind invalidTargetForAnnotation = new Kind("invalidTargetForAnnotation",
"{0} is not a valid target for annotation {1}, this annotation can only be applied to {2}");

public final Kind elementAlreadyAnnotated = new Kind("elementAlreadyAnnotated",
"{0} - already has an annotation of type {1}, cannot add a second instance");

public final Kind runtimeExceptionNotSoftened = new Kind("runtimeExceptionNotSoftened",
"{0} will not be softened as it is already a RuntimeException");

public final Kind uncheckedArgument = new Kind("uncheckedArgument",
"unchecked match of {0} with {1} when argument is an instance of {2} at join point {3}");

public final Kind uncheckedAdviceConversion = new Kind("uncheckedAdviceConversion",
"unchecked conversion when advice applied at shadow {0}, expected {1} but advice uses {2}");

public final Kind noGuardForLazyTjp = new Kind("noGuardForLazyTjp",
"can not build thisJoinPoint lazily for this advice since it has no suitable guard");

public final Kind noExplicitConstructorCall = new Kind("noExplicitConstructorCall",
"inter-type constructor does not contain explicit constructor call: field initializers in the target type will not be executed");

public final Kind aspectExcludedByConfiguration = new Kind("aspectExcludedByConfiguration",
"aspect {0} exluded for class loader {1}");

public final Kind unorderedAdviceAtShadow = new Kind("unorderedAdviceAtShadow",
"at this shadow {0} no precedence is specified between advice applying from aspect {1} and aspect {2}");

public final Kind swallowedExceptionInCatchBlock = new Kind("swallowedExceptionInCatchBlock",
"exception swallowed in catch block");

public final Kind calculatingSerialVersionUID = new Kind("calculatingSerialVersionUID",
"calculated SerialVersionUID for type {0} to be {1}");

// there are a lot of messages in the cant find type family - I'm defining an umbrella lint warning that
// allows a user to control their severity (for e.g. ltw or binary weaving)
public final Kind cantFindType = new Kind("cantFindType", "{0}");

public final Kind cantFindTypeAffectingJoinPointMatch = new Kind("cantFindTypeAffectingJPMatch", "{0}");

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}''");

/**
* Indicates an aspect could not be found when attempting reweaving.
*/
public final Kind missingAspectForReweaving = new Kind("missingAspectForReweaving",
"aspect {0} cannot be found when reweaving {1}");

private static Trace trace = TraceFactory.getTraceFactory().getTrace(Lint.class);

public Lint(World world) {
if (trace.isTraceEnabled())
trace.enter("<init>", this, world);
this.world = world;
if (trace.isTraceEnabled())
trace.exit("<init>");
}

public void setAll(String messageKind) {
if (trace.isTraceEnabled())
trace.enter("setAll", this, messageKind);
setAll(getMessageKind(messageKind));
if (trace.isTraceEnabled())
trace.exit("setAll");
}

private void setAll(IMessage.Kind messageKind) {
for (Iterator i = kinds.values().iterator(); i.hasNext();) {
Kind kind = (Kind) i.next();
kind.setKind(messageKind);
}
}

public void setFromProperties(File file) {
if (trace.isTraceEnabled())
trace.enter("setFromProperties", this, file);
try {
InputStream s = new FileInputStream(file);
setFromProperties(s);
} catch (IOException ioe) {
MessageUtil.error(world.getMessageHandler(), WeaverMessages.format(WeaverMessages.XLINT_LOAD_ERROR, file.getPath(), ioe
.getMessage()));
}
if (trace.isTraceEnabled())
trace.exit("setFromProperties");
}

public void loadDefaultProperties() {
InputStream s = getClass().getResourceAsStream("XlintDefault.properties");
if (s == null) {
MessageUtil.warn(world.getMessageHandler(), WeaverMessages.format(WeaverMessages.XLINTDEFAULT_LOAD_ERROR));
return;
}
try {
setFromProperties(s);
} catch (IOException ioe) {
MessageUtil.error(world.getMessageHandler(), WeaverMessages.format(WeaverMessages.XLINTDEFAULT_LOAD_PROBLEM, ioe
.getMessage()));
}

}

private void setFromProperties(InputStream s) throws IOException {
Properties p = new Properties();
p.load(s);
setFromProperties(p);
}

public void setFromProperties(Properties properties) {
for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
Kind kind = (Kind) kinds.get(entry.getKey());
if (kind == null) {
MessageUtil.error(world.getMessageHandler(), WeaverMessages.format(WeaverMessages.XLINT_KEY_ERROR, entry.getKey()));
} else {
kind.setKind(getMessageKind((String) entry.getValue()));
}
}
}

public Collection allKinds() {
return kinds.values();
}

public Kind getLintKind(String name) {
return (Kind) kinds.get(name);
}

// temporarily suppress the given lint messages
public void suppressKinds(Collection lintKind) {
if (lintKind.isEmpty())
return;
for (Iterator iter = lintKind.iterator(); iter.hasNext();) {
Kind k = (Kind) iter.next();
k.setSuppressed(true);
}
}

// remove any suppression of lint warnings in place
public void clearAllSuppressions() {
for (Iterator iter = kinds.values().iterator(); iter.hasNext();) {
Kind k = (Kind) iter.next();
k.setSuppressed(false);
}
}

public void clearSuppressions(Collection lintKind) {
if (lintKind.isEmpty())
return;
for (Iterator iter = lintKind.iterator(); iter.hasNext();) {
Kind k = (Kind) iter.next();
k.setSuppressed(false);
}
}

private IMessage.Kind getMessageKind(String v) {
if (v.equals("ignore"))
return null;
else if (v.equals("warning"))
return IMessage.WARNING;
else if (v.equals("error"))
return IMessage.ERROR;

MessageUtil.error(world.getMessageHandler(), WeaverMessages.format(WeaverMessages.XLINT_VALUE_ERROR, v));
return null;
}

public Kind fromKey(String lintkey) {
return (Lint.Kind) kinds.get(lintkey);
}

public class Kind {
private final String name;
private final String message;
private IMessage.Kind kind = IMessage.WARNING;
private boolean isSupressed = false; // by SuppressAjWarnings

public Kind(String name, String message) {
this.name = name;
this.message = message;
kinds.put(this.name, this);
}

public void setSuppressed(boolean shouldBeSuppressed) {
this.isSupressed = shouldBeSuppressed;
}

public boolean isEnabled() {
return (kind != null) && !isSupressed();
}

private boolean isSupressed() {
// can't suppress errors!
return isSupressed && (kind != IMessage.ERROR);
}

public String getName() {
return name;
}

public IMessage.Kind getKind() {
return kind;
}

public void setKind(IMessage.Kind kind) {
this.kind = kind;
}

public void signal(String info, ISourceLocation location) {
if (kind == null)
return;

String text = MessageFormat.format(message, new Object[] { info });
text += " [Xlint:" + name + "]";
world.getMessageHandler().handleMessage(new LintMessage(text, kind, location, null, getLintKind(name)));
}

public void signal(String[] infos, ISourceLocation location, ISourceLocation[] extraLocations) {
if (kind == null)
return;

String text = MessageFormat.format(message, (Object[]) infos);
text += " [Xlint:" + name + "]";
world.getMessageHandler().handleMessage(new LintMessage(text, kind, location, extraLocations, getLintKind(name)));
}

}

}

+ 47
- 0
org.aspectj.matcher/src/org/aspectj/weaver/LintMessage.java Переглянути файл

@@ -0,0 +1,47 @@
/* *******************************************************************
* Copyright (c) 2002-2006 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:
* PARC initial implementation
* AndyClement extracted as self contained type from Lint type (4-Aug-06)
* ******************************************************************/
package org.aspectj.weaver;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;

public class LintMessage extends Message {
// private Lint.Kind lintKind;
private String lintKind;
public LintMessage(
String message,
IMessage.Kind messageKind,
ISourceLocation location,
ISourceLocation[] extraLocations,
Lint.Kind lintKind) {
super(message,"",messageKind,location,null,extraLocations);
this.lintKind = lintKind.getName();
}
public LintMessage(String message, String extraDetails, org.aspectj.weaver.Lint.Kind kind2, Kind kind, ISourceLocation sourceLocation, Throwable object,
ISourceLocation[] seeAlsoLocations, boolean declared, int id, int sourceStart, int sourceEnd) {
super(message,extraDetails,kind,sourceLocation,object,seeAlsoLocations,declared,id,sourceStart,sourceEnd);
this.lintKind = kind2.getName();
}

/**
* @return Returns the Lint kind of this message
*/
public String getLintKind() {
return lintKind;
}
}

+ 102
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Member.java Переглянути файл

@@ -0,0 +1,102 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* 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://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* AMC extracted as interface
* ******************************************************************/
package org.aspectj.weaver;

import java.util.Collection;
import java.util.Iterator;

/**
* Abstract representation of a member within a type.
*/
public interface Member extends Comparable {

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 AnnotationAJ[][] NO_PARAMETER_ANNOTATIONXS = new AnnotationAJ[][] {};
public static final ResolvedType[][] NO_PARAMETER_ANNOTATION_TYPES = new ResolvedType[][] {};

public MemberKind getKind();

public ResolvedMember resolve(World world);

public int compareTo(Object other);

public UnresolvedType getDeclaringType();

public UnresolvedType getReturnType();

public UnresolvedType getGenericReturnType();

public UnresolvedType[] getGenericParameterTypes();

public UnresolvedType getType();

public String getName();

public UnresolvedType[] getParameterTypes();

/**
* Return full signature, including return type, e.g. "()LFastCar;". For a
* signature without the return type, use getParameterSignature() - it is
* important to choose the right one in the face of covariance.
*/
public String getSignature();

public Iterator getJoinPointSignatures(World world);

public int getArity();

/**
* Return signature without return type, e.g. "()" for a signature *with*
* the return type, use getSignature() - it is important to choose the right
* one in the face of covariance.
*/
public String getParameterSignature();

public int getModifiers(World world);

public int getModifiers();

public boolean isStatic();

public boolean isInterface();

public boolean isPrivate();

/**
* Returns true iff the member is generic (NOT parameterized)
*/
public boolean canBeParameterized();

public AnnotationAJ[] getAnnotations();

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

public String[] getParameterNames(World world);

public UnresolvedType[] getExceptions(World world);
}

+ 565
- 0
org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java Переглянути файл

@@ -0,0 +1,565 @@
/* *******************************************************************
* 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.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

public class MemberImpl implements Member {

protected MemberKind kind;
protected int modifiers;
protected String name;
protected UnresolvedType returnType;
protected UnresolvedType declaringType;
protected UnresolvedType[] parameterTypes;
private final String signature;
private String paramSignature;

// OPTIMIZE move out of the member!
private boolean reportedCantFindDeclaringType = false;
private boolean reportedUnresolvableMember = false;

/**
* All the signatures that a join point with this member as its signature
* has.
*/
private JoinPointSignatureIterator joinPointSignatures = null;

public MemberImpl(MemberKind kind, UnresolvedType declaringType,
int modifiers, String name, String signature) {
this.kind = kind;
this.declaringType = declaringType;
this.modifiers = modifiers;
this.name = name;
this.signature = signature;
if (kind == FIELD) {
this.returnType = UnresolvedType.forSignature(signature);
this.parameterTypes = UnresolvedType.NONE;
} else {
Object[] returnAndParams = signatureToTypes(signature, false);
this.returnType = (UnresolvedType) returnAndParams[0];
this.parameterTypes = (UnresolvedType[]) returnAndParams[1];
// always safe not to do this ?!?
// String oldsig=new String(signature);
// signature = typesToSignature(returnType,parameterTypes,true);
}
}

public MemberImpl(MemberKind kind, UnresolvedType declaringType,
int modifiers, UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes) {
this.kind = kind;
this.declaringType = declaringType;
this.modifiers = modifiers;
this.returnType = returnType;
this.name = name;
this.parameterTypes = parameterTypes;
if (kind == FIELD) {
this.signature = returnType.getErasureSignature();
} else {
this.signature = typesToSignature(returnType, parameterTypes, true);
}
}

public ResolvedMember resolve(World world) {
return world.resolve(this);
}

// ---- utility methods

/**
* returns an Object[] pair of UnresolvedType, UnresolvedType[] representing
* return type, argument types parsed from the JVM bytecode signature of a
* method. Yes, this should actually return a nice statically-typed pair
* object, but we don't have one of those.
*
* <blockquote>
*
* <pre>
* UnresolvedType.signatureToTypes(&quot;()[Z&quot;)[0].equals(Type.forSignature(&quot;[Z&quot;))
* UnresolvedType.signatureToTypes(&quot;(JJ)I&quot;)[1]
* .equals(UnresolvedType.forSignatures(new String[] {&quot;J&quot;, &quot;J&quot;}))
* </pre>
*
* </blockquote>
*
* @param signature
* the JVM bytecode method signature string we want to break
* apart
* @return a pair of UnresolvedType, UnresolvedType[] representing the
* return types and parameter types.
*/
// OPTIMIZE move static util methods out into a memberutils class
public static String typesToSignature(UnresolvedType returnType,
UnresolvedType[] paramTypes, boolean useRawTypes) {
StringBuffer buf = new StringBuffer();
buf.append("(");
for (int i = 0, len = paramTypes.length; i < len; i++) {
if (paramTypes[i].isParameterizedType() && useRawTypes)
buf.append(paramTypes[i].getErasureSignature());
else if (paramTypes[i].isTypeVariableReference() && useRawTypes)
buf.append(paramTypes[i].getErasureSignature());
else
buf.append(paramTypes[i].getSignature());
}
buf.append(")");
if (returnType.isParameterizedType() && useRawTypes)
buf.append(returnType.getErasureSignature());
else if (returnType.isTypeVariableReference() && useRawTypes)
buf.append(returnType.getErasureSignature());
else
buf.append(returnType.getSignature());
return buf.toString();
}

/**
* Returns "(<signaturesOfParamTypes>,...)" - unlike the other
* typesToSignature that also includes the return type, this one just deals
* with the parameter types.
*/
public static String typesToSignature(UnresolvedType[] paramTypes) {
StringBuffer buf = new StringBuffer();
buf.append("(");
for (int i = 0; i < paramTypes.length; i++) {
buf.append(paramTypes[i].getSignature());
}
buf.append(")");
return buf.toString();
}

/**
* returns an Object[] pair of UnresolvedType, UnresolvedType[] representing
* return type, argument types parsed from the JVM bytecode signature of a
* method. Yes, this should actually return a nice statically-typed pair
* object, but we don't have one of those.
*
* <blockquote>
*
* <pre>
* UnresolvedType.signatureToTypes(&quot;()[Z&quot;)[0].equals(Type.forSignature(&quot;[Z&quot;))
* UnresolvedType.signatureToTypes(&quot;(JJ)I&quot;)[1]
* .equals(UnresolvedType.forSignatures(new String[] {&quot;J&quot;, &quot;J&quot;}))
* </pre>
*
* </blockquote>
*
* @param signature
* the JVM bytecode method signature string we want to break
* apart
* @return a pair of UnresolvedType, UnresolvedType[] representing the
* return types and parameter types.
*/
private static Object[] signatureToTypes(String sig,
boolean keepParameterizationInfo) {
boolean hasParameters = sig.charAt(1) != ')';
if (hasParameters) {
List l = new ArrayList();
int i = 1;
boolean hasAnyAnglies = sig.indexOf('<') != -1;
while (true) {
char c = sig.charAt(i);
if (c == ')')
break; // break out when the hit the ')'
int start = i;
while (c == '[')
c = sig.charAt(++i);
if (c == 'L' || c == 'P') {
int nextSemicolon = sig.indexOf(';', start);
int firstAngly = (hasAnyAnglies ? sig.indexOf('<', start)
: -1);
if (!hasAnyAnglies || firstAngly == -1
|| firstAngly > nextSemicolon) {
i = nextSemicolon + 1;
l.add(UnresolvedType.forSignature(sig.substring(start,
i)));
} else {
// generics generics generics
// Have to skip to the *correct* ';'
boolean endOfSigReached = false;
int posn = firstAngly;
int genericDepth = 0;
while (!endOfSigReached) {
switch (sig.charAt(posn)) {
case '<':
genericDepth++;
break;
case '>':
genericDepth--;
break;
case ';':
if (genericDepth == 0)
endOfSigReached = true;
break;
default:
}
posn++;
}
// posn now points to the correct nextSemicolon :)
i = posn;
l.add(UnresolvedType.forSignature(sig.substring(start,
i)));
}
} else if (c == 'T') { // assumed 'reference' to a type
// variable, so just "Tname;"
int nextSemicolon = sig.indexOf(';', start);
String nextbit = sig.substring(start, nextSemicolon);
l.add(UnresolvedType.forSignature(nextbit));
i = nextSemicolon + 1;
} else {
i++;
l.add(UnresolvedType.forSignature(sig.substring(start, i)));
}
}
UnresolvedType[] paramTypes = (UnresolvedType[]) l
.toArray(new UnresolvedType[l.size()]);
UnresolvedType returnType = UnresolvedType.forSignature(sig
.substring(i + 1, sig.length()));
return new Object[] { returnType, paramTypes };
} else {
UnresolvedType returnType = UnresolvedType.forSignature(sig
.substring(2));
return new Object[] { returnType, UnresolvedType.NONE };
}
}

// ---- factory methods
public static MemberImpl field(String declaring, int mods, String name,
String signature) {
return field(declaring, mods, UnresolvedType.forSignature(signature),
name);
}

// public static Member field(UnresolvedType declaring, int mods, String
// name, UnresolvedType type) {
// return new MemberImpl(FIELD, declaring, mods, type, name,
// UnresolvedType.NONE);
// }
// OPTIMIZE do we need to call this? unless necessary the signatureToTypes()
// call smacks of laziness on the behalf of the caller
// of this method
public static MemberImpl method(UnresolvedType declaring, int mods,
String name, String signature) {
Object[] pair = signatureToTypes(signature, false);
return method(declaring, mods, (UnresolvedType) pair[0], name,
(UnresolvedType[]) pair[1]);
}

public static MemberImpl monitorEnter() {
return new MemberImpl(MONITORENTER, UnresolvedType.OBJECT,
Modifier.STATIC, ResolvedType.VOID, "<lock>",
UnresolvedType.ARRAY_WITH_JUST_OBJECT);
}

public static MemberImpl monitorExit() {
return new MemberImpl(MONITOREXIT, UnresolvedType.OBJECT,
Modifier.STATIC, ResolvedType.VOID, "<unlock>",
UnresolvedType.ARRAY_WITH_JUST_OBJECT);
}

public static Member pointcut(UnresolvedType declaring, String name,
String signature) {
Object[] pair = signatureToTypes(signature, false);
return pointcut(declaring, 0, (UnresolvedType) pair[0], name,
(UnresolvedType[]) pair[1]);
}

private static MemberImpl field(String declaring, int mods,
UnresolvedType ty, String name) {
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) {
return new MemberImpl(
// ??? this calls <clinit> a method
name.equals("<init>") ? CONSTRUCTOR : METHOD, declTy, mods,
rTy, name, paramTys);
}

private static Member pointcut(UnresolvedType declTy, int mods,
UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
return new MemberImpl(POINTCUT, declTy, mods, rTy, name, paramTys);
}

public static ResolvedMemberImpl makeExceptionHandlerSignature(
UnresolvedType inType, UnresolvedType catchType) {
return new ResolvedMemberImpl(HANDLER, inType, Modifier.STATIC,
"<catch>", "(" + catchType.getSignature() + ")V");
}

public boolean equals(Object other) {
if (!(other instanceof Member))
return false;
Member o = (Member) other;
return (getKind() == o.getKind() && getName().equals(o.getName())
&& getSignature().equals(o.getSignature()) && getDeclaringType()
.equals(o.getDeclaringType()));
}

/**
* Equality is checked based on the underlying signature, so the hash code
* of a member is based on its kind, name, signature, and declaring type.
* The algorithm for this was taken from page 38 of effective java.
*/
private volatile int hashCode = 0;

public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37 * result + getKind().hashCode();
result = 37 * result + getName().hashCode();
result = 37 * result + getSignature().hashCode();
result = 37 * result + getDeclaringType().hashCode();
hashCode = result;
}
return hashCode;
}

public int compareTo(Object other) {
Member o = (Member) other;
int i = getName().compareTo(o.getName());
if (i != 0)
return i;
return getSignature().compareTo(o.getSignature());
}

public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(returnType.getName());
buf.append(' ');
buf.append(declaringType.getName());
buf.append('.');
buf.append(name);
if (kind != FIELD) {
buf.append("(");
if (parameterTypes.length != 0) {
buf.append(parameterTypes[0]);
for (int i = 1, len = parameterTypes.length; i < len; i++) {
buf.append(", ");
buf.append(parameterTypes[i].getName());
}
}
buf.append(")");
}
return buf.toString();
}

public MemberKind getKind() {
return kind;
}

public UnresolvedType getDeclaringType() {
return declaringType;
}

public UnresolvedType getReturnType() {
return returnType;
}

public UnresolvedType getGenericReturnType() {
return getReturnType();
}

public UnresolvedType[] getGenericParameterTypes() {
return getParameterTypes();
}

public final UnresolvedType getType() {
return returnType;
}

public String getName() {
return name;
}

public UnresolvedType[] getParameterTypes() {
return parameterTypes;
}

public String getSignature() {
return signature;
}

public int getArity() {
return parameterTypes.length;
}

public String getParameterSignature() {
if (paramSignature != null)
return paramSignature;
StringBuffer sb = new StringBuffer();
sb.append("(");
for (int i = 0; i < parameterTypes.length; i++) {
UnresolvedType tx = parameterTypes[i];
sb.append(tx.getSignature());
}
sb.append(")");
paramSignature = sb.toString();
return paramSignature;
}

// OPTIMIZE see next line. Why the hell are they in here if we only know it
// once resolution has occurred...
// ---- things we know only with resolution

public int getModifiers(World world) {
ResolvedMember resolved = resolve(world);
if (resolved == null) {
reportDidntFindMember(world);
return 0;
}
return resolved.getModifiers();
}

public UnresolvedType[] getExceptions(World world) {
ResolvedMember resolved = resolve(world);
if (resolved == null) {
reportDidntFindMember(world);
return UnresolvedType.NONE;
}
return resolved.getExceptions();
}

public final boolean isStatic() {
return Modifier.isStatic(modifiers);
}

public final boolean isInterface() {
return Modifier.isInterface(modifiers);
}

public final boolean isPrivate() {
return Modifier.isPrivate(modifiers);
}

public boolean canBeParameterized() {
return false;
}

public int getModifiers() {
return modifiers;
}

public AnnotationAJ[] getAnnotations() {
throw new UnsupportedOperationException(
"You should resolve this member '" + this
+ "' and call getAnnotations() on the result...");
}

// ---- fields 'n' stuff

public Collection/* ResolvedType */getDeclaringTypes(World world) {
ResolvedType myType = getDeclaringType().resolve(world);
Collection ret = new HashSet();
if (kind == CONSTRUCTOR) {
// this is wrong if the member doesn't exist, but that doesn't
// matter
ret.add(myType);
} else if (isStatic() || kind == FIELD) {
walkUpStatic(ret, myType);
} else {
walkUp(ret, myType);
}

return ret;
}

private boolean walkUp(Collection acc, ResolvedType curr) {
if (acc.contains(curr))
return true;

boolean b = false;
for (Iterator i = curr.getDirectSupertypes(); i.hasNext();) {
b |= walkUp(acc, (ResolvedType) i.next());
}

if (!b && curr.isParameterizedType()) {
b = walkUp(acc, curr.getGenericType());
}

if (!b) {
b = curr.lookupMemberNoSupers(this) != null;
}
if (b)
acc.add(curr);
return b;
}

private boolean walkUpStatic(Collection acc, ResolvedType curr) {
if (curr.lookupMemberNoSupers(this) != null) {
acc.add(curr);
return true;
} else {
boolean b = false;
for (Iterator i = curr.getDirectSupertypes(); i.hasNext();) {
b |= walkUpStatic(acc, (ResolvedType) i.next());
}
if (!b && curr.isParameterizedType()) {
b = walkUpStatic(acc, curr.getGenericType());
}
if (b)
acc.add(curr);
return b;
}
}

public String[] getParameterNames(World world) {
ResolvedMember resolved = resolve(world);
if (resolved == null) {
reportDidntFindMember(world);
return null;
}
return resolved.getParameterNames();
}

/**
* All the signatures that a join point with this member as its signature
* has.
*/
public Iterator getJoinPointSignatures(World inAWorld) {
if (joinPointSignatures == null) {
joinPointSignatures = new JoinPointSignatureIterator(this, inAWorld);
}
joinPointSignatures.reset();
return joinPointSignatures;
}

/**
* Raises an [Xlint:cantFindType] message if the declaring type cannot be
* found or an [Xlint:unresolvableMember] message if the type can be found
* (bug 149908)
*/
private void reportDidntFindMember(World world) {
if (reportedCantFindDeclaringType || reportedUnresolvableMember)
return;
ResolvedType rType = getDeclaringType().resolve(world);
if (rType.isMissing()) {
world.getLint().cantFindType.signal(WeaverMessages.format(
WeaverMessages.CANT_FIND_TYPE, rType.getName()), null);
reportedCantFindDeclaringType = true;
} else {
world.getLint().unresolvableMember.signal(getName(), null);
reportedUnresolvableMember = true;
}
}

public void wipeJoinpointSignatures() {
joinPointSignatures = null;
}
}

+ 37
- 0
org.aspectj.matcher/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("Unexpected memberkind, should be (1-9) but was " + key);
}
}

+ 202
- 0
org.aspectj.matcher/src/org/aspectj/weaver/MethodDelegateTypeMunger.java Переглянути файл

@@ -0,0 +1,202 @@
/* *******************************************************************
* 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:
* Alexandre Vasseur initial implementation
* ******************************************************************/


package org.aspectj.weaver;

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

import org.aspectj.weaver.patterns.TypePattern;

/**
* Type munger for @AspectJ ITD declare parents ie with an interface AND an implementation.
* Given the aspect that has a field public static Interface fieldI = ... // impl.
* we will weave in the Interface' methods and delegate to the aspect public static field fieldI
*
* Note: this munger DOES NOT handles the interface addition to the target classes - a regular Parent kinded munger
* must be added in coordination.
*/
public class MethodDelegateTypeMunger extends ResolvedTypeMunger {

private final UnresolvedType aspect;

/**
* The mixin impl (no arg ctor)
*/
private final String implClassName;

/**
* Type pattern this munger applies to
*/
private final TypePattern typePattern;

/**
* Construct a new type munger for @AspectJ ITD
*
* @param signature
* @param aspect
* @param implClassName
* @param typePattern
*/
public MethodDelegateTypeMunger(ResolvedMember signature, UnresolvedType aspect, String implClassName, TypePattern typePattern) {
super(MethodDelegate, signature);
this.aspect = aspect;
this.typePattern = typePattern;
this.implClassName = implClassName;
}

public boolean equals(Object other) {
if (!(other instanceof MethodDelegateTypeMunger)) return false;
MethodDelegateTypeMunger o = (MethodDelegateTypeMunger)other;
return ((o.aspect == null) ? (aspect == null ) : aspect.equals(o.aspect))
&& ((o.typePattern == null) ? (typePattern == null ) : typePattern.equals(o.typePattern))
&& ((o.implClassName == null) ? (implClassName == null) : implClassName.equals(o.implClassName));
}

private volatile int hashCode = 0;
public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37*result + ((aspect == null) ? 0 : aspect.hashCode());
result = 37*result + ((typePattern == null) ? 0 : typePattern.hashCode());
result = 37*result + ((implClassName == null) ? 0 : implClassName.hashCode());
hashCode = result;
}
return hashCode;
}
public ResolvedMember getDelegate(ResolvedType targetType) {
return AjcMemberMaker.itdAtDeclareParentsField(
targetType,
signature.getDeclaringType(),
aspect
);
}

public String getImplClassName() {
return implClassName;
}

public void write(DataOutputStream s) throws IOException {
kind.write(s);
signature.write(s);
aspect.write(s);
s.writeUTF(implClassName);
typePattern.write(s);
}

public static ResolvedTypeMunger readMethod(VersionedDataInputStream s, ISourceContext context) throws IOException {
ResolvedMemberImpl signature = ResolvedMemberImpl.readResolvedMember(s, context);
UnresolvedType aspect = UnresolvedType.read(s);
String implClassName = s.readUTF();
TypePattern tp = TypePattern.read(s, context);
return new MethodDelegateTypeMunger(signature, aspect, implClassName, tp);
}

/**
* Match based on given type pattern, only classes can be matched
*
* @param matchType
* @param aspectType
* @return true if match
*/
public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
// match only on class
if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
return false;
}

return typePattern.matchesStatically(matchType);
}

/**
* Needed for reweavable
*
* @return true
*/
public boolean changesPublicSignature() {
return true;
}

public static class FieldHostTypeMunger extends ResolvedTypeMunger {

private UnresolvedType aspect;

/**
* Type pattern this munger applies to
*/
private final TypePattern typePattern;

/**
* Construct a new type munger for @AspectJ ITD
*
* @param field
* @param aspect
* @param typePattern
*/
public FieldHostTypeMunger(ResolvedMember field, UnresolvedType aspect, TypePattern typePattern) {
super(FieldHost, field);
this.aspect = aspect;
this.typePattern = typePattern;
}

public boolean equals(Object other) {
if (!(other instanceof FieldHostTypeMunger)) return false;
FieldHostTypeMunger o = (FieldHostTypeMunger)other;
return ((o.aspect == null) ? (aspect == null ) : aspect.equals(o.aspect))
&& ((o.typePattern == null) ? (typePattern == null ) : typePattern.equals(o.typePattern));
}

public int hashCode() {
int result = 17;
result = 37*result + ((aspect == null) ? 0 : aspect.hashCode());
result = 37*result + ((typePattern == null) ? 0 : typePattern.hashCode());
return result;
}
public void write(DataOutputStream s) throws IOException {
kind.write(s);
signature.write(s);
aspect.write(s);
typePattern.write(s);
}

public static ResolvedTypeMunger readFieldHost(VersionedDataInputStream s, ISourceContext context) throws IOException {
ResolvedMemberImpl signature = ResolvedMemberImpl.readResolvedMember(s, context);
UnresolvedType aspect = UnresolvedType.read(s);
TypePattern tp = TypePattern.read(s, context);
return new FieldHostTypeMunger(signature, aspect, tp);
}

/**
* Match based on given type pattern, only classes can be matched
*
* @param matchType
* @param aspectType
* @return true if match
*/
public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
// match only on class
if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
return false;
}

return typePattern.matchesStatically(matchType);
}

public boolean changesPublicSignature() {
return false;
}

}
}

+ 212
- 0
org.aspectj.matcher/src/org/aspectj/weaver/MissingResolvedTypeWithKnownSignature.java Переглянути файл

@@ -0,0 +1,212 @@
/* *******************************************************************
* 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;

import java.util.Collections;
import java.util.List;

import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.context.CompilationAndWeavingContext;

/**
* When we try to resolve a type in the world that we require to be present,
* and then fail to find it, we return an instance of this class. This class
* defers the production of the "can't find type error" until the first time
* that someone asks a question that can't be answered solely from the signature.
* This enables the weaver to be more tolerant of missing types.
*
*/
public class MissingResolvedTypeWithKnownSignature extends ResolvedType {

private static ResolvedMember[] NO_MEMBERS = new ResolvedMember[0];
private static ResolvedType[] NO_TYPES = new ResolvedType[0];
private boolean issuedCantFindTypeError = false;
private boolean issuedJoinPointWarning = false;
private boolean issuedMissingInterfaceWarning = false;
/**
* @param signature
* @param world
*/
public MissingResolvedTypeWithKnownSignature(String signature, World world) {
super(signature, world);
}

public boolean isMissing() { return true; }
/**
* @param signature
* @param signatureErasure
* @param world
*/
public MissingResolvedTypeWithKnownSignature(String signature,
String signatureErasure, World world) {
super(signature, signatureErasure, world);
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#getDeclaredFields()
*/
public ResolvedMember[] getDeclaredFields() {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_FIELDS);
return NO_MEMBERS;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#getDeclaredMethods()
*/
public ResolvedMember[] getDeclaredMethods() {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_METHODS);
return NO_MEMBERS;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#getDeclaredInterfaces()
*/
public ResolvedType[] getDeclaredInterfaces() {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_INTERFACES);
return NO_TYPES;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#getDeclaredPointcuts()
*/
public ResolvedMember[] getDeclaredPointcuts() {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_POINTCUTS);
return NO_MEMBERS;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#getSuperclass()
*/
public ResolvedType getSuperclass() {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_SUPERCLASS);
return ResolvedType.MISSING;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#getModifiers()
*/
public int getModifiers() {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_MODIFIERS);
return 0;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#getSourceContext()
*/
public ISourceContext getSourceContext() {
return new ISourceContext() {

public ISourceLocation makeSourceLocation(IHasPosition position) {
return null;
}

public ISourceLocation makeSourceLocation(int line, int offset) {
return null;
}

public int getOffset() {
return 0;
}
public void tidy() {}
};
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#isAssignableFrom(org.aspectj.weaver.ResolvedType)
*/
public boolean isAssignableFrom(ResolvedType other) {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_ASSIGNABLE,other.getName());
return false;
}
public boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
if (allowMissing) return false;
else return isAssignableFrom(other);
}

/* (non-Javadoc)
* @see org.aspectj.weaver.ResolvedType#isCoerceableFrom(org.aspectj.weaver.ResolvedType)
*/
public boolean isCoerceableFrom(ResolvedType other) {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_COERCEABLE,other.getName());
return false;
}

/* (non-Javadoc)
* @see org.aspectj.weaver.AnnotatedElement#hasAnnotation(org.aspectj.weaver.UnresolvedType)
*/
public boolean hasAnnotation(UnresolvedType ofType) {
raiseCantFindType(WeaverMessages.CANT_FIND_TYPE_ANNOTATION);
return false;
}
public List getInterTypeMungers() {
return Collections.EMPTY_LIST;
}
public List getInterTypeMungersIncludingSupers() {
return Collections.EMPTY_LIST;
}
public List getInterTypeParentMungers() {
return Collections.EMPTY_LIST;
}
public List getInterTypeParentMungersIncludingSupers() {
return Collections.EMPTY_LIST;
}
protected void collectInterTypeMungers(List collector) {
return;
}
public void raiseWarningOnJoinPointSignature(String signature) {
if (issuedJoinPointWarning) return;
String message = WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_JOINPOINT,getName(),signature);
message += "\n" + CompilationAndWeavingContext.getCurrentContext();
world.getLint().cantFindTypeAffectingJoinPointMatch.signal(message,null);
// MessageUtil.warn(world.getMessageHandler(),message);
issuedJoinPointWarning = true;
}
public void raiseWarningOnMissingInterfaceWhilstFindingMethods() {
if (issuedMissingInterfaceWarning) return;
String message = WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_INTERFACE_METHODS,getName(),signature);
message += "\n" + CompilationAndWeavingContext.getCurrentContext();
world.getLint().cantFindTypeAffectingJoinPointMatch.signal(message,null);
//MessageUtil.warn(world.getMessageHandler(),message);
issuedMissingInterfaceWarning = true;
}
private void raiseCantFindType(String key) {
if (issuedCantFindTypeError) return;
String message = WeaverMessages.format(key,getName());
message += "\n" + CompilationAndWeavingContext.getCurrentContext();
world.getLint().cantFindType.signal(message,null);
// MessageUtil.error(world.getMessageHandler(),message);
issuedCantFindTypeError = true;
}

private void raiseCantFindType(String key,String insert) {
if (issuedCantFindTypeError) return;
String message = WeaverMessages.format(key,getName(),insert);
message += "\n" + CompilationAndWeavingContext.getCurrentContext();
world.getLint().cantFindType.signal(message,null);
// MessageUtil.error(world.getMessageHandler(),message);
issuedCantFindTypeError = true;
}

}

+ 334
- 0
org.aspectj.matcher/src/org/aspectj/weaver/NameMangler.java Переглянути файл

@@ -0,0 +1,334 @@
/* *******************************************************************
* 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.lang.reflect.Modifier;

public class NameMangler {

// public static final char[] AJC_DOLLAR_PREFIX = { 'a', 'j', 'c', '$' };
// public static final char[] CLINIT = { '<', 'c', 'l', 'i', 'n', 'i', 't', '>' };
public static final String PREFIX = "ajc$";
// public static final char[] INIT = { '<', 'i', 'n', 'i', 't', '>' };
public static final String ITD_PREFIX = PREFIX + "interType$";
// public static final char[] METHOD_ASPECTOF = {'a', 's', 'p','e','c','t','O','f'};
// public static final char[] METHOD_HASASPECT = { 'h', 'a', 's', 'A', 's', 'p', 'e', 'c', 't' };
// public static final char[] STATIC_INITIALIZER = { '<', 'c', 'l', 'i', 'n', 'i', 't', '>' };

public static final String CFLOW_STACK_TYPE = "org.aspectj.runtime.internal.CFlowStack";
public static final String CFLOW_COUNTER_TYPE = "org.aspectj.runtime.internal.CFlowCounter";

public static final UnresolvedType CFLOW_STACK_UNRESOLVEDTYPE = UnresolvedType
.forSignature("Lorg/aspectj/runtime/internal/CFlowStack;");

public static final UnresolvedType CFLOW_COUNTER_UNRESOLVEDTYPE = UnresolvedType
.forSignature("Lorg/aspectj/runtime/internal/CFlowCounter;");

public static final String SOFT_EXCEPTION_TYPE = "org.aspectj.lang.SoftException";

public static final String PERSINGLETON_FIELD_NAME = PREFIX + "perSingletonInstance";
public static final String PERCFLOW_FIELD_NAME = PREFIX + "perCflowStack";
// public static final String PERTHIS_FIELD_NAME = PREFIX + "perSingletonInstance";

// -----
public static final String PERCFLOW_PUSH_METHOD = PREFIX + "perCflowPush";

public static final String PEROBJECT_BIND_METHOD = PREFIX + "perObjectBind";

// PTWIMPL Method and field names
public static final String PERTYPEWITHIN_GETINSTANCE_METHOD = PREFIX + "getInstance";
public static final String PERTYPEWITHIN_CREATEASPECTINSTANCE_METHOD = PREFIX + "createAspectInstance";
public static final String PERTYPEWITHIN_WITHINTYPEFIELD = PREFIX + "withinType";
public static final String PERTYPEWITHIN_GETWITHINTYPENAME_METHOD = "getWithinTypeName";

public static final String AJC_PRE_CLINIT_NAME = PREFIX + "preClinit";

public static final String AJC_POST_CLINIT_NAME = PREFIX + "postClinit";

public static final String INITFAILURECAUSE_FIELD_NAME = PREFIX + "initFailureCause";

public static boolean isSyntheticMethod(String methodName, boolean declaredInAspect) {
if (methodName.startsWith(PREFIX)) {
// it's synthetic unless it is an advice method
if (methodName.startsWith("ajc$before") || methodName.startsWith("ajc$after")) {
return false;
} else if (methodName.startsWith("ajc$around")) {
// around advice method is not synthetic, but generated proceed is...
return (methodName.endsWith("proceed"));
} else if (methodName.startsWith("ajc$interMethod$")) {
return false; // body of an itd-m
}
return true;
} else if (methodName.indexOf("_aroundBody") != -1) {
return true;
}
// these aren't the droids you're looking for...move along...... pr148727
// else if (declaredInAspect) {
// if (methodName.equals("aspectOf") || methodName.equals("hasAspect")) {
// return true;
// }
// }
return false;
}

public static String perObjectInterfaceGet(UnresolvedType aspectType) {
return makeName(aspectType.getNameAsIdentifier(), "perObjectGet");
}

public static String perObjectInterfaceSet(UnresolvedType aspectType) {
return makeName(aspectType.getNameAsIdentifier(), "perObjectSet");
}

public static String perObjectInterfaceField(UnresolvedType aspectType) {
return makeName(aspectType.getNameAsIdentifier(), "perObjectField");
}

// PTWIMPL method names that must include aspect type
public static String perTypeWithinFieldForTarget(UnresolvedType aspectType) {
return makeName(aspectType.getNameAsIdentifier(), "ptwAspectInstance");
}

public static String perTypeWithinLocalAspectOf(UnresolvedType aspectType) {
return makeName(aspectType.getNameAsIdentifier(), "localAspectOf");
}

public static String itdAtDeclareParentsField(UnresolvedType aspectType, UnresolvedType itdType) {
return makeName("instance", aspectType.getNameAsIdentifier(), itdType.getNameAsIdentifier());
}

public static String privilegedAccessMethodForMethod(String name, UnresolvedType objectType, UnresolvedType aspectType) {
return makeName("privMethod", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name);
}

public static String privilegedAccessMethodForFieldGet(String name, UnresolvedType objectType, UnresolvedType aspectType) {
return makeName("privFieldGet", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name);
}

public static String privilegedAccessMethodForFieldSet(String name, UnresolvedType objectType, UnresolvedType aspectType) {
return makeName("privFieldSet", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name);
}

public static String inlineAccessMethodForMethod(String name, UnresolvedType objectType, UnresolvedType aspectType) {
return makeName("inlineAccessMethod", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name);
}

public static String inlineAccessMethodForFieldGet(String name, UnresolvedType objectType, UnresolvedType aspectType) {
return makeName("inlineAccessFieldGet", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name);
}

public static String inlineAccessMethodForFieldSet(String name, UnresolvedType objectType, UnresolvedType aspectType) {
return makeName("inlineAccessFieldSet", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name);
}

/**
* The name of methods corresponding to advice declarations Of the form:
* "ajc$[AdviceKind]$[AspectName]$[NumberOfAdviceInAspect]$[PointcutHash]"
*/
public static String adviceName(String nameAsIdentifier, AdviceKind kind, int adviceSeqNumber, int pcdHash) {
String newname = makeName(kind.getName(), nameAsIdentifier, Integer.toString(adviceSeqNumber), Integer.toHexString(pcdHash));
return newname;
}

/**
* This field goes on top-most implementers of the interface the field is declared onto
*/
public static String interFieldInterfaceField(UnresolvedType aspectType, UnresolvedType interfaceType, String name) {
return makeName("interField", aspectType.getNameAsIdentifier(), interfaceType.getNameAsIdentifier(), name);
}

/**
* This instance method goes on the interface the field is declared onto as well as its top-most implementors
*/
public static String interFieldInterfaceSetter(UnresolvedType aspectType, UnresolvedType interfaceType, String name) {
return makeName("interFieldSet", aspectType.getNameAsIdentifier(), interfaceType.getNameAsIdentifier(), name);
}

/**
* This instance method goes on the interface the field is declared onto as well as its top-most implementors
*/
public static String interFieldInterfaceGetter(UnresolvedType aspectType, UnresolvedType interfaceType, String name) {
return makeName("interFieldGet", aspectType.getNameAsIdentifier(), interfaceType.getNameAsIdentifier(), name);
}

/**
* This static method goes on the aspect that declares the inter-type field
*/
public static String interFieldSetDispatcher(UnresolvedType aspectType, UnresolvedType onType, String name) {
return makeName("interFieldSetDispatch", aspectType.getNameAsIdentifier(), onType.getNameAsIdentifier(), name);
}

/**
* This static method goes on the aspect that declares the inter-type field
*/
public static String interFieldGetDispatcher(UnresolvedType aspectType, UnresolvedType onType, String name) {
return makeName("interFieldGetDispatch", aspectType.getNameAsIdentifier(), onType.getNameAsIdentifier(), name);
}

/**
* This field goes on the class the field is declared onto
*/
public static String interFieldClassField(int modifiers, UnresolvedType aspectType, UnresolvedType classType, String name) {
if (Modifier.isPublic(modifiers))
return name;
// ??? might want to handle case where aspect and class are in same package similar to public
return makeName("interField", makeVisibilityName(modifiers, aspectType), name);
}

// /**
// * This static method goes on the aspect that declares the inter-type field
// */
// public static String classFieldSetDispatcher(UnresolvedType aspectType, UnresolvedType classType, String name) {
// return makeName("interFieldSetDispatch", aspectType.getNameAsIdentifier(),
// classType.getNameAsIdentifier(), name);
// }
//
// /**
// * This static method goes on the aspect that declares the inter-type field
// */
// public static String classFieldGetDispatcher(UnresolvedType aspectType, UnresolvedType classType, String name)
// {
// return makeName(
// "interFieldGetDispatch",
// aspectType.getNameAsIdentifier(),
// classType.getNameAsIdentifier(),
// name);
// }

/**
* This static void method goes on the aspect that declares the inter-type field and is called from the appropriate place
* (target's initializer, or clinit, or topmost implementer's inits), to initialize the field;
*/

public static String interFieldInitializer(UnresolvedType aspectType, UnresolvedType classType, String name) {
return makeName("interFieldInit", aspectType.getNameAsIdentifier(), classType.getNameAsIdentifier(), name);
}

// ----

/**
* This method goes on the target type of the inter-type method. (and possibly the topmost-implemeters, if the target type is an
* interface)
*/
public static String interMethod(int modifiers, UnresolvedType aspectType, UnresolvedType classType, String name) {
if (Modifier.isPublic(modifiers))
return name;
// ??? might want to handle case where aspect and class are in same package similar to public
return makeName("interMethodDispatch2", makeVisibilityName(modifiers, aspectType), name);
}

/**
* This static method goes on the declaring aspect of the inter-type method.
*/
public static String interMethodDispatcher(UnresolvedType aspectType, UnresolvedType classType, String name) {
return makeName("interMethodDispatch1", aspectType.getNameAsIdentifier(), classType.getNameAsIdentifier(), name);
}

/**
* This static method goes on the declaring aspect of the inter-type method.
*/
public static String interMethodBody(UnresolvedType aspectType, UnresolvedType classType, String name) {
return makeName("interMethod", aspectType.getNameAsIdentifier(), classType.getNameAsIdentifier(), name);
}

// ----

/**
* This static method goes on the declaring aspect of the inter-type constructor.
*/
public static String preIntroducedConstructor(UnresolvedType aspectType, UnresolvedType targetType) {
return makeName("preInterConstructor", aspectType.getNameAsIdentifier(), targetType.getNameAsIdentifier());
}

/**
* This static method goes on the declaring aspect of the inter-type constructor.
*/
public static String postIntroducedConstructor(UnresolvedType aspectType, UnresolvedType targetType) {
return makeName("postInterConstructor", aspectType.getNameAsIdentifier(), targetType.getNameAsIdentifier());
}

// ----

/**
* This static method goes on the target class of the inter-type method.
*/
public static String superDispatchMethod(UnresolvedType classType, String name) {
return makeName("superDispatch", classType.getNameAsIdentifier(), name);
}

/**
* This static method goes on the target class of the inter-type method.
*/
public static String protectedDispatchMethod(UnresolvedType classType, String name) {
return makeName("protectedDispatch", classType.getNameAsIdentifier(), name);
}

// ----

private static String makeVisibilityName(int modifiers, UnresolvedType aspectType) {
if (Modifier.isPrivate(modifiers)) {
return aspectType.getOutermostType().getNameAsIdentifier();
} else if (Modifier.isProtected(modifiers)) {
throw new RuntimeException("protected inter-types not allowed");
} else if (Modifier.isPublic(modifiers)) {
return "";
} else {
return aspectType.getPackageNameAsIdentifier();
}
}

private static String makeName(String s1, String s2) {
return "ajc$" + s1 + "$" + s2;
}

public static String makeName(String s1, String s2, String s3) {
return "ajc$" + s1 + "$" + s2 + "$" + s3;
}

public static String makeName(String s1, String s2, String s3, String s4) {
return "ajc$" + s1 + "$" + s2 + "$" + s3 + "$" + s4;
}

public static String cflowStack(CrosscuttingMembers xcut) {
return makeName("cflowStack", Integer.toHexString(xcut.getCflowEntries().size()));
}

public static String cflowCounter(CrosscuttingMembers xcut) {
return makeName("cflowCounter", Integer.toHexString(xcut.getCflowEntries().size()));
}

public static String makeClosureClassName(UnresolvedType enclosingType, int index) {
return enclosingType.getName() + "$AjcClosure" + index;
}

public static String aroundCallbackMethodName(Member shadowSig, String suffixTag) {
StringBuffer ret = new StringBuffer();
ret.append(getExtractableName(shadowSig)).append("_aroundBody").append(suffixTag);
return ret.toString();
}

public static String getExtractableName(Member shadowSignature) {
String name = shadowSignature.getName();
MemberKind kind = shadowSignature.getKind();
if (kind == Member.CONSTRUCTOR)
return "init$";
else if (kind == Member.STATIC_INITIALIZATION)
return "clinit$";
else
return name;
}

public static String proceedMethodName(String adviceMethodName) {
return adviceMethodName + "proceed";
}

}

+ 144
- 0
org.aspectj.matcher/src/org/aspectj/weaver/NewConstructorTypeMunger.java Переглянути файл

@@ -0,0 +1,144 @@
/* *******************************************************************
* 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.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;

public class NewConstructorTypeMunger extends ResolvedTypeMunger {
private ResolvedMember syntheticConstructor;
private ResolvedMember explicitConstructor;


public NewConstructorTypeMunger(
ResolvedMember signature,
ResolvedMember syntheticConstructor,
ResolvedMember explicitConstructor,
Set superMethodsCalled,
List typeVariableAliases) {
super(Constructor, signature);
this.syntheticConstructor = syntheticConstructor;
this.typeVariableAliases = typeVariableAliases;
this.explicitConstructor = explicitConstructor;
this.setSuperMethodsCalled(superMethodsCalled);

}
public boolean equals(Object other) {
if (!(other instanceof NewConstructorTypeMunger)) return false;
NewConstructorTypeMunger o = (NewConstructorTypeMunger)other;
return ((o.syntheticConstructor == null) ? (syntheticConstructor == null )
: syntheticConstructor.equals(o.syntheticConstructor))
& ((o.explicitConstructor == null) ? (explicitConstructor == null )
: explicitConstructor.equals(o.explicitConstructor));
}

private volatile int hashCode = 0;
public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37*result + ((syntheticConstructor == null) ? 0 : syntheticConstructor.hashCode());
result = 37*result + ((explicitConstructor == null) ? 0 : explicitConstructor.hashCode());
hashCode = result;
}
return hashCode;
}
// doesnt seem required....
// public ResolvedMember getDispatchMethod(UnresolvedType aspectType) {
// return AjcMemberMaker.interMethodBody(signature, aspectType);
// }

public void write(DataOutputStream s) throws IOException {
kind.write(s);
signature.write(s);
syntheticConstructor.write(s);
explicitConstructor.write(s);
writeSuperMethodsCalled(s);
writeSourceLocation(s);
writeOutTypeAliases(s);
}
public static ResolvedTypeMunger readConstructor(VersionedDataInputStream s, ISourceContext context) throws IOException {
ISourceLocation sloc = null;
ResolvedMember sig = ResolvedMemberImpl.readResolvedMember(s, context);
ResolvedMember syntheticCtor = ResolvedMemberImpl.readResolvedMember(s, context);
ResolvedMember explicitCtor = ResolvedMemberImpl.readResolvedMember(s, context);
Set superMethodsCalled = readSuperMethodsCalled(s);
sloc = readSourceLocation(s);
List typeVarAliases = readInTypeAliases(s);
ResolvedTypeMunger munger = new NewConstructorTypeMunger(sig,syntheticCtor,explicitCtor,superMethodsCalled,typeVarAliases);
if (sloc!=null) munger.setSourceLocation(sloc);
return munger;
}

public ResolvedMember getExplicitConstructor() {
return explicitConstructor;
}

public ResolvedMember getSyntheticConstructor() {
return syntheticConstructor;
}

public void setExplicitConstructor(ResolvedMember explicitConstructor) {
this.explicitConstructor = explicitConstructor;
// reset hashCode so that its recalculated with new value
hashCode = 0;
}
public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) {
ResolvedMember ret = getSyntheticConstructor();
if (ResolvedType.matches(ret, member)) return getSignature();
return super.getMatchingSyntheticMember(member, aspectType);
}
public void check(World world) {
if (getSignature().getDeclaringType().resolve(world).isAspect()) {
world.showMessage(IMessage.ERROR,
WeaverMessages.format(WeaverMessages.ITD_CONS_ON_ASPECT),
getSignature().getSourceLocation(), null);
}
}

/**
* see ResolvedTypeMunger.parameterizedFor(ResolvedType)
*/
public ResolvedTypeMunger parameterizedFor(ResolvedType target) {
ResolvedType genericType = target;
if (target.isRawType() || target.isParameterizedType()) genericType = genericType.getGenericType();
ResolvedMember parameterizedSignature = null;
// If we are parameterizing it for a generic type, we just need to 'swap the letters' from the ones used
// in the original ITD declaration to the ones used in the actual target type declaration.
if (target.isGenericType()) {
TypeVariable vars[] = target.getTypeVariables();
UnresolvedTypeVariableReferenceType[] varRefs = new UnresolvedTypeVariableReferenceType[vars.length];
for (int i = 0; i < vars.length; i++) {
varRefs[i] = new UnresolvedTypeVariableReferenceType(vars[i]);
}
parameterizedSignature = getSignature().parameterizedWith(varRefs,genericType,true,typeVariableAliases);
} else {
// For raw and 'normal' parameterized targets (e.g. Interface, Interface<String>)
parameterizedSignature = getSignature().parameterizedWith(target.getTypeParameters(),genericType,target.isParameterizedType(),typeVariableAliases);
}
NewConstructorTypeMunger nctm = new NewConstructorTypeMunger(parameterizedSignature,syntheticConstructor,explicitConstructor,getSuperMethodsCalled(),typeVariableAliases);
nctm.setSourceLocation(getSourceLocation());
return nctm;
}

}

+ 124
- 0
org.aspectj.matcher/src/org/aspectj/weaver/NewFieldTypeMunger.java Переглянути файл

@@ -0,0 +1,124 @@
/* *******************************************************************
* 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.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aspectj.bridge.ISourceLocation;

public class NewFieldTypeMunger extends ResolvedTypeMunger {

public NewFieldTypeMunger(ResolvedMember signature, Set superMethodsCalled, List typeVariableAliases) {
super(Field, signature);
this.typeVariableAliases = typeVariableAliases;
signature.setAnnotatedElsewhere(true);
this.setSuperMethodsCalled(superMethodsCalled);
}

public ResolvedMember getInitMethod(UnresolvedType aspectType) {
return AjcMemberMaker.interFieldInitializer(signature, aspectType);
}

public void write(DataOutputStream s) throws IOException {
kind.write(s);
signature.write(s);
writeSuperMethodsCalled(s);
writeSourceLocation(s);
writeOutTypeAliases(s);
}

public static ResolvedTypeMunger readField(VersionedDataInputStream s, ISourceContext context) throws IOException {
ISourceLocation sloc = null;
ResolvedMember fieldSignature = ResolvedMemberImpl.readResolvedMember(s, context);
Set superMethodsCalled = readSuperMethodsCalled(s);
sloc = readSourceLocation(s);
List aliases = readInTypeAliases(s);
ResolvedTypeMunger munger = new NewFieldTypeMunger(fieldSignature,superMethodsCalled,aliases);
if (sloc!=null) munger.setSourceLocation(sloc);
return munger;
}
public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) {
//??? might give a field where a method is expected
ResolvedType onType = aspectType.getWorld().resolve(getSignature().getDeclaringType());
if (onType.isRawType()) onType = onType.getGenericType();
ResolvedMember ret = AjcMemberMaker.interFieldGetDispatcher(getSignature(), aspectType);
if (ResolvedType.matches(ret, member)) return getSignature();
ret = AjcMemberMaker.interFieldSetDispatcher(getSignature(), aspectType);
if (ResolvedType.matches(ret, member)) return getSignature();
ret = AjcMemberMaker.interFieldInterfaceGetter(getSignature(), onType, aspectType);
if (ResolvedType.matches(ret, member)) return getSignature();
ret = AjcMemberMaker.interFieldInterfaceSetter(getSignature(), onType, aspectType);
if (ResolvedType.matches(ret, member)) return getSignature();
return super.getMatchingSyntheticMember(member, aspectType);
}

/**
* see ResolvedTypeMunger.parameterizedFor(ResolvedType)
*/
public ResolvedTypeMunger parameterizedFor(ResolvedType target) {
ResolvedType genericType = target;
if (target.isRawType() || target.isParameterizedType()) genericType = genericType.getGenericType();
ResolvedMember parameterizedSignature = null;
// If we are parameterizing it for a generic type, we just need to 'swap the letters' from the ones used
// in the original ITD declaration to the ones used in the actual target type declaration.
if (target.isGenericType()) {
TypeVariable vars[] = target.getTypeVariables();
UnresolvedTypeVariableReferenceType[] varRefs = new UnresolvedTypeVariableReferenceType[vars.length];
for (int i = 0; i < vars.length; i++) {
varRefs[i] = new UnresolvedTypeVariableReferenceType(vars[i]);
}
parameterizedSignature = getSignature().parameterizedWith(varRefs,genericType,true,typeVariableAliases);
} else {
// For raw and 'normal' parameterized targets (e.g. Interface, Interface<String>)
parameterizedSignature = getSignature().parameterizedWith(target.getTypeParameters(),genericType,target.isParameterizedType(),typeVariableAliases);
}
NewFieldTypeMunger nftm = new NewFieldTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases);
nftm.setDeclaredSignature(getSignature());
nftm.setSourceLocation(getSourceLocation());
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;
return kind.equals(o.kind)
&& ((o.signature == null) ? (signature == null ) : signature.equals(o.signature))
&& ((o.declaredSignature == null) ? (declaredSignature == null ) : declaredSignature.equals(o.declaredSignature))
&& ((o.typeVariableAliases == null) ? (typeVariableAliases == null ) : typeVariableAliases.equals(o.typeVariableAliases));
}
public int hashCode() {
int result = 17;
result = 37*result + kind.hashCode();
result = 37*result + ((signature == null) ? 0 : signature.hashCode());
result = 37*result + ((declaredSignature == null) ? 0 : declaredSignature.hashCode());
result = 37*result + ((typeVariableAliases == null) ? 0 : typeVariableAliases.hashCode());
return result;
}
}

+ 146
- 0
org.aspectj.matcher/src/org/aspectj/weaver/NewMethodTypeMunger.java Переглянути файл

@@ -0,0 +1,146 @@
/* *******************************************************************
* 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.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, List typeVariableAliases) {
super(Method, signature);
this.typeVariableAliases = typeVariableAliases;
this.setSuperMethodsCalled(superMethodsCalled);
}

public ResolvedMember getInterMethodBody(UnresolvedType aspectType) {
return AjcMemberMaker.interMethodBody(signature, aspectType);
}

/**
* If the munger has a declared signature
*/
public ResolvedMember getDeclaredInterMethodBody(UnresolvedType aspectType, World w) {
if (declaredSignature != null) {
ResolvedMember rm = declaredSignature.parameterizedWith(null, signature.getDeclaringType().resolve(w), false,
getTypeVariableAliases());
return AjcMemberMaker.interMethodBody(rm, aspectType);
} else {
return AjcMemberMaker.interMethodBody(signature, aspectType);
}
}

// public ResolvedMember getInterMethodDispatcher(UnresolvedType aspectType) {
// return AjcMemberMaker.interMethodDispatcher(signature, aspectType);
// }

public ResolvedMember getDeclaredInterMethodDispatcher(UnresolvedType aspectType, World w) {
if (declaredSignature != null) {
ResolvedMember rm = declaredSignature.parameterizedWith(null, signature.getDeclaringType().resolve(w), false,
getTypeVariableAliases());
return AjcMemberMaker.interMethodDispatcher(rm, aspectType);
} else {
return AjcMemberMaker.interMethodDispatcher(signature, aspectType);
}
}

public void write(DataOutputStream s) throws IOException {
kind.write(s);
signature.write(s);
writeSuperMethodsCalled(s);
writeSourceLocation(s);
writeOutTypeAliases(s);
}

public static ResolvedTypeMunger readMethod(VersionedDataInputStream s, ISourceContext context) throws IOException {
ISourceLocation sloc = null;
ResolvedMemberImpl rmImpl = ResolvedMemberImpl.readResolvedMember(s, context);
Set superMethodsCalled = readSuperMethodsCalled(s);
sloc = readSourceLocation(s);
List typeVarAliases = readInTypeAliases(s);

ResolvedTypeMunger munger = new NewMethodTypeMunger(rmImpl, superMethodsCalled, typeVarAliases);
if (sloc != null)
munger.setSourceLocation(sloc);
return munger;
}

public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) {
ResolvedMember ret = AjcMemberMaker.interMethodDispatcher(getSignature(), aspectType);
if (ResolvedType.matches(ret, member))
return getSignature();
return super.getMatchingSyntheticMember(member, aspectType);
}

/**
* see ResolvedTypeMunger.parameterizedFor(ResolvedType)
*/
public ResolvedTypeMunger parameterizedFor(ResolvedType target) {
ResolvedType genericType = target;
if (target.isRawType() || target.isParameterizedType())
genericType = genericType.getGenericType();
ResolvedMember parameterizedSignature = null;
// If we are parameterizing it for a generic type, we just need to 'swap the letters' from the ones used
// in the original ITD declaration to the ones used in the actual target type declaration.
if (target.isGenericType()) {
TypeVariable vars[] = target.getTypeVariables();
UnresolvedTypeVariableReferenceType[] varRefs = new UnresolvedTypeVariableReferenceType[vars.length];
for (int i = 0; i < vars.length; i++) {
varRefs[i] = new UnresolvedTypeVariableReferenceType(vars[i]);
}
parameterizedSignature = getSignature().parameterizedWith(varRefs, genericType, true, typeVariableAliases);
} else {
// For raw and 'normal' parameterized targets (e.g. Interface, Interface<String>)
parameterizedSignature = getSignature().parameterizedWith(target.getTypeParameters(), genericType,
target.isParameterizedType(), typeVariableAliases);
}
NewMethodTypeMunger nmtm = new NewMethodTypeMunger(parameterizedSignature, getSuperMethodsCalled(), typeVariableAliases);
nmtm.setDeclaredSignature(getSignature());
nmtm.setSourceLocation(getSourceLocation());
return nmtm;
}

public boolean equals(Object other) {
if (!(other instanceof NewMethodTypeMunger))
return false;
NewMethodTypeMunger o = (NewMethodTypeMunger) other;
return kind.equals(o.kind)
&& ((o.signature == null) ? (signature == null) : signature.equals(o.signature))
&& ((o.declaredSignature == null) ? (declaredSignature == null) : declaredSignature.equals(o.declaredSignature))
&& ((o.typeVariableAliases == null) ? (typeVariableAliases == null) : typeVariableAliases
.equals(o.typeVariableAliases));
}

public int hashCode() {
int result = 17;
result = 37 * result + kind.hashCode();
result = 37 * result + ((signature == null) ? 0 : signature.hashCode());
result = 37 * result + ((declaredSignature == null) ? 0 : declaredSignature.hashCode());
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;
}

}

+ 51
- 0
org.aspectj.matcher/src/org/aspectj/weaver/NewParentTypeMunger.java Переглянути файл

@@ -0,0 +1,51 @@
/* *******************************************************************
* 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.DataOutputStream;
import java.io.IOException;

public class NewParentTypeMunger extends ResolvedTypeMunger {
ResolvedType newParent;
public NewParentTypeMunger(ResolvedType newParent) {
super(Parent, null);
this.newParent = newParent;
}

public void write(DataOutputStream s) throws IOException {
throw new RuntimeException("unimplemented");
}


public ResolvedType getNewParent() {
return newParent;
}

public boolean equals(Object other) {
if (! (other instanceof NewParentTypeMunger)) return false;
NewParentTypeMunger o = (NewParentTypeMunger) other;
return newParent.equals(o.newParent);
}
private volatile int hashCode = 0;
public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37*result + newParent.hashCode();
hashCode = result;
}
return hashCode;
}
}

+ 91
- 0
org.aspectj.matcher/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java Переглянути файл

@@ -0,0 +1,91 @@
/* *******************************************************************
* 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
* Alexandre Vasseur rearchitected for #75442 finer grained matching
* ******************************************************************/
package org.aspectj.weaver;

import org.aspectj.weaver.patterns.PerFromSuper;
import org.aspectj.weaver.patterns.PerObject;
import org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.TypePattern;

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

public class PerObjectInterfaceTypeMunger extends ResolvedTypeMunger {

private final UnresolvedType interfaceType;
private final Pointcut testPointcut;
private TypePattern lazyTestTypePattern;
public boolean equals(Object other) {
if (other==null || !(other instanceof PerObjectInterfaceTypeMunger)) return false;
PerObjectInterfaceTypeMunger o = (PerObjectInterfaceTypeMunger)other;
return ((testPointcut == null) ? (o.testPointcut == null ) : testPointcut.equals(o.testPointcut))
&& ((lazyTestTypePattern == null) ? (o.lazyTestTypePattern == null ) : lazyTestTypePattern.equals(o.lazyTestTypePattern));
}

private volatile int hashCode = 0;
public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37*result + ((testPointcut == null) ? 0 : testPointcut.hashCode());
result = 37*result + ((lazyTestTypePattern == null) ? 0 : lazyTestTypePattern.hashCode());
hashCode = result;
}
return hashCode;
}
public PerObjectInterfaceTypeMunger(UnresolvedType aspectType, Pointcut testPointcut) {
super(PerObjectInterface, null);
this.testPointcut = testPointcut;
this.interfaceType = AjcMemberMaker.perObjectInterfaceType(aspectType);
}

private TypePattern getTestTypePattern(ResolvedType aspectType) {
if (lazyTestTypePattern == null) {
final boolean isPerThis;
if (aspectType.getPerClause() instanceof PerFromSuper) {
PerFromSuper ps = (PerFromSuper) aspectType.getPerClause();
isPerThis = ((PerObject) ps.lookupConcretePerClause(aspectType)).isThis();
} else {
isPerThis = ((PerObject) aspectType.getPerClause()).isThis();
}
PerThisOrTargetPointcutVisitor v = new PerThisOrTargetPointcutVisitor(!isPerThis, aspectType);
lazyTestTypePattern = v.getPerTypePointcut(testPointcut);
// reset hashCode so that its recalculated with the new lazyTestTypePattern
hashCode = 0;
}
return lazyTestTypePattern;
}

public void write(DataOutputStream s) throws IOException {
throw new RuntimeException("shouldn't be serialized");
}

public UnresolvedType getInterfaceType() {
return interfaceType;
}

public Pointcut getTestPointcut() {
return testPointcut;
}

public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
if (matchType.isInterface()) return false;
return getTestTypePattern(aspectType).matchesStatically(matchType);
}
public boolean isLateMunger() {
return true;
}
}

+ 81
- 0
org.aspectj.matcher/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java Переглянути файл

@@ -0,0 +1,81 @@
/* *******************************************************************
* Copyright (c) 2005 IBM, 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.io.DataOutputStream;
import java.io.IOException;

import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.patterns.PerTypeWithin;
import org.aspectj.weaver.patterns.Pointcut;

// PTWIMPL Target type munger adds the localAspectOf() method
public class PerTypeWithinTargetTypeMunger extends ResolvedTypeMunger {
private UnresolvedType aspectType;
private PerTypeWithin testPointcut;

public PerTypeWithinTargetTypeMunger(UnresolvedType aspectType, PerTypeWithin testPointcut) {
super(PerTypeWithinInterface, null);
this.aspectType = aspectType;
this.testPointcut = testPointcut;
}

public boolean equals(Object other) {
if (!(other instanceof PerTypeWithinTargetTypeMunger)) return false;
PerTypeWithinTargetTypeMunger o = (PerTypeWithinTargetTypeMunger)other;
return ((o.testPointcut == null) ? (testPointcut == null ) : testPointcut.equals(o.testPointcut))
&& ((o.aspectType == null) ? (aspectType == null ) : aspectType.equals(o.aspectType));
}

private volatile int hashCode = 0;
public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37*result + ((testPointcut == null) ? 0 : testPointcut.hashCode());
result = 37*result + ((aspectType == null) ? 0 : aspectType.hashCode());
hashCode = result;
}
return hashCode;
}
public void write(DataOutputStream s) throws IOException {
throw new RuntimeException("shouldn't be serialized");
}
public UnresolvedType getAspectType() {
return aspectType;
}

public Pointcut getTestPointcut() {
return testPointcut;
}
// This is a lexical within() so if you say PerTypeWithin(Test) and matchType is an
// inner type (e.g. Test$NestedType) then it should match successfully
// Does not match if the target is an interface
public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
return isWithinType(matchType).alwaysTrue() &&
!matchType.isInterface();
}
private FuzzyBoolean isWithinType(ResolvedType type) {
while (type != null) {
if (testPointcut.getTypePattern().matchesStatically(type)) {
return FuzzyBoolean.YES;
}
type = type.getDeclaringType();
}
return FuzzyBoolean.NO;
}

}

+ 80
- 0
org.aspectj.matcher/src/org/aspectj/weaver/PoliceExtensionUse.java Переглянути файл

@@ -0,0 +1,80 @@
/*******************************************************************************
* Copyright (c) 2006 IBM
* 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 API and implementation
*******************************************************************************/
package org.aspectj.weaver;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
import org.aspectj.weaver.patterns.AndPointcut;
import org.aspectj.weaver.patterns.KindedPointcut;
import org.aspectj.weaver.patterns.NotPointcut;
import org.aspectj.weaver.patterns.OrPointcut;
import org.aspectj.weaver.patterns.Pointcut;

/**
* Walks a pointcut and determines if the synchronization related designators have been used: lock() or unlock()
*/
public class PoliceExtensionUse extends AbstractPatternNodeVisitor {

private boolean synchronizationDesignatorEncountered;
private World world;
private Pointcut p;

public PoliceExtensionUse(World w, Pointcut p) {
this.world = w;
this.p = p;
this.synchronizationDesignatorEncountered = false;
}

public boolean synchronizationDesignatorEncountered() {
return synchronizationDesignatorEncountered;
}

public Object visit(KindedPointcut node, Object data) {
if (world == null)
return super.visit(node, data); // error scenario can sometimes lead to this LazyClassGen.toLongString()
if (node.getKind() == Shadow.SynchronizationLock || node.getKind() == Shadow.SynchronizationUnlock)
synchronizationDesignatorEncountered = true;
// Check it!
if (!world.isJoinpointSynchronizationEnabled()) {
if (node.getKind() == Shadow.SynchronizationLock) {
IMessage m = MessageUtil.warn(
"lock() pointcut designator cannot be used without the option -Xjoinpoints:synchronization", p
.getSourceLocation());
world.getMessageHandler().handleMessage(m);
} else if (node.getKind() == Shadow.SynchronizationUnlock) {
IMessage m = MessageUtil.warn(
"unlock() pointcut designator cannot be used without the option -Xjoinpoints:synchronization", p
.getSourceLocation());
world.getMessageHandler().handleMessage(m);
}
}
return super.visit(node, data);
}

public Object visit(AndPointcut node, Object data) {
node.getLeft().accept(this, data);
node.getRight().accept(this, data);
return node;
}

public Object visit(NotPointcut node, Object data) {
node.getNegatedPointcut().accept(this, data);
return node;
}

public Object visit(OrPointcut node, Object data) {
node.getLeft().accept(this, data);
node.getRight().accept(this, data);
return node;
}

}

+ 32
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Position.java Переглянути файл

@@ -0,0 +1,32 @@
/* *******************************************************************
* 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;

public class Position implements IHasPosition {
private int start, end;
public Position(int start, int end) {
this.start = start;
this.end = end;
}

public int getEnd() {
return end;
}

public int getStart() {
return start;
}

}

+ 69
- 0
org.aspectj.matcher/src/org/aspectj/weaver/PrivilegedAccessMunger.java Переглянути файл

@@ -0,0 +1,69 @@
/* *******************************************************************
* 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.DataOutputStream;
import java.io.IOException;

public class PrivilegedAccessMunger extends ResolvedTypeMunger {
public PrivilegedAccessMunger(ResolvedMember member) {
super(PrivilegedAccess, member);
}

public void write(DataOutputStream s) throws IOException {
throw new RuntimeException("shouldn't be serialized");
}

public ResolvedMember getMember() {
return getSignature();
}

public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) {
ResolvedMember ret;
if (getSignature().getKind() == Member.FIELD) {
ret = AjcMemberMaker.privilegedAccessMethodForFieldGet(aspectType, getSignature());
if (ResolvedType.matches(ret, member)) return getSignature();
ret = AjcMemberMaker.privilegedAccessMethodForFieldSet(aspectType, getSignature());
if (ResolvedType.matches(ret, member)) return getSignature();
} else {
//System.err.println("sig: " + getSignature());
ret = AjcMemberMaker.privilegedAccessMethodForMethod(aspectType, getSignature());
if (ResolvedType.matches(ret, member)) return getSignature();
}
return null;
}

public boolean equals(Object other) {
if (! (other instanceof PrivilegedAccessMunger)) return false;
PrivilegedAccessMunger o = (PrivilegedAccessMunger) other;
return kind.equals(o.kind)
&& ((o.signature == null) ? (signature == null ) : signature.equals(o.signature))
&& ((o.declaredSignature == null) ? (declaredSignature == null ) : declaredSignature.equals(o.declaredSignature))
&& ((o.typeVariableAliases == null) ? (typeVariableAliases == null ) : typeVariableAliases.equals(o.typeVariableAliases));
}
public int hashCode() {
int result = 17;
result = 37*result + kind.hashCode();
result = 37*result + ((signature == null) ? 0 : signature.hashCode());
result = 37*result + ((declaredSignature == null) ? 0 : declaredSignature.hashCode());
result = 37*result + ((typeVariableAliases == null) ? 0 : typeVariableAliases.hashCode());
return result;
}
public boolean existsToSupportShadowMunging() {
return true;
}
}

+ 810
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java Переглянути файл

@@ -0,0 +1,810 @@
/* *******************************************************************
* Copyright (c) 2002 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:
* PARC initial implementation
* Andy Clement - June 2005 - separated out from ResolvedType
* ******************************************************************/
package org.aspectj.weaver;

import java.util.ArrayList;
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.patterns.Declare;
import org.aspectj.weaver.patterns.PerClause;

/**
* A reference type represents some 'real' type, not a primitive, not an array - but a real type, for example java.util.List. Each
* ReferenceType has a delegate that is the underlying artifact - either an eclipse artifact or a bcel artifact. If the type
* represents a raw type (i.e. there is a generic form) then the genericType field is set to point to the generic type. If it is for
* a parameterized type then the generic type is also set to point to the generic form.
*/
public class ReferenceType extends ResolvedType {

/**
* For generic types, this list holds references to all the derived raw and parameterized versions. We need this so that if the
* generic delegate is swapped during incremental compilation, the delegate of the derivatives is swapped also.
*/
private final List/* ReferenceType */derivativeTypes = new ArrayList();

/**
* For parameterized types (or the raw type) - this field points to the actual reference type from which they are derived.
*/
ReferenceType genericType = null;

ReferenceTypeDelegate delegate = null;
int startPos = 0;
int endPos = 0;

// cached values for members
ResolvedMember[] parameterizedMethods = null;
ResolvedMember[] parameterizedFields = null;
ResolvedMember[] parameterizedPointcuts = null;
ResolvedType[] parameterizedInterfaces = null;
Collection parameterizedDeclares = null;
Collection parameterizedTypeMungers = null;

// ??? should set delegate before any use
public ReferenceType(String signature, World world) {
super(signature, world);
}

public ReferenceType(String signature, String signatureErasure, World world) {
super(signature, signatureErasure, world);
}

public static ReferenceType fromTypeX(UnresolvedType tx, World world) {
ReferenceType rt = new ReferenceType(tx.getErasureSignature(), world);
rt.typeKind = tx.typeKind;
return rt;
}

/**
* Constructor used when creating a parameterized type.
*/
public ReferenceType(ResolvedType theGenericType, ResolvedType[] theParameters, World aWorld) {
super(makeParameterizedSignature(theGenericType, theParameters), theGenericType.signatureErasure, aWorld);
ReferenceType genericReferenceType = (ReferenceType) theGenericType;
this.typeParameters = theParameters;
this.genericType = genericReferenceType;
this.typeKind = TypeKind.PARAMETERIZED;
this.delegate = genericReferenceType.getDelegate();
genericReferenceType.addDependentType(this);
}

/**
* Constructor used when creating a raw type.
*/
// public ReferenceType(
// ResolvedType theGenericType,
// World aWorld) {
// super(theGenericType.getErasureSignature(),
// theGenericType.getErasureSignature(),
// aWorld);
// ReferenceType genericReferenceType = (ReferenceType) theGenericType;
// this.typeParameters = null;
// this.genericType = genericReferenceType;
// this.typeKind = TypeKind.RAW;
// this.delegate = genericReferenceType.getDelegate();
// genericReferenceType.addDependentType(this);
// }
private void addDependentType(ReferenceType dependent) {
this.derivativeTypes.add(dependent);
}

public String getSignatureForAttribute() {
if (genericType == null || typeParameters == null)
return getSignature();
return makeDeclaredSignature(genericType, typeParameters);
}

/**
* Create a reference type for a generic type
*/
public ReferenceType(UnresolvedType genericType, World world) {
super(genericType.getSignature(), world);
typeKind = TypeKind.GENERIC;
}

public boolean isClass() {
return delegate.isClass();
}

public boolean isGenericType() {
return !isParameterizedType() && !isRawType() && delegate.isGeneric();
}

public String getGenericSignature() {
String sig = delegate.getDeclaredGenericSignature();
return (sig == null) ? "" : sig;
}

public AnnotationAJ[] getAnnotations() {
return delegate.getAnnotations();
}

public void addAnnotation(AnnotationAJ annotationX) {
delegate.addAnnotation(annotationX);
}

public boolean hasAnnotation(UnresolvedType ofType) {
return delegate.hasAnnotation(ofType);
}

public ResolvedType[] getAnnotationTypes() {
if (delegate == null) {
throw new BCException("Unexpected null delegate for type " + this.getName());
}
return delegate.getAnnotationTypes();
}

public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
AnnotationAJ[] axs = delegate.getAnnotations();
if (axs == null) {
return null;
}
for (int i = 0; i < axs.length; i++) {
if (axs[i].getTypeSignature().equals(ofType.getSignature())) {
return axs[i];
}
}
return null;
}

public boolean isAspect() {
return delegate.isAspect();
}

public boolean isAnnotationStyleAspect() {
return delegate.isAnnotationStyleAspect();
}

public boolean isEnum() {
return delegate.isEnum();
}

public boolean isAnnotation() {
return delegate.isAnnotation();
}

public boolean isAnonymous() {
return delegate.isAnonymous();
}

public boolean isNested() {
return delegate.isNested();
}

public ResolvedType getOuterClass() {
return delegate.getOuterClass();
}

public String getRetentionPolicy() {
return delegate.getRetentionPolicy();
}

public boolean isAnnotationWithRuntimeRetention() {
return delegate.isAnnotationWithRuntimeRetention();
}

public boolean canAnnotationTargetType() {
return delegate.canAnnotationTargetType();
}

public AnnotationTargetKind[] getAnnotationTargetKinds() {
return delegate.getAnnotationTargetKinds();
}

// true iff the statement "this = (ThisType) other" would compile
public boolean isCoerceableFrom(ResolvedType o) {
ResolvedType other = o.resolve(world);

if (this.isAssignableFrom(other) || other.isAssignableFrom(this)) {
return true;
}

if (this.isParameterizedType() && other.isParameterizedType()) {
return isCoerceableFromParameterizedType(other);
}

if (!this.isInterface() && !other.isInterface()) {
return false;
}
if (this.isFinal() || other.isFinal()) {
return false;
}
// ??? needs to be Methods, not just declared methods? JLS 5.5 unclear
ResolvedMember[] a = getDeclaredMethods();
ResolvedMember[] b = other.getDeclaredMethods(); // ??? is this cast
// always safe
for (int ai = 0, alen = a.length; ai < alen; ai++) {
for (int bi = 0, blen = b.length; bi < blen; bi++) {
if (!b[bi].isCompatibleWith(a[ai]))
return false;
}
}
return true;
}

private final boolean isCoerceableFromParameterizedType(ResolvedType other) {
if (!other.isParameterizedType())
return false;
ResolvedType myRawType = (ResolvedType) getRawType();
ResolvedType theirRawType = (ResolvedType) other.getRawType();
if (myRawType == theirRawType) {
if (getTypeParameters().length == other.getTypeParameters().length) {
// there's a chance it can be done
ResolvedType[] myTypeParameters = getResolvedTypeParameters();
ResolvedType[] theirTypeParameters = other.getResolvedTypeParameters();
for (int i = 0; i < myTypeParameters.length; i++) {
if (myTypeParameters[i] != theirTypeParameters[i]) {
// thin ice now... but List<String> may still be
// coerceable from e.g. List<T>
if (myTypeParameters[i].isGenericWildcard()) {
BoundedReferenceType wildcard = (BoundedReferenceType) myTypeParameters[i];
if (!wildcard.canBeCoercedTo(theirTypeParameters[i]))
return false;
} else if (myTypeParameters[i].isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) myTypeParameters[i];
TypeVariable tv = tvrt.getTypeVariable();
tv.resolve(world);
if (!tv.canBeBoundTo(theirTypeParameters[i]))
return false;
} else if (theirTypeParameters[i].isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) theirTypeParameters[i];
TypeVariable tv = tvrt.getTypeVariable();
tv.resolve(world);
if (!tv.canBeBoundTo(myTypeParameters[i]))
return false;
} else {
return false;
}
}
}
return true;
}
} else {
// we do this walk for situations like the following:
// Base<T>, Sub<S,T> extends Base<S>
// is Sub<Y,Z> coerceable from Base<X> ???
for (Iterator i = getDirectSupertypes(); i.hasNext();) {
ReferenceType parent = (ReferenceType) i.next();
if (parent.isCoerceableFromParameterizedType(other))
return true;
}
}
return false;
}

public boolean isAssignableFrom(ResolvedType other) {
return isAssignableFrom(other, false);
}

// true iff the statement "this = other" would compile.
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;
}
if (this == other)
return true;
if (this.getSignature().equals(ResolvedType.OBJECT.getSignature()))
return true;

if ((this.isRawType() || this.isGenericType()) && other.isParameterizedType()) {
if (isAssignableFrom((ResolvedType) other.getRawType()))
return true;
}
if (this.isRawType() && other.isGenericType()) {
if (isAssignableFrom((ResolvedType) other.getRawType()))
return true;
}
if (this.isGenericType() && other.isRawType()) {
if (isAssignableFrom(other.getGenericType()))
return true;
}

if (this.isParameterizedType()) {
// look at wildcards...
if (((ReferenceType) this.getRawType()).isAssignableFrom(other)) {
boolean wildcardsAllTheWay = true;
ResolvedType[] myParameters = this.getResolvedTypeParameters();
for (int i = 0; i < myParameters.length; i++) {
if (!myParameters[i].isGenericWildcard()) {
wildcardsAllTheWay = false;
} else {
BoundedReferenceType boundedRT = (BoundedReferenceType) myParameters[i];
if (boundedRT.isExtends() || boundedRT.isSuper()) {
wildcardsAllTheWay = false;
}
}
}
if (wildcardsAllTheWay && !other.isParameterizedType())
return true;
// we have to match by parameters one at a time
ResolvedType[] theirParameters = other.getResolvedTypeParameters();
boolean parametersAssignable = true;
if (myParameters.length == theirParameters.length) {
for (int i = 0; i < myParameters.length; i++) {
if (myParameters[i] == theirParameters[i])
continue;
if (myParameters[i].isAssignableFrom(theirParameters[i], allowMissing)) {
continue;
}
if (!myParameters[i].isGenericWildcard()) {
parametersAssignable = false;
break;
} else {
BoundedReferenceType wildcardType = (BoundedReferenceType) myParameters[i];
if (!wildcardType.alwaysMatches(theirParameters[i])) {
parametersAssignable = false;
break;
}
}
}
} else {
parametersAssignable = false;
}
if (parametersAssignable)
return true;
}
}

if (isTypeVariableReference() && !other.isTypeVariableReference()) { // eg
// .
// this
// =
// T
// other
// =
// Ljava
// /
// lang
// /
// Object
// ;
TypeVariable aVar = ((TypeVariableReference) this).getTypeVariable();
return aVar.resolve(world).canBeBoundTo(other);
}

if (other.isTypeVariableReference()) {
TypeVariableReferenceType otherType = (TypeVariableReferenceType) other;
if (this instanceof TypeVariableReference) {
return ((TypeVariableReference) this).getTypeVariable().resolve(world).canBeBoundTo(
otherType.getTypeVariable().getFirstBound().resolve(world));// pr171952
// return
// ((TypeVariableReference)this).getTypeVariable()==otherType
// .getTypeVariable();
} else {
// FIXME asc should this say canBeBoundTo??
return this.isAssignableFrom(otherType.getTypeVariable().getFirstBound().resolve(world));
}
}

if (allowMissing && other.isMissing())
return false;

for (Iterator i = other.getDirectSupertypes(); i.hasNext();) {
if (this.isAssignableFrom((ResolvedType) i.next(), allowMissing))
return true;
}
return false;
}

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

public ISourceLocation getSourceLocation() {
ISourceContext isc = delegate.getSourceContext();
return isc.makeSourceLocation(new Position(startPos, endPos));
}

public boolean isExposedToWeaver() {
return (delegate == null) || delegate.isExposedToWeaver(); // ??? where
// does this
// belong
}

public WeaverStateInfo getWeaverState() {
return delegate.getWeaverState();
}

public ResolvedMember[] getDeclaredFields() {
if (parameterizedFields != null)
return parameterizedFields;
if (isParameterizedType() || isRawType()) {
ResolvedMember[] delegateFields = delegate.getDeclaredFields();
parameterizedFields = new ResolvedMember[delegateFields.length];
for (int i = 0; i < delegateFields.length; i++) {
parameterizedFields[i] = delegateFields[i].parameterizedWith(getTypesForMemberParameterization(), this,
isParameterizedType());
}
return parameterizedFields;
} else {
return delegate.getDeclaredFields();
}
}

/**
* Find out from the generic signature the true signature of any interfaces I implement. If I am parameterized, these may then
* need to be parameterized before returning.
*/
public ResolvedType[] getDeclaredInterfaces() {
if (parameterizedInterfaces != null)
return parameterizedInterfaces;
if (isParameterizedType()) {
ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces();
// UnresolvedType[] paramTypes =
// getTypesForMemberParameterization();
parameterizedInterfaces = new ResolvedType[delegateInterfaces.length];
for (int i = 0; i < delegateInterfaces.length; i++) {
// We may have to sub/super set the set of parametertypes if the
// implemented interface
// needs more or less than this type does. (pr124803/pr125080)

if (delegateInterfaces[i].isParameterizedType()) {
parameterizedInterfaces[i] = delegateInterfaces[i].parameterize(getMemberParameterizationMap()).resolve(world);
} else {
parameterizedInterfaces[i] = delegateInterfaces[i];
}
}
return parameterizedInterfaces;
} else if (isRawType()) {
ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces();
UnresolvedType[] paramTypes = getTypesForMemberParameterization();
parameterizedInterfaces = new ResolvedType[delegateInterfaces.length];
for (int i = 0; i < parameterizedInterfaces.length; i++) {
parameterizedInterfaces[i] = delegateInterfaces[i];
if (parameterizedInterfaces[i].isGenericType()) {
// a generic supertype of a raw type is replaced by its raw
// equivalent
parameterizedInterfaces[i] = parameterizedInterfaces[i].getRawType().resolve(getWorld());
} else if (parameterizedInterfaces[i].isParameterizedType()) {
// a parameterized supertype collapses any type vars to
// their upper bounds
UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(parameterizedInterfaces[i], paramTypes);
parameterizedInterfaces[i] = parameterizedInterfaces[i].parameterizedWith(toUseForParameterization);
}
}
return parameterizedInterfaces;
}
return delegate.getDeclaredInterfaces();
}

/**
* Locates the named type variable in the list of those on this generic type and returns the type parameter from the second list
* supplied. Returns null if it can't be found
*/
// private UnresolvedType findTypeParameterInList(String name,
// TypeVariable[] tvarsOnThisGenericType, UnresolvedType[]
// paramTypes) {
// int position = -1;
// for (int i = 0; i < tvarsOnThisGenericType.length; i++) {
// TypeVariable tv = tvarsOnThisGenericType[i];
// if (tv.getName().equals(name)) position = i;
// }
// if (position == -1 ) return null;
// return paramTypes[position];
// }
/**
* It is possible this type has multiple type variables but the interface we are about to parameterize only uses a subset - this
* method determines the subset to use by looking at the type variable names used. For example: <code>
* class Foo<T extends String,E extends Number> implements SuperInterface<T> {}
* </code> where <code>
* interface SuperInterface<Z> {}
* </code> In that
* example, a use of the 'Foo' raw type should know that it implements the SuperInterface<String>.
*/
private UnresolvedType[] determineThoseTypesToUse(ResolvedType parameterizedInterface, UnresolvedType[] paramTypes) {
// What are the type parameters for the supertype?
UnresolvedType[] tParms = parameterizedInterface.getTypeParameters();
UnresolvedType[] retVal = new UnresolvedType[tParms.length];

// Go through the supertypes type parameters, if any of them is a type
// variable, use the
// real type variable on the declaring type.

// it is possibly overkill to look up the type variable - ideally the
// entry in the type parameter list for the
// interface should be the a ref to the type variable in the current
// type ... but I'm not 100% confident right now.
for (int i = 0; i < tParms.length; i++) {
UnresolvedType tParm = tParms[i];
if (tParm.isTypeVariableReference()) {
TypeVariableReference tvrt = (TypeVariableReference) tParm;
TypeVariable tv = tvrt.getTypeVariable();
int rank = getRank(tv.getName());
// -1 probably means it is a reference to a type variable on the
// outer generic type (see pr129566)
if (rank != -1) {
retVal[i] = paramTypes[rank];
} else {
retVal[i] = tParms[i];
}
} else {
retVal[i] = tParms[i];
}

}
return retVal;
}

/**
* Returns the position within the set of type variables for this type for the specified type variable name. Returns -1 if there
* is no type variable with the specified name.
*/
private int getRank(String tvname) {
TypeVariable[] thisTypesTVars = getGenericType().getTypeVariables();
for (int i = 0; i < thisTypesTVars.length; i++) {
TypeVariable tv = thisTypesTVars[i];
if (tv.getName().equals(tvname))
return i;
}
return -1;
}

public ResolvedMember[] getDeclaredMethods() {
if (parameterizedMethods != null)
return parameterizedMethods;
if (isParameterizedType() || isRawType()) {
ResolvedMember[] delegateMethods = delegate.getDeclaredMethods();
UnresolvedType[] parameters = getTypesForMemberParameterization();
parameterizedMethods = new ResolvedMember[delegateMethods.length];
for (int i = 0; i < delegateMethods.length; i++) {
parameterizedMethods[i] = delegateMethods[i].parameterizedWith(parameters, this, isParameterizedType());
}
return parameterizedMethods;
} else {
return delegate.getDeclaredMethods();
}
}

public ResolvedMember[] getDeclaredPointcuts() {
if (parameterizedPointcuts != null)
return parameterizedPointcuts;
if (isParameterizedType()) {
ResolvedMember[] delegatePointcuts = delegate.getDeclaredPointcuts();
parameterizedPointcuts = new ResolvedMember[delegatePointcuts.length];
for (int i = 0; i < delegatePointcuts.length; i++) {
parameterizedPointcuts[i] = delegatePointcuts[i].parameterizedWith(getTypesForMemberParameterization(), this,
isParameterizedType());
}
return parameterizedPointcuts;
} else {
return delegate.getDeclaredPointcuts();
}
}

private UnresolvedType[] getTypesForMemberParameterization() {
UnresolvedType[] parameters = null;
if (isParameterizedType()) {
parameters = getTypeParameters();
} else if (isRawType()) {
// raw type, use upper bounds of type variables on generic type
TypeVariable[] tvs = getGenericType().getTypeVariables();
parameters = new UnresolvedType[tvs.length];
for (int i = 0; i < tvs.length; i++) {
parameters[i] = tvs[i].getFirstBound();
}
}
return parameters;
}

public UnresolvedType getRawType() {
return super.getRawType().resolve(getWorld());
}

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

public PerClause getPerClause() {
PerClause pclause = delegate.getPerClause();
if (isParameterizedType()) { // could cache the result here...
Map parameterizationMap = getAjMemberParameterizationMap();
pclause = (PerClause) pclause.parameterizeWith(parameterizationMap, world);
}
return pclause;
}

public Collection getDeclares() {
if (parameterizedDeclares != null)
return parameterizedDeclares;
Collection declares = null;
if (ajMembersNeedParameterization()) {
Collection genericDeclares = delegate.getDeclares();
parameterizedDeclares = new ArrayList();
Map parameterizationMap = getAjMemberParameterizationMap();
for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) {
Declare declareStatement = (Declare) iter.next();
parameterizedDeclares.add(declareStatement.parameterizeWith(parameterizationMap, world));
}
declares = parameterizedDeclares;
} else {
declares = delegate.getDeclares();
}
for (Iterator iter = declares.iterator(); iter.hasNext();) {
Declare d = (Declare) iter.next();
d.setDeclaringType(this);
}
return declares;
}

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();
}

public int getModifiers() {
return delegate.getModifiers();
}

public ResolvedType getSuperclass() {
ResolvedType ret = null;
try {
world.setTypeVariableLookupScope(this);
ret = delegate.getSuperclass();
} finally {
world.setTypeVariableLookupScope(null);
}
if (this.isParameterizedType() && ret.isParameterizedType()) {
ret = ret.parameterize(getMemberParameterizationMap()).resolve(getWorld());
}
return ret;
}

public ReferenceTypeDelegate getDelegate() {
return delegate;
}

public void setDelegate(ReferenceTypeDelegate delegate) {
// Don't copy from BcelObjectType to EclipseSourceType - the context may
// be tidied (result null'd) after previous weaving
if (this.delegate != null && this.delegate.copySourceContext()
&& this.delegate.getSourceContext() != SourceContextImpl.UNKNOWN_SOURCE_CONTEXT)
((AbstractReferenceTypeDelegate) delegate).setSourceContext(this.delegate.getSourceContext());
this.delegate = delegate;
for (Iterator it = this.derivativeTypes.iterator(); it.hasNext();) {
ReferenceType dependent = (ReferenceType) it.next();
dependent.setDelegate(delegate);
}

// If we are raw, we have a generic type - we should ensure it uses the
// same delegate
if (isRawType() && getGenericType() != null) {
ReferenceType genType = (ReferenceType) getGenericType();
if (genType.getDelegate() != delegate) { // avoids circular updates
genType.setDelegate(delegate);
}
}
clearParameterizationCaches();
}

private void clearParameterizationCaches() {
parameterizedFields = null;
parameterizedInterfaces = null;
parameterizedMethods = null;
parameterizedPointcuts = null;
}

public int getEndPos() {
return endPos;
}

public int getStartPos() {
return startPos;
}

public void setEndPos(int endPos) {
this.endPos = endPos;
}

public void setStartPos(int startPos) {
this.startPos = startPos;
}

public boolean doesNotExposeShadowMungers() {
return delegate.doesNotExposeShadowMungers();
}

public String getDeclaredGenericSignature() {
return delegate.getDeclaredGenericSignature();
}

public void setGenericType(ReferenceType rt) {
genericType = rt;
// Should we 'promote' this reference type from simple to raw?
// makes sense if someone is specifying that it has a generic form
if (typeKind == TypeKind.SIMPLE) {
typeKind = TypeKind.RAW;
signatureErasure = signature;
}
}

public void demoteToSimpleType() {
genericType = null;
typeKind = TypeKind.SIMPLE;
signatureErasure = null;
}

public ResolvedType getGenericType() {
if (isGenericType())
return this;
return genericType;
}

/**
* a parameterized signature starts with a "P" in place of the "L", see the comment on signatures in UnresolvedType.
*
* @param aGenericType
* @param someParameters
* @return
*/
private static String makeParameterizedSignature(ResolvedType aGenericType, ResolvedType[] someParameters) {
String rawSignature = aGenericType.getErasureSignature();
StringBuffer ret = new StringBuffer();
ret.append(PARAMETERIZED_TYPE_IDENTIFIER);
ret.append(rawSignature.substring(1, rawSignature.length() - 1));
ret.append("<");
for (int i = 0; i < someParameters.length; i++) {
ret.append(someParameters[i].getSignature());
}
ret.append(">;");
return ret.toString();
}

private static String makeDeclaredSignature(ResolvedType aGenericType, UnresolvedType[] someParameters) {
StringBuffer ret = new StringBuffer();
String rawSig = aGenericType.getErasureSignature();
ret.append(rawSig.substring(0, rawSig.length() - 1));
ret.append("<");
for (int i = 0; i < someParameters.length; i++) {
ret.append(((ReferenceType) someParameters[i]).getSignatureForAttribute());
}
ret.append(">;");
return ret.toString();
}

}

+ 105
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ReferenceTypeDelegate.java Переглянути файл

@@ -0,0 +1,105 @@
/* *******************************************************************
* Copyright (c) 2002 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:
* PARC initial implementation
* Andy Clement - June 2005 - separated out from ResolvedType
* ******************************************************************/
package org.aspectj.weaver;

import java.util.Collection;

import org.aspectj.weaver.patterns.PerClause;

/**
* 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 {

// TODO asc move to proxy
public void addAnnotation(AnnotationAJ annotationX);

public void ensureDelegateConsistent(); // Required evil because of mutator

// methods in delegates :( (see
// pr85132)

public boolean isAspect();

public boolean isAnnotationStyleAspect();

public boolean isInterface();

public boolean isEnum();

public boolean isAnnotation();

public String getRetentionPolicy();

public boolean canAnnotationTargetType();

public AnnotationTargetKind[] getAnnotationTargetKinds();

public boolean isAnnotationWithRuntimeRetention();

public boolean isClass();

public boolean isGeneric();

public boolean isAnonymous();

public boolean isNested();

public boolean isExposedToWeaver();

public boolean hasAnnotation(UnresolvedType ofType);

public AnnotationAJ[] getAnnotations();

public ResolvedType[] getAnnotationTypes();

public ResolvedMember[] getDeclaredFields();

public ResolvedType[] getDeclaredInterfaces();

public ResolvedMember[] getDeclaredMethods();

public ResolvedMember[] getDeclaredPointcuts();

public TypeVariable[] getTypeVariables();

public PerClause getPerClause();

public Collection getDeclares();

public Collection getTypeMungers();

public Collection getPrivilegedAccesses();

public int getModifiers();

public ResolvedType getSuperclass();

public WeaverStateInfo getWeaverState();

public ReferenceType getResolvedTypeX();

public boolean doesNotExposeShadowMungers();

public ISourceContext getSourceContext();

public String getSourcefilename();

public String getDeclaredGenericSignature();

public ResolvedType getOuterClass();

public boolean copySourceContext();

}

+ 191
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java Переглянути файл

@@ -0,0 +1,191 @@
/* *******************************************************************
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
* 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://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* AMC extracted as interface
* ******************************************************************/
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;

public interface ResolvedMember extends Member, AnnotatedElement,
TypeVariableDeclaringElement {

public static final ResolvedMember[] NONE = new ResolvedMember[0];

public int getModifiers(World world);

public int getModifiers();

public UnresolvedType[] getExceptions(World world);

public UnresolvedType[] getExceptions();

public ShadowMunger getAssociatedShadowMunger();

public boolean isAjSynthetic();

public boolean isCompatibleWith(Member am);

public boolean hasAnnotations();

public boolean hasAnnotation(UnresolvedType ofType);

public AnnotationAJ[] getAnnotations();

public ResolvedType[] getAnnotationTypes();

public void setAnnotationTypes(UnresolvedType[] annotationtypes);

public void addAnnotation(AnnotationAJ annotation);

public boolean isBridgeMethod();

public boolean isVarargsMethod();

public boolean isSynthetic();

public void write(DataOutputStream s) throws IOException;

public ISourceContext getSourceContext(World world);

public String[] getParameterNames();

public void setParameterNames(String[] names);

public AnnotationAJ[][] getParameterAnnotations();

public ResolvedType[][] getParameterAnnotationTypes();

public String getAnnotationDefaultValue();

public String getParameterSignatureErased();

public String getSignatureErased();

public String[] getParameterNames(World world);

public AjAttribute.EffectiveSignatureAttribute getEffectiveSignature();

public ISourceLocation getSourceLocation();

public int getEnd();

public ISourceContext getSourceContext();

public int getStart();

public void setPosition(int sourceStart, int sourceEnd);

public void setSourceContext(ISourceContext sourceContext);

public boolean isAbstract();

public boolean isPublic();

public boolean isProtected();

public boolean isNative();

public boolean isDefault();

public boolean isVisible(ResolvedType fromType);

public void setCheckedExceptions(UnresolvedType[] checkedExceptions);

public void setAnnotatedElsewhere(boolean b);

public boolean isAnnotatedElsewhere();

// like toString but include generic signature info
public String toGenericString();

public String toDebugString();

public boolean hasBackingGenericMember();

public ResolvedMember getBackingGenericMember();

/**
* Get the UnresolvedType for the return type, taking generic signature into
* account
*/
public UnresolvedType getGenericReturnType();

/**
* Get the TypeXs of the parameter types, taking generic signature into
* account
*/
public UnresolvedType[] getGenericParameterTypes();

// return a resolved member in which all type variables in the signature of
// this
// member have been replaced with the given bindings.
// the isParameterized flag tells us whether we are creating a raw type
// version or not
// if isParameterized List<T> will turn into List<String> (for example),
// but if !isParameterized List<T> will turn into List.
public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized);

// this variant allows for aliases for type variables (i.e. allowing them to
// have another name)
// this is used for processing ITDs that share type variables with their
// target generic type
public ResolvedMemberImpl parameterizedWith(
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized, List aliases);

public void setTypeVariables(TypeVariable[] types);

public TypeVariable[] getTypeVariables();

// /**
// * If this member is defined by a parameterized super-type, return the
// erasure
// * of that member.
// * For example:
// * interface I<T> { T foo(T aTea); }
// * class C implements I<String> {
// * String foo(String aString) { return "something"; }
// * }
// * The resolved member for C.foo has signature String foo(String). The
// * erasure of that member is Object foo(Object) -- use upper bound of type
// * variable.
// * A type is a supertype of itself.
// */
// public ResolvedMember getErasure();

/**
* Returns true if this member matches the other. The matching takes into
* account name and parameter types only. When comparing parameter types, we
* allow any type variable to match any other type variable regardless of
* bounds.
*/
public boolean matches(ResolvedMember aCandidateMatch);

public void resetName(String newName);

public void resetKind(MemberKind newKind);

public void resetModifiers(int newModifiers);

public void resetReturnTypeToObjectArray();

public void evictWeavingState();

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

+ 1156
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMemberImpl.java
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 165
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedPointcutDefinition.java Переглянути файл

@@ -0,0 +1,165 @@
/* *******************************************************************
* 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.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.weaver.patterns.Pointcut;


public class ResolvedPointcutDefinition extends ResolvedMemberImpl {
private Pointcut pointcut;

public ResolvedPointcutDefinition(
UnresolvedType declaringType,
int modifiers,
String name,
UnresolvedType[] parameterTypes,
Pointcut pointcut)
{
this(declaringType, modifiers, name, parameterTypes, ResolvedType.VOID, pointcut);
}

/**
* An instance which can be given a specific returnType, used f.e. in if() pointcut for @AJ
*
* @param declaringType
* @param modifiers
* @param name
* @param parameterTypes
* @param returnType
* @param pointcut
*/
public ResolvedPointcutDefinition(
UnresolvedType declaringType,
int modifiers,
String name,
UnresolvedType[] parameterTypes,
UnresolvedType returnType,
Pointcut pointcut)
{
super(
POINTCUT,
declaringType,
modifiers,
returnType,
name,
parameterTypes);
this.pointcut = pointcut;
//XXXpointcut.assertState(Pointcut.RESOLVED);
checkedExceptions = UnresolvedType.NONE;
}
// ----

public void write(DataOutputStream s) throws IOException {
getDeclaringType().write(s);
s.writeInt(getModifiers());
s.writeUTF(getName());
UnresolvedType.writeArray(getParameterTypes(), s);
pointcut.write(s);
}
public static ResolvedPointcutDefinition read(VersionedDataInputStream s, ISourceContext context) throws IOException {
ResolvedPointcutDefinition rpd =
new ResolvedPointcutDefinition(
UnresolvedType.read(s),
s.readInt(),
s.readUTF(),
UnresolvedType.readArray(s),
Pointcut.read(s, context));
rpd.setSourceContext(context); // whilst we have a source context, let's remember it
return rpd;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("pointcut ");
buf.append((getDeclaringType()==null?"<nullDeclaringType>":getDeclaringType().getName()));
buf.append(".");
buf.append(getName());
buf.append("(");
for (int i=0; i < getParameterTypes().length; i++) {
if (i > 0) buf.append(", ");
buf.append(getParameterTypes()[i].toString());
}
buf.append(")");
//buf.append(pointcut);
return buf.toString();
}
public Pointcut getPointcut() {
return pointcut;
}
public boolean isAjSynthetic() {
return true;
}
/**
* Called when asking a parameterized super-aspect for its pointcuts.
*/
public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, boolean isParameterized) {
TypeVariable[] typeVariables = getDeclaringType().resolve(newDeclaringType.getWorld()).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);
}
}
UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),typeMap,isParameterized);
UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];
for (int i = 0; i < parameterizedParameterTypes.length; i++) {
parameterizedParameterTypes[i] =
parameterize(getGenericParameterTypes()[i], typeMap,isParameterized);
}
ResolvedPointcutDefinition ret = new ResolvedPointcutDefinition(
newDeclaringType,
getModifiers(),
getName(),
parameterizedParameterTypes,
parameterizedReturnType,
pointcut.parameterizeWith(typeMap,newDeclaringType.getWorld())
);
ret.setTypeVariables(getTypeVariables());
ret.setSourceContext(getSourceContext());
ret.setPosition(getStart(),getEnd());
ret.setParameterNames(getParameterNames());
return ret;
//return this;
}
// for testing
public static final ResolvedPointcutDefinition DUMMY =
new ResolvedPointcutDefinition(UnresolvedType.OBJECT, 0, "missing",
UnresolvedType.NONE, Pointcut.makeMatchesNothing(Pointcut.RESOLVED));
public static final ResolvedPointcutDefinition[] NO_POINTCUTS = new ResolvedPointcutDefinition[]{};

public void setPointcut(Pointcut pointcut) {
this.pointcut = pointcut;
}

}

+ 2201
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 446
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedTypeMunger.java Переглянути файл

@@ -0,0 +1,446 @@
/* *******************************************************************
* 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
* Alexandre Vasseur @AspectJ ITDs
* ******************************************************************/

package org.aspectj.weaver;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
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;
import org.aspectj.bridge.SourceLocation;
import org.aspectj.util.TypeSafeEnum;

/**
* This is an abstraction over method/field introduction. It might not have the chops to handle other inter-type declarations. This
* is the thing that is used on the eclipse side and serialized into a ConcreteTypeMunger.
*/
public abstract class ResolvedTypeMunger {
protected Kind kind;
protected ResolvedMember signature;

/**
* The declared signature is filled in when a type munger is parameterized for application to a particular type. It represents
* the signature originally declared in the source file.
*/
protected ResolvedMember declaredSignature;

// This list records the occurences (in order) of any names specified in the <>
// for a target type for the ITD. So for example, for List<C,B,A> this list
// will be C,B,A - the list is used later to map other occurrences of C,B,A
// across the intertype declaration to the right type variables in the generic
// type upon which the itd is being made.
// might need serializing the class file for binary weaving.
protected List /* String */typeVariableAliases;

private Set /* resolvedMembers */superMethodsCalled = Collections.EMPTY_SET;

private ISourceLocation location; // Lost during serialize/deserialize !

public ResolvedTypeMunger(Kind kind, ResolvedMember signature) {
this.kind = kind;
this.signature = signature;
UnresolvedType declaringType = signature != null ? signature.getDeclaringType() : null;
if (declaringType != null) {
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) {
location = isl;
}

public ISourceLocation getSourceLocation() {
return location;
}

// ----

// fromType is guaranteed to be a non-abstract aspect
// public ConcreteTypeMunger concretize(World world, ResolvedType aspectType) {
//
// ConcreteTypeMunger munger = world.concreteTypeMunger(this, aspectType);
// return munger;
// }

public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
ResolvedType onType = matchType.getWorld().resolve(signature.getDeclaringType());
if (onType.isRawType())
onType = onType.getGenericType();
// System.err.println("matching: " + this + " to " + matchType + " onType = " + onType);
if (matchType.equals(onType)) {
if (!onType.isExposedToWeaver()) {
// if the onType is an interface, and it already has the member we are about
// to munge, then this is ok...
boolean ok = (onType.isInterface() && (onType.lookupMemberWithSupersAndITDs(getSignature()) != null));

if (!ok && onType.getWeaverState() == null) {
if (matchType.getWorld().getLint().typeNotExposedToWeaver.isEnabled()) {
matchType.getWorld().getLint().typeNotExposedToWeaver.signal(matchType.getName(), signature
.getSourceLocation());
}
}
}
return true;
}
// System.err.println("NO MATCH DIRECT");

if (onType.isInterface()) {
return matchType.isTopmostImplementor(onType);
} else {
return false;
}
}

// ----

public String toString() {
return "ResolvedTypeMunger(" + getKind() + ", " + getSignature() + ")";
// .superMethodsCalled + ")";
}

// ----

public static ResolvedTypeMunger read(VersionedDataInputStream s, ISourceContext context) throws IOException {
Kind kind = Kind.read(s);
if (kind == Field) {
return NewFieldTypeMunger.readField(s, context);
} else if (kind == Method) {
return NewMethodTypeMunger.readMethod(s, context);
} else if (kind == Constructor) {
return NewConstructorTypeMunger.readConstructor(s, context);
} else if (kind == MethodDelegate) {
return MethodDelegateTypeMunger.readMethod(s, context);
} else if (kind == FieldHost) {
return MethodDelegateTypeMunger.FieldHostTypeMunger.readFieldHost(s, context);
} else {
throw new RuntimeException("unimplemented");
}
}

protected static Set readSuperMethodsCalled(VersionedDataInputStream s) throws IOException {

Set ret = new HashSet();
int n = s.readInt();
if (n < 0)
throw new BCException("Problem deserializing type munger");
for (int i = 0; i < n; i++) {
ret.add(ResolvedMemberImpl.readResolvedMember(s, null));
}
return ret;
}

protected void writeSuperMethodsCalled(DataOutputStream s) throws IOException {

if (superMethodsCalled == null || superMethodsCalled.size() == 0) {
s.writeInt(0);
return;
}

List ret = new ArrayList(superMethodsCalled);
Collections.sort(ret);
int n = ret.size();
s.writeInt(n);
for (Iterator i = ret.iterator(); i.hasNext();) {
ResolvedMember m = (ResolvedMember) i.next();
m.write(s);
}

}

protected static ISourceLocation readSourceLocation(VersionedDataInputStream s) throws IOException {
// Location persistence for type mungers was added after 1.2.1 was shipped...
if (s.getMajorVersion() < AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150)
return null;
SourceLocation ret = null;
ObjectInputStream ois = null;
try {
// This logic copes with the location missing from the attribute - an EOFException will
// occur on the next line and we ignore it.
ois = new ObjectInputStream(s);
Boolean validLocation = (Boolean) ois.readObject();
if (validLocation.booleanValue()) {
File f = (File) ois.readObject();
Integer ii = (Integer) ois.readObject();
Integer offset = (Integer) ois.readObject();
ret = new SourceLocation(f, ii.intValue());
ret.setOffset(offset.intValue());
}
} catch (EOFException eof) {
return null; // This exception occurs if processing an 'old style' file where the
// type munger attributes don't include the source location.
} catch (IOException ioe) {
// Something went wrong, maybe this is an 'old style' file that doesnt attach locations to mungers?
// (but I thought that was just an EOFException?)
ioe.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
} finally {
if (ois != null)
ois.close();
}
return ret;
}

protected void writeSourceLocation(DataOutputStream s) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(s);
// oos.writeObject(location);
oos.writeObject(new Boolean(location != null));
if (location != null) {
oos.writeObject(location.getSourceFile());
oos.writeObject(new Integer(location.getLine()));
oos.writeObject(new Integer(location.getOffset()));
}
oos.flush();
oos.close();
}

public abstract void write(DataOutputStream s) throws IOException;

public Kind getKind() {
return kind;
}

public static class Kind extends TypeSafeEnum {
/* private */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 Field;
case 2:
return Method;
case 5:
return Constructor;
case 9:
return MethodDelegate;
case 10:
return FieldHost;
}
throw new BCException("bad kind: " + key);
}

public String toString() {
// we want MethodDelegate to appear as Method in WeaveInfo messages
// TODO we may want something for fieldhost ?
if (MethodDelegate.getName().equals(getName())) {
return Method.toString();
} else {
return super.toString();
}
}
}

// ---- fields

public static final Kind Field = new Kind("Field", 1);
public static final Kind Method = new Kind("Method", 2);
public static final Kind Constructor = new Kind("Constructor", 5);

// not serialized, only created during concretization of aspects
public static final Kind PerObjectInterface = new Kind("PerObjectInterface", 3);
public static final Kind PrivilegedAccess = new Kind("PrivilegedAccess", 4);

public static final Kind Parent = new Kind("Parent", 6);
public static final Kind PerTypeWithinInterface = new Kind("PerTypeWithinInterface", 7); // PTWIMPL not serialized, used during
// concretization of aspects

public static final Kind AnnotationOnType = new Kind("AnnotationOnType", 8); // not serialized

public static final Kind MethodDelegate = new Kind("MethodDelegate", 9);// serialized, @AJ ITDs
public static final Kind FieldHost = new Kind("FieldHost", 10);// serialized, @AJ ITDs

public static final String SUPER_DISPATCH_NAME = "superDispatch";

public void setSuperMethodsCalled(Set c) {
this.superMethodsCalled = c;
}

public Set getSuperMethodsCalled() {
return superMethodsCalled;
}

public ResolvedMember getSignature() {
return signature;
}

// ----

public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) {
if ((getSignature() != null) && getSignature().isPublic() && member.equals(getSignature())) {
return getSignature();
}

return null;
}

public boolean changesPublicSignature() {
return kind == Field || kind == Method || kind == Constructor;
}

public boolean needsAccessToTopmostImplementor() {
if (kind == Field) {
return true;
} else if (kind == Method) {
return !signature.isAbstract();
} else {
return false;
}
}

protected static List readInTypeAliases(VersionedDataInputStream s) throws IOException {
if (s.getMajorVersion() >= AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
int count = s.readInt();
if (count != 0) {
List aliases = new ArrayList();
for (int i = 0; i < count; i++) {
aliases.add(s.readUTF());
}
return aliases;
}
}
return null;
}

protected void writeOutTypeAliases(DataOutputStream s) throws IOException {
// Write any type variable aliases
if (typeVariableAliases == null || typeVariableAliases.size() == 0) {
s.writeInt(0);
} else {
s.writeInt(typeVariableAliases.size());
for (Iterator iter = typeVariableAliases.iterator(); iter.hasNext();) {
String element = (String) iter.next();
s.writeUTF(element);
}
}
}

public List getTypeVariableAliases() {
return typeVariableAliases;
}

public boolean hasTypeVariableAliases() {
return (typeVariableAliases != null && typeVariableAliases.size() > 0);
}

/**
* return true if type variables are specified with the target type for this ITD. e.g. this would return true:
* "int I<A,B>.m() { return 42; }"
*/
public boolean sharesTypeVariablesWithGenericType() {
return (typeVariableAliases != null && typeVariableAliases.size() > 0);
}

/**
* Parameterizes a resolved type munger for a particular usage of its target type (this is used when the target type is generic
* and the ITD shares type variables with the target) see ConcreteTypeMunger.parameterizedFor
*/
public ResolvedTypeMunger parameterizedFor(ResolvedType target) {
throw new BCException("Dont call parameterizedFor on a type munger of this kind: " + this.getClass());
}

// ResolvedType genericType = target;
// if (target.isRawType() || target.isParameterizedType()) genericType = genericType.getGenericType();
// ResolvedMember parameterizedSignature = null;
// // If we are parameterizing it for a generic type, we just need to 'swap the letters' from the ones used
// // in the original ITD declaration to the ones used in the actual target type declaration.
// if (target.isGenericType()) {
// TypeVariable vars[] = target.getTypeVariables();
// UnresolvedTypeVariableReferenceType[] varRefs = new UnresolvedTypeVariableReferenceType[vars.length];
// for (int i = 0; i < vars.length; i++) {
// varRefs[i] = new UnresolvedTypeVariableReferenceType(vars[i]);
// }
// parameterizedSignature = getSignature().parameterizedWith(varRefs,genericType,true,typeVariableAliases);
// } else {
// // For raw and 'normal' parameterized targets (e.g. Interface, Interface<String>)
// parameterizedSignature =
// getSignature().parameterizedWith(target.getTypeParameters(),genericType,target.isParameterizedType(),typeVariableAliases);
// }
// return new NewMethodTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases);
// }
// /**
// * see ResolvedTypeMunger.parameterizedFor(ResolvedType)
// */
// public ResolvedTypeMunger parameterizedFor(ResolvedType target) {
// ResolvedType genericType = target;
// if (target.isRawType() || target.isParameterizedType()) genericType = genericType.getGenericType();
// ResolvedMember parameterizedSignature =
// getSignature().parameterizedWith(target.getTypeParameters(),genericType,target.isParameterizedType(),typeVariableAliases);
// return new NewFieldTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases);
// }

public void setDeclaredSignature(ResolvedMember rm) {
declaredSignature = rm;
}

public ResolvedMember getDeclaredSignature() {
return declaredSignature;
}

/**
* A late munger has to be done after shadow munging since which shadows are matched can affect the operation of the late
* munger. e.g. perobjectinterfacemunger
*/
public boolean isLateMunger() {
return false;
}

/**
* Some type mungers are created purely to help with the implementation of shadow mungers. For example to support the cflow()
* pointcut we create a new cflow field in the aspect, and that is added via a BcelCflowCounterFieldAdder.
*
* During compilation we need to compare sets of type mungers, and if some only come into existence after the 'shadowy' type
* things have been processed, we need to ignore them during the comparison.
*
* Returning true from this method indicates the type munger exists to support 'shadowy' stuff - and so can be ignored in some
* comparison.
*/
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());
}

}

+ 666
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Shadow.java Переглянути файл

@@ -0,0 +1,666 @@
/* *******************************************************************
* 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 java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.PartialOrder;
import org.aspectj.util.TypeSafeEnum;
import org.aspectj.weaver.ast.Var;

/*
* The superclass of anything representing a the shadow of a join point. A shadow represents
* some bit of code, and encompasses both entry and exit from that code. All shadows have a kind
* and a signature.
*/

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. // OPTIMIZE is this a bug? static?

private final Kind kind;
private final Member signature;
private Member matchingSignature;
private ResolvedMember resolvedSignature;
protected final Shadow enclosingShadow;
protected List mungers = Collections.EMPTY_LIST;

public int shadowId = nextShadowID++; // every time we build a shadow, it gets a new id

// ----
protected Shadow(Kind kind, Member signature, Shadow enclosingShadow) {
this.kind = kind;
this.signature = signature;
this.enclosingShadow = enclosingShadow;
}

// ----

public abstract World getIWorld();

public List /* ShadowMunger */getMungers() {
return mungers;
}

/**
* could this(*) pcd ever match
*/
public final boolean hasThis() {
if (getKind().neverHasThis()) {
return false;
} else if (getKind().isEnclosingKind()) {
return !getSignature().isStatic();
} else if (enclosingShadow == null) {
return false;
} else {
return enclosingShadow.hasThis();
}
}

/**
* the type of the this object here
*
* @throws IllegalStateException if there is no this here
*/
public final UnresolvedType getThisType() {
if (!hasThis())
throw new IllegalStateException("no this");
if (getKind().isEnclosingKind()) {
return getSignature().getDeclaringType();
} else {
return enclosingShadow.getThisType();
}
}

/**
* a var referencing this
*
* @throws IllegalStateException if there is no target here
*/
public abstract Var getThisVar();

/**
* could target(*) pcd ever match
*/
public final boolean hasTarget() {
if (getKind().neverHasTarget()) {
return false;
} else if (getKind().isTargetSameAsThis()) {
return hasThis();
} else {
return !getSignature().isStatic();
}
}

/**
* the type of the target object here
*
* @throws IllegalStateException if there is no target here
*/
public final UnresolvedType getTargetType() {
if (!hasTarget())
throw new IllegalStateException("no target");
return getSignature().getDeclaringType();
}

/**
* a var referencing the target
*
* @throws IllegalStateException if there is no target here
*/
public abstract Var getTargetVar();

public UnresolvedType[] getArgTypes() {
if (getKind() == FieldSet)
return new UnresolvedType[] { getSignature().getReturnType() };
return getSignature().getParameterTypes();
}

public boolean isShadowForArrayConstructionJoinpoint() {
return (getKind() == ConstructorCall && signature.getDeclaringType().isArray());
}

public boolean isShadowForMonitor() {
return (getKind() == SynchronizationLock || getKind() == SynchronizationUnlock);
}

// will return the right length array of ints depending on how many dimensions the array has
public ResolvedType[] getArgumentTypesForArrayConstructionShadow() {
String s = signature.getDeclaringType().getSignature();
int pos = s.indexOf("[");
int dims = 1;
while (pos < s.length()) {
pos++;
if (pos < s.length())
dims += (s.charAt(pos) == '[' ? 1 : 0);
}
if (dims == 1)
return new ResolvedType[] { ResolvedType.INT };
ResolvedType[] someInts = new ResolvedType[dims];
for (int i = 0; i < dims; i++)
someInts[i] = ResolvedType.INT;
return someInts;
}

public UnresolvedType[] getGenericArgTypes() {
if (isShadowForArrayConstructionJoinpoint()) {
return getArgumentTypesForArrayConstructionShadow();
}
if (isShadowForMonitor()) {
return UnresolvedType.ARRAY_WITH_JUST_OBJECT;
}
if (getKind() == FieldSet)
return new UnresolvedType[] { getResolvedSignature().getGenericReturnType() };
return getResolvedSignature().getGenericParameterTypes();
}

public UnresolvedType getArgType(int arg) {
if (getKind() == FieldSet)
return getSignature().getReturnType();
return getSignature().getParameterTypes()[arg];
}

public int getArgCount() {
if (getKind() == FieldSet)
return 1;
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();

public abstract Var getArgVar(int i);

public abstract Var getThisJoinPointVar();

public abstract Var getThisJoinPointStaticPartVar();

public abstract Var getThisEnclosingJoinPointStaticPartVar();

// annotation variables
public abstract Var getKindedAnnotationVar(UnresolvedType forAnnotationType);

public abstract Var getWithinAnnotationVar(UnresolvedType forAnnotationType);

public abstract Var getWithinCodeAnnotationVar(UnresolvedType forAnnotationType);

public abstract Var getThisAnnotationVar(UnresolvedType forAnnotationType);

public abstract Var getTargetAnnotationVar(UnresolvedType forAnnotationType);

public abstract Var getArgAnnotationVar(int i, UnresolvedType forAnnotationType);

public abstract Member getEnclosingCodeSignature();

/**
* returns the kind of shadow this is, representing what happens under this shadow
*/
public Kind getKind() {
return kind;
}

/**
* returns the signature of the thing under this shadow
*/
public Member getSignature() {
return signature;
}

/**
* returns the signature of the thing under this shadow, with any synthetic arguments removed
*/
public Member getMatchingSignature() {
return matchingSignature != null ? matchingSignature : signature;
}

public void setMatchingSignature(Member member) {
this.matchingSignature = member;
}

/**
* returns the resolved signature of the thing under this shadow
*
*/
public ResolvedMember getResolvedSignature() {
if (resolvedSignature == null) {
resolvedSignature = signature.resolve(getIWorld());
}
return resolvedSignature;
}

public UnresolvedType getReturnType() {
if (kind == ConstructorCall)
return getSignature().getDeclaringType();
else if (kind == FieldSet)
return ResolvedType.VOID;
else if (kind == SynchronizationLock || kind == SynchronizationUnlock)
return ResolvedType.VOID;
return getResolvedSignature().getGenericReturnType();
}

public static String METHOD_EXECUTION = "method-execution";
public static String METHOD_CALL = "method-call";
public static String CONSTRUCTOR_EXECUTION = "constructor-execution";
public static String CONSTRUCTOR_CALL = "constructor-call";
public static String FIELD_GET = "field-get";
public static String FIELD_SET = "field-set";
public static String STATICINITIALIZATION = "staticinitialization";
public static String PREINITIALIZATION = "preinitialization";
public static String INITIALIZATION = "initialization";
public static String EXCEPTION_HANDLER = "exception-handler";
public static String SYNCHRONIZATION_LOCK = "lock";
public static String SYNCHRONIZATION_UNLOCK = "unlock";
public static String ADVICE_EXECUTION = "adviceexecution";

/**
* These names are the ones that will be returned by thisJoinPoint.getKind() Those need to be documented somewhere
*/
public static final Kind MethodCall = new Kind(METHOD_CALL, 1, true);
public static final Kind ConstructorCall = new Kind(CONSTRUCTOR_CALL, 2, true);
public static final Kind MethodExecution = new Kind(METHOD_EXECUTION, 3, false);
public static final Kind ConstructorExecution = new Kind(CONSTRUCTOR_EXECUTION, 4, false);
public static final Kind FieldGet = new Kind(FIELD_GET, 5, true);
public static final Kind FieldSet = new Kind(FIELD_SET, 6, true);
public static final Kind StaticInitialization = new Kind(STATICINITIALIZATION, 7, false);
public static final Kind PreInitialization = new Kind(PREINITIALIZATION, 8, false);
public static final Kind AdviceExecution = new Kind(ADVICE_EXECUTION, 9, false);
public static final Kind Initialization = new Kind(INITIALIZATION, 10, false);
public static final Kind ExceptionHandler = new Kind(EXCEPTION_HANDLER, 11, true);
public static final Kind SynchronizationLock = new Kind(SYNCHRONIZATION_LOCK, 12, true);
public static final Kind SynchronizationUnlock = new Kind(SYNCHRONIZATION_UNLOCK, 13, true);

// Bits here are 1<<(Kind.getKey()) - and unfortunately keys didn't start at zero so bits here start at 2
public static final int MethodCallBit = 0x002;
public static final int ConstructorCallBit = 0x004;
public static final int MethodExecutionBit = 0x008;
public static final int ConstructorExecutionBit = 0x010;
public static final int FieldGetBit = 0x020;
public static final int FieldSetBit = 0x040;
public static final int StaticInitializationBit = 0x080;
public static final int PreInitializationBit = 0x100;
public static final int AdviceExecutionBit = 0x200;
public static final int InitializationBit = 0x400;
public static final int ExceptionHandlerBit = 0x800;
public static final int SynchronizationLockBit = 0x1000;
public static final int SynchronizationUnlockBit = 0x2000;

public static final int MAX_SHADOW_KIND = 13;
public static final Kind[] SHADOW_KINDS = new Kind[] { MethodCall, ConstructorCall, MethodExecution, ConstructorExecution,
FieldGet, FieldSet, StaticInitialization, PreInitialization, AdviceExecution, Initialization, ExceptionHandler,
SynchronizationLock, SynchronizationUnlock };

public static final int ALL_SHADOW_KINDS_BITS;
public static final int NO_SHADOW_KINDS_BITS;

static {
ALL_SHADOW_KINDS_BITS = 0x3ffe;
NO_SHADOW_KINDS_BITS = 0x0000;
}

/**
* Return count of how many bits set in the supplied parameter.
*/
public static int howMany(int i) {
int count = 0;
for (int j = 0; j < SHADOW_KINDS.length; j++) {
if ((i & SHADOW_KINDS[j].bit) != 0)
count++;
}
return count;
}

/**
* A type-safe enum representing the kind of shadows
*/
public static final class Kind extends TypeSafeEnum {
// private boolean argsOnStack; //XXX unused

public int bit;

public Kind(String name, int key, boolean argsOnStack) {
super(name, key);
bit = 1 << key;
// this.argsOnStack = argsOnStack;
}

public String toLegalJavaIdentifier() {
return getName().replace('-', '_');
}

public boolean argsOnStack() {
return !isTargetSameAsThis();
}

// !!! this is false for handlers!
public boolean allowsExtraction() {
return true;
}

public boolean isSet(int i) {
return (i & bit) != 0;
}

// XXX revisit along with removal of priorities
public boolean hasHighPriorityExceptions() {
return !isTargetSameAsThis();
}

private final static int hasReturnValueFlag = MethodCallBit | ConstructorCallBit | MethodExecutionBit | FieldGetBit
| AdviceExecutionBit;

/**
* These shadow kinds have return values that can be bound in after returning(Dooberry doo) advice.
*
* @return
*/
public boolean hasReturnValue() {
return (bit & hasReturnValueFlag) != 0;
}

private final static int isEnclosingKindFlag = MethodExecutionBit | ConstructorExecutionBit | AdviceExecutionBit
| StaticInitializationBit | InitializationBit;

/**
* These are all the shadows that contains other shadows within them and are often directly associated with methods.
*/
public boolean isEnclosingKind() {
return (bit & isEnclosingKindFlag) != 0;
}

private final static int isTargetSameAsThisFlag = MethodExecutionBit | ConstructorExecutionBit | StaticInitializationBit
| PreInitializationBit | AdviceExecutionBit | InitializationBit;

public boolean isTargetSameAsThis() {
return (bit & isTargetSameAsThisFlag) != 0;
}

private final static int neverHasTargetFlag = ConstructorCallBit | ExceptionHandlerBit | PreInitializationBit
| StaticInitializationBit | SynchronizationLockBit | SynchronizationUnlockBit;

public boolean neverHasTarget() {
return (bit & neverHasTargetFlag) != 0;
}

private final static int neverHasThisFlag = PreInitializationBit | StaticInitializationBit;

public boolean neverHasThis() {
return (bit & neverHasThisFlag) != 0;
}

public String getSimpleName() {
int dash = getName().lastIndexOf('-');
if (dash == -1)
return getName();
else
return getName().substring(dash + 1);
}

public static Kind read(DataInputStream s) throws IOException {
int key = s.readByte();
switch (key) {
case 1:
return MethodCall;
case 2:
return ConstructorCall;
case 3:
return MethodExecution;
case 4:
return ConstructorExecution;
case 5:
return FieldGet;
case 6:
return FieldSet;
case 7:
return StaticInitialization;
case 8:
return PreInitialization;
case 9:
return AdviceExecution;
case 10:
return Initialization;
case 11:
return ExceptionHandler;
case 12:
return SynchronizationLock;
case 13:
return SynchronizationUnlock;
}
throw new BCException("unknown kind: " + key);
}
}

/**
* Only does the check if the munger requires it (@AJ aspects don't)
*
* @param munger
* @return
*/
protected boolean checkMunger(ShadowMunger munger) {
if (munger.mustCheckExceptions()) {
for (Iterator i = munger.getThrownExceptions().iterator(); i.hasNext();) {
if (!checkCanThrow(munger, (ResolvedType) i.next()))
return false;
}
}
return true;
}

protected boolean checkCanThrow(ShadowMunger munger, ResolvedType resolvedTypeX) {
if (getKind() == ExceptionHandler) {
// XXX much too lenient rules here, need to walk up exception handlers
return true;
}

if (!isDeclaredException(resolvedTypeX, getSignature())) {
getIWorld().showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CANT_THROW_CHECKED, resolvedTypeX, this), // from
// advice
// in
// \
// '"
// +
// munger
// .
// +
// "\'"
// ,
getSourceLocation(), munger.getSourceLocation());
}

return true;
}

private boolean isDeclaredException(ResolvedType resolvedTypeX, Member member) {
ResolvedType[] excs = getIWorld().resolve(member.getExceptions(getIWorld()));
for (int i = 0, len = excs.length; i < len; i++) {
if (excs[i].isAssignableFrom(resolvedTypeX))
return true;
}
return false;
}

public void addMunger(ShadowMunger munger) {
if (checkMunger(munger)) {
if (mungers == Collections.EMPTY_LIST)
mungers = new ArrayList();
this.mungers.add(munger);
}
}

public final void implement() {
sortMungers();
if (mungers == null)
return;
prepareForMungers();
implementMungers();
}

private void sortMungers() {

List sorted = PartialOrder.sort(mungers);

// Bunch of code to work out whether to report xlints for advice that isn't ordered at this Joinpoint
possiblyReportUnorderedAdvice(sorted);

if (sorted == null) {
// this means that we have circular dependencies
for (Iterator i = mungers.iterator(); i.hasNext();) {
ShadowMunger m = (ShadowMunger) i.next();
getIWorld().getMessageHandler().handleMessage(
MessageUtil.error(WeaverMessages.format(WeaverMessages.CIRCULAR_DEPENDENCY, this), m.getSourceLocation()));
}
}
mungers = sorted;
}

// not quite optimal... but the xlint is ignore by default
private void possiblyReportUnorderedAdvice(List sorted) {
if (sorted != null && getIWorld().getLint().unorderedAdviceAtShadow.isEnabled() && mungers.size() > 1) {

// Stores a set of strings of the form 'aspect1:aspect2' which indicates there is no
// precedence specified between the two aspects at this shadow.
Set clashingAspects = new HashSet();
int max = mungers.size();

// Compare every pair of advice mungers
for (int i = max - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
Object a = mungers.get(i);
Object b = mungers.get(j);

// Make sure they are the right type
if (a instanceof Advice && b instanceof Advice) {
Advice adviceA = (Advice) a;
Advice adviceB = (Advice) b;
if (!adviceA.concreteAspect.equals(adviceB.concreteAspect)) {
AdviceKind adviceKindA = adviceA.getKind();
AdviceKind adviceKindB = adviceB.getKind();

// make sure they are the nice ones (<6) and not any synthetic advice ones we
// create to support other features of the language.
if (adviceKindA.getKey() < (byte) 6 && adviceKindB.getKey() < (byte) 6
&& adviceKindA.getPrecedence() == adviceKindB.getPrecedence()) {

// Ask the world if it knows about precedence between these
Integer order = getIWorld().getPrecedenceIfAny(adviceA.concreteAspect, adviceB.concreteAspect);

if (order != null && order.equals(new Integer(0))) {
String key = adviceA.getDeclaringAspect() + ":" + adviceB.getDeclaringAspect();
String possibleExistingKey = adviceB.getDeclaringAspect() + ":" + adviceA.getDeclaringAspect();
if (!clashingAspects.contains(possibleExistingKey))
clashingAspects.add(key);
}
}
}
}
}
}
for (Iterator iter = clashingAspects.iterator(); iter.hasNext();) {
String element = (String) iter.next();
String aspect1 = element.substring(0, element.indexOf(":"));
String aspect2 = element.substring(element.indexOf(":") + 1);
getIWorld().getLint().unorderedAdviceAtShadow.signal(new String[] { this.toString(), aspect1, aspect2 }, this
.getSourceLocation(), null);
}
}
}

/**
* Prepare the shadow for implementation. After this is done, the shadow should be in such a position that each munger simply
* needs to be implemented.
*/
protected void prepareForMungers() {
throw new RuntimeException("Generic shadows cannot be prepared");
}

/** Actually implement the (non-empty) mungers associated with this shadow */
private void implementMungers() {
World world = getIWorld();
for (Iterator iter = mungers.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
munger.implementOn(this);
world.reportMatch(munger, this);
}
}

public abstract ISourceLocation getSourceLocation();

// ---- utility

public String toString() {
return getKind() + "(" + getSignature() + ")"; // + getSourceLines();
}

public String toResolvedString(World world) {
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() + ")";
}

/**
* Convert a bit array for the shadow kinds into a set of them... should only be used for testing - mainline code should do bit
* manipulation!
*/
public static Set toSet(int i) {
Set results = new HashSet();
for (int j = 0; j < Shadow.SHADOW_KINDS.length; j++) {
Kind k = Shadow.SHADOW_KINDS[j];
if (k.isSet(i))
results.add(k);
}
return results;
}

}

+ 191
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ShadowMunger.java Переглянути файл

@@ -0,0 +1,191 @@
/* *******************************************************************
* 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.File;
import java.util.Collection;
import java.util.Map;

import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.SourceLocation;
import org.aspectj.util.PartialOrder;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;

/**
* For every shadow munger, nothing can be done with it until it is concretized. Then...
*
* (Then we call fast match.)
*
* For every shadow munger, for every shadow, first match is called, then (if match returned true) the shadow munger is specialized
* for the shadow, which may modify state. Then implement is called.
*/
public abstract class ShadowMunger implements PartialOrder.PartialComparable, IHasPosition {

protected Pointcut pointcut;

// these three fields hold the source location of this munger
protected int start, end;
protected ISourceContext sourceContext;
private ISourceLocation sourceLocation;
private ISourceLocation binarySourceLocation;
private File binaryFile;
public String handle = null;
private ResolvedType declaringType; // the type that declared this munger.

public ShadowMunger(Pointcut pointcut, int start, int end, ISourceContext sourceContext) {
this.pointcut = pointcut;
this.start = start;
this.end = end;
this.sourceContext = sourceContext;
}

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

public abstract void specializeOn(Shadow shadow);

public abstract void implementOn(Shadow shadow);

/**
* All overriding methods should call super
*/
public boolean match(Shadow shadow, World world) {
return pointcut.match(shadow).maybeTrue();
}

public abstract ShadowMunger parameterizeWith(ResolvedType declaringType, Map typeVariableMap);

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

public int getEnd() {
return end;
}

public int getStart() {
return start;
}

public ISourceLocation getSourceLocation() {
if (sourceLocation == null) {
if (sourceContext != null) {
sourceLocation = sourceContext.makeSourceLocation(this);
}
}
if (isBinary()) {
if (binarySourceLocation == null) {
binarySourceLocation = getBinarySourceLocation(sourceLocation);
}
return binarySourceLocation;
}
return sourceLocation;
}

// ---- fields

public static final ShadowMunger[] NONE = new ShadowMunger[0];

public Pointcut getPointcut() {
return pointcut;
}

// pointcut may be updated during rewriting...
public void setPointcut(Pointcut pointcut) {
this.pointcut = pointcut;
}

/**
* Invoked when the shadow munger of a resolved type are processed.
*
* @param aType
*/
public void setDeclaringType(ResolvedType aType) {
declaringType = aType;
}

public ResolvedType getDeclaringType() {
return declaringType;
}

/**
* @return a Collection of ResolvedType for all checked exceptions that might be thrown by this munger
*/
public abstract Collection getThrownExceptions();

/**
* Does the munger has to check that its exception are accepted by the shadow ? ATAJ: It s not the case for @AJ around advice
* f.e. that can throw Throwable, even if the advised method does not throw any exceptions.
*
* @return true if munger has to check that its exceptions can be throwned based on the shadow
*/
public abstract boolean mustCheckExceptions();

/**
* Returns the binarySourceLocation for the given sourcelocation. This isn't cached because it's used when faulting in the
* binary nodes and is called with ISourceLocations for all advice, pointcuts and deows contained within the
* resolvedDeclaringAspect.
*/
public ISourceLocation getBinarySourceLocation(ISourceLocation sl) {
if (sl == null)
return null;
String sourceFileName = null;
if (getDeclaringType() instanceof ReferenceType) {
String s = ((ReferenceType) getDeclaringType()).getDelegate().getSourcefilename();
int i = s.lastIndexOf('/');
if (i != -1) {
sourceFileName = s.substring(i + 1);
} else {
sourceFileName = s;
}
}
ISourceLocation sLoc = new SourceLocation(getBinaryFile(), sl.getLine(), sl.getEndLine(),
((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), sl.getContext(), sourceFileName);
return sLoc;
}

/**
* Returns the File with pathname to the class file, for example either C:\temp
* \ajcSandbox\workspace\ajcTest16957.tmp\simple.jar!pkg\BinaryAspect.class if the class file is in a jar file, or
* C:\temp\ajcSandbox\workspace\ajcTest16957.tmp!pkg\BinaryAspect.class if the class file is in a directory
*/
private File getBinaryFile() {
if (binaryFile == null) {
String s = getDeclaringType().getBinaryPath();
File f = getDeclaringType().getSourceLocation().getSourceFile();
int i = f.getPath().lastIndexOf('.');
String path = f.getPath().substring(0, i) + ".class";
binaryFile = new File(s + "!" + path);
}
return binaryFile;
}

/**
* Returns whether or not this shadow munger came from a binary aspect - keep a record of whether or not we've checked if we're
* binary otherwise we keep caluclating the same thing many times
*/
public boolean isBinary() {
if (!checkedIsBinary) {
ResolvedType rt = getDeclaringType();
if (rt != null) {
isBinary = ((rt.getBinaryPath() == null) ? false : true);
}
checkedIsBinary = true;
}
return isBinary;
}

private boolean isBinary;
private boolean checkedIsBinary;

}

+ 246
- 0
org.aspectj.matcher/src/org/aspectj/weaver/SignatureUtils.java Переглянути файл

@@ -0,0 +1,246 @@
/* *******************************************************************
* 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 - refactored out of MemberImpl
* ******************************************************************/
package org.aspectj.weaver;

import java.lang.reflect.Modifier;

public class SignatureUtils {

public static String getSignatureString(Member m, World world) {
MemberKind kind = m.getKind();
if (kind == Member.METHOD) {
return getMethodSignatureString(m,world);
} else if (kind == Member.CONSTRUCTOR) {
return getConstructorSignatureString(m,world);
} else if (kind == Member.FIELD) {
return getFieldSignatureString(m,world);
} else if (kind == Member.HANDLER) {
return getHandlerSignatureString(m,world);
} else if (kind == Member.STATIC_INITIALIZATION) {
return getStaticInitializationSignatureString(m,world);
} else if (kind == Member.ADVICE) {
return getAdviceSignatureString(m,world);
} else if (kind == Member.MONITORENTER || kind == Member.MONITOREXIT) {
return getMonitorSignatureString(m,world);
} else {
throw new BCException("Do not know the signature string for MemberKind "+kind);
}
}

public static String getSignatureMakerName(Member m) {
MemberKind kind = m.getKind();
if (kind == Member.METHOD) {
return "makeMethodSig";
} else if (kind == Member.CONSTRUCTOR) {
return "makeConstructorSig";
} else if (kind == Member.FIELD) {
return "makeFieldSig";
} else if (kind == Member.HANDLER) {
return "makeCatchClauseSig";
} else if (kind == Member.STATIC_INITIALIZATION) {
return "makeInitializerSig";
} else if (kind == Member.ADVICE) {
return "makeAdviceSig";
} else if (kind == Member.MONITORENTER) {
return "makeLockSig";
} else if (kind == Member.MONITOREXIT) {
return "makeUnlockSig";
} else {
throw new BCException("Do not know the signature maker name for MemberKind "+kind);
}
}

public static String getSignatureType(Member m) {
MemberKind kind = m.getKind();
if (m.getName().equals("<clinit>") && kind!=Member.STATIC_INITIALIZATION) throw new BCException();
// if (m.getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature";
if (kind == Member.METHOD) {
return "org.aspectj.lang.reflect.MethodSignature";
} else if (kind == Member.CONSTRUCTOR) {
return "org.aspectj.lang.reflect.ConstructorSignature";
} else if (kind == Member.FIELD) {
return "org.aspectj.lang.reflect.FieldSignature";
} else if (kind == Member.HANDLER) {
return "org.aspectj.lang.reflect.CatchClauseSignature";
} else if (kind == Member.STATIC_INITIALIZATION) {
return "org.aspectj.lang.reflect.InitializerSignature";
} else if (kind == Member.ADVICE) {
return "org.aspectj.lang.reflect.AdviceSignature";
} else if (kind == Member.MONITORENTER) {
return "org.aspectj.lang.reflect.LockSignature";
} else if (kind == Member.MONITOREXIT) {
return "org.aspectj.lang.reflect.UnlockSignature";
} else {
throw new BCException("Do not know the signature type for MemberKind "+kind);
}
}

// ---

private static String getHandlerSignatureString(Member m, World world) {
StringBuffer buf = new StringBuffer();
buf.append(makeString(0));
buf.append('-');
//buf.append(getName());
buf.append('-');
buf.append(makeString(m.getDeclaringType()));
buf.append('-');
buf.append(makeString(m.getParameterTypes()[0]));
buf.append('-');
String pName = "<missing>";
String[] names = m.getParameterNames(world);
if (names != null) pName = names[0];
buf.append(pName);
buf.append('-');
return buf.toString();
}
private static String getStaticInitializationSignatureString(Member m, World world) {
StringBuffer buf = new StringBuffer();
buf.append(makeString(m.getModifiers(world)));
buf.append('-');
//buf.append(getName());
buf.append('-');
buf.append(makeString(m.getDeclaringType()));
buf.append('-');
return buf.toString();
}

protected static String getAdviceSignatureString(Member m, World world) {
StringBuffer buf = new StringBuffer();
buf.append(makeString(m.getModifiers(world)));
buf.append('-');
buf.append(m.getName());
buf.append('-');
buf.append(makeString(m.getDeclaringType()));
buf.append('-');
buf.append(makeString(m.getParameterTypes()));
buf.append('-');
buf.append(makeString(m.getParameterNames(world)));
buf.append('-');
buf.append(makeString(m.getExceptions(world)));
buf.append('-');
buf.append(makeString(m.getReturnType()));
buf.append('-');
return buf.toString();
}


protected static String getMethodSignatureString(Member m, World world) {
StringBuffer buf = new StringBuffer();
buf.append(makeString(m.getModifiers(world)));
buf.append('-');
buf.append(m.getName());
buf.append('-');
buf.append(makeString(m.getDeclaringType()));
buf.append('-');
buf.append(makeString(m.getParameterTypes()));
buf.append('-');
buf.append(makeString(m.getParameterNames(world)));
buf.append('-');
buf.append(makeString(m.getExceptions(world)));
buf.append('-');
buf.append(makeString(m.getReturnType()));
buf.append('-');
return buf.toString();
}
protected static String getMonitorSignatureString(Member m, World world) {
StringBuffer buf = new StringBuffer();
buf.append(makeString(Modifier.STATIC)); // modifiers
buf.append('-');
buf.append(m.getName()); // name
buf.append('-');
buf.append(makeString(m.getDeclaringType())); // Declaring Type
buf.append('-');
buf.append(makeString(m.getParameterTypes()[0])); // Parameter Types
buf.append('-');
buf.append(""); // Parameter names
buf.append('-');
return buf.toString();
}

protected static String getConstructorSignatureString(Member m, World world) {
StringBuffer buf = new StringBuffer();
buf.append(makeString(m.getModifiers(world)));
buf.append('-');
buf.append('-');
buf.append(makeString(m.getDeclaringType()));
buf.append('-');
buf.append(makeString(m.getParameterTypes()));
buf.append('-');
buf.append(makeString(m.getParameterNames(world)));
buf.append('-');
buf.append(makeString(m.getExceptions(world)));
buf.append('-');
return buf.toString();
}


protected static String getFieldSignatureString(Member m, World world) {
StringBuffer buf = new StringBuffer();
buf.append(makeString(m.getModifiers(world)));
buf.append('-');
buf.append(m.getName());
buf.append('-');
buf.append(makeString(m.getDeclaringType()));
buf.append('-');
buf.append(makeString(m.getReturnType()));
buf.append('-');
return buf.toString();
}

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

protected static String makeString(UnresolvedType t) {
// this is the inverse of the odd behavior for Class.forName w/ arrays
if (t.isArray()) {
// this behavior matches the string used by the eclipse compiler for Foo.class literals
return t.getSignature().replace('/', '.');
} else {
return t.getName();
}
}


protected static String makeString(UnresolvedType[] types) {
if (types == null) return "";
StringBuffer buf = new StringBuffer();
for (int i = 0, len=types.length; i < len; i++) {
buf.append(makeString(types[i]));
buf.append(':');
}
return buf.toString();
}


protected static String makeString(String[] names) {
if (names == null) return "";
StringBuffer buf = new StringBuffer();
for (int i = 0, len=names.length; i < len; i++) {
buf.append(names[i]);
buf.append(':');
}
return buf.toString();
}

}

+ 82
- 0
org.aspectj.matcher/src/org/aspectj/weaver/SimpleAnnotationValue.java Переглянути файл

@@ -0,0 +1,82 @@
/* *******************************************************************
* Copyright (c) 2006 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 IBM initial implementation
* ******************************************************************/
package org.aspectj.weaver;

public class SimpleAnnotationValue extends AnnotationValue {

public SimpleAnnotationValue(int kind) {
super(kind);
}

public SimpleAnnotationValue(int kind, Object value) {
super(kind);
switch (kind) {
case AnnotationValue.PRIMITIVE_BYTE: theByte = ((Byte)value).byteValue(); break;
case AnnotationValue.PRIMITIVE_CHAR: theChar = ((Character)value).charValue(); break;
case AnnotationValue.PRIMITIVE_INT: theInt = ((Integer)value).intValue(); break;
case AnnotationValue.STRING: theString = (String)value; break;
case AnnotationValue.PRIMITIVE_DOUBLE: theDouble = ((Double)value).doubleValue(); break;
case AnnotationValue.PRIMITIVE_FLOAT: theFloat = ((Float)value).floatValue(); break;
case AnnotationValue.PRIMITIVE_LONG: theLong = ((Long)value).longValue(); break;
case AnnotationValue.PRIMITIVE_SHORT: theShort = ((Short)value).shortValue(); break;
case AnnotationValue.PRIMITIVE_BOOLEAN: theBoolean = ((Boolean)value).booleanValue(); break;
default:
throw new BCException("Not implemented for this kind: "+whatKindIsThis(kind));
}
}

private byte theByte;
private char theChar;
private int theInt;
private String theString;
private double theDouble;
private float theFloat;
private long theLong;
private short theShort;
private boolean theBoolean;
public void setValueString(String s) { theString = s; }
public void setValueByte(byte b) { theByte = b; }
public void setValueChar(char c) { theChar = c; }
public void setValueInt(int i) { theInt = i; }

public String stringify() {
switch (valueKind) {
case 'B': // byte
return Byte.toString(theByte);
case 'C': // char
return new Character(theChar).toString();
case 'D': // double
return Double.toString(theDouble);
case 'F': // float
return Float.toString(theFloat);
case 'I': // int
return Integer.toString(theInt);
case 'J': // long
return Long.toString(theLong);
case 'S': // short
return Short.toString(theShort);
case 'Z': // boolean
return new Boolean(theBoolean).toString();
case 's': // String
return theString;
default: throw new BCException("Do not understand this kind: "+valueKind);
}
}
public String toString() {
return stringify();
}


}

+ 109
- 0
org.aspectj.matcher/src/org/aspectj/weaver/SourceContextImpl.java Переглянути файл

@@ -0,0 +1,109 @@
/* *******************************************************************
* 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.File;
import java.util.Arrays;

import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.SourceLocation;

public class SourceContextImpl implements ISourceContext {
// private AbstractReferenceTypeDelegate delegate;
private int[] lineBreaks;
String sfname;
public SourceContextImpl(AbstractReferenceTypeDelegate delegate) {
// this.delegate = delegate;
sfname = delegate.getSourcefilename();
}
public void configureFromAttribute(String name,int []linebreaks) {
// this.delegate.setSourcefilename(name);
sfname = name;
this.lineBreaks = linebreaks;
}
public void setSourceFileName(String name) {
sfname = name;
}
private File getSourceFile() {
return new File(sfname);
// return new File(delegate.getSourcefilename());
}
public void tidy() {}
public int getOffset() { return 0; }
/*
// AMC - a temporary "fudge" to give as much information as possible about the identity of the
// source file this source location points to.
String internalClassName = getEnclosingClass().getInternalClassName();
String fileName = getEnclosingClass().getFileName();
String extension = fileName.substring( fileName.lastIndexOf("."), fileName.length());
String filePrefix = fileName.substring( 0, fileName.lastIndexOf("."));
// internal class name is e.g. figures/Point, we don't know whether the file was
// .aj or .java so we put it together with the file extension of the enclosing class
// BUT... sometimes internalClassName is a different class (an aspect), so we only use it if it
// matches the file name.
String mostAccurateFileNameGuess;
if ( internalClassName.endsWith(filePrefix)) {
mostAccurateFileNameGuess = internalClassName + extension;
} else {
mostAccurateFileNameGuess = fileName;
}
return new SourceLocation(new File(mostAccurateFileNameGuess), getSourceLine());
*/



public ISourceLocation makeSourceLocation(IHasPosition position) {
if (lineBreaks != null) {
int line = Arrays.binarySearch(lineBreaks, position.getStart());
if (line < 0) line = -line;
return new SourceLocation(getSourceFile(), line); //??? have more info
} else {
return new SourceLocation(getSourceFile(), 0);
}
}
public ISourceLocation makeSourceLocation(int line, int offset) {
if (line < 0) line = 0;
SourceLocation sl = new SourceLocation(getSourceFile(), line);
if (offset > 0) {
sl.setOffset(offset);
} else {
if (lineBreaks != null) {
int likelyOffset = 0;
if (line > 0 && line < lineBreaks.length) {
//1st char of given line is next char after previous end of line
likelyOffset = lineBreaks[line-1] + 1;
}
sl.setOffset(likelyOffset);
}
}
return sl;
}


public final static ISourceContext UNKNOWN_SOURCE_CONTEXT = new ISourceContext() {
public ISourceLocation makeSourceLocation(IHasPosition position) {return null;}
public ISourceLocation makeSourceLocation(int line, int offset) {return null;}
public int getOffset() {return 0;}
public void tidy() {}
};
}

+ 153
- 0
org.aspectj.matcher/src/org/aspectj/weaver/StandardAnnotation.java Переглянути файл

@@ -0,0 +1,153 @@
/* *******************************************************************
* 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
*
* ******************************************************************/
package org.aspectj.weaver;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
* This type represents the weavers abstraction of an annotation - it is not tied to any underlying BCI toolkit. The weaver actualy
* handles these through AnnotationX wrapper objects - until we start transforming the BCEL annotations into this form (expensive)
* or offer a clever visitor mechanism over the BCEL annotation stuff that builds these annotation types directly.
*
* @author AndyClement
*/
public class StandardAnnotation extends AbstractAnnotationAJ {

private final boolean isRuntimeVisible;

private List /* of AnnotationNVPair */nvPairs = null;

public StandardAnnotation(ResolvedType type, boolean isRuntimeVisible) {
super(type);
this.isRuntimeVisible = isRuntimeVisible;
}

/**
* {@inheritDoc}
*/
public boolean isRuntimeVisible() {
return isRuntimeVisible;
}

/**
* {@inheritDoc}
*/
public String stringify() {
StringBuffer sb = new StringBuffer();
sb.append("@").append(type.getClassName());
if (hasNameValuePairs()) {
sb.append("(");
for (Iterator iter = nvPairs.iterator(); iter.hasNext();) {
AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next();
sb.append(element.stringify());
}
sb.append(")");
}
return sb.toString();
}

public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("ANNOTATION [" + getTypeSignature() + "] [" + (isRuntimeVisible ? "runtimeVisible" : "runtimeInvisible") + "] [");
if (nvPairs != null) {
for (Iterator iter = nvPairs.iterator(); iter.hasNext();) {
AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next();
sb.append(element.toString());
if (iter.hasNext())
sb.append(",");
}
}
sb.append("]");
return sb.toString();
}

/**
* {@inheritDoc}
*/
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;
}

/**
* {@inheritDoc}
*/
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;
}

/**
* {@inheritDoc}
*/
public Set /* <String> */getTargets() {
if (!type.equals(UnresolvedType.AT_TARGET)) {
return Collections.EMPTY_SET;
}
AnnotationNameValuePair nvp = (AnnotationNameValuePair) nvPairs.get(0);
ArrayAnnotationValue aav = (ArrayAnnotationValue) nvp.getValue();
AnnotationValue[] avs = aav.getValues();
Set targets = new HashSet();
for (int i = 0; i < avs.length; i++) {
AnnotationValue value = avs[i];
targets.add(value.stringify());
}
return targets;
}

public List getNameValuePairs() {
return nvPairs;
}

public boolean hasNameValuePairs() {
return nvPairs != null && nvPairs.size() != 0;
}

public void addNameValuePair(AnnotationNameValuePair pair) {
if (nvPairs == null) {
nvPairs = new ArrayList();
}
nvPairs.add(pair);
}

/**
* {@inheritDoc}
*/
public String getStringFormOfValue(String name) {
if (hasNameValuePairs()) {
for (Iterator iterator = nvPairs.iterator(); iterator.hasNext();) {
AnnotationNameValuePair nvPair = (AnnotationNameValuePair) iterator.next();
if (nvPair.getName().equals(name)) {
return nvPair.getValue().stringify();
}
}
}
return null;
}
}

+ 56
- 0
org.aspectj.matcher/src/org/aspectj/weaver/StaticJoinPointFactory.java Переглянути файл

@@ -0,0 +1,56 @@
/* *******************************************************************
* 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;


public class StaticJoinPointFactory {
// int usedKeys;
//
// List/*String*/ strings = new ArrayList();
// Map/*String,Integer*/ keysForStrings = new HashMap();
//
// public StaticJoinPointFactory() {
// super();
// }
//
// static char[] encoding = new char[] {
// '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',//10
// 'a', 'b', 'z', //36
// 'A', 'B', 'Z', //62
// '%', '$', //64
// };
//
// static int TWO_WORDS = 64*64-1;
// static int WORD_MASK = 63;
//
// public void write(String s, StringBuffer result) {
// int i = getIndex(s);
// encode(i, result);
// }
//
// void encode(int i, StringBuffer result) {
// if (i > TWO_WORDS) {
// throw new RuntimeException("unimplemented");
// } else {
// result.append( encoding[(i >> 6) & WORD_MASK] );
// result.append( encoding[i & WORD_MASK] );
// }
// }
//
// public String read(StringReader reader) {
// int i = reader.read();
//
// }

}

+ 35
- 0
org.aspectj.matcher/src/org/aspectj/weaver/TemporaryTypeMunger.java Переглянути файл

@@ -0,0 +1,35 @@
/* *******************************************************************
* 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
*
* ******************************************************************/
package org.aspectj.weaver;

import java.util.Map;

/**
* Some methods need a temporary type munger (because ConcreteTypeMunger is abstract - dont ask...).
*
* TODO ought to remove the need for this or at least sort out the two methods that are in it, they look wierd...
*
* @author AndyClement
*/
public class TemporaryTypeMunger extends ConcreteTypeMunger {

public TemporaryTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) {
super(munger, aspectType);
}

public ConcreteTypeMunger parameterizeWith(Map parameterizationMap, World world) {
throw new UnsupportedOperationException("Cannot be called on a TemporaryTypeMunger");
}

public ConcreteTypeMunger parameterizedFor(ResolvedType targetType) {
throw new UnsupportedOperationException("Cannot be called on a TemporaryTypeMunger");
}

}

+ 293
- 0
org.aspectj.matcher/src/org/aspectj/weaver/TypeFactory.java Переглянути файл

@@ -0,0 +1,293 @@
/* *******************************************************************
* 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;

import java.util.ArrayList;
import java.util.List;

/**
* @author colyer
*
*/
public class TypeFactory {

/**
* Create a parameterized version of a generic type.
*
* @param aGenericType
* @param someTypeParameters note, in the case of an inner type of a parameterized type, this parameter may legitimately be null
* @param inAWorld
* @return
*/
public static ReferenceType createParameterizedType(ResolvedType aBaseType, UnresolvedType[] someTypeParameters, World inAWorld) {
ResolvedType baseType = aBaseType;
if (!aBaseType.isGenericType()) {
// try and find the generic type...
if (someTypeParameters != null && someTypeParameters.length > 0) {
if (!aBaseType.isRawType())
throw new IllegalStateException("Expecting raw type, not: " + aBaseType);
baseType = baseType.getGenericType();
if (baseType == null)
throw new IllegalStateException("Raw type does not have generic type set");
} // else if someTypeParameters is null, then the base type is allowed to be non-generic, it's an inner
}
ResolvedType[] resolvedParameters = inAWorld.resolve(someTypeParameters);
ReferenceType pType = new ReferenceType(baseType, resolvedParameters, inAWorld);
// pType.setSourceContext(aBaseType.getSourceContext());
return (ReferenceType) pType.resolve(inAWorld);
}

/**
* Create an *unresolved* parameterized version of a generic type.
*/
public static UnresolvedType createUnresolvedParameterizedType(String sig, String erasuresig, UnresolvedType[] arguments) {
return new UnresolvedType(sig, erasuresig, arguments);
}

// public static ReferenceType createRawType(
// ResolvedType aBaseType,
// World inAWorld
// ) {
// if (aBaseType.isRawType()) return (ReferenceType) aBaseType;
// if (!aBaseType.isGenericType()) {
// if (!aBaseType.isRawType()) throw new IllegalStateException("Expecting generic type");
// }
// ReferenceType rType = new ReferenceType(aBaseType,inAWorld);
// //rType.setSourceContext(aBaseType.getSourceContext());
// return (ReferenceType) rType.resolve(inAWorld);
// }

/**
* Creates a sensible unresolvedtype from some signature, for example: signature = LIGuard<TT;>; bound = toString=IGuard<T>
* sig=PIGuard<TT;>; sigErasure=LIGuard; kind=parameterized
*/
private static UnresolvedType convertSigToType(String aSignature) {
UnresolvedType bound = null;
int startOfParams = aSignature.indexOf('<');
if (startOfParams == -1) {
bound = UnresolvedType.forSignature(aSignature);
} else {
int endOfParams = aSignature.lastIndexOf('>');
String signatureErasure = "L" + aSignature.substring(1, startOfParams) + ";";
UnresolvedType[] typeParams = createTypeParams(aSignature.substring(startOfParams + 1, endOfParams));
bound = new UnresolvedType("P" + aSignature.substring(1), signatureErasure, typeParams);
}
return bound;
}

/**
* Used by UnresolvedType.read, creates a type from a full signature.
*
* @param signature
* @return
*/
public static UnresolvedType createTypeFromSignature(String signature) {
if (signature.equals(ResolvedType.MISSING_NAME))
return ResolvedType.MISSING;
char firstChar = signature.charAt(0);
if (firstChar == 'P') {
// parameterized type, calculate signature erasure and type parameters
// (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);
UnresolvedType[] typeParams = new UnresolvedType[0];
return new UnresolvedType(signature, signatureErasure, typeParams);
} else {
int endOfParams = locateMatchingEndBracket(signature, startOfParams);// signature.lastIndexOf('>');
StringBuffer erasureSig = new StringBuffer(signature);
while (startOfParams != -1) {
erasureSig.delete(startOfParams, endOfParams + 1);
startOfParams = locateFirstBracket(erasureSig);
if (startOfParams != -1)
endOfParams = locateMatchingEndBracket(erasureSig, startOfParams);
}

String signatureErasure = "L" + erasureSig.toString().substring(1);

// 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("$", endOfParams); // don't look for $ INSIDE the parameters
if (nestedTypePosition != -1)
lastType = signature.substring(nestedTypePosition + 1);
else
lastType = new String(signature);
startOfParams = lastType.indexOf("<");
endOfParams = locateMatchingEndBracket(lastType, startOfParams);
UnresolvedType[] typeParams = UnresolvedType.NONE;
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
} else if (signature.equals("?") || signature.equals("*")) {
return WildcardedUnresolvedType.QUESTIONMARK;
} else if (firstChar == '+') {
// ? extends ...
UnresolvedType upperBound = convertSigToType(signature.substring(1));
WildcardedUnresolvedType wildcardedUT = new WildcardedUnresolvedType(signature, upperBound, null);
return wildcardedUT;
} else if (firstChar == '-') {
// ? super ...
UnresolvedType lowerBound = convertSigToType(signature.substring(1));
WildcardedUnresolvedType wildcardedUT = new WildcardedUnresolvedType(signature, null, lowerBound);
return wildcardedUT;
} else if (firstChar == 'T') {
String typeVariableName = signature.substring(1);
if (typeVariableName.endsWith(";")) {
typeVariableName = typeVariableName.substring(0, typeVariableName.length() - 1);
}
return new UnresolvedTypeVariableReferenceType(new TypeVariable(typeVariableName));
} else if (firstChar == '[') {
int dims = 0;
while (signature.charAt(dims) == '[')
dims++;
UnresolvedType componentType = createTypeFromSignature(signature.substring(dims));
return new UnresolvedType(signature, signature.substring(0, dims) + componentType.getErasureSignature());
} else if (signature.length() == 1) { // could be a primitive
switch (firstChar) {
case 'V':
return ResolvedType.VOID;
case 'Z':
return ResolvedType.BOOLEAN;
case 'B':
return ResolvedType.BYTE;
case 'C':
return ResolvedType.CHAR;
case 'D':
return ResolvedType.DOUBLE;
case 'F':
return ResolvedType.FLOAT;
case 'I':
return ResolvedType.INT;
case 'J':
return ResolvedType.LONG;
case 'S':
return ResolvedType.SHORT;
}
}
return new UnresolvedType(signature);
}

private static int locateMatchingEndBracket(String signature, int startOfParams) {
if (startOfParams == -1)
return -1;
int count = 1;
int idx = startOfParams;
while (count > 0 && idx < signature.length()) {
idx++;
if (signature.charAt(idx) == '<')
count++;
if (signature.charAt(idx) == '>')
count--;
}
return idx;
}

private static int locateMatchingEndBracket(StringBuffer signature, int startOfParams) {
if (startOfParams == -1)
return -1;
int count = 1;
int idx = startOfParams;
while (count > 0 && idx < signature.length()) {
idx++;
if (signature.charAt(idx) == '<')
count++;
if (signature.charAt(idx) == '>')
count--;
}
return idx;
}

private static int locateFirstBracket(StringBuffer signature) {
int idx = 0;
while (idx < signature.length()) {
if (signature.charAt(idx) == '<')
return idx;
idx++;
}
return -1;
}

private static UnresolvedType[] createTypeParams(String typeParameterSpecification) {
String remainingToProcess = typeParameterSpecification;
List types = new ArrayList();
while (!remainingToProcess.equals("")) {
int endOfSig = 0;
int anglies = 0;
boolean sigFound = false; // OPTIMIZE can this be done better?
for (endOfSig = 0; (endOfSig < remainingToProcess.length()) && !sigFound; endOfSig++) {
char thisChar = remainingToProcess.charAt(endOfSig);
switch (thisChar) {
case '<':
anglies++;
break;
case '>':
anglies--;
break;
case '[':
if (anglies == 0) {
// the next char might be a [ or a primitive type ref (BCDFIJSZ)
int nextChar = endOfSig + 1;
while (remainingToProcess.charAt(nextChar) == '[') {
nextChar++;
}
if ("BCDFIJSZ".indexOf(remainingToProcess.charAt(nextChar)) != -1) {
// it is something like [I or [[S
sigFound = true;
endOfSig = nextChar;
break;
}
}
break;
case ';':
if (anglies == 0) {
sigFound = true;
break;
}
}
}
types.add(createTypeFromSignature(remainingToProcess.substring(0, endOfSig)));
remainingToProcess = remainingToProcess.substring(endOfSig);
}
UnresolvedType[] typeParams = new UnresolvedType[types.size()];
types.toArray(typeParams);
return typeParams;
}

// OPTIMIZE improve all this signature processing stuff, use char arrays, etc

/**
* Create a signature then delegate to the other factory method. Same input/output: baseTypeSignature="LSomeType;" arguments[0]=
* something with sig "Pcom/Foo<Ljava/lang/String;>;" signature created = "PSomeType<Pcom/Foo<Ljava/lang/String;>;>;"
*/
public static UnresolvedType createUnresolvedParameterizedType(String baseTypeSignature, UnresolvedType[] arguments) {
StringBuffer parameterizedSig = new StringBuffer();
parameterizedSig.append(ResolvedType.PARAMETERIZED_TYPE_IDENTIFIER);
parameterizedSig.append(baseTypeSignature.substring(1, baseTypeSignature.length() - 1));
if (arguments.length > 0) {
parameterizedSig.append("<");
for (int i = 0; i < arguments.length; i++) {
parameterizedSig.append(arguments[i].getSignature());
}
parameterizedSig.append(">");
}
parameterizedSig.append(";");
return createUnresolvedParameterizedType(parameterizedSig.toString(), baseTypeSignature, arguments);
}
}

+ 372
- 0
org.aspectj.matcher/src/org/aspectj/weaver/TypeVariable.java Переглянути файл

@@ -0,0 +1,372 @@
/* *******************************************************************
* 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;

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

/**
* Represents a type variable with bounds
*/
public class TypeVariable {
public static final TypeVariable[] NONE = new TypeVariable[0];
/**
* whether or not the bounds of this type variable have been
* resolved
*/
private boolean isResolved = false;
private boolean beingResolved = false;
/**
* the name of the type variable as recorded in the generic signature
*/
private String name;
private int rank;

// It would be nice to push this field onto the TypeVariableDeclaringElement
// interface (a getKind()) but at the moment we don't always guarantee
// to set the declaring element (eclipse seems to utilise the knowledge of
// what declared the type variable, but we dont yet...)
/**
* What kind of element declared this type variable?
*/
private int declaringElementKind = UNKNOWN;
public static final int UNKNOWN = -1;
public static final int METHOD = 1;
public static final int TYPE = 2;
private TypeVariableDeclaringElement declaringElement;
/**
* the upper bound of the type variable (default to Object).
* From the extends clause, eg. T extends Number.
*/
private UnresolvedType upperBound = UnresolvedType.OBJECT;
/**
* any additional upper (interface) bounds.
* from the extends clause, e.g. T extends Number & Comparable
*/
private UnresolvedType[] additionalInterfaceBounds = new UnresolvedType[0];
/**
* any lower bound.
* from the super clause, eg T super Foo
*/
private UnresolvedType lowerBound = null;
public TypeVariable(String aName) {
this.name = aName;
}
public TypeVariable(String aName, UnresolvedType anUpperBound) {
this(aName);
this.upperBound = anUpperBound;
}
public TypeVariable(String aName, UnresolvedType anUpperBound,
UnresolvedType[] someAdditionalInterfaceBounds) {
this(aName,anUpperBound);
this.additionalInterfaceBounds = someAdditionalInterfaceBounds;
}
public TypeVariable(String aName, UnresolvedType anUpperBound,
UnresolvedType[] someAdditionalInterfaceBounds, UnresolvedType aLowerBound) {
this(aName,anUpperBound,someAdditionalInterfaceBounds);
this.lowerBound = aLowerBound;
}
// First bound is the first 'real' bound, this can be an interface if
// no class bound was specified (it will default to object)
public UnresolvedType getFirstBound() {
if (upperBound.equals(UnresolvedType.OBJECT) && additionalInterfaceBounds!=null && additionalInterfaceBounds.length!=0) {
return additionalInterfaceBounds[0];
}
return upperBound;
}
public UnresolvedType getUpperBound() {
return upperBound;
}
public UnresolvedType[] getAdditionalInterfaceBounds() {
return additionalInterfaceBounds;
}
public UnresolvedType getLowerBound() {
return lowerBound;
}
public String getName() {
return name;
}
/**
* resolve all the bounds of this type variable
*/
public TypeVariable resolve(World inSomeWorld) {
if (beingResolved) { return this; } // avoid spiral of death
beingResolved = true;
if (isResolved) return this;

TypeVariable resolvedTVar = null;

if (declaringElement != null) {
// resolve by finding the real type var that we refer to...
if (declaringElementKind == TYPE) {
UnresolvedType declaring = (UnresolvedType) declaringElement;
ReferenceType rd = (ReferenceType) declaring.resolve(inSomeWorld);
TypeVariable[] tVars = rd.getTypeVariables();
for (int i = 0; i < tVars.length; i++) {
if (tVars[i].getName().equals(getName())) {
resolvedTVar = tVars[i];
break;
}
}
} else {
// look for type variable on method...
ResolvedMember declaring = (ResolvedMember) declaringElement;
TypeVariable[] tvrts = declaring.getTypeVariables();
for (int i = 0; i < tvrts.length; i++) {
if (tvrts[i].getName().equals(getName())) resolvedTVar = tvrts[i];
// if (tvrts[i].isTypeVariableReference()) {
// TypeVariableReferenceType tvrt = (TypeVariableReferenceType) tvrts[i].resolve(inSomeWorld);
// TypeVariable tv = tvrt.getTypeVariable();
// if (tv.getName().equals(getName())) resolvedTVar = tv;
// }
}
}
if (resolvedTVar == null) {
// well, this is bad... we didn't find the type variable on the member
// could be a separate compilation issue...
// should issue message, this is a workaround to get us going...
resolvedTVar = this;
}
} else {
resolvedTVar = this;
}
upperBound = resolvedTVar.upperBound;
lowerBound = resolvedTVar.lowerBound;
additionalInterfaceBounds = resolvedTVar.additionalInterfaceBounds;
upperBound = upperBound.resolve(inSomeWorld);
if (lowerBound != null) lowerBound = lowerBound.resolve(inSomeWorld);
if (additionalInterfaceBounds!=null) {
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
additionalInterfaceBounds[i] = additionalInterfaceBounds[i].resolve(inSomeWorld);
}
}
isResolved = true;
beingResolved = false;
return this;
}
/**
* answer true if the given type satisfies all of the bound constraints of this
* type variable.
* If type variable has not been resolved then throws IllegalStateException
*/
public boolean canBeBoundTo(ResolvedType aCandidateType) {
if (!isResolved) throw new IllegalStateException("Can't answer binding questions prior to resolving");
// wildcard can accept any binding
if (aCandidateType.isGenericWildcard()) { // AMC - need a more robust test!
return true;
}
// otherwise can be bound iff...
// aCandidateType is a subtype of upperBound
if (!isASubtypeOf(upperBound,aCandidateType)) {
return false;
}
// aCandidateType is a subtype of all additionalInterfaceBounds
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
if (!isASubtypeOf(additionalInterfaceBounds[i], aCandidateType)) {
return false;
}
}
// lowerBound is a subtype of aCandidateType
if ((lowerBound != null) && (!isASubtypeOf(aCandidateType,lowerBound))) {
return false;
}
return true;
}
private boolean isASubtypeOf(UnresolvedType candidateSuperType, UnresolvedType candidateSubType) {
ResolvedType superType = (ResolvedType) candidateSuperType;
ResolvedType subType = (ResolvedType) candidateSubType;
return superType.isAssignableFrom(subType);
}

// only used when resolving
public void setUpperBound(UnresolvedType aTypeX) {
this.upperBound = aTypeX;
}
// only used when resolving
public void setLowerBound(UnresolvedType aTypeX) {
this.lowerBound = aTypeX;
}
// only used when resolving
public void setAdditionalInterfaceBounds(UnresolvedType[] someTypeXs) {
this.additionalInterfaceBounds = someTypeXs;
}
public String toDebugString() {
return getDisplayName();
}
public String getDisplayName() {
StringBuffer ret = new StringBuffer();
ret.append(name);
if (!getFirstBound().getName().equals("java.lang.Object")) {
ret.append(" extends ");
ret.append(getFirstBound().getName());
if (additionalInterfaceBounds != null) {
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
if (!getFirstBound().equals(additionalInterfaceBounds[i])) {
ret.append(" & ");
ret.append(additionalInterfaceBounds[i].getName());
}
}
}
}
if (lowerBound != null) {
ret.append(" super ");
ret.append(lowerBound.getName());
}
return ret.toString();
}
// good enough approximation
public String toString() {
return "TypeVar " + getDisplayName();
}
/**
* Return complete signature, e.g. "T extends Number" would return "T:Ljava/lang/Number;"
* note: MAY INCLUDE P types if bounds are parameterized types
*/
public String getSignature() {
StringBuffer sb = new StringBuffer();
sb.append(name);
sb.append(":");
sb.append(upperBound.getSignature());
if (additionalInterfaceBounds!=null && additionalInterfaceBounds.length!=0) {
sb.append(":");
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
UnresolvedType iBound = additionalInterfaceBounds[i];
sb.append(iBound.getSignature());
}
}
return sb.toString();
}
/**
* @return signature for inclusion in an attribute, there must be no 'P' in it signatures
*/
public String getSignatureForAttribute() {
StringBuffer sb = new StringBuffer();
sb.append(name);
sb.append(":");
sb.append(((ResolvedType)upperBound).getSignatureForAttribute());
if (additionalInterfaceBounds!=null && additionalInterfaceBounds.length!=0) {
sb.append(":");
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
ResolvedType iBound = (ResolvedType)additionalInterfaceBounds[i];
sb.append(iBound.getSignatureForAttribute());
}
}
return sb.toString();
}

public void setRank(int rank) {
this.rank=rank;
}
public int getRank() {
return rank;
}

public void setDeclaringElement(TypeVariableDeclaringElement element) {
this.declaringElement = element;
if (element instanceof UnresolvedType) {
this.declaringElementKind = TYPE;
} else {
this.declaringElementKind = METHOD;
}
}
public TypeVariableDeclaringElement getDeclaringElement() {
return declaringElement;
}
public void setDeclaringElementKind(int kind) {
this.declaringElementKind = kind;
}
public int getDeclaringElementKind() {
// if (declaringElementKind==UNKNOWN) throw new RuntimeException("Dont know declarer of this tvar : "+this);
return declaringElementKind;
}
public void write(DataOutputStream s) throws IOException {
// name, upperbound, additionalInterfaceBounds, lowerbound
s.writeUTF(name);
upperBound.write(s);
if (additionalInterfaceBounds==null || additionalInterfaceBounds.length==0) {
s.writeInt(0);
} else {
s.writeInt(additionalInterfaceBounds.length);
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
UnresolvedType ibound = additionalInterfaceBounds[i];
ibound.write(s);
}
}
}
public static TypeVariable read(VersionedDataInputStream s) throws IOException {
//if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
String name = s.readUTF();
UnresolvedType ubound = UnresolvedType.read(s);
int iboundcount = s.readInt();
UnresolvedType[] ibounds = UnresolvedType.NONE;
if (iboundcount>0) {
ibounds = new UnresolvedType[iboundcount];
for (int i=0; i<iboundcount; i++) {
ibounds[i] = UnresolvedType.read(s);
}
}
TypeVariable newVariable = new TypeVariable(name,ubound,ibounds);
return newVariable;
}

public String getGenericSignature() {
return "T"+name+";";
// return "T"+getSignature();
}
public String getErasureSignature() {
return getFirstBound().getErasureSignature();
}

}

+ 23
- 0
org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableDeclaringElement.java Переглянути файл

@@ -0,0 +1,23 @@
/* *******************************************************************
* 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:
* Andy Clement Initial implementation
* ******************************************************************/

package org.aspectj.weaver;


/**
* Tag interface - methods and types can be declaring elements for
* type variables. See the TypeVariable class which holds onto
* the declaring element
*/
public interface TypeVariableDeclaringElement {
public TypeVariable getTypeVariableNamed(String name);
}

+ 22
- 0
org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReference.java Переглянути файл

@@ -0,0 +1,22 @@
/* *******************************************************************
* 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;

/**
* Implemented by Types that represent references to type variables
*
*/
public interface TypeVariableReference {

TypeVariable getTypeVariable();
}

+ 146
- 0
org.aspectj.matcher/src/org/aspectj/weaver/TypeVariableReferenceType.java Переглянути файл

@@ -0,0 +1,146 @@
/* *******************************************************************
* 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;

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

/**
* Represents a type variable in a type or generic method declaration
*/
public class TypeVariableReferenceType extends BoundedReferenceType implements TypeVariableReference {

private TypeVariable typeVariable;
private boolean resolvedIfBounds = false;
// If 'fixedUp' then the type variable in here is a reference to the real one that may
// exist either on a member or a type. Not fixedUp means that we unpacked a generic
// signature and weren't able to fix it up during resolution (didn't quite know enough
// at the right time). Wonder if we can fix it up late?
boolean fixedUp = false;
public TypeVariableReferenceType(
TypeVariable aTypeVariable,
World aWorld) {
super(
aTypeVariable.getGenericSignature(),
aTypeVariable.getErasureSignature(),
aWorld);
this.typeVariable = aTypeVariable;
this.isExtends = false;
this.isSuper = false;
}
public ReferenceTypeDelegate getDelegate() {
if (delegate==null)
setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)typeVariable.getFirstBound()));
return delegate;
}

public UnresolvedType getUpperBound() {
if (typeVariable==null) return super.getUpperBound();
return typeVariable.getUpperBound();
}
public UnresolvedType getLowerBound() {
return typeVariable.getLowerBound();
}
private void setAdditionalInterfaceBoundsFromTypeVar() {
if (typeVariable.getAdditionalInterfaceBounds() == null) {
return;
} else {
UnresolvedType [] ifBounds = typeVariable.getAdditionalInterfaceBounds();
additionalInterfaceBounds = new ReferenceType[ifBounds.length];
for (int i = 0; i < ifBounds.length; i++) {
additionalInterfaceBounds[i] = (ReferenceType) ifBounds[i].resolve(getWorld());
}
}
}

public UnresolvedType parameterize(Map typeBindings) {
UnresolvedType ut = (UnresolvedType) typeBindings.get(getName());
if (ut!=null) return world.resolve(ut);
return this;
}
public ReferenceType[] getAdditionalBounds() {
if (!resolvedIfBounds) {
setAdditionalInterfaceBoundsFromTypeVar();
resolvedIfBounds = true;
}
return super.getAdditionalBounds();
}
public TypeVariable getTypeVariable() {
// if (!fixedUp) throw new BCException("ARGH"); // fix it up now?
return typeVariable;
}
public boolean isTypeVariableReference() {
return true;
}
public String toString() {
return typeVariable.getName();
}
public boolean isGenericWildcard() {
return false;
}
//public ResolvedType resolve(World world) {
// return super.resolve(world);
//}
public boolean isAnnotation() {
World world = ((ReferenceType)getUpperBound()).getWorld();
ResolvedType annotationType = ResolvedType.ANNOTATION.resolve(world);
if (getUpperBound() != null && ((ReferenceType)getUpperBound()).isAnnotation()) return true;
ReferenceType[] ifBounds = getAdditionalBounds();
for (int i = 0; i < ifBounds.length; i++) {
if (ifBounds[i].isAnnotation()) return true;
if (ifBounds[i] == annotationType) return true; // annotation itself does not have the annotation flag set in Java!
}
return false;
}
/**
* return the signature for a *REFERENCE* to a type variable, which is simply:
* Tname;
* there is no bounds info included, that is in the signature of the type variable itself
*/
public String getSignature() {
StringBuffer sb = new StringBuffer();
sb.append("T");
sb.append(typeVariable.getName());
sb.append(";");
return sb.toString();
}
public void write(DataOutputStream s) throws IOException {
super.write(s);
// TypeVariableDeclaringElement tvde = typeVariable.getDeclaringElement();
// if (tvde == null) {
// s.writeInt(TypeVariable.UNKNOWN);
// } else {
// s.writeInt(typeVariable.getDeclaringElementKind());
// if (typeVariable.getDeclaringElementKind() == TypeVariable.TYPE) {
// ((UnresolvedType)tvde).write(s);
// } else if (typeVariable.getDeclaringElementKind() == TypeVariable.METHOD){
// // it's a method
// ((ResolvedMember)tvde).write(s);
// }
// }
}
}

+ 914
- 0
org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java Переглянути файл

@@ -0,0 +1,914 @@
/* *******************************************************************
* Copyright (c) 2002,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://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* Andy Clement start of generics upgrade...
* Adrian Colyer - overhaul
* ******************************************************************/

package org.aspectj.weaver;

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

import org.aspectj.util.GenericSignature;
import org.aspectj.util.GenericSignatureParser;
import org.aspectj.util.GenericSignature.ClassSignature;
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.. 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, or a ReferenceType. ReferenceTypes may refer to simple, generic, parameterized
* or type-variable based reference types. A ReferenceType is backed by a delegate that provides information about the type based on
* some repository (currently either BCEL or an EclipseSourceType, but in the future we probably need to support java.lang.reflect
* based delegates too).
*
* Every UnresolvedType has a signature, the unique key for the type in the world.
*
*
* TypeXs are fully aware of their complete type information (there is no erasure in the UnresolvedType world). To achieve this, the
* signature of TypeXs combines the basic Java signature and the generic signature information into one complete signature.
*
* The format of a UnresolvedType signature is as follows:
*
* a simple (non-generic, non-parameterized) type has the as its signature the Java signature. e.g. Ljava/lang/String;
*
* a generic type has signature: TypeParamsOpt ClassSig SuperClassSig SuperIntfListOpt
*
* following the Generic signature grammar in the JVM spec., but with the addition of the ClassSignature (which is not in the
* generic signature). In addition type variable names are replaced by a simple number which represents their declaration order in
* the type declaration.
*
* e.g. public class Foo<T extends Number> would have signature: <1:Ljava/lang/Number>Lorg.xyz.Foo;Ljava/lang/Object;
*
* A parameterized type is a distinct type in the world with its own signature following the grammar:
*
* TypeParamsOpt ClassSig<ParamSigList>;
*
* but with the L for the class sig replaced by "P". For example List<String> has signature
*
* Pjava/util/List<Ljava/lang/String>;
*
* and List<T> in the following class : class Foo<T> { List<T> lt; }
*
* has signature: <1:>Pjava/util/List<T1;>;
*
* A typex that represents a type variable has its own unique signature, following the grammar for a FormalTypeParameter in the JVM
* spec.
*
* A generic typex has its true signature and also an erasure signature. Both of these are keys pointing to the same UnresolvedType
* in the world. For example List has signature:
*
* <1:>Ljava/util/List;Ljava/lang/Object;
*
* and the erasure signature
*
* Ljava/util/List;
*
* Generics wildcards introduce their own special signatures for type parameters. The wildcard ? has signature * The wildcard ?
* extends Foo has signature +LFoo; The wildcard ? super Foo has signature -LFoo;
*/
public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {

// common types referred to by the weaver
public static final UnresolvedType[] NONE = new UnresolvedType[0];
public static final UnresolvedType OBJECT = forSignature("Ljava/lang/Object;");
public static final UnresolvedType OBJECTARRAY = forSignature("[Ljava/lang/Object;");
public static final UnresolvedType CLONEABLE = forSignature("Ljava/lang/Cloneable;");
public static final UnresolvedType SERIALIZABLE = forSignature("Ljava/io/Serializable;");
public static final UnresolvedType THROWABLE = forSignature("Ljava/lang/Throwable;");
public static final UnresolvedType RUNTIME_EXCEPTION = forSignature("Ljava/lang/RuntimeException;");
public static final UnresolvedType ERROR = forSignature("Ljava/lang/Error;");
public static final UnresolvedType AT_INHERITED = forSignature("Ljava/lang/annotation/Inherited;");
public static final UnresolvedType AT_RETENTION = forSignature("Ljava/lang/annotation/Retention;");
public static final UnresolvedType ENUM = forSignature("Ljava/lang/Enum;");
public static final UnresolvedType ANNOTATION = forSignature("Ljava/lang/annotation/Annotation;");
public static final UnresolvedType JAVA_LANG_CLASS = forSignature("Ljava/lang/Class;");
public static final UnresolvedType JAVA_LANG_CLASS_ARRAY = forSignature("[Ljava/lang/Class;");
public static final UnresolvedType JAVA_LANG_STRING = forSignature("Ljava/lang/String;");
public static final UnresolvedType JAVA_LANG_EXCEPTION = forSignature("Ljava/lang/Exception;");
public static final UnresolvedType JAVA_LANG_REFLECT_METHOD = forSignature("Ljava/lang/reflect/Method;");
public static final UnresolvedType JAVA_LANG_ANNOTATION = UnresolvedType.forSignature("Ljava.lang.annotation.Annotation;");
public static final UnresolvedType SUPPRESS_AJ_WARNINGS = forSignature("Lorg/aspectj/lang/annotation/SuppressAjWarnings;");
public static final UnresolvedType AT_TARGET = forSignature("Ljava/lang/annotation/Target;");
public static final UnresolvedType SOMETHING = new UnresolvedType("?");
public static final UnresolvedType[] ARRAY_WITH_JUST_OBJECT = new UnresolvedType[] { OBJECT };
public static final UnresolvedType JOINPOINT_STATICPART = forSignature("Lorg/aspectj/lang/JoinPoint$StaticPart;");
public static final UnresolvedType JOINPOINT_ENCLOSINGSTATICPART = forSignature("Lorg/aspectj/lang/JoinPoint$EnclosingStaticPart;");

// 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?

/**
* THE SIGNATURE - see the comments above for how this is defined
*/
protected String signature;

/**
* The erasure of the signature. Contains only the Java signature of the type with all supertype, superinterface, type variable,
* and parameter information removed.
*/
protected String signatureErasure;

/**
* Iff isParameterized(), then these are the type parameters
*/
protected UnresolvedType[] typeParameters;

/**
* Iff isGeneric(), then these are the type variables declared on the type Iff isParameterized(), then these are the type
* variables bound as parameters in the type
*/
// OPTIMIZE should be no state in here that will damage whether equals() is correct...
protected TypeVariable[] typeVariables;

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 TypeKind getTypekind() {
return typeKind;
}

// for any reference type, we can get some extra information...
public final boolean isArray() {
return signature.length() > 0 && signature.charAt(0) == '[';
}

/**
* Equality is checked based on the underlying signature. {@link ResolvedType} objects' equals is by reference.
*/
public boolean equals(Object other) {
if (!(other instanceof UnresolvedType))
return false;
return signature.equals(((UnresolvedType) other).signature);
}

/**
* Equality is checked based on the underlying signature, so the hash code of a particular type is the hash code of its
* signature string.
*/
public final int hashCode() {
return signature.hashCode();
}

protected UnresolvedType(String signature) {
this.signature = signature;
this.signatureErasure = signature;
}

protected UnresolvedType(String signature, String signatureErasure) {
this.signature = signature;
this.signatureErasure = signatureErasure;
}

// called from TypeFactory
public UnresolvedType(String signature, String signatureErasure, UnresolvedType[] typeParams) {
this.signature = signature;
this.signatureErasure = signatureErasure;
this.typeParameters = typeParams;
if (typeParams != null)
this.typeKind = TypeKind.PARAMETERIZED;
}

// ---- Things we can do without a world

/**
* This is the size of this type as used in JVM.
*/
public int getSize() {
return 1;
}

public static UnresolvedType makeArray(UnresolvedType base, int dims) {
StringBuffer sig = new StringBuffer();
for (int i = 0; i < dims; i++)
sig.append("[");
sig.append(base.getSignature());
return UnresolvedType.forSignature(sig.toString());
}

/**
* NOTE: Use forSignature() if you can, it'll be cheaper ! Constructs a UnresolvedType for a java language type name. For
* example:
*
* <blockquote>
*
* <pre>
* UnresolvedType.forName(&quot;java.lang.Thread[]&quot;)
* UnresolvedType.forName(&quot;int&quot;)
* </pre>
*
* </blockquote>
*
* Types may equivalently be produced by this or by {@link #forSignature(String)}.
*
* <blockquote>
*
* <pre>
* UnresolvedType.forName(&quot;java.lang.Thread[]&quot;).equals(Type.forSignature(&quot;[Ljava/lang/Thread;&quot;)
* UnresolvedType.forName(&quot;int&quot;).equals(Type.forSignature(&quot;I&quot;))
* </pre>
*
* </blockquote>
*
* @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));
}

/**
* Constructs a UnresolvedType for each java language type name in an incoming array.
*
* @param names an array of java language type names.
* @return an array of UnresolvedType objects.
* @see #forName(String)
*/
public static UnresolvedType[] forNames(String[] names) {
UnresolvedType[] ret = new UnresolvedType[names.length];
for (int i = 0, len = names.length; i < len; i++) {
ret[i] = UnresolvedType.forName(names[i]);
}
return ret;
}

public static UnresolvedType forGenericType(String name, TypeVariable[] tvbs, String genericSig) {
// TODO asc generics needs a declared sig
String sig = nameToSignature(name);
UnresolvedType ret = UnresolvedType.forSignature(sig);
ret.typeKind = TypeKind.GENERIC;
ret.typeVariables = tvbs;
ret.signatureErasure = sig;
return ret;
}

public static UnresolvedType forGenericTypeSignature(String sig, String declaredGenericSig) {
UnresolvedType ret = UnresolvedType.forSignature(sig);
ret.typeKind = TypeKind.GENERIC;

ClassSignature csig = new GenericSignatureParser().parseAsClassSignature(declaredGenericSig);

GenericSignature.FormalTypeParameter[] ftps = csig.formalTypeParameters;
ret.typeVariables = new TypeVariable[ftps.length];
for (int i = 0; i < ftps.length; i++) {
GenericSignature.FormalTypeParameter parameter = ftps[i];
if (parameter.classBound instanceof GenericSignature.ClassTypeSignature) {
GenericSignature.ClassTypeSignature cts = (GenericSignature.ClassTypeSignature) parameter.classBound;
ret.typeVariables[i] = new TypeVariable(ftps[i].identifier, UnresolvedType.forSignature(cts.outerType.identifier
+ ";"));
} else if (parameter.classBound instanceof GenericSignature.TypeVariableSignature) {
GenericSignature.TypeVariableSignature tvs = (GenericSignature.TypeVariableSignature) parameter.classBound;
UnresolvedTypeVariableReferenceType utvrt = new UnresolvedTypeVariableReferenceType(new TypeVariable(
tvs.typeVariableName));
ret.typeVariables[i] = new TypeVariable(ftps[i].identifier, utvrt);
} else {
throw new BCException(
"UnresolvedType.forGenericTypeSignature(): Do not know how to process type variable bound of type '"
+ parameter.classBound.getClass() + "'. Full signature is '" + sig + "'");
}
}
ret.signatureErasure = sig;
ret.signature = ret.signatureErasure;
return ret;
}

public static UnresolvedType forGenericTypeVariables(String sig, TypeVariable[] tVars) {
UnresolvedType ret = UnresolvedType.forSignature(sig);
ret.typeKind = TypeKind.GENERIC;
ret.typeVariables = tVars;
ret.signatureErasure = sig;
ret.signature = ret.signatureErasure;
return ret;
}

public static UnresolvedType forRawTypeName(String name) {
UnresolvedType ret = UnresolvedType.forName(name);
ret.typeKind = TypeKind.RAW;
return ret;
}

/**
* Creates a new type array with a fresh type appended to the end.
*
* @param types the left hand side of the new array
* @param end the right hand side of the new array
*/
public static UnresolvedType[] add(UnresolvedType[] types, UnresolvedType end) {
int len = types.length;
UnresolvedType[] ret = new UnresolvedType[len + 1];
System.arraycopy(types, 0, ret, 0, len);
ret[len] = end;
return ret;
}

/**
* Creates a new type array with a fresh type inserted at the beginning.
*
*
* @param start the left hand side of the new array
* @param types the right hand side of the new array
*/
public static UnresolvedType[] insert(UnresolvedType start, UnresolvedType[] types) {
int len = types.length;
UnresolvedType[] ret = new UnresolvedType[len + 1];
ret[0] = start;
System.arraycopy(types, 0, ret, 1, len);
return ret;
}

/**
* Constructs a Type for a JVM bytecode signature string. For example:
*
* <blockquote>
*
* <pre>
* UnresolvedType.forSignature(&quot;[Ljava/lang/Thread;&quot;)
* UnresolvedType.forSignature(&quot;I&quot;);
* </pre>
*
* </blockquote>
*
* Types may equivalently be produced by this or by {@link #forName(String)}.
*
* <blockquote>
*
* <pre>
* UnresolvedType.forName(&quot;java.lang.Thread[]&quot;).equals(Type.forSignature(&quot;[Ljava/lang/Thread;&quot;)
* UnresolvedType.forName(&quot;int&quot;).equals(Type.forSignature(&quot;I&quot;))
* </pre>
*
* </blockquote>
*
* @param signature the JVM bytecode signature string for the desired type.
* @return a type object represnting that JVM bytecode signature.
*/
public static UnresolvedType forSignature(String signature) {
switch (signature.charAt(0)) {
case 'B':
return ResolvedType.BYTE;
case 'C':
return ResolvedType.CHAR;
case 'D':
return ResolvedType.DOUBLE;
case 'F':
return ResolvedType.FLOAT;
case 'I':
return ResolvedType.INT;
case 'J':
return ResolvedType.LONG;
case 'L':
return TypeFactory.createTypeFromSignature(signature);
case 'P':
return TypeFactory.createTypeFromSignature(signature);
case 'S':
return ResolvedType.SHORT;
case 'V':
return ResolvedType.VOID;
case 'Z':
return ResolvedType.BOOLEAN;
case '[':
return TypeFactory.createTypeFromSignature(signature);
case '+':
return TypeFactory.createTypeFromSignature(signature);
case '-':
return TypeFactory.createTypeFromSignature(signature);
case '?':
return TypeFactory.createTypeFromSignature(signature);
case 'T':
return TypeFactory.createTypeFromSignature(signature);
default:
throw new BCException("Bad type signature " + signature);
}
}

/**
* Constructs a UnresolvedType for each JVM bytecode type signature in an incoming array.
*
* @param names an array of JVM bytecode type signatures
* @return an array of UnresolvedType objects.
* @see #forSignature(String)
*/
public static UnresolvedType[] forSignatures(String[] sigs) {
UnresolvedType[] ret = new UnresolvedType[sigs.length];
for (int i = 0, len = sigs.length; i < len; i++) {
ret[i] = UnresolvedType.forSignature(sigs[i]);
}
return ret;
}

/**
* Returns the name of this type in java language form (e.g. java.lang.Thread or boolean[]). This produces a more aesthetically
* pleasing string than {@link java.lang.Class#getName()}.
*
* @return the java language name of this type.
*/
public String getName() {
return signatureToName(signature);
}

public String getSimpleName() {
String name = getRawName();
int lastDot = name.lastIndexOf('.');
if (lastDot != -1) {
name = name.substring(lastDot + 1);
}
if (isParameterizedType()) {
StringBuffer sb = new StringBuffer(name);
sb.append("<");
for (int i = 0; i < (typeParameters.length - 1); i++) {
sb.append(typeParameters[i].getSimpleName());
sb.append(",");
}
sb.append(typeParameters[typeParameters.length - 1].getSimpleName());
sb.append(">");
name = sb.toString();
}
return name;
}

public String getRawName() {
return signatureToName((signatureErasure == null ? signature : signatureErasure));
}

public String getBaseName() {
String name = getName();
if (isParameterizedType() || isGenericType()) {
if (typeParameters == null)
return name;
else
return name.substring(0, name.indexOf("<"));
} else {
return name;
}
}

public String getSimpleBaseName() {
String name = getBaseName();
int lastDot = name.lastIndexOf('.');
if (lastDot != -1) {
name = name.substring(lastDot + 1);
}
return name;
}

/**
* Returns an array of strings representing the java langauge names of an array of types.
*
* @param types an array of UnresolvedType objects
* @return an array of Strings fo the java language names of types.
* @see #getName()
*/
public static String[] getNames(UnresolvedType[] types) {
String[] ret = new String[types.length];
for (int i = 0, len = types.length; i < len; i++) {
ret[i] = types[i].getName();
}
return ret;
}

/**
* Returns the name of this type in JVM signature form. For all UnresolvedType t:
*
* <blockquote>
*
* <pre>
* UnresolvedType.forSignature(t.getSignature()).equals(t)
* </pre>
*
* </blockquote>
*
* and for all String s where s is a lexically valid JVM type signature string:
*
* <blockquote>
*
* <pre>
* UnresolvedType.forSignature(s).getSignature().equals(s)
* </pre>
*
* </blockquote>
*
* @return the java JVM signature string for this type.
*/
public String getSignature() {
return signature;
}

/**
* For parameterized types, return the signature for the raw type
*/
public String getErasureSignature() {
if (signatureErasure == null)
return signature;
return signatureErasure;
}

private boolean needsModifiableDelegate = false;

public boolean needsModifiableDelegate() {
return needsModifiableDelegate;
}

public void setNeedsModifiableDelegate(boolean b) {
this.needsModifiableDelegate = b;
}

public UnresolvedType getRawType() {
return UnresolvedType.forSignature(getErasureSignature());
}

/**
* Returns a UnresolvedType object representing the effective outermost enclosing type for a name type. For all other types,
* this will return the type itself.
*
* The only guarantee is given in JLS 13.1 where code generated according to those rules will have type names that can be split
* apart in this way.
*
* @return the outermost enclosing UnresolvedType object or this.
*/
public UnresolvedType getOutermostType() {
if (isArray() || isPrimitiveType())
return this;
String sig = getErasureSignature();
int dollar = sig.indexOf('$');
if (dollar != -1) {
return UnresolvedType.forSignature(sig.substring(0, dollar) + ';');
} else {
return this;
}
}

/**
* Returns a UnresolvedType object representing the component type of this array, or null if this type does not represent an
* array type.
*
* @return the component UnresolvedType object, or null.
*/
public UnresolvedType getComponentType() {
if (isArray()) {
return forSignature(signature.substring(1));
} else {
return null;
}
}

/**
* Returns a java language string representation of this type.
*/
public String toString() {
return getName(); // + " - " + getKind();
}

public String toDebugString() {
return getName();
}

// ---- requires worlds

/**
* Returns a resolved version of this type according to a particular world.
*
* @param world thie {@link World} within which to resolve.
* @return a resolved type representing this type in the appropriate world.
*/
public ResolvedType resolve(World world) {
return world.resolve(this);
}

// ---- helpers

private static String signatureToName(String signature) {
switch (signature.charAt(0)) {
case 'B':
return "byte";
case 'C':
return "char";
case 'D':
return "double";
case 'F':
return "float";
case 'I':
return "int";
case 'J':
return "long";
case 'L':
String name = signature.substring(1, signature.length() - 1).replace('/', '.');
return name;
case 'T':
StringBuffer nameBuff2 = new StringBuffer();
int colon = signature.indexOf(";");
String tvarName = signature.substring(1, colon);
nameBuff2.append(tvarName);
return nameBuff2.toString();
case 'P': // it's one of our parameterized type sigs
StringBuffer nameBuff = new StringBuffer();
// signature for parameterized types is e.g.
// List<String> -> Ljava/util/List<Ljava/lang/String;>;
// Map<String,List<Integer>> -> Ljava/util/Map<java/lang/String;Ljava/util/List<Ljava/lang/Integer;>;>;
int paramNestLevel = 0;
for (int i = 1; i < signature.length(); i++) {
char c = signature.charAt(i);
switch (c) {
case '/':
nameBuff.append('.');
break;
case '<':
nameBuff.append("<");
paramNestLevel++;
StringBuffer innerBuff = new StringBuffer();
while (paramNestLevel > 0) {
c = signature.charAt(++i);
if (c == '<')
paramNestLevel++;
if (c == '>')
paramNestLevel--;
if (paramNestLevel > 0)
innerBuff.append(c);
if (c == ';' && paramNestLevel == 1) {
nameBuff.append(signatureToName(innerBuff.toString()));
if (signature.charAt(i + 1) != '>')
nameBuff.append(',');
innerBuff = new StringBuffer();
}
}
nameBuff.append(">");
break;
case ';':
break;
default:
nameBuff.append(c);
}
}
return nameBuff.toString();
case 'S':
return "short";
case 'V':
return "void";
case 'Z':
return "boolean";
case '[':
return signatureToName(signature.substring(1, signature.length())) + "[]";
// case '<':
// // its a generic!
// if (signature.charAt(1)=='>') return signatureToName(signature.substring(2));
case '+':
return "? extends " + signatureToName(signature.substring(1, signature.length()));
case '-':
return "? super " + signatureToName(signature.substring(1, signature.length()));
case '*':
return "?";
default:
throw new BCException("Bad type signature: " + signature);
}
}

private static String nameToSignature(String name) {
if (name.equals("byte"))
return "B";
if (name.equals("char"))
return "C";
if (name.equals("double"))
return "D";
if (name.equals("float"))
return "F";
if (name.equals("int"))
return "I";
if (name.equals("long"))
return "J";
if (name.equals("short"))
return "S";
if (name.equals("boolean"))
return "Z";
if (name.equals("void"))
return "V";
if (name.equals("?"))
return name;
if (name.endsWith("[]"))
return "[" + nameToSignature(name.substring(0, name.length() - 2));
if (name.length() != 0) {
// lots more tests could be made here...

// check if someone is calling us with something that is a signature already
if (name.charAt(0) == '[') {
throw new BCException("Do not call nameToSignature with something that looks like a signature (descriptor): '"
+ name + "'");
}

if (name.indexOf("<") == -1) {
// not parameterised
return "L" + name.replace('.', '/') + ";";
} else {
StringBuffer nameBuff = new StringBuffer();
int nestLevel = 0;
nameBuff.append("P");
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
switch (c) {
case '.':
nameBuff.append('/');
break;
case '<':
nameBuff.append("<");
nestLevel++;
StringBuffer innerBuff = new StringBuffer();
while (nestLevel > 0) {
c = name.charAt(++i);
if (c == '<')
nestLevel++;
if (c == '>')
nestLevel--;
if (c == ',' && nestLevel == 1) {
nameBuff.append(nameToSignature(innerBuff.toString()));
innerBuff = new StringBuffer();
} else {
if (nestLevel > 0)
innerBuff.append(c);
}
}
nameBuff.append(nameToSignature(innerBuff.toString()));
nameBuff.append('>');
break;
case '>':
throw new IllegalStateException("Should by matched by <");
case ',':
throw new IllegalStateException("Should only happen inside <...>");
default:
nameBuff.append(c);
}
}
nameBuff.append(";");
return nameBuff.toString();
}
} else
throw new BCException("Bad type name: " + name);
}

public void write(DataOutputStream s) throws IOException {
s.writeUTF(getSignature());
}

public static UnresolvedType read(DataInputStream s) throws IOException {
String sig = s.readUTF();
if (sig.equals(MISSING_NAME)) {
return ResolvedType.MISSING;
} else {
UnresolvedType ret = UnresolvedType.forSignature(sig);
return ret;
}
}

public static void writeArray(UnresolvedType[] types, DataOutputStream s) throws IOException {
int len = types.length;
s.writeShort(len);
for (int i = 0; i < len; i++) {
types[i].write(s);
}
}

public static UnresolvedType[] readArray(DataInputStream s) throws IOException {
int len = s.readShort();
if (len == 0)
return UnresolvedType.NONE;
UnresolvedType[] types = new UnresolvedType[len];
for (int i = 0; i < len; i++) {
types[i] = UnresolvedType.read(s);
}
return types;
}

public String getNameAsIdentifier() {
return getName().replace('.', '_');
}

public String getPackageNameAsIdentifier() {
String name = getName();
int index = name.lastIndexOf('.');
if (index == -1) {
return "";
} else {
return name.substring(0, index).replace('.', '_');
}
}

public String getPackageName() {
String name = getName();
if (name.indexOf("<") != -1) {
name = name.substring(0, name.indexOf("<"));
}
int index = name.lastIndexOf('.');
if (index == -1) {
return "";
} else {
return name.substring(0, index);
}
}

public UnresolvedType[] getTypeParameters() {
return typeParameters == null ? UnresolvedType.NONE : typeParameters;
}

/**
* Doesn't include the package
*/
public String getClassName() {
String name = getName();
int index = name.lastIndexOf('.');
if (index == -1) {
return name;
} else {
return name.substring(index + 1);
}
}

public TypeVariable[] getTypeVariables() {
return typeVariables;
}

public static class TypeKind {
// Note: It is not sufficient to say that a parameterized type with no type parameters in fact
// represents a raw type - a parameterized type with no type parameters can represent
// an inner type of a parameterized type that specifies no type parameters of its own.
public final static TypeKind PRIMITIVE = new TypeKind("primitive");
public final static TypeKind SIMPLE = new TypeKind("simple"); // a type with NO type parameters/vars
public final static TypeKind RAW = new TypeKind("raw"); // the erasure of a generic type
public final static TypeKind GENERIC = new TypeKind("generic"); // a generic type
public final static TypeKind PARAMETERIZED = new TypeKind("parameterized"); // a parameterized type
public final static TypeKind TYPE_VARIABLE = new TypeKind("type_variable"); // a type variable
public final static TypeKind WILDCARD = new TypeKind("wildcard"); // a generic wildcard type

public String toString() {
return type;
}

private TypeKind(String type) {
this.type = type;
}

private final String type;
}

public TypeVariable getTypeVariableNamed(String name) {
TypeVariable[] vars = getTypeVariables();
if (vars == null || vars.length == 0)
return null;
for (int i = 0; i < vars.length; i++) {
TypeVariable aVar = vars[i];
if (aVar.getName().equals(name))
return aVar;
}
return null;
}

public String toTraceString() {
return getClass().getName() + "[" + getName() + "]";
}

/**
* Return a version of this parameterized type in which any type parameters 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);
}
}

+ 102
- 0
org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java Переглянути файл

@@ -0,0 +1,102 @@
/* *******************************************************************
* 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;

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

/**
* @author colyer
* Represents a type variable encountered in the Eclipse Source world,
* which when resolved will turn into a TypeVariableReferenceType
*/
public class UnresolvedTypeVariableReferenceType extends UnresolvedType implements TypeVariableReference {

private TypeVariable typeVariable;
// constructor used as place-holder when dealing with circular refs such as Enum
public UnresolvedTypeVariableReferenceType() {
super("Ljava/lang/Object;");
}
public UnresolvedTypeVariableReferenceType(TypeVariable aTypeVariable) {
super(aTypeVariable.getFirstBound().getSignature());
this.typeVariable = aTypeVariable;
}
// only used when resolving circular refs...
public void setTypeVariable(TypeVariable aTypeVariable) {
this.signature = "T" + aTypeVariable.getName() + ";"; //aTypeVariable.getUpperBound().getSignature();
this.typeVariable = aTypeVariable;
this.typeKind=TypeKind.TYPE_VARIABLE;
}
public ResolvedType resolve(World world) {
TypeVariableDeclaringElement typeVariableScope = world.getTypeVariableLookupScope();
TypeVariable resolvedTypeVariable = null;
TypeVariableReferenceType tvrt = null;
if (typeVariableScope == null) {
// throw new BCException("There is no scope in which to lookup type variables!");
// FIXME asc correct thing to do is go bang, but to limp along, lets cope with the scope missing
resolvedTypeVariable = typeVariable.resolve(world);
tvrt = new TypeVariableReferenceType(resolvedTypeVariable,world);
} else {
boolean foundOK = false;
resolvedTypeVariable = typeVariableScope.getTypeVariableNamed(typeVariable.getName());
// FIXME asc remove this when the shared type var stuff is sorted
if (resolvedTypeVariable == null) {
resolvedTypeVariable = typeVariable.resolve(world);
} else {
foundOK = true;
}
tvrt = new TypeVariableReferenceType(resolvedTypeVariable,world);
tvrt.fixedUp = foundOK;
}
return tvrt;
}
public boolean isTypeVariableReference() {
return true;
}
public TypeVariable getTypeVariable() {
return typeVariable;
}

// public String getName() {
// if (typeVariable == null) return "<type variable not set!>";
// return typeVariable.getDisplayName();
// }
public String toString() {
if (typeVariable == null) {
return "<type variable not set!>";
} else {
return "T" + typeVariable.getName() + ";";
}
}
public String toDebugString() {
return typeVariable.getName();
}
public void write(DataOutputStream s) throws IOException {
super.write(s);
}

public String getErasureSignature() {
return typeVariable.getFirstBound().getSignature();
}
}

+ 43
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Utils.java Переглянути файл

@@ -0,0 +1,43 @@
/* *******************************************************************
* 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://eclipse.org/legal/epl-v10.html
*
* ******************************************************************/
package org.aspectj.weaver;

/**
*
* @author Andy Clement
*/
public class Utils {

/**
* Check if the annotations contain a SuppressAjWarnings annotation and if that annotation specifies that the given lint message
* (identified by its key) should be ignored.
*
*/
public static boolean isSuppressing(AnnotationAJ[] anns, String lintkey) {
if (anns == null) {
return false;
}
// Go through the annotation types on the advice
for (int i = 0; i < anns.length; i++) {
if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getTypeSignature())) {
// Two possibilities:
// 1. there are no values specified (i.e. @SuppressAjWarnings)
// 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
String value = anns[i].getStringFormOfValue("value");
// Slightly lazy, just doing a string indexof
if (value == null || value.indexOf(lintkey) != -1) {
return true;
}
}
}
return false;
}

}

+ 32
- 0
org.aspectj.matcher/src/org/aspectj/weaver/VersionedDataInputStream.java Переглянути файл

@@ -0,0 +1,32 @@
/* *******************************************************************
* Copyright (c) 2005 IBM
* 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.io.DataInputStream;
import java.io.InputStream;

import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;

/**
* Lightweight subclass of DataInputStream that knows what version of the weaver was used to construct the data in it.
*/
public class VersionedDataInputStream extends DataInputStream {
private WeaverVersionInfo version = new WeaverVersionInfo();// assume we are the latest unless something tells us otherwise...
public VersionedDataInputStream(InputStream is) { super(is); }
public int getMajorVersion() { return version.getMajorVersion(); }
public int getMinorVersion() { return version.getMinorVersion(); }
public long getBuildstamp() { return version.getBuildstamp(); }
public void setVersion(WeaverVersionInfo version) { this.version = version; }
}

+ 63
- 0
org.aspectj.matcher/src/org/aspectj/weaver/WeakClassLoaderReference.java Переглянути файл

@@ -0,0 +1,63 @@
/* *******************************************************************
* 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.ref.WeakReference;

/**
* Wraps a reference to a classloader inside a WeakReference. This should be used where we do not want the existence of a
* classloader reference to prevent garbage collection of that classloader (and possibly an associated weaver instance in the case
* of load time weaving).
* <p>
* In more detail:<br>
* When load time weaving, the class Aj maintains a WeakHashMap from the classloader instance to a weaver instance. The aim is that
* the weaver is around as long as the classloader is and should the classloader be dereferenced then the weaver can also be garbage
* collected. The problem is that if there are many references to the classloader from within the weaver, these are considered hard
* references and cause the classloader to be long lived - even if the user of the classloader has dereferenced it in their code.
* The solution is that the weaver should use instances of WeakClassLoaderReference objects - so that when the users hard reference
* to the classloader goes, nothing in the weaver will cause it to hang around. There is a big assertion here that the
* WeakClassLoaderReference instances will not 'lose' their ClassLoader references until the top level ClassLoader reference is
* null'd. This means there is no need to check for the null case on get() in this WeakReference logic below, because we shouldn't
* be using this weaver if its associated ClassLoader has been collected. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=210470
*
*
* @author Andy Clement
*/
public class WeakClassLoaderReference {

protected final int hashcode;

private final WeakReference loaderRef;

public WeakClassLoaderReference(ClassLoader loader) {
loaderRef = new WeakReference(loader);
hashcode = loader.hashCode() * 37;
}

public ClassLoader getClassLoader() {
ClassLoader instance = (ClassLoader) loaderRef.get();
// Assert instance!=null
return instance;
}

public boolean equals(Object obj) {
if (!(obj instanceof WeakClassLoaderReference))
return false;
WeakClassLoaderReference other = (WeakClassLoaderReference) obj;
return (other.hashcode == hashcode);
}

public int hashCode() {
return hashcode;
}

}

+ 210
- 0
org.aspectj.matcher/src/org/aspectj/weaver/WeaverMessages.java Переглянути файл

@@ -0,0 +1,210 @@
/*******************************************************************************
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.weaver;

import java.text.MessageFormat;
import java.util.ResourceBundle;


public class WeaverMessages {
private static ResourceBundle bundle = ResourceBundle.getBundle("org.aspectj.weaver.weaver-messages");

public static final String ARGS_IN_DECLARE = "argsInDeclare";
public static final String CFLOW_IN_DECLARE = "cflowInDeclare";
public static final String IF_IN_DECLARE = "ifInDeclare";
public static final String THIS_OR_TARGET_IN_DECLARE = "thisOrTargetInDeclare";
public static final String ABSTRACT_POINTCUT = "abstractPointcut";
public static final String POINCUT_NOT_CONCRETE = "abstractPointcutNotMadeConcrete";
public static final String POINTCUT_NOT_VISIBLE = "pointcutNotVisible";
public static final String CONFLICTING_INHERITED_POINTCUTS = "conflictingInheritedPointcuts";
public static final String CIRCULAR_POINTCUT = "circularPointcutDeclaration";
public static final String CANT_FIND_POINTCUT = "cantFindPointcut";
public static final String EXACT_TYPE_PATTERN_REQD = "exactTypePatternRequired";
public static final String CANT_BIND_TYPE = "cantBindType";
public static final String WILDCARD_NOT_ALLOWED = "wildcardTypePatternNotAllowed";
public static final String FIELDS_CANT_HAVE_VOID_TYPE = "fieldCantBeVoid";
public static final String NO_NEWARRAY_JOINPOINTS_BY_DEFAULT = "noNewArrayJoinpointsByDefault";
public static final String UNSUPPORTED_POINTCUT_PRIMITIVE = "unsupportedPointcutPrimitive";
public static final String MISSING_TYPE_PREVENTS_MATCH = "missingTypePreventsMatch";
public static final String DECP_OBJECT = "decpObject";
public static final String CANT_EXTEND_SELF="cantExtendSelf";
public static final String INTERFACE_CANT_EXTEND_CLASS="interfaceExtendClass";
public static final String DECP_HIERARCHY_ERROR = "decpHierarchy";
public static final String MULTIPLE_MATCHES_IN_PRECEDENCE = "multipleMatchesInPrecedence";
public static final String TWO_STARS_IN_PRECEDENCE = "circularityInPrecedenceStar";
public static final String CLASSES_IN_PRECEDENCE = "nonAspectTypesInPrecedence";
public static final String TWO_PATTERN_MATCHES_IN_PRECEDENCE = "circularityInPrecedenceTwo";
public static final String NOT_THROWABLE = "notThrowable";
public static final String ITD_CONS_ON_ASPECT = "itdConsOnAspect";
public static final String ITD_RETURN_TYPE_MISMATCH = "returnTypeMismatch";
public static final String ITD_PARAM_TYPE_MISMATCH = "paramTypeMismatch";
public static final String ITD_VISIBILITY_REDUCTION = "visibilityReduction";
public static final String ITD_DOESNT_THROW = "doesntThrow";
public static final String ITD_OVERRIDDEN_STATIC = "overriddenStatic";
public static final String ITD_OVERIDDING_STATIC = "overridingStatic";
public static final String ITD_CONFLICT = "itdConflict";
public static final String ITD_MEMBER_CONFLICT = "itdMemberConflict";
public static final String ITD_NON_EXPOSED_IMPLEMENTOR = "itdNonExposedImplementor";
public static final String ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE = "itdAbstractMustBePublicOnInterface";
public static final String CANT_OVERRIDE_FINAL_MEMBER = "cantOverrideFinalMember";
public static final String NON_VOID_RETURN = "nonVoidReturn";
public static final String INCOMPATIBLE_RETURN_TYPE="incompatibleReturnType";
public static final String CANT_THROW_CHECKED = "cantThrowChecked";
public static final String CIRCULAR_DEPENDENCY = "circularDependency";
public static final String MISSING_PER_CLAUSE = "missingPerClause";
public static final String WRONG_PER_CLAUSE = "wrongPerClause";
public static final String ALREADY_WOVEN = "alreadyWoven";
public static final String REWEAVABLE_MODE = "reweavableMode";
public static final String PROCESSING_REWEAVABLE = "processingReweavable";
public static final String MISSING_REWEAVABLE_TYPE = "missingReweavableType";
public static final String VERIFIED_REWEAVABLE_TYPE = "verifiedReweavableType";
public static final String ASPECT_NEEDED = "aspectNeeded";
public static final String REWEAVABLE_ASPECT_NOT_REGISTERED = "reweavableAspectNotRegistered";

public static final String CANT_FIND_TYPE = "cantFindType";
public static final String CANT_FIND_CORE_TYPE = "cantFindCoreType";
public static final String CANT_FIND_TYPE_WITHINPCD = "cantFindTypeWithinpcd";
public static final String CANT_FIND_TYPE_DURING_AROUND_WEAVE = "cftDuringAroundWeave";
public static final String CANT_FIND_TYPE_DURING_AROUND_WEAVE_PREINIT = "cftDuringAroundWeavePreinit";
public static final String CANT_FIND_TYPE_EXCEPTION_TYPE = "cftExceptionType";
public static final String CANT_FIND_TYPE_ARG_TYPE = "cftArgType";
public static final String CANT_FIND_PARENT_TYPE = "cantFindParentType";
public static final String CANT_FIND_PARENT_TYPE_NO_SUB = "cantFindParentTypeNoSub";
public static final String CANT_FIND_TYPE_FIELDS = "cantFindTypeFields";
public static final String CANT_FIND_TYPE_SUPERCLASS = "cantFindTypeSuperclass";
public static final String CANT_FIND_TYPE_INTERFACES = "cantFindTypeInterfaces";
public static final String CANT_FIND_TYPE_METHODS = "cantFindTypeMethods";
public static final String CANT_FIND_TYPE_POINTCUTS = "cantFindTypePointcuts";
public static final String CANT_FIND_TYPE_MODIFIERS = "cantFindTypeModifiers";
public static final String CANT_FIND_TYPE_ANNOTATION = "cantFindTypeAnnotation";
public static final String CANT_FIND_TYPE_ASSIGNABLE = "cantFindTypeAssignable";
public static final String CANT_FIND_TYPE_COERCEABLE = "cantFindTypeCoerceable";
public static final String CANT_FIND_TYPE_JOINPOINT = "cantFindTypeJoinPoint";
public static final String CANT_FIND_TYPE_INTERFACE_METHODS = "cantFindTypeInterfaceMethods";
public static final String DECP_BINARY_LIMITATION = "decpBinaryLimitation";
public static final String OVERWRITE_JSR45 = "overwriteJSR45";
public static final String IF_IN_PERCLAUSE = "ifInPerClause";
public static final String IF_LEXICALLY_IN_CFLOW = "ifLexicallyInCflow";
public static final String ONLY_BEFORE_ON_HANDLER = "onlyBeforeOnHandler";
public static final String NO_AROUND_ON_SYNCHRONIZATION = "noAroundOnSynchronization";
public static final String AROUND_ON_PREINIT = "aroundOnPreInit";
public static final String AROUND_ON_INIT = "aroundOnInit";
public static final String AROUND_ON_INTERFACE_STATICINIT = "aroundOnInterfaceStaticInit";
public static final String PROBLEM_GENERATING_METHOD = "problemGeneratingMethod";
public static final String CLASS_TOO_BIG = "classTooBig";
public static final String ZIPFILE_ENTRY_MISSING = "zipfileEntryMissing";
public static final String ZIPFILE_ENTRY_INVALID = "zipfileEntryInvalid";
public static final String DIRECTORY_ENTRY_MISSING = "directoryEntryMissing";
public static final String OUTJAR_IN_INPUT_PATH = "outjarInInputPath";
public static final String XLINT_LOAD_ERROR = "problemLoadingXLint";
public static final String XLINTDEFAULT_LOAD_ERROR = "unableToLoadXLintDefault";
public static final String XLINTDEFAULT_LOAD_PROBLEM = "errorLoadingXLintDefault";
public static final String XLINT_KEY_ERROR = "invalidXLintKey";
public static final String XLINT_VALUE_ERROR = "invalidXLintMessageKind";
public static final String UNBOUND_FORMAL = "unboundFormalInPC";
public static final String AMBIGUOUS_BINDING = "ambiguousBindingInPC";
public static final String AMBIGUOUS_BINDING_IN_OR = "ambiguousBindingInOrPC";
public static final String NEGATION_DOESNT_ALLOW_BINDING = "negationDoesntAllowBinding";
// Java5 messages
public static final String ITDC_ON_ENUM_NOT_ALLOWED = "itdcOnEnumNotAllowed";
public static final String ITDM_ON_ENUM_NOT_ALLOWED = "itdmOnEnumNotAllowed";
public static final String ITDF_ON_ENUM_NOT_ALLOWED = "itdfOnEnumNotAllowed";
public static final String CANT_DECP_ON_ENUM_TO_IMPL_INTERFACE = "cantDecpOnEnumToImplInterface";
public static final String CANT_DECP_ON_ENUM_TO_EXTEND_CLASS = "cantDecpOnEnumToExtendClass";
public static final String CANT_DECP_TO_MAKE_ENUM_SUPERTYPE = "cantDecpToMakeEnumSupertype";
public static final String ITDC_ON_ANNOTATION_NOT_ALLOWED = "itdcOnAnnotationNotAllowed";
public static final String ITDM_ON_ANNOTATION_NOT_ALLOWED = "itdmOnAnnotationNotAllowed";
public static final String ITDF_ON_ANNOTATION_NOT_ALLOWED = "itdfOnAnnotationNotAllowed";
public static final String CANT_DECP_ON_ANNOTATION_TO_IMPL_INTERFACE = "cantDecpOnAnnotationToImplInterface";
public static final String CANT_DECP_ON_ANNOTATION_TO_EXTEND_CLASS = "cantDecpOnAnnotationToExtendClass";
public static final String CANT_DECP_TO_MAKE_ANNOTATION_SUPERTYPE = "cantDecpToMakeAnnotationSupertype";
public static final String REFERENCE_TO_NON_ANNOTATION_TYPE = "referenceToNonAnnotationType";
public static final String BINDING_NON_RUNTIME_RETENTION_ANNOTATION = "bindingNonRuntimeRetentionAnnotation";
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";
public static final String ATWITHINCODE_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "atwithincodeNeedsJava5";
public static final String ATTHIS_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "atthisNeedsJava5";
public static final String ATTARGET_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "attargetNeedsJava5";
public static final String ATARGS_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "atargsNeedsJava5";
public static final String DECLARE_ATTYPE_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "declareAtTypeNeedsJava5";
public static final String DECLARE_ATMETHOD_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "declareAtMethodNeedsJava5";
public static final String DECLARE_ATFIELD_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "declareAtFieldNeedsJava5";
public static final String DECLARE_ATCONS_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "declareAtConsNeedsJava5";
public static final String ANNOTATIONS_NEED_JAVA5 = "annotationsRequireJava5";
// Generics
public static final String CANT_DECP_MULTIPLE_PARAMETERIZATIONS="cantDecpMultipleParameterizations";
public static final String HANDLER_PCD_DOESNT_SUPPORT_PARAMETERS="noParameterizedTypePatternInHandler";
public static final String INCORRECT_NUMBER_OF_TYPE_ARGUMENTS = "incorrectNumberOfTypeArguments";
public static final String VIOLATES_TYPE_VARIABLE_BOUNDS = "violatesTypeVariableBounds";
public static final String NO_STATIC_INIT_JPS_FOR_PARAMETERIZED_TYPES = "noStaticInitJPsForParameterizedTypes";
public static final String NOT_A_GENERIC_TYPE="notAGenericType";
public static final String WITHIN_PCD_DOESNT_SUPPORT_PARAMETERS="noParameterizedTypePatternInWithin";
public static final String THIS_AND_TARGET_DONT_SUPPORT_PARAMETERS="noParameterizedTypesInThisAndTarget";
public static final String GET_AND_SET_DONT_SUPPORT_DEC_TYPE_PARAMETERS="noParameterizedTypesInGetAndSet";
public static final String NO_INIT_JPS_FOR_PARAMETERIZED_TYPES = "noInitJPsForParameterizedTypes";
public static final String NO_GENERIC_THROWABLES = "noGenericThrowables";
public static final String WITHINCODE_DOESNT_SUPPORT_PARAMETERIZED_DECLARING_TYPES="noParameterizedDeclaringTypesWithinCode";
public static final String EXECUTION_DOESNT_SUPPORT_PARAMETERIZED_DECLARING_TYPES="noParameterizedDeclaringTypesInExecution";
public static final String CALL_DOESNT_SUPPORT_PARAMETERIZED_DECLARING_TYPES="noParameterizedDeclaringTypesInCall";
public static final String CANT_REFERENCE_POINTCUT_IN_RAW_TYPE="noRawTypePointcutReferences";
public static final String HAS_MEMBER_NOT_ENABLED="hasMemberNotEnabled";
// @AspectJ
public static final String RETURNING_FORMAL_NOT_DECLARED_IN_ADVICE = "returningFormalNotDeclaredInAdvice";
public static final String THROWN_FORMAL_NOT_DECLARED_IN_ADVICE = "thrownFormalNotDeclaredInAdvice";
public static String format(String key) {
return bundle.getString(key);
}
public static String format(String key, Object insert) {
return MessageFormat.format(bundle.getString(key),new Object[] {insert});
}

public static String format(String key, Object insert1, Object insert2) {
return MessageFormat.format(bundle.getString(key),new Object[] {insert1,insert2});
}

public static String format(String key, Object insert1, Object insert2, Object insert3) {
return MessageFormat.format(bundle.getString(key),new Object[] {insert1, insert2, insert3});
}

public static String format(String key, Object insert1, Object insert2, Object insert3, Object insert4) {
return MessageFormat.format(bundle.getString(key),new Object[] {insert1, insert2, insert3, insert4});
}

}

+ 476
- 0
org.aspectj.matcher/src/org/aspectj/weaver/WeaverStateInfo.java Переглянути файл

@@ -0,0 +1,476 @@
/* *******************************************************************
* 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.aspectj.bridge.IMessage;

/**
* WeaverStateInfo represents how a type was processed. It is used by the weaver to determine how a type was previously treated and
* whether reweaving is allowed. The format in the data stream is:
*
* Byte: Kind. UNTOUCHED|WOVEN|EXTENDED - If extended it can have two extra bits set 'REWEAVABLE' and 'REWEAVABLE_COMPRESSION_BIT'
* Short: typeMungerCount - how many type mungers have affected this type <UnresolvedType & ResolvedTypeMunger>: The type mungers
* themselves If we are reweavable then we also have: Short: Number of aspects that touched this type in some way when it was
* previously woven <String> The fully qualified name of each type Int: Length of class file data (i.e. the unwovenclassfile)
* Byte[]: The class file data, compressed if REWEAVABLE_COMPRESSION_BIT set.
*/

public class WeaverStateInfo {
private List/* Entry */typeMungers;
private boolean oldStyle;

private boolean reweavable;
private boolean reweavableCompressedMode; // If true, unwovenClassFile is uncompressed on read
private boolean reweavableDiffMode; // if true, unwovenClassFile is written and read as a diff

private Set /* String */aspectsAffectingType; // These must exist in the world for reweaving to be valid
private byte[] unwovenClassFile; // Original 'untouched' class file
private static boolean reweavableDefault = true; // ajh02: changed from false;
private static boolean reweavableCompressedModeDefault = false;
private static boolean reweavableDiffModeDefault = true;

// when serializing the WeaverStateInfo we come to adding the reweavable data,
// we'd like to add a diff of the unwovenClassFile and the wovenClassFile,
// but we don't have the wovenClassFile yet as we're still in the process of making it.
// so we put this key there instead as a stub.
// Then when the wovenClassFile has been made, replaceKeyWithDiff is called.
private static byte[] key = { -51, 34, 105, 56, -34, 65, 45, 78, -26, 125, 114, 97, 98, 1, -1, -42 };
private boolean unwovenClassFileIsADiff = false;

private WeaverStateInfo() {
// this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault,reweavableDiffModeDefault);
}

public WeaverStateInfo(boolean reweavable) {
this(new ArrayList(), false, reweavable, reweavableCompressedModeDefault, reweavableDiffModeDefault);
}

private WeaverStateInfo(List typeMungers, boolean oldStyle, boolean reweavableMode, boolean reweavableCompressedMode,
boolean reweavableDiffMode) {
this.typeMungers = typeMungers;
this.oldStyle = oldStyle;
this.reweavable = reweavableMode;
this.reweavableCompressedMode = reweavableCompressedMode;
this.reweavableDiffMode = reweavableMode ? reweavableDiffMode : false;
this.aspectsAffectingType = new HashSet();
this.unwovenClassFile = null;
}

public static void setReweavableModeDefaults(boolean mode, boolean compress, boolean diff) {
reweavableDefault = mode;
reweavableCompressedModeDefault = compress;
reweavableDiffModeDefault = diff;
}

private static final int UNTOUCHED = 0, WOVEN = 2, EXTENDED = 3;

// Use 'bits' for these capabilities - only valid in EXTENDED mode
private static final byte REWEAVABLE_BIT = 1 << 4;
private static final byte REWEAVABLE_COMPRESSION_BIT = 1 << 5;
private static final byte REWEAVABLE_DIFF_BIT = 1 << 6;

/** See comments on write() */
public static final WeaverStateInfo read(VersionedDataInputStream s, ISourceContext context) throws IOException {
byte b = s.readByte();

boolean isReweavable = ((b & REWEAVABLE_BIT) != 0);
if (isReweavable) {
b = (byte) (b - REWEAVABLE_BIT);
}

boolean isReweavableCompressed = ((b & REWEAVABLE_COMPRESSION_BIT) != 0);
if (isReweavableCompressed) {
b = (byte) (b - REWEAVABLE_COMPRESSION_BIT);
}

boolean isReweavableDiff = ((b & REWEAVABLE_DIFF_BIT) != 0);
if (isReweavableDiff) {
b = (byte) (b - REWEAVABLE_DIFF_BIT);
}

switch (b) {
case UNTOUCHED:
throw new RuntimeException("unexpected UNWOVEN");
case WOVEN:
return new WeaverStateInfo(Collections.EMPTY_LIST, true, isReweavable, isReweavableCompressed, isReweavableDiff);
case EXTENDED:
int n = s.readShort();
List l = new ArrayList();
for (int i = 0; i < n; i++) {
UnresolvedType aspectType = UnresolvedType.read(s);
ResolvedTypeMunger typeMunger = ResolvedTypeMunger.read(s, context);
l.add(new Entry(aspectType, typeMunger));
}
WeaverStateInfo wsi = new WeaverStateInfo(l, false, isReweavable, isReweavableCompressed, isReweavableDiff);
readAnyReweavableData(wsi, s);
return wsi;
}
throw new RuntimeException("bad WeaverState.Kind: " + b + ". File was :"
+ (context == null ? "unknown" : context.makeSourceLocation(0, 0).toString()));
}

private static class Entry {
public UnresolvedType aspectType;
public ResolvedTypeMunger typeMunger;

public Entry(UnresolvedType aspectType, ResolvedTypeMunger typeMunger) {
this.aspectType = aspectType;
this.typeMunger = typeMunger;
}

public String toString() {
return "<" + aspectType + ", " + typeMunger + ">";
}
}

/**
* Serialize the WeaverStateInfo. Various bits are set within the 'kind' flag to indicate the structure of the attribute. In
* reweavable diff mode a 'marker' is inserted at the start of the attribute to indicate where the final calculated diff should
* be inserted. When the key is replaced with the diff, the 'kind' byte moves to the front of the attribute - thats why in the
* read logic you'll see it expecting the kind as the first byte.
*/
public void write(DataOutputStream s) throws IOException {
if (oldStyle || reweavableCompressedMode) {
throw new RuntimeException("shouldn't be writing this");
}

byte weaverStateInfoKind = EXTENDED;
if (reweavable)
weaverStateInfoKind |= REWEAVABLE_BIT;

if (reweavableDiffMode) {
s.write(key); // put key in so we can replace it with the diff later
weaverStateInfoKind |= REWEAVABLE_DIFF_BIT;
}

s.writeByte(weaverStateInfoKind);

int n = typeMungers.size();
s.writeShort(n);
for (int i = 0; i < n; i++) {
Entry e = (Entry) typeMungers.get(i);
e.aspectType.write(s);
e.typeMunger.write(s);
}
writeAnyReweavableData(this, s);
}

public void addConcreteMunger(ConcreteTypeMunger munger) {
typeMungers.add(new Entry(munger.getAspectType(), munger.getMunger()));
}

public String toString() {
return "WeaverStateInfo(" + typeMungers + ", " + oldStyle + ")";
}

public List getTypeMungers(ResolvedType onType) {
World world = onType.getWorld();
List ret = new ArrayList();
for (Iterator i = typeMungers.iterator(); i.hasNext();) {
Entry entry = (Entry) i.next();
ResolvedType aspectType = world.resolve(entry.aspectType, true);
if (aspectType.isMissing()) {
world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ASPECT_NEEDED, entry.aspectType, onType),
onType.getSourceLocation(), null);
continue;
}

ret.add(new TemporaryTypeMunger(entry.typeMunger, aspectType));
}
return ret;
}

public boolean isOldStyle() {
return oldStyle;
}

public byte[] getUnwovenClassFileData(byte wovenClassFile[]) {
if (unwovenClassFileIsADiff) {
unwovenClassFile = applyDiff(wovenClassFile, unwovenClassFile);
unwovenClassFileIsADiff = false;
}
return unwovenClassFile;
}

public void setUnwovenClassFileData(byte[] data) {
unwovenClassFile = data;
}

public boolean isReweavable() {
return reweavable;
}

public void setReweavable(boolean rw) {
reweavable = rw;
}

public void addAspectsAffectingType(Collection /* String */aspects) {
aspectsAffectingType.addAll(aspects);
}

public void addAspectAffectingType(String aspectType) {
aspectsAffectingType.add(aspectType);
}

public Set /* String */getAspectsAffectingType() {
return this.aspectsAffectingType;
}

private static void readAnyReweavableData(WeaverStateInfo wsi, DataInputStream s) throws IOException {
if (wsi.isReweavable()) {
// Load list of aspects that need to exist in the world for reweaving to be 'legal'
int numberAspectsAffectingType = s.readShort();
for (int i = 0; i < numberAspectsAffectingType; i++) {
wsi.addAspectAffectingType(s.readUTF());
}

int unwovenClassFileSize = s.readInt();
byte[] classData = null;
// the unwovenClassFile may have been compressed:
if (wsi.reweavableCompressedMode) {
classData = new byte[unwovenClassFileSize];
ZipInputStream zis = new ZipInputStream(s);
ZipEntry zen = zis.getNextEntry();
int current = 0;
int bytesToGo = unwovenClassFileSize;
while (bytesToGo > 0) {
int amount = zis.read(classData, current, bytesToGo);
current += amount;
bytesToGo -= amount;
}
zis.closeEntry();
if (bytesToGo != 0)
throw new IOException("ERROR whilst reading compressed reweavable data, expected " + unwovenClassFileSize
+ " bytes, only found " + current);
} else {
classData = new byte[unwovenClassFileSize];
int bytesread = s.read(classData);
if (bytesread != unwovenClassFileSize)
throw new IOException("ERROR whilst reading reweavable data, expected " + unwovenClassFileSize
+ " bytes, only found " + bytesread);
}

// if it was diffMode we'll have to remember to apply the diff if someone
// asks for the unwovenClassFile
wsi.unwovenClassFileIsADiff = wsi.reweavableDiffMode;
wsi.setUnwovenClassFileData(classData);
}
}

/**
* Here is the cleverness for reweavable diff mode. The class file on disk contains, inside the weaverstateinfo attribute, a
* diff that can be applied to 'itself' to recover the original class - which can then be rewoven.
*/
public byte[] replaceKeyWithDiff(byte wovenClassFile[]) {
// we couldn't have made the diff earlier
// as we didn't have the wovenClassFile
// so we left a key there as a marker to come back to

if (reweavableDiffMode) {
ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
DataOutputStream s = new DataOutputStream(arrayStream);

int endOfKey = findEndOfKey(wovenClassFile);
int startOfKey = endOfKey - key.length;
// the length of the wsi attribute is written infront of it in the classFile,
// swapping the diff for the key will probably change the length of the wsi,
// so we'll have to fiddle with the four 'int length' bytes
int oldLengthLocation = startOfKey - 4;
int oldLength = readInt(wovenClassFile, oldLengthLocation);
wovenClassFile = deleteInArray(wovenClassFile, startOfKey, endOfKey); // delete the key

byte[] wovenClassFileUpToWSI = new byte[oldLengthLocation];
System.arraycopy(wovenClassFile, 0, wovenClassFileUpToWSI, 0, oldLengthLocation);

byte[] diff = generateDiff(wovenClassFileUpToWSI, unwovenClassFile);
try { // put the length of the diff infront of the diff
s.writeInt(diff.length);
s.write(diff);
} catch (IOException e) {
}
diff = arrayStream.toByteArray();
// we have to swap the oldLength for the new one,
// and add the diff, using the oldLength to work out where it should go :)

int newLength = oldLength - key.length + diff.length;
byte newLengthBytes[] = serializeInt(newLength);

// swap in the serialized newLength for the oldOne:
wovenClassFile[oldLengthLocation] = newLengthBytes[0];
wovenClassFile[oldLengthLocation + 1] = newLengthBytes[1];
wovenClassFile[oldLengthLocation + 2] = newLengthBytes[2];
wovenClassFile[oldLengthLocation + 3] = newLengthBytes[3];

// add the diff
wovenClassFile = insertArray(diff, wovenClassFile, oldLengthLocation + 4 + oldLength - key.length);
}
return wovenClassFile;
}

private static final int findEndOfKey(byte[] wovenClassFile) {
// looks through the classfile backwards (as the attributes are all near the end)
for (int i = wovenClassFile.length - 1; i > 0; i--)
if (endOfKeyHere(wovenClassFile, i)) {
return i + 1;
}
throw new RuntimeException("key not found in wovenClassFile"); // should never happen
}

private static final boolean endOfKeyHere(byte lookIn[], int i) {
for (int j = 0; j < key.length; j++)
if (key[key.length - 1 - j] != lookIn[i - j]) {
return false;
}
return true;
}

private static final byte[] insertArray(byte toInsert[], byte original[], int offset) {
byte result[] = new byte[original.length + toInsert.length];
System.arraycopy(original, 0, result, 0, offset);
System.arraycopy(toInsert, 0, result, offset, toInsert.length);
System.arraycopy(original, offset, result, offset + toInsert.length, original.length - offset);
return result;
}

private static final int readInt(byte[] a, int offset) {
ByteArrayInputStream b = new ByteArrayInputStream(a, offset, 4);
DataInputStream d = new DataInputStream(b);
int length = -1;
try {
length = d.readInt();
} catch (IOException e) {
throw (new RuntimeException("readInt called with a bad array or offset")); // should never happen
}
return length;
}

private static final byte[] deleteInArray(byte a[], int start, int end) {
int lengthToDelete = end - start;
byte result[] = new byte[a.length - lengthToDelete]; // make a new array
System.arraycopy(a, 0, result, 0, start); // copy in the bit before the deleted bit
System.arraycopy(a, end, result, start, a.length - end); // copy in the bit after the deleted bit
return result;
}

// ajh02: a quick note about the diff format...
//
// classfiles consist of:
// 8 bytes: magic number and minor and major versions,
// 2 bytes: its constant pool count
// n bytes: the rest of the class file
//
// weaving a classfile never changes the classfile's first 8 bytes,
// and after the constant pool count there's usually a run of bytes that weaving didn't change
// hereafter referred to as the run
//
// so the diff consists of:
// 2 bytes: its constant pool count
// 4 bytes: length of the run
// n bytes: the rest of the unwovenClassFile

byte[] generateDiff(byte[] wovenClassFile, byte[] unWovenClassFile) {

// find how long the run is
int lookingAt = 10;
int shorterLength = (wovenClassFile.length < unWovenClassFile.length) ? wovenClassFile.length : unWovenClassFile.length;
while (lookingAt < shorterLength && (wovenClassFile[lookingAt] == unWovenClassFile[lookingAt])) {
lookingAt++;
}
int lengthInCommon = lookingAt - 10;
byte[] diff = new byte[unWovenClassFile.length - 4 - lengthInCommon];

// first 2 bytes of the diff are the constant pool count
diff[0] = unWovenClassFile[8];
diff[1] = unWovenClassFile[9];

// then 4 bytes saying how long the run is
byte[] lengthInCommonBytes = serializeInt(lengthInCommon);
diff[2] = lengthInCommonBytes[0];
diff[3] = lengthInCommonBytes[1];
diff[4] = lengthInCommonBytes[2];
diff[5] = lengthInCommonBytes[3];

// then we just dump the rest of the unWovenClassFile verbatim
System.arraycopy(unWovenClassFile, 10 + lengthInCommon, diff, 6, diff.length - 6);

return diff;
}

byte[] applyDiff(byte[] wovenClassFile, byte[] diff) {

int lengthInCommon = readInt(diff, 2);
byte[] unWovenClassFile = new byte[4 + diff.length + lengthInCommon];

// copy the first 8 bytes from the wovenClassFile
System.arraycopy(wovenClassFile, 0, unWovenClassFile, 0, 8);

// copy the constant pool count from the diff
unWovenClassFile[8] = diff[0];
unWovenClassFile[9] = diff[1];

// copy the run from the wovenClassFile
System.arraycopy(wovenClassFile, 10, unWovenClassFile, 10, lengthInCommon);

// copy the stuff after the run from the diff
System.arraycopy(diff, 6, unWovenClassFile, 10 + lengthInCommon, diff.length - 6);

return unWovenClassFile;
}

private byte[] serializeInt(int i) {
ByteArrayOutputStream bos = new ByteArrayOutputStream(4);
DataOutputStream dos = new DataOutputStream(bos);
try {
dos.writeInt(i);
} catch (IOException e) {
}
return bos.toByteArray();
}

private static void writeAnyReweavableData(WeaverStateInfo wsi, DataOutputStream s) throws IOException {
if (wsi.isReweavable()) {
// Write out list of aspects that must exist next time we try and weave this class
s.writeShort(wsi.aspectsAffectingType.size());
if (wsi.aspectsAffectingType.size() > 0) {
for (Iterator iter = wsi.aspectsAffectingType.iterator(); iter.hasNext();) {
String type = (String) iter.next();
s.writeUTF(type);
}
}
byte[] data = wsi.unwovenClassFile;

// if we're not in diffMode, write the unwovenClassFile now,
// otherwise we'll insert it as a diff later
if (!wsi.reweavableDiffMode) {
s.writeInt(data.length);
s.write(wsi.unwovenClassFile);
}
}
}

}

+ 69
- 0
org.aspectj.matcher/src/org/aspectj/weaver/WildcardedUnresolvedType.java Переглянути файл

@@ -0,0 +1,69 @@
/* *******************************************************************
* 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;

/**
* Represents a wildcarded bound for a generic type, this can be unbounded '?' or bounded via extends '? extends Foo' or
* super '? super Foo'. The signature for a ? is in fact "*" and the erasure signature is the upper bound which defaults
* to java.lang.Object if nothing is specified. On resolution, this becomes a BoundedReferenceType
*
* @author Andy Clement
*/
public class WildcardedUnresolvedType extends UnresolvedType {

// TODO does not cope with extra bounds '? extends A & B & C'
public static final int UNBOUND = 0;

public static final int EXTENDS = 1;

public static final int SUPER = 2;
public static final WildcardedUnresolvedType QUESTIONMARK = new WildcardedUnresolvedType("*", UnresolvedType.OBJECT, null);

private int boundKind = UNBOUND; // UNBOUND, EXTENDS, SUPER

private UnresolvedType lowerBound;

private UnresolvedType upperBound;

public WildcardedUnresolvedType(String signature, UnresolvedType upperBound, UnresolvedType lowerBound) {
super(signature, (upperBound == null ? UnresolvedType.OBJECT.signature : upperBound.signatureErasure));
this.typeKind = TypeKind.WILDCARD;
this.upperBound = upperBound;
this.lowerBound = lowerBound;
if (signature.charAt(0) == '-') boundKind = SUPER;
if (signature.charAt(0) == '+') boundKind = EXTENDS;
}

public UnresolvedType getUpperBound() {
return upperBound;
}

public UnresolvedType getLowerBound() {
return lowerBound;
}

public boolean isExtends() {
return boundKind == EXTENDS;
}

public boolean isSuper() {
return boundKind == SUPER;
}

public boolean isUnbound() {
return boundKind == UNBOUND;
}


}

+ 1286
- 0
org.aspectj.matcher/src/org/aspectj/weaver/World.java
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 47
- 0
org.aspectj.matcher/src/org/aspectj/weaver/XlintDefault.properties Переглянути файл

@@ -0,0 +1,47 @@
invalidAbsoluteTypeName = warning
invalidWildcardTypeName = ignore

unresolvableMember = warning

typeNotExposedToWeaver = warning

shadowNotInStructure = ignore

unmatchedSuperTypeInCall = warning

canNotImplementLazyTjp = ignore
multipleAdviceStoppingLazyTjp=ignore
noGuardForLazyTjp=ignore

uncheckedAdviceConversion = warning

needsSerialVersionUIDField = ignore
brokeSerialVersionCompatibility = ignore

noInterfaceCtorJoinpoint = warning

noJoinpointsForBridgeMethods = warning
cantMatchArrayTypeOnVarargs = ignore
enumAsTargetForDecpIgnored = warning
annotationAsTargetForDecpIgnored = warning
adviceDidNotMatch = warning
invalidTargetForAnnotation = warning
elementAlreadyAnnotated = warning
runtimeExceptionNotSoftened = warning
uncheckedArgument = warning
noExplicitConstructorCall = warning

aspectExcludedByConfiguration = ignore

unmatchedTargetKind = warning

cantFindType = error
cantFindTypeAffectingJPMatch = warning

unorderedAdviceAtShadow=ignore
swallowedExceptionInCatchBlock=ignore
calculatingSerialVersionUID=ignore
advisingSynchronizedMethods=warning
mustWeaveXmlDefinedAspects=warning

missingAspectForReweaving=error

+ 22
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/ASTNode.java Переглянути файл

@@ -0,0 +1,22 @@
/* *******************************************************************
* 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.ast;

public abstract class ASTNode {

public ASTNode() {
super();
}

}

+ 51
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/And.java Переглянути файл

@@ -0,0 +1,51 @@
/* *******************************************************************
* 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.ast;


public class And extends Test {
Test left, right;

public And(Test left, Test right) {
super();
this.left = left;
this.right = right;
}

public void accept(ITestVisitor v) {
v.visit(this);
}
public String toString() {
return "(" + left + " && " + right + ")";
}

public boolean equals(Object other) {
if (other instanceof And) {
And o = (And) other;
return o.left.equals(left) && o.right.equals(right);
} else {
return false;
}
}

public Test getLeft() {
return left;
}

public Test getRight() {
return right;
}

}

+ 41
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/Call.java Переглянути файл

@@ -0,0 +1,41 @@
/* *******************************************************************
* 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.ast;

import org.aspectj.weaver.Member;

public class Call extends Test {
// assert m.return value is boolean
private final Member method;
private final Expr[] args;

public Call(Member m, Expr[] args) {
super();
this.method = m;
this.args = args;
}

public void accept(ITestVisitor v) {
v.visit(this);
}

public Expr[] getArgs() {
return args;
}

public Member getMethod() {
return method;
}

}

+ 48
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/CallExpr.java Переглянути файл

@@ -0,0 +1,48 @@
/* *******************************************************************
* 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.ast;

import org.aspectj.weaver.Member;
import org.aspectj.weaver.ResolvedType;

public class CallExpr extends Expr {
// assert m.return value is boolean
private final Member method;
private final Expr[] args;
private final ResolvedType returnType; // yes, stored in method as well, but that one isn't resolved

public CallExpr(Member m, Expr[] args, ResolvedType returnType) {
super();
this.method = m;
this.args = args;
this.returnType = returnType;
}

public void accept(IExprVisitor v) {
v.visit(this);
}

public Expr[] getArgs() {
return args;
}

public Member getMethod() {
return method;
}

public ResolvedType getType() {
return returnType;
}

}

+ 34
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/Expr.java Переглянути файл

@@ -0,0 +1,34 @@
/* *******************************************************************
* 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.ast;

import org.aspectj.weaver.Member;
import org.aspectj.weaver.ResolvedType;

public abstract class Expr extends ASTNode {

public Expr() {
super();
}

public static final Expr[] NONE = new Expr[0];

public abstract void accept(IExprVisitor v);

public abstract ResolvedType getType();

public static CallExpr makeCallExpr(Member member, Expr[] exprs, ResolvedType returnType) {
return new CallExpr(member, exprs, returnType);
}

}

+ 44
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/FieldGet.java Переглянути файл

@@ -0,0 +1,44 @@
/* *******************************************************************
* 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.ast;

import org.aspectj.weaver.Member;
import org.aspectj.weaver.ResolvedType;

public class FieldGet extends Expr {
Member field;
ResolvedType resolvedType;

public FieldGet(Member field, ResolvedType resolvedType) {
super();
this.field = field;
this.resolvedType = resolvedType;
}

public ResolvedType getType() {
return resolvedType;
}

public String toString() {
return "(FieldGet " + field + ")";
}

public void accept(IExprVisitor v) {
v.visit(this);
}

public Member getField() {
return field;
}

}

+ 47
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/FieldGetCall.java Переглянути файл

@@ -0,0 +1,47 @@
/* *******************************************************************
* 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.ast;

import org.aspectj.weaver.Member;

public class FieldGetCall extends Test {
// assert m.return value is boolean
private final Member field;
private final Member method;
private final Expr[] args;

public FieldGetCall(Member f, Member m, Expr[] args) {
super();
this.field = f;
this.method = m;
this.args = args;
}

public void accept(ITestVisitor v) {
v.visit(this);
}

public Expr[] getArgs() {
return args;
}

public Member getMethod() {
return method;
}

public Member getField() {
return field;
}

}

+ 59
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/HasAnnotation.java Переглянути файл

@@ -0,0 +1,59 @@
/*******************************************************************************
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.weaver.ast;

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

public class HasAnnotation extends Test {

private Var v;
private ResolvedType annType;
public HasAnnotation(Var v, ResolvedType annType) {
super();
this.v = v;
this.annType = annType;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.ast.Test#accept(org.aspectj.weaver.ast.ITestVisitor)
*/
public void accept(ITestVisitor v) {
v.visit(this);
}

public String toString() {
return "(" + v + " has annotation @" + annType + ")";
}

public boolean equals(Object other) {
if (other instanceof HasAnnotation) {
HasAnnotation o = (HasAnnotation) other;
return o.v.equals(v) && o.annType.equals(annType);
} else {
return false;
}
}
public int hashCode() {
return v.hashCode()*37+annType.hashCode();
}

public Var getVar() {
return v;
}

public UnresolvedType getAnnotationType() {
return annType;
}
}

+ 23
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/IExprVisitor.java Переглянути файл

@@ -0,0 +1,23 @@
/* *******************************************************************
* 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.ast;

public interface IExprVisitor {

void visit(Var i);

void visit(FieldGet fieldGet);

void visit(CallExpr callExpr);

}

+ 0
- 0
org.aspectj.matcher/src/org/aspectj/weaver/ast/ITestVisitor.java Переглянути файл


Деякі файли не було показано, через те що забагато файлів було змінено

Завантаження…
Відмінити
Зберегти