diff options
author | aclement <aclement> | 2008-08-31 20:25:13 +0000 |
---|---|---|
committer | aclement <aclement> | 2008-08-31 20:25:13 +0000 |
commit | 8c37e52c5a50fb145215817403efdd1bcb82d3db (patch) | |
tree | 0d31d9d53378e9217a4540d06cebc187581d20db | |
parent | 64709897b88148635900ed94f6b633f53d4ff19f (diff) | |
download | aspectj-8c37e52c5a50fb145215817403efdd1bcb82d3db.tar.gz aspectj-8c37e52c5a50fb145215817403efdd1bcb82d3db.zip |
removing unused code
20 files changed, 7128 insertions, 7577 deletions
diff --git a/weaver/src/org/aspectj/weaver/Advice.java b/weaver/src/org/aspectj/weaver/Advice.java index 6efb959af..731ee9b86 100644 --- a/weaver/src/org/aspectj/weaver/Advice.java +++ b/weaver/src/org/aspectj/weaver/Advice.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver; import java.util.Collections; @@ -29,74 +28,70 @@ 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; - - // 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 - - 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()); + protected AdviceKind kind; // alias of attribute.getKind() + protected Member signature; + + // 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 + + 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; this.kind = attribute.getKind(); // alias this.signature = signature; @@ -105,142 +100,129 @@ public abstract class Advice extends ShadowMunger { } else { this.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), + 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), + 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), + 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()); + 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()); + } 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), + } 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; - } - } - } - } - return true; - } else { - return false; - } + 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 + * 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); + 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 (!Utility.isSuppressing(getSignature().getAnnotations(), "uncheckedArgument")) { - world.getLint().uncheckedArgument.signal( - new String[] { - afterReturningType.getSimpleName(), - uncheckedMatchWith, - afterReturningType.getSimpleBaseName(), - shadow.toResolvedString(world)}, - getSourceLocation(), - new ISourceLocation[] {shadow.getSourceLocation()}); - } - } + world.getLint().uncheckedArgument.signal(new String[] { afterReturningType.getSimpleName(), uncheckedMatchWith, + afterReturningType.getSimpleBaseName(), shadow.toResolvedString(world) }, getSourceLocation(), + new ISourceLocation[] { shadow.getSourceLocation() }); + } + } } // ---- @@ -252,14 +234,7 @@ public abstract class Advice extends ShadowMunger { public Member getSignature() { return signature; } - - // only called as part of parameterization.... - public void setSignature(Member signature) { - this.signature = signature; - // reset hashCode value so it can be recalculated next time - hashCode = 0; - } - + public boolean hasExtraParameter() { return (getExtraParameterFlags() & ExtraArgument) != 0; } @@ -271,20 +246,25 @@ public abstract class Advice extends ShadowMunger { protected int getExtraParameterCount() { return countOnes(getExtraParameterFlags() & ParameterMask); } - - public UnresolvedType[] getBindingParameterTypes() { return this.bindingParameterTypes; } - - public void setBindingParameterTypes(UnresolvedType[] types) { this.bindingParameterTypes = types; } - + + public UnresolvedType[] getBindingParameterTypes() { + return this.bindingParameterTypes; + } + + public void setBindingParameterTypes(UnresolvedType[] types) { + this.bindingParameterTypes = types; + } + public static int countOnes(int bits) { int ret = 0; while (bits != 0) { - if ((bits & 1) != 0) ret += 1; + if ((bits & 1) != 0) + ret += 1; bits = bits >> 1; } return ret; } - + public int getBaseParameterCount() { return getSignature().getParameterTypes().length - getExtraParameterCount(); } @@ -292,82 +272,85 @@ public abstract class Advice extends ShadowMunger { public String[] getBaseParameterNames(World world) { String[] allNames = getSignature().getParameterNames(world); int extras = getExtraParameterCount(); - if (extras == 0) return allNames; + 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 (!hasExtraParameter()) + return ResolvedType.MISSING; if (signature instanceof ResolvedMember) { if (getConcreteAspect().isAnnotationStyleAspect()) { - // bug 122742 - if we're an annotation style aspect then one + // 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(); + 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))) { + || genericParameterTypes[baseParmCnt].equals(AjcMemberMaker.TYPEX_STATICJOINPOINT) || genericParameterTypes[baseParmCnt] + .equals(AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT))) { baseParmCnt++; } - return ((ResolvedMember)signature).getGenericParameterTypes()[baseParmCnt]; + return ((ResolvedMember) signature).getGenericParameterTypes()[baseParmCnt]; } - return ((ResolvedMember)signature).getGenericParameterTypes()[getBaseParameterCount()]; + return ((ResolvedMember) signature).getGenericParameterTypes()[getBaseParameterCount()]; } else { return signature.getParameterTypes()[getBaseParameterCount()]; } } - + public UnresolvedType getDeclaringAspect() { return getOriginalSignature().getDeclaringType(); } - protected Member getOriginalSignature() { + 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; - } - + + /** + * @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.createAdviceMunger(attribute, p, signature); munger.concreteAspect = fromType; munger.bindingParameterTypes = this.bindingParameterTypes; munger.setDeclaringType(getDeclaringType()); - //System.err.println("concretizing here " + p + " with clause " + clause); - return munger; - } + // System.err.println("concretizing here " + p + " with clause " + clause); + return munger; + } // ---- from object @@ -376,54 +359,55 @@ public abstract class Advice extends ShadowMunger { sb.append("(").append(getKind()).append(extraParametersToString()); sb.append(": ").append(pointcut).append("->").append(signature).append(")"); return sb.toString(); -// return "(" -// + getKind() -// + extraParametersToString() -// + ": " -// + pointcut -// + "->" -// + signature -// + ")"; + // 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 - ; - - } + 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; + + 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 + 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; + public static final int CanInline = 0x40; - // for testing only + // for testing only public void setLexicalPosition(int lexicalPosition) { start = lexicalPosition; } @@ -431,5 +415,5 @@ public abstract class Advice extends ShadowMunger { public ResolvedType getConcreteAspect() { return concreteAspect; } - + } diff --git a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java index 219d365ac..d556fb935 100644 --- a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java +++ b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver; import java.lang.reflect.Modifier; @@ -19,299 +18,198 @@ import org.aspectj.lang.JoinPoint; //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 PUBLIC_STATIC_FINAL = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL; + + private static final int PRIVATE_STATIC = Modifier.PRIVATE | Modifier.STATIC; - private static final int PRIVATE_STATIC = - Modifier.PRIVATE | Modifier.STATIC; + private static final int PUBLIC_STATIC = Modifier.PUBLIC | Modifier.STATIC; - private static final int PUBLIC_STATIC = - Modifier.PUBLIC | Modifier.STATIC; + private static final int VISIBILITY = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED; - 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 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 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"); + 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"); + 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"); - } - + 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"); + 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"); + 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"); - } - + 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()); + 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()); + 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, + 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); - } - + 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); + return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, aspectType, NameMangler + .perTypeWithinFieldForTarget(aspectType), UnresolvedType.NONE); } - - // PTWIMPL ResolvedMember for type instance field, declared in aspect + + // 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.forSignature("Ljava/lang/String;"), NameMangler.PERTYPEWITHIN_WITHINTYPEFIELD, UnresolvedType.NONE); + return new ResolvedMemberImpl(Member.FIELD, declaringType, modifiers, UnresolvedType.forSignature("Ljava/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"); - } - + 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} - ); + // 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 - ); + 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; + 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"); + 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()); + 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"); - } - + 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 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"); + 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()); + 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"); + 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) { + 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[]{}); - }*/ - + 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; @@ -320,32 +218,21 @@ public class AjcMemberMaker { } 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"); - } - + 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()); + 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()) { @@ -353,15 +240,12 @@ public class AjcMemberMaker { } 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); - } - + + 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()) { @@ -369,43 +253,33 @@ public class AjcMemberMaker { } 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); - } - + + 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 + // ??? 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()); - } - + 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()); - } - + 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()) { @@ -413,15 +287,12 @@ public class AjcMemberMaker { } 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); - } - + + 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()) { @@ -429,125 +300,64 @@ public class AjcMemberMaker { } 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); - } - + 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;"); + 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"); + 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"); + 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"); + 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;"); + 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)); + 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) { @@ -556,14 +366,12 @@ public class AjcMemberMaker { 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" - ); + 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 @@ -571,263 +379,232 @@ public class AjcMemberMaker { 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()} - ); + 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 - ); + 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; -// } - - + + // 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 - ); - } - - + 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 + * 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 - ); + 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 + * 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 - ); + 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 + * 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 - ); + 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. + * 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; - + 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()); + 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()' + * 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()); + + 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. + * 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) - { + 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()); - + + 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. + * 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) - { + 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()); + + 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()); + 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); + 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"); + 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 + // -- 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 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 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 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 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 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 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 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 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 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 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 DECLAREPARENTS_ANNOTATION = UnresolvedType.forSignature("Lorg/aspectj/lang/annotation/DeclareParents;"); + public final static UnresolvedType TYPEX_JOINPOINT = UnresolvedType.forSignature("Lorg/aspectj/lang/JoinPoint;");// UnresolvedType + // .forName( + // JoinPoint + // .class. + // getName + // (). + // replace + // ('/' + // ,'.')); - public final static UnresolvedType TYPEX_JOINPOINT = UnresolvedType.forSignature("Lorg/aspectj/lang/JoinPoint;");// UnresolvedType.forName(JoinPoint.class.getName().replace('/','.')); + public final static UnresolvedType TYPEX_PROCEEDINGJOINPOINT = UnresolvedType + .forSignature("Lorg/aspectj/lang/ProceedingJoinPoint;");// UnresolvedType.forName(ProceedingJoinPoint.class.getName(). + // replace('/','.')); - public final static UnresolvedType TYPEX_PROCEEDINGJOINPOINT = UnresolvedType.forSignature("Lorg/aspectj/lang/ProceedingJoinPoint;");// UnresolvedType.forName(ProceedingJoinPoint.class.getName().replace('/','.')); - - public final static UnresolvedType TYPEX_STATICJOINPOINT = UnresolvedType.forName(JoinPoint.StaticPart.class.getName().replace('/','.')); - public final static UnresolvedType TYPEX_ENCLOSINGSTATICJOINPOINT = UnresolvedType.forName(JoinPoint.EnclosingStaticPart.class.getName().replace('/','.')); + public final static UnresolvedType TYPEX_STATICJOINPOINT = UnresolvedType.forName(JoinPoint.StaticPart.class.getName().replace( + '/', '.')); + public final static UnresolvedType TYPEX_ENCLOSINGSTATICJOINPOINT = UnresolvedType.forName(JoinPoint.EnclosingStaticPart.class + .getName().replace('/', '.')); } diff --git a/weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java b/weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java index b955cc859..e42b93501 100644 --- a/weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java +++ b/weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver; import java.util.Iterator; @@ -30,196 +29,202 @@ import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.SourceLocation; import org.aspectj.weaver.bcel.BcelAdvice; - public class AsmRelationshipProvider { - - protected static AsmRelationshipProvider INSTANCE = new AsmRelationshipProvider(); - + + protected static AsmRelationshipProvider INSTANCE = new AsmRelationshipProvider(); + public static final String ADVISES = "advises"; public static final String ADVISED_BY = "advised by"; public static final String DECLARES_ON = "declares on"; public static final String DECLAREDY_BY = "declared by"; - public static final String SOFTENS = "softens"; - public static final String SOFTENED_BY = "softened by"; - public static final String MATCHED_BY = "matched by"; + public static final String SOFTENS = "softens"; + public static final String SOFTENED_BY = "softened by"; + public static final String MATCHED_BY = "matched by"; public static final String MATCHES_DECLARE = "matches declare"; public static final String INTER_TYPE_DECLARES = "declared on"; public static final String INTER_TYPE_DECLARED_BY = "aspect declarations"; - + public static final String ANNOTATES = "annotates"; public static final String ANNOTATED_BY = "annotated by"; - + public void checkerMunger(IHierarchy model, Shadow shadow, Checker checker) { - if (!AsmManager.isCreatingModel()) return; - if (shadow.getSourceLocation() == null || checker.getSourceLocation() == null) return; + if (!AsmManager.isCreatingModel()) + return; + if (shadow.getSourceLocation() == null || checker.getSourceLocation() == null) + return; if (World.createInjarHierarchy) { checker.createHierarchy(); } - + // Ensure a node for the target exists - IProgramElement targetNode = getNode(AsmManager.getDefault().getHierarchy(),shadow); - if (targetNode == null) return; - String targetHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(targetNode); - if (targetHandle == null) return; - - IProgramElement sourceNode = AsmManager.getDefault().getHierarchy() - .findElementForSourceLine(checker.getSourceLocation()); - String sourceHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(sourceNode); - if (sourceHandle == null) return; - + IProgramElement targetNode = getNode(AsmManager.getDefault().getHierarchy(), shadow); + if (targetNode == null) + return; + String targetHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(targetNode); + if (targetHandle == null) + return; + + IProgramElement sourceNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(checker.getSourceLocation()); + String sourceHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceNode); + if (sourceHandle == null) + return; + IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); - IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE, MATCHED_BY,false,true); + IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE, MATCHED_BY, false, true); foreward.addTarget(targetHandle); - - IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, MATCHES_DECLARE,false,true); + + IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, MATCHES_DECLARE, false, true); if (back != null && back.getTargets() != null) { back.addTarget(sourceHandle); } } - // For ITDs - public void addRelationship( - ResolvedType onType, - ResolvedTypeMunger munger, - ResolvedType originatingAspect) { + // For ITDs + public void addRelationship(ResolvedType onType, ResolvedTypeMunger munger, ResolvedType originatingAspect) { - if (!AsmManager.isCreatingModel()) return; + if (!AsmManager.isCreatingModel()) + return; if (originatingAspect.getSourceLocation() != null) { String sourceHandle = ""; - if (munger.getSourceLocation()!=null && munger.getSourceLocation().getOffset()!=-1) { - IProgramElement sourceNode = AsmManager.getDefault().getHierarchy() - .findElementForSourceLine(munger.getSourceLocation()); - sourceHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(sourceNode); + if (munger.getSourceLocation() != null && munger.getSourceLocation().getOffset() != -1) { + IProgramElement sourceNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine( + munger.getSourceLocation()); + sourceHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceNode); } else { - IProgramElement sourceNode = AsmManager.getDefault().getHierarchy() - .findElementForSourceLine(originatingAspect.getSourceLocation()); - sourceHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(sourceNode); + IProgramElement sourceNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine( + originatingAspect.getSourceLocation()); + sourceHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceNode); } - if (sourceHandle == null) return; + if (sourceHandle == null) + return; IProgramElement targetNode = AsmManager.getDefault().getHierarchy() .findElementForSourceLine(onType.getSourceLocation()); - String targetHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(targetNode); - if (targetHandle == null) return; - + String targetHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(targetNode); + if (targetHandle == null) + return; + IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); - IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES,false,true); + IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES, false, + true); foreward.addTarget(targetHandle); - - IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY,false,true); + + IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY, false, + true); back.addTarget(sourceHandle); } } - - public void addDeclareParentsRelationship(ISourceLocation decp,ResolvedType targetType, List newParents) { - if (!AsmManager.isCreatingModel()) return; - - IProgramElement sourceNode = AsmManager.getDefault().getHierarchy() - .findElementForSourceLine(decp); - String sourceHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(sourceNode); - if (sourceHandle == null) return; - + + public void addDeclareParentsRelationship(ISourceLocation decp, ResolvedType targetType, List newParents) { + if (!AsmManager.isCreatingModel()) + return; + + IProgramElement sourceNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(decp); + String sourceHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceNode); + if (sourceHandle == null) + return; + IProgramElement targetNode = AsmManager.getDefault().getHierarchy() .findElementForSourceLine(targetType.getSourceLocation()); - String targetHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(targetNode); - if (targetHandle == null) return; - + String targetHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(targetNode); + if (targetHandle == null) + return; + IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); - IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES,false,true); + IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARES, false, true); foreward.addTarget(targetHandle); - - IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY,false,true); + + IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, INTER_TYPE_DECLARED_BY, false, true); back.addTarget(sourceHandle); } - + /** - * Adds a declare annotation relationship, sometimes entities don't have source locs (methods/fields) so use other - * variants of this method if that is the case as they will look the entities up in the structure model. + * Adds a declare annotation relationship, sometimes entities don't have source locs (methods/fields) so use other variants of + * this method if that is the case as they will look the entities up in the structure model. */ - public void addDeclareAnnotationRelationship(ISourceLocation declareAnnotationLocation,ISourceLocation annotatedLocation) { - if (!AsmManager.isCreatingModel()) return; - - IProgramElement sourceNode = AsmManager.getDefault().getHierarchy() - .findElementForSourceLine(declareAnnotationLocation); - String sourceHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(sourceNode); - if (sourceHandle == null) return; - - IProgramElement targetNode = AsmManager.getDefault().getHierarchy() - .findElementForSourceLine(annotatedLocation); - String targetHandle = AsmManager.getDefault().getHandleProvider() - .createHandleIdentifier(targetNode); - if (targetHandle == null) return; - + public void addDeclareAnnotationRelationship(ISourceLocation declareAnnotationLocation, ISourceLocation annotatedLocation) { + if (!AsmManager.isCreatingModel()) + return; + + IProgramElement sourceNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(declareAnnotationLocation); + String sourceHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceNode); + if (sourceHandle == null) + return; + + IProgramElement targetNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(annotatedLocation); + String targetHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(targetNode); + if (targetHandle == null) + return; + IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); - IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES,false,true); + IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true); foreward.addTarget(targetHandle); - - IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY,false,true); + + IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true); back.addTarget(sourceHandle); } - + public void adviceMunger(IHierarchy model, Shadow shadow, ShadowMunger munger) { - if (!AsmManager.isCreatingModel()) return; + if (!AsmManager.isCreatingModel()) + return; if (munger instanceof Advice) { - Advice advice = (Advice)munger; - + Advice advice = (Advice) munger; + if (advice.getKind().isPerEntry() || advice.getKind().isCflow()) { // TODO: might want to show these in the future return; } - + if (World.createInjarHierarchy) { munger.createHierarchy(); } IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); IProgramElement targetNode = getNode(AsmManager.getDefault().getHierarchy(), shadow); - if (targetNode == null) return; - boolean runtimeTest = ((BcelAdvice)munger).hasDynamicTests(); - + if (targetNode == null) + return; + boolean runtimeTest = ((BcelAdvice) munger).hasDynamicTests(); + // Work out extra info to inform interested UIs ! IProgramElement.ExtraInformation ai = new IProgramElement.ExtraInformation(); - String adviceHandle = advice.getHandle(); - if (adviceHandle == null) return; - + String adviceHandle = advice.getHandle(); + if (adviceHandle == null) + return; + // What kind of advice is it? // TODO: Prob a better way to do this but I just want to // get it into CVS !!! - AdviceKind ak = ((Advice)munger).getKind(); + AdviceKind ak = ((Advice) munger).getKind(); ai.setExtraAdviceInformation(ak.getName()); IProgramElement adviceElement = AsmManager.getDefault().getHierarchy().findElementForHandle(adviceHandle); if (adviceElement != null) { - adviceElement.setExtraInfo(ai); + adviceElement.setExtraInfo(ai); + } + String targetHandle = targetNode.getHandleIdentifier(); + if (advice.getKind().equals(AdviceKind.Softener)) { + IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.DECLARE_SOFT, SOFTENS, runtimeTest, true); + if (foreward != null) + foreward.addTarget(targetHandle);// foreward.getTargets().add(targetHandle); + + IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, SOFTENED_BY, runtimeTest, true); + if (back != null) + back.addTarget(adviceHandle);// back.getTargets().add(adviceHandle); + } else { + IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.ADVICE, ADVISES, runtimeTest, true); + if (foreward != null) + foreward.addTarget(targetHandle);// foreward.getTargets().add(targetHandle); + + IRelationship back = mapper.get(targetHandle, IRelationship.Kind.ADVICE, ADVISED_BY, runtimeTest, true); + if (back != null) + back.addTarget(adviceHandle);// back.getTargets().add(adviceHandle); } - String targetHandle = targetNode.getHandleIdentifier(); - if (advice.getKind().equals(AdviceKind.Softener)) { - IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.DECLARE_SOFT, SOFTENS,runtimeTest,true); - if (foreward != null) foreward.addTarget(targetHandle);//foreward.getTargets().add(targetHandle); - - IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE, SOFTENED_BY,runtimeTest,true); - if (back != null) back.addTarget(adviceHandle);//back.getTargets().add(adviceHandle); - } else { - IRelationship foreward = mapper.get(adviceHandle, IRelationship.Kind.ADVICE, ADVISES,runtimeTest,true); - if (foreward != null) foreward.addTarget(targetHandle);//foreward.getTargets().add(targetHandle); - - IRelationship back = mapper.get(targetHandle, IRelationship.Kind.ADVICE, ADVISED_BY,runtimeTest,true); - if (back != null) back.addTarget(adviceHandle);//back.getTargets().add(adviceHandle); - } } } protected IProgramElement getNode(IHierarchy model, Shadow shadow) { Member enclosingMember = shadow.getEnclosingCodeSignature(); - + IProgramElement enclosingNode = lookupMember(model, enclosingMember); if (enclosingNode == null) { Lint.Kind err = shadow.getIWorld().getLint().shadowNotInStructure; @@ -228,241 +233,230 @@ public class AsmRelationshipProvider { } return null; } - + Member shadowSig = shadow.getSignature(); // pr235204 - if (shadow.getKind() == Shadow.MethodCall || - !shadowSig.equals(enclosingMember)) { + if (shadow.getKind() == Shadow.MethodCall || !shadowSig.equals(enclosingMember)) { IProgramElement bodyNode = findOrCreateCodeNode(enclosingNode, shadowSig, shadow); return bodyNode; } else { return enclosingNode; } } - - private boolean sourceLinesMatch(ISourceLocation loc1,ISourceLocation loc2) { - if (loc1.getLine()!=loc2.getLine()) return false; + + private boolean sourceLinesMatch(ISourceLocation loc1, ISourceLocation loc2) { + if (loc1.getLine() != loc2.getLine()) + return false; return true; } - + /** - * Finds or creates a code IProgramElement for the given shadow. + * Finds or creates a code IProgramElement for the given shadow. * - * The byteCodeName of the created node is set to 'shadowSig.getName() + "!" + counter', - * eg "println!3". The counter is the occurence count of children within - * the enclosingNode which have the same name. So, for example, if a method - * contains two System.out.println statements, the first one will have - * byteCodeName 'println!1' and the second will have byteCodeName 'println!2'. - * This is to ensure the two nodes have unique handles when the handles - * do not depend on sourcelocations. + * The byteCodeName of the created node is set to 'shadowSig.getName() + "!" + counter', eg "println!3". The counter is the + * occurence count of children within the enclosingNode which have the same name. So, for example, if a method contains two + * System.out.println statements, the first one will have byteCodeName 'println!1' and the second will have byteCodeName + * 'println!2'. This is to ensure the two nodes have unique handles when the handles do not depend on sourcelocations. * - * Currently the shadows are examined in the sequence they appear in the - * source file. This means that the counters are consistent over incremental - * builds. All aspects are compiled up front and any new aspect created will force - * a full build. Moreover, if the body of the enclosingShadow is changed, then - * the model for this is rebuilt from scratch. + * Currently the shadows are examined in the sequence they appear in the source file. This means that the counters are + * consistent over incremental builds. All aspects are compiled up front and any new aspect created will force a full build. + * Moreover, if the body of the enclosingShadow is changed, then the model for this is rebuilt from scratch. */ - private IProgramElement findOrCreateCodeNode(IProgramElement enclosingNode, Member shadowSig, Shadow shadow) - { - for (Iterator it = enclosingNode.getChildren().iterator(); it.hasNext(); ) { - IProgramElement node = (IProgramElement)it.next(); + private IProgramElement findOrCreateCodeNode(IProgramElement enclosingNode, Member shadowSig, Shadow shadow) { + for (Iterator it = enclosingNode.getChildren().iterator(); it.hasNext();) { + IProgramElement node = (IProgramElement) it.next(); int excl = node.getBytecodeName().lastIndexOf('!'); - if (((excl != -1 - && shadowSig.getName().equals(node.getBytecodeName().substring(0,excl))) - || shadowSig.getName().equals(node.getBytecodeName())) - && shadowSig.getSignature().equals(node.getBytecodeSignature()) - && sourceLinesMatch(node.getSourceLocation(),shadow.getSourceLocation())){ + if (((excl != -1 && shadowSig.getName().equals(node.getBytecodeName().substring(0, excl))) || shadowSig.getName() + .equals(node.getBytecodeName())) + && shadowSig.getSignature().equals(node.getBytecodeSignature()) + && sourceLinesMatch(node.getSourceLocation(), shadow.getSourceLocation())) { return node; } } - + ISourceLocation sl = shadow.getSourceLocation(); - -// XXX why not use shadow file? new SourceLocation(sl.getSourceFile(), sl.getLine()), - SourceLocation peLoc = new SourceLocation(enclosingNode.getSourceLocation().getSourceFile(),sl.getLine()); + + // XXX why not use shadow file? new SourceLocation(sl.getSourceFile(), sl.getLine()), + SourceLocation peLoc = new SourceLocation(enclosingNode.getSourceLocation().getSourceFile(), sl.getLine()); peLoc.setOffset(sl.getOffset()); - IProgramElement peNode = new ProgramElement( - shadow.toString(), - IProgramElement.Kind.CODE, - peLoc,0,null,null); - - // check to see if the enclosing shadow already has children with the + IProgramElement peNode = new ProgramElement(shadow.toString(), IProgramElement.Kind.CODE, peLoc, 0, null, null); + + // check to see if the enclosing shadow already has children with the // same name. If so we want to add a counter to the byteCodeName otherwise // we wont get unique handles int numberOfChildrenWithThisName = 0; - for (Iterator it = enclosingNode.getChildren().iterator(); it.hasNext(); ) { - IProgramElement child = (IProgramElement)it.next(); + for (Iterator it = enclosingNode.getChildren().iterator(); it.hasNext();) { + IProgramElement child = (IProgramElement) it.next(); if (child.getName().equals(shadow.toString())) { numberOfChildrenWithThisName++; } - } - peNode.setBytecodeName(shadowSig.getName() + "!" + String.valueOf(numberOfChildrenWithThisName+1)); + } + peNode.setBytecodeName(shadowSig.getName() + "!" + String.valueOf(numberOfChildrenWithThisName + 1)); peNode.setBytecodeSignature(shadowSig.getSignature()); enclosingNode.addChild(peNode); return peNode; } - + protected IProgramElement lookupMember(IHierarchy model, Member member) { UnresolvedType declaringType = member.getDeclaringType(); - IProgramElement classNode = - model.findElementForType(declaringType.getPackageName(), declaringType.getClassName()); + IProgramElement classNode = model.findElementForType(declaringType.getPackageName(), declaringType.getClassName()); return findMemberInClass(classNode, member); } - - protected IProgramElement findMemberInClass( - IProgramElement classNode, - Member member) - { - if (classNode == null) return null; // XXX remove this check - for (Iterator it = classNode.getChildren().iterator(); it.hasNext(); ) { - IProgramElement node = (IProgramElement)it.next(); - if (member.getName().equals(node.getBytecodeName()) && - member.getSignature().equals(node.getBytecodeSignature())) - { + + protected IProgramElement findMemberInClass(IProgramElement classNode, Member member) { + if (classNode == null) + return null; // XXX remove this check + for (Iterator it = classNode.getChildren().iterator(); it.hasNext();) { + IProgramElement node = (IProgramElement) it.next(); + if (member.getName().equals(node.getBytecodeName()) && member.getSignature().equals(node.getBytecodeSignature())) { return node; } } - // if we can't find the member, we'll just put it in the class + // if we can't find the member, we'll just put it in the class return classNode; } - -// private static IProgramElement.Kind genShadowKind(Shadow shadow) { -// IProgramElement.Kind shadowKind; -// if (shadow.getKind() == Shadow.MethodCall -// || shadow.getKind() == Shadow.ConstructorCall -// || shadow.getKind() == Shadow.FieldGet -// || shadow.getKind() == Shadow.FieldSet -// || shadow.getKind() == Shadow.ExceptionHandler) { -// return IProgramElement.Kind.CODE; -// -// } else if (shadow.getKind() == Shadow.MethodExecution) { -// return IProgramElement.Kind.METHOD; -// -// } else if (shadow.getKind() == Shadow.ConstructorExecution) { -// return IProgramElement.Kind.CONSTRUCTOR; -// -// } else if (shadow.getKind() == Shadow.PreInitialization -// || shadow.getKind() == Shadow.Initialization) { -// return IProgramElement.Kind.CLASS; -// -// } else if (shadow.getKind() == Shadow.AdviceExecution) { -// return IProgramElement.Kind.ADVICE; -// -// } else { -// return IProgramElement.Kind.ERROR; -// } -// } - - public static AsmRelationshipProvider getDefault() { - return INSTANCE; - } - - /** - * Reset the instance of this class, intended for extensibility. - * This enables a subclass to become used as the default instance. - */ - public static void setDefault(AsmRelationshipProvider instance) { - INSTANCE = instance; - } - - /** - * Add a relationship to the known set for a declare @method/@constructor construct. - * Locating the method is a messy (for messy read 'fragile') bit of code that could break at any moment - * but it's working for my simple testcase. Currently just fails silently if any of the lookup code - * doesn't find anything... - */ - public void addDeclareAnnotationRelationship(ISourceLocation sourceLocation, String typename,Method method) { - if (!AsmManager.isCreatingModel()) return; - - String pkg = null; - String type = typename; - int packageSeparator = typename.lastIndexOf("."); - if (packageSeparator!=-1) { - pkg = typename.substring(0,packageSeparator); - type = typename.substring(packageSeparator+1); - } - - IProgramElement typeElem = AsmManager.getDefault().getHierarchy().findElementForType(pkg,type); - if (typeElem == null) return; - - - StringBuffer parmString = new StringBuffer("("); - Type[] args = method.getArgumentTypes(); - for (int i = 0; i < args.length; i++) { + + // private static IProgramElement.Kind genShadowKind(Shadow shadow) { + // IProgramElement.Kind shadowKind; + // if (shadow.getKind() == Shadow.MethodCall + // || shadow.getKind() == Shadow.ConstructorCall + // || shadow.getKind() == Shadow.FieldGet + // || shadow.getKind() == Shadow.FieldSet + // || shadow.getKind() == Shadow.ExceptionHandler) { + // return IProgramElement.Kind.CODE; + // + // } else if (shadow.getKind() == Shadow.MethodExecution) { + // return IProgramElement.Kind.METHOD; + // + // } else if (shadow.getKind() == Shadow.ConstructorExecution) { + // return IProgramElement.Kind.CONSTRUCTOR; + // + // } else if (shadow.getKind() == Shadow.PreInitialization + // || shadow.getKind() == Shadow.Initialization) { + // return IProgramElement.Kind.CLASS; + // + // } else if (shadow.getKind() == Shadow.AdviceExecution) { + // return IProgramElement.Kind.ADVICE; + // + // } else { + // return IProgramElement.Kind.ERROR; + // } + // } + + public static AsmRelationshipProvider getDefault() { + return INSTANCE; + } + + /** + * Add a relationship to the known set for a declare @method/@constructor construct. Locating the method is a messy (for messy + * read 'fragile') bit of code that could break at any moment but it's working for my simple testcase. Currently just fails + * silently if any of the lookup code doesn't find anything... + */ + public void addDeclareAnnotationRelationship(ISourceLocation sourceLocation, String typename, Method method) { + if (!AsmManager.isCreatingModel()) + return; + + String pkg = null; + String type = typename; + int packageSeparator = typename.lastIndexOf("."); + if (packageSeparator != -1) { + pkg = typename.substring(0, packageSeparator); + type = typename.substring(packageSeparator + 1); + } + + IProgramElement typeElem = AsmManager.getDefault().getHierarchy().findElementForType(pkg, type); + if (typeElem == null) + return; + + StringBuffer parmString = new StringBuffer("("); + Type[] args = method.getArgumentTypes(); + for (int i = 0; i < args.length; i++) { Type type2 = args[i]; - String s = Utility.signatureToString(type2.getSignature(),false); + String s = Utility.signatureToString(type2.getSignature(), false); parmString.append(s); - if ((i+1)<args.length) parmString.append(","); - } - parmString.append(")"); - IProgramElement methodElem = null; - - if (method.getName().startsWith("<init>")) { - // its a ctor - methodElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem,IProgramElement.Kind.CONSTRUCTOR,type+parmString); - if (methodElem == null && args.length==0) methodElem = typeElem; // assume default ctor - } else { - // its a method - methodElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem,IProgramElement.Kind.METHOD,method.getName()+parmString); - } - - if (methodElem == null) return; - - try { - String targetHandle = methodElem.getHandleIdentifier(); - if (targetHandle == null) return; - - IProgramElement sourceNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(sourceLocation); - String sourceHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceNode); - if (sourceHandle == null) return; - - IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); - IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES,false,true); - foreward.addTarget(targetHandle); - - IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY,false,true); - back.addTarget(sourceHandle); - } catch (Throwable t) { // I'm worried about that code above, this will make sure we don't explode if it plays up - t.printStackTrace(); // I know I know .. but I don't want to lose it! - } + if ((i + 1) < args.length) + parmString.append(","); + } + parmString.append(")"); + IProgramElement methodElem = null; + + if (method.getName().startsWith("<init>")) { + // its a ctor + methodElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem, IProgramElement.Kind.CONSTRUCTOR, + type + parmString); + if (methodElem == null && args.length == 0) + methodElem = typeElem; // assume default ctor + } else { + // its a method + methodElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem, IProgramElement.Kind.METHOD, + method.getName() + parmString); + } + + if (methodElem == null) + return; + + try { + String targetHandle = methodElem.getHandleIdentifier(); + if (targetHandle == null) + return; + + IProgramElement sourceNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(sourceLocation); + String sourceHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceNode); + if (sourceHandle == null) + return; + + IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); + IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true); + foreward.addTarget(targetHandle); + + IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true); + back.addTarget(sourceHandle); + } catch (Throwable t) { // I'm worried about that code above, this will make sure we don't explode if it plays up + t.printStackTrace(); // I know I know .. but I don't want to lose it! + } } - - /** - * Add a relationship to the known set for a declare @field construct. Locating the field is trickier than - * it might seem since we have no line number info for it, we have to dig through the structure model under - * the fields' type in order to locate it. Currently just fails silently if any of the lookup code - * doesn't find anything... - */ - public void addDeclareAnnotationRelationship(ISourceLocation sourceLocation, String typename,Field field) { - if (!AsmManager.isCreatingModel()) return; - - String pkg = null; - String type = typename; - int packageSeparator = typename.lastIndexOf("."); - if (packageSeparator!=-1) { - pkg = typename.substring(0,packageSeparator); - type = typename.substring(packageSeparator+1); - } - - IProgramElement typeElem = AsmManager.getDefault().getHierarchy().findElementForType(pkg,type); - if (typeElem == null) return; - - IProgramElement fieldElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem,IProgramElement.Kind.FIELD,field.getName()); - if (fieldElem== null) return; + + /** + * Add a relationship to the known set for a declare @field construct. Locating the field is trickier than it might seem since + * we have no line number info for it, we have to dig through the structure model under the fields' type in order to locate it. + * Currently just fails silently if any of the lookup code doesn't find anything... + */ + public void addDeclareAnnotationRelationship(ISourceLocation sourceLocation, String typename, Field field) { + if (!AsmManager.isCreatingModel()) + return; + + String pkg = null; + String type = typename; + int packageSeparator = typename.lastIndexOf("."); + if (packageSeparator != -1) { + pkg = typename.substring(0, packageSeparator); + type = typename.substring(packageSeparator + 1); + } + + IProgramElement typeElem = AsmManager.getDefault().getHierarchy().findElementForType(pkg, type); + if (typeElem == null) + return; + + IProgramElement fieldElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem, + IProgramElement.Kind.FIELD, field.getName()); + if (fieldElem == null) + return; String targetHandle = fieldElem.getHandleIdentifier(); - if (targetHandle == null) return; - + if (targetHandle == null) + return; + IProgramElement sourceNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(sourceLocation); String sourceHandle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceNode); - if (sourceHandle == null) return; - - IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); - IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES,false,true); + if (sourceHandle == null) + return; + + IRelationshipMap mapper = AsmManager.getDefault().getRelationshipMap(); + IRelationship foreward = mapper.get(sourceHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATES, false, true); foreward.addTarget(targetHandle); - - IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY,false,true); + + IRelationship back = mapper.get(targetHandle, IRelationship.Kind.DECLARE_INTER_TYPE, ANNOTATED_BY, false, true); back.addTarget(sourceHandle); } - + } diff --git a/weaver/src/org/aspectj/weaver/IntMap.java b/weaver/src/org/aspectj/weaver/IntMap.java index dd3ef6e9e..6f37f20f2 100644 --- a/weaver/src/org/aspectj/weaver/IntMap.java +++ b/weaver/src/org/aspectj/weaver/IntMap.java @@ -10,56 +10,54 @@ * 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 - }; - - + // 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(); - + private List/* ResolvedPointcutDefinition */enclosingDefinition = new ArrayList(); + public void pushEnclosingDefinition(ResolvedPointcutDefinition def) { enclosingDefinition.add(def); } - + public void popEnclosingDefinitition() { - enclosingDefinition.remove(enclosingDefinition.size()-1); + enclosingDefinition.remove(enclosingDefinition.size() - 1); } - - + public ResolvedPointcutDefinition peekEnclosingDefinition() { - if (enclosingDefinition.size()==0) return null; - return (ResolvedPointcutDefinition)enclosingDefinition.get(enclosingDefinition.size()-1); + 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; + if (enclosingAdvice instanceof Advice) + return ((Advice) enclosingAdvice).getSignature(); + else + return null; } - public ResolvedType getConcreteAspect() { return concreteAspect; @@ -68,68 +66,70 @@ public class IntMap { 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++) { + + 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(", "); @@ -139,11 +139,9 @@ public class IntMap { buf.append(" -> "); buf.append(map[i]); } - } - buf.append("]"); - return buf.toString(); - } - - + } + buf.append("]"); + return buf.toString(); + } } diff --git a/weaver/src/org/aspectj/weaver/Iterators.java b/weaver/src/org/aspectj/weaver/Iterators.java index bfbad72d8..1e5e6e6f5 100644 --- a/weaver/src/org/aspectj/weaver/Iterators.java +++ b/weaver/src/org/aspectj/weaver/Iterators.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver; import java.util.HashSet; @@ -20,199 +19,246 @@ import java.util.Set; public final class Iterators { - /** - * Private constructor, nobody should ever make one of these - */ - private Iterators() { - super(); - } - - /** - * 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(); } - }; - } - /** creates an empty iterator. - */ - public static final Iterator EMPTY = new Iterator() { - public boolean hasNext() { return false; } - public Object next() { throw new NoSuchElementException(); } - public void remove() { throw new UnsupportedOperationException(); } - }; + /** + * 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(); + } + }; + } } diff --git a/weaver/src/org/aspectj/weaver/MemberImpl.java b/weaver/src/org/aspectj/weaver/MemberImpl.java index bd08b7bea..06640e3ff 100644 --- a/weaver/src/org/aspectj/weaver/MemberImpl.java +++ b/weaver/src/org/aspectj/weaver/MemberImpl.java @@ -20,393 +20,407 @@ 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("()[Z")[0].equals(Type.forSignature("[Z")) - * UnresolvedType.signatureToTypes("(JJ)I")[1] - * .equals(UnresolvedType.forSignatures(new String[] {"J", "J"})) - * </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("()[Z")[0].equals(Type.forSignature("[Z")) - * UnresolvedType.signatureToTypes("(JJ)I")[1] - * .equals(UnresolvedType.forSignatures(new String[] {"J", "J"})) - * </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))); + + 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("()[Z")[0].equals(Type.forSignature("[Z")) + * UnresolvedType.signatureToTypes("(JJ)I")[1] + * .equals(UnresolvedType.forSignatures(new String[] {"J", "J"})) + * </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("()[Z")[0].equals(Type.forSignature("[Z")) + * UnresolvedType.signatureToTypes("(JJ)I")[1] + * .equals(UnresolvedType.forSignatures(new String[] {"J", "J"})) + * </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; + int genericDepth = 0; while (!endOfSigReached) { switch (sig.charAt(posn)) { - case '<': genericDepth++;break; - case '>': genericDepth--;break; - case ';': if (genericDepth==0) endOfSigReached=true;break; - default: + 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))); + 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); + } 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); - } - + 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++) { + 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; + 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; + } + + 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 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 AnnotationX[] getAnnotations() { - throw new UnsupportedOperationException("You should resolve this member '"+this+"' and call getAnnotations() on the result..."); + throw new UnsupportedOperationException("You should resolve this member '" + this + + "' and call getAnnotations() on the result..."); } // ---- fields 'n' stuff - public Collection/*ResolvedType*/ getDeclaringTypes(World world) { + public Collection/* ResolvedType */getDeclaringTypes(World world) { ResolvedType myType = getDeclaringType().resolve(world); Collection ret = new HashSet(); if (kind == CONSTRUCTOR) { @@ -417,85 +431,87 @@ public class MemberImpl implements Member { } else { walkUp(ret, myType); } - + return ret; } - + private boolean walkUp(Collection acc, ResolvedType curr) { - if (acc.contains(curr)) return true; - + if (acc.contains(curr)) + return true; + boolean b = false; - for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) { - b |= walkUp(acc, (ResolvedType)i.next()); + for (Iterator i = curr.getDirectSupertypes(); i.hasNext();) { + b |= walkUp(acc, (ResolvedType) i.next()); } - + if (!b && curr.isParameterizedType()) { - b = walkUp(acc,curr.getGenericType()); + b = walkUp(acc, curr.getGenericType()); } - + if (!b) { b = curr.lookupMemberNoSupers(this) != null; - } - if (b) acc.add(curr); + } + 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()); + for (Iterator i = curr.getDirectSupertypes(); i.hasNext();) { + b |= walkUpStatic(acc, (ResolvedType) i.next()); } if (!b && curr.isParameterizedType()) { - b = walkUpStatic(acc,curr.getGenericType()); + b = walkUpStatic(acc, curr.getGenericType()); } - if (b) acc.add(curr); + if (b) + acc.add(curr); return b; } } public String[] getParameterNames(World world) { - ResolvedMember resolved = resolve(world); - if (resolved == null) { - reportDidntFindMember(world); - return null; + 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. - */ + } + + /** + * 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 = 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 + * 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; + 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); + world.getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE, rType.getName()), null); reportedCantFindDeclaringType = true; } else { - world.getLint().unresolvableMember.signal(getName(),null); - reportedUnresolvableMember = true; + world.getLint().unresolvableMember.signal(getName(), null); + reportedUnresolvableMember = true; } - } - - public void wipeJoinpointSignatures() { - joinPointSignatures = null; - } + } + + public void wipeJoinpointSignatures() { + joinPointSignatures = null; + } } - diff --git a/weaver/src/org/aspectj/weaver/NameMangler.java b/weaver/src/org/aspectj/weaver/NameMangler.java index a69420850..6aa483ed4 100644 --- a/weaver/src/org/aspectj/weaver/NameMangler.java +++ b/weaver/src/org/aspectj/weaver/NameMangler.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver; import java.lang.reflect.Modifier; @@ -18,72 +17,72 @@ import java.lang.reflect.Modifier; import org.aspectj.weaver.bcel.LazyClassGen; 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 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 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 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 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 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 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_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 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")) { + 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 false; // body of an itd-m } return true; - } - else if (methodName.indexOf("_aroundBody") != -1) { + } 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; -// } -// } + // 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"); } @@ -96,230 +95,183 @@ public class NameMangler { 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) { + 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 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); + 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); + 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); + 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); + 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); + 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); + return makeName("inlineAccessFieldSet", aspectType.getNameAsIdentifier(), objectType.getNameAsIdentifier(), name); } - - + /** - * The name of methods corresponding to advice declarations - * Of the form: "ajc$[AdviceKind]$[AspectName]$[NumberOfAdviceInAspect]$[PointcutHash]" + * 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)); + 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 + * 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); + 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 + * 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); + 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 + * 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); + 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); + 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); + return makeName("interFieldGetDispatch", aspectType.getNameAsIdentifier(), onType.getNameAsIdentifier(), name); } - /** - * This field goes on the class the field - * is declared onto + * 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 + 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 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; + * 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); + 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) + * 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); + 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); + 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); + 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()); - } - + 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()); + 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); + 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); + public static String protectedDispatchMethod(UnresolvedType classType, String name) { + return makeName("protectedDispatch", classType.getNameAsIdentifier(), name); } // ---- @@ -335,30 +287,29 @@ public class NameMangler { return aspectType.getPackageNameAsIdentifier(); } } - + private static String makeName(String s1, String s2) { - return "ajc$" + s1 + "$" + s2; + return "ajc$" + s1 + "$" + s2; } + public static String makeName(String s1, String s2, String s3) { - return "ajc$" + s1 + "$" + s2 + "$" + s3; + return "ajc$" + s1 + "$" + s2 + "$" + s3; } + public static String makeName(String s1, String s2, String s3, String s4) { - return "ajc$" + s1 + "$" + s2 + "$" + s3 + "$" + 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())); + return makeName("cflowCounter", Integer.toHexString(xcut.getCflowEntries().size())); } - - - public static String makeClosureClassName( - UnresolvedType enclosingType, - int index) - { - return enclosingType.getName() + "$AjcClosure" + index; + public static String makeClosureClassName(UnresolvedType enclosingType, int index) { + return enclosingType.getName() + "$AjcClosure" + index; } public static String aroundCallbackMethodName(Member shadowSig, LazyClassGen enclosingType) { @@ -366,15 +317,17 @@ public class NameMangler { ret.append(getExtractableName(shadowSig)).append("_aroundBody").append(enclosingType.getNewGeneratedNameTag()); return ret.toString(); } - - public static String getExtractableName(Member shadowSignature) { + + 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; - } - + 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"; diff --git a/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java b/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java index 9b13f780e..2fa3a57e2 100644 --- a/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver; import java.io.DataOutputStream; @@ -23,42 +22,40 @@ import org.aspectj.bridge.ISourceLocation; public class NewMethodTypeMunger extends ResolvedTypeMunger { - - public NewMethodTypeMunger( - ResolvedMember signature, - Set superMethodsCalled, - List typeVariableAliases) { + 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 + * 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()); + 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); + 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()); + + // 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); + return AjcMemberMaker.interMethodDispatcher(signature, aspectType); } } @@ -69,33 +66,36 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger { 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); + + ResolvedTypeMunger munger = new NewMethodTypeMunger(rmImpl, superMethodsCalled, typeVarAliases); + if (sloc != null) + munger.setSourceLocation(sloc); return munger; } - - public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) { + + public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) { ResolvedMember ret = AjcMemberMaker.interMethodDispatcher(getSignature(), aspectType); - if (ResolvedType.matches(ret, member)) return getSignature(); + if (ResolvedType.matches(ret, member)) + return getSignature(); return super.getMatchingSyntheticMember(member, aspectType); } /** - * see ResolvedTypeMunger.parameterizedFor(ResolvedType) - */ + * see ResolvedTypeMunger.parameterizedFor(ResolvedType) + */ public ResolvedTypeMunger parameterizedFor(ResolvedType target) { ResolvedType genericType = target; - if (target.isRawType() || target.isParameterizedType()) genericType = genericType.getGenericType(); + 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 + // 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(); @@ -103,38 +103,41 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger { for (int i = 0; i < vars.length; i++) { varRefs[i] = new UnresolvedTypeVariableReferenceType(vars[i]); } - parameterizedSignature = getSignature().parameterizedWith(varRefs,genericType,true,typeVariableAliases); + 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); + // 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); + 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 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); + ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m, w); + NewMethodTypeMunger nmtm = new NewMethodTypeMunger(parameterizedSignature, getSuperMethodsCalled(), typeVariableAliases); nmtm.setDeclaredSignature(getSignature()); nmtm.setSourceLocation(getSourceLocation()); return nmtm; diff --git a/weaver/src/org/aspectj/weaver/ReferenceType.java b/weaver/src/org/aspectj/weaver/ReferenceType.java index 4487f50cd..86f9c792d 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceType.java +++ b/weaver/src/org/aspectj/weaver/ReferenceType.java @@ -24,40 +24,33 @@ 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. + * 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. + * 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 List/*ReferenceType*/ derivativeTypes = new ArrayList(); - + private 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. + * 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; - - public static ReferenceType fromTypeX(UnresolvedType tx, World world) { - ReferenceType rt = new ReferenceType(tx.getErasureSignature(),world); - rt.typeKind = tx.typeKind; - return rt; - } - + + public static ReferenceType fromTypeX(UnresolvedType tx, World world) { + ReferenceType rt = new ReferenceType(tx.getErasureSignature(), world); + rt.typeKind = tx.typeKind; + return rt; + } // cached values for members ResolvedMember[] parameterizedMethods = null; @@ -66,100 +59,97 @@ public class ReferenceType extends ResolvedType { 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); - } - - /** - * 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 - */ + + // ??? 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); + } + + /** + * 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 AnnotationX[] getAnnotations() { - return delegate.getAnnotations(); - } - - public void addAnnotation(AnnotationX annotationX) { - delegate.addAnnotation(annotationX); - } - public boolean hasAnnotation(UnresolvedType ofType) { - return delegate.hasAnnotation(ofType); - } - - public ResolvedType[] getAnnotationTypes() { - return delegate.getAnnotationTypes(); - } - + 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 AnnotationX[] getAnnotations() { + return delegate.getAnnotations(); + } + + public void addAnnotation(AnnotationX annotationX) { + delegate.addAnnotation(annotationX); + } + + public boolean hasAnnotation(UnresolvedType ofType) { + return delegate.hasAnnotation(ofType); + } + + public ResolvedType[] getAnnotationTypes() { + return delegate.getAnnotationTypes(); + } + public AnnotationX getAnnotationOfType(UnresolvedType ofType) { AnnotationX[] axs = delegate.getAnnotations(); - if (axs==null) return null; - for (int i=0;i<axs.length;i++) { + if (axs == null) + return null; + for (int i = 0; i < axs.length; i++) { if (axs[i].getSignature().equals(ofType)) { return axs[i]; } @@ -168,168 +158,183 @@ public class ReferenceType extends ResolvedType { } 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++) { + 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; + 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; + 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; + 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++) { + 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; - } + 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)) { + 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()) { @@ -343,62 +348,67 @@ public class ReferenceType extends ResolvedType { } } } - } 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; - } + } 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 + return (delegate == null) || delegate.isExposedToWeaver(); // ??? where does this belong } - + public WeaverStateInfo getWeaverState() { return delegate.getWeaverState(); } public ResolvedMember[] getDeclaredFields() { - if (parameterizedFields != null) return parameterizedFields; + 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()); + parameterizedFields[i] = delegateFields[i].parameterizedWith(getTypesForMemberParameterization(), this, + isParameterizedType()); } return parameterizedFields; } else { @@ -407,20 +417,20 @@ public class ReferenceType extends ResolvedType { } /** - * 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. + * 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 (parameterizedInterfaces != null) + return parameterizedInterfaces; if (isParameterizedType()) { ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces(); -// UnresolvedType[] paramTypes = getTypesForMemberParameterization(); + // 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 { @@ -428,7 +438,7 @@ public class ReferenceType extends ResolvedType { } } return parameterizedInterfaces; - } else if (isRawType()){ + } else if (isRawType()) { ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces(); UnresolvedType[] paramTypes = getTypesForMemberParameterization(); parameterizedInterfaces = new ResolvedType[delegateInterfaces.length]; @@ -436,66 +446,60 @@ public class ReferenceType extends ResolvedType { 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()); + 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); + 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 + * 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]; -// } - + // 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> + * 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> + * </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>. + * </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? + 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; + 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) { + if (rank != -1) { retVal[i] = paramTypes[rank]; } else { retVal[i] = tParms[i]; @@ -503,32 +507,34 @@ public class ReferenceType extends ResolvedType { } 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. + * 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; + if (tv.getName().equals(tvname)) + return i; } return -1; } public ResolvedMember[] getDeclaredMethods() { - if (parameterizedMethods != null) return parameterizedMethods; + 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()); + parameterizedMethods[i] = delegateMethods[i].parameterizedWith(parameters, this, isParameterizedType()); } return parameterizedMethods; } else { @@ -537,24 +543,26 @@ public class ReferenceType extends ResolvedType { } public ResolvedMember[] getDeclaredPointcuts() { - if (parameterizedPointcuts != null) return parameterizedPointcuts; + 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()); + parameterizedPointcuts[i] = delegatePointcuts[i].parameterizedWith(getTypesForMemberParameterization(), this, + isParameterizedType()); } return parameterizedPointcuts; } else { return delegate.getDeclaredPointcuts(); } } - - private UnresolvedType[] getTypesForMemberParameterization() { + + private UnresolvedType[] getTypesForMemberParameterization() { UnresolvedType[] parameters = null; if (isParameterizedType()) { parameters = getTypeParameters(); - } else if (isRawType()){ + } else if (isRawType()) { // raw type, use upper bounds of type variables on generic type TypeVariable[] tvs = getGenericType().getTypeVariables(); parameters = new UnresolvedType[tvs.length]; @@ -564,33 +572,33 @@ public class ReferenceType extends ResolvedType { } 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() { + + public PerClause getPerClause() { PerClause pclause = delegate.getPerClause(); if (isParameterizedType()) { // could cache the result here... Map parameterizationMap = getAjMemberParameterizationMap(); - pclause = (PerClause)pclause.parameterizeWith(parameterizationMap,world); + pclause = (PerClause) pclause.parameterizeWith(parameterizationMap, world); } return pclause; } - - + protected Collection getDeclares() { - if (parameterizedDeclares != null) return parameterizedDeclares; + if (parameterizedDeclares != null) + return parameterizedDeclares; Collection declares = null; if (ajMembersNeedParameterization()) { Collection genericDeclares = delegate.getDeclares(); @@ -598,7 +606,7 @@ public class ReferenceType extends ResolvedType { Map parameterizationMap = getAjMemberParameterizationMap(); for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) { Declare declareStatement = (Declare) iter.next(); - parameterizedDeclares.add(declareStatement.parameterizeWith(parameterizationMap,world)); + parameterizedDeclares.add(declareStatement.parameterizeWith(parameterizationMap, world)); } declares = parameterizedDeclares; } else { @@ -610,32 +618,34 @@ public class ReferenceType extends ResolvedType { } return declares; } - - protected Collection getTypeMungers() { + + protected Collection getTypeMungers() { return delegate.getTypeMungers(); } - // GENERICITDFIX -//// Map parameterizationMap = getAjMemberParameterizationMap(); -// -// // if (parameterizedTypeMungers != null) return parameterizedTypeMungers; -// Collection ret = null; -// if (ajMembersNeedParameterization()) { -// Collection genericDeclares = delegate.getTypeMungers(); -// parameterizedTypeMungers = new ArrayList(); -// Map parameterizationMap = getAjMemberParameterizationMap(); -// for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) { -// ConcreteTypeMunger munger = (ConcreteTypeMunger)iter.next(); -// parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap,world)); -// } -// ret = parameterizedTypeMungers; -// } else { -// ret = delegate.getTypeMungers(); -// } -// return ret; -// } - - protected Collection getPrivilegedAccesses() { return delegate.getPrivilegedAccesses(); } + // 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(); @@ -643,36 +653,36 @@ public class ReferenceType extends ResolvedType { public ResolvedType getSuperclass() { ResolvedType ret = null; - try { + try { world.setTypeVariableLookupScope(this); ret = delegate.getSuperclass(); - } finally { - world.setTypeVariableLookupScope(null); - } + } 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 instanceof BcelObjectType) && this.delegate.getSourceContext()!=SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) - ((AbstractReferenceTypeDelegate)delegate).setSourceContext(this.delegate.getSourceContext()); + if (this.delegate != null && !(this.delegate instanceof BcelObjectType) + && this.delegate.getSourceContext() != SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) + ((AbstractReferenceTypeDelegate) delegate).setSourceContext(this.delegate.getSourceContext()); this.delegate = delegate; - for(Iterator it = this.derivativeTypes.iterator(); it.hasNext(); ) { + 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 ) { + if (isRawType() && getGenericType() != null) { ReferenceType genType = (ReferenceType) getGenericType(); if (genType.getDelegate() != delegate) { // avoids circular updates genType.setDelegate(delegate); @@ -680,7 +690,7 @@ public class ReferenceType extends ResolvedType { } clearParameterizationCaches(); } - + private void clearParameterizationCaches() { parameterizedFields = null; parameterizedInterfaces = null; @@ -703,67 +713,68 @@ public class ReferenceType extends ResolvedType { 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? + // 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; + if (typeKind == TypeKind.SIMPLE) { + typeKind = TypeKind.RAW; signatureErasure = signature; } } - + public void demoteToSimpleType() { - genericType = null; - typeKind = TypeKind.SIMPLE; + genericType = null; + typeKind = TypeKind.SIMPLE; signatureErasure = null; } - + public ResolvedType getGenericType() { - if (isGenericType()) return this; + 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. + * 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(); - String prefix = PARAMETERIZED_TYPE_IDENTIFIER + rawSignature.substring(1,rawSignature.length()-1); - + String prefix = PARAMETERIZED_TYPE_IDENTIFIER + rawSignature.substring(1, rawSignature.length() - 1); + StringBuffer ret = new StringBuffer(); ret.append(prefix); ret.append("<"); for (int i = 0; i < someParameters.length; i++) { - ret.append(someParameters[i].getSignature()); + ret.append(someParameters[i].getSignature()); } ret.append(">;"); return ret.toString(); } - - private static String makeDeclaredSignature(ResolvedType aGenericType, UnresolvedType[] someParameters) { + + 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(rawSig.substring(0, rawSig.length() - 1)); ret.append("<"); for (int i = 0; i < someParameters.length; i++) { - ret.append(((ReferenceType)someParameters[i]).getSignatureForAttribute()); + ret.append(((ReferenceType) someParameters[i]).getSignatureForAttribute()); } ret.append(">;"); return ret.toString(); } - + }
\ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index 0e910c047..f9af41da6 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -119,9 +119,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return null; } - public final UnresolvedType getSuperclass(World world) { - return getSuperclass(); - } + // public final UnresolvedType getSuperclass(World world) { + // return getSuperclass(); + // } // This set contains pairs of types whose signatures are concatenated // together, this means with a fast lookup we can tell if two types @@ -509,40 +509,6 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return crosscuttingMembers; } - public final Collection collectTypeMungers() { - if (!this.isAspect()) - return Collections.EMPTY_LIST; - - ArrayList ret = new ArrayList(); - // if (this.isAbstract()) { - // for (Iterator i = getDeclares().iterator(); i.hasNext();) { - // Declare dec = (Declare) i.next(); - // if (!dec.isAdviceLike()) ret.add(dec); - // } - // - // if (!includeAdviceLike) return ret; - - if (!this.isAbstract()) { - final Iterators.Filter dupFilter = Iterators.dupFilter(); - Iterators.Getter typeGetter = new Iterators.Getter() { - public Iterator get(Object o) { - return dupFilter.filter(((ResolvedType) o).getDirectSupertypes()); - } - }; - Iterator typeIterator = Iterators.recur(this, typeGetter); - - while (typeIterator.hasNext()) { - ResolvedType ty = (ResolvedType) typeIterator.next(); - for (Iterator i = ty.getTypeMungers().iterator(); i.hasNext();) { - ConcreteTypeMunger dec = (ConcreteTypeMunger) i.next(); - ret.add(dec); - } - } - } - - return ret; - } - public final Collection collectDeclares(boolean includeAdviceLike) { if (!this.isAspect()) return Collections.EMPTY_LIST; @@ -1269,10 +1235,6 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } } - public static boolean hasBridgeModifier(int modifiers) { - return (modifiers & Constants.ACC_BRIDGE) != 0; - } - private static boolean samePackage(ResolvedType targetType, ResolvedType fromType) { String p1 = targetType.getPackageName(); String p2 = fromType.getPackageName(); @@ -1910,14 +1872,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return parameterizedSuperTypes.length > 0; } - public boolean hasGenericSuperType() { - ResolvedType[] superTypes = getDeclaredInterfaces(); - for (int i = 0; i < superTypes.length; i++) { - if (superTypes[i].isGenericType()) - return true; - } - return false; - } + // public boolean hasGenericSuperType() { + // ResolvedType[] superTypes = getDeclaredInterfaces(); + // for (int i = 0; i < superTypes.length; i++) { + // if (superTypes[i].isGenericType()) + // return true; + // } + // return false; + // } private ResolvedType[] parameterizedSuperTypes = null; diff --git a/weaver/src/org/aspectj/weaver/TypeFactory.java b/weaver/src/org/aspectj/weaver/TypeFactory.java index b085e5866..2200224ae 100644 --- a/weaver/src/org/aspectj/weaver/TypeFactory.java +++ b/weaver/src/org/aspectj/weaver/TypeFactory.java @@ -16,191 +16,209 @@ 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 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 - ) { + 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); + 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"); + 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()); + 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 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); - } - + // 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 + * 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; + private static UnresolvedType convertSigToType(String aSignature) { + UnresolvedType bound = null; int startOfParams = aSignature.indexOf('<'); - if (startOfParams==-1) { + 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); + 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; + if (signature.equals(ResolvedType.MISSING_NAME)) + return ResolvedType.MISSING; char firstChar = signature.charAt(0); - if (firstChar=='P') { + 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. + // of its parent. In this case it is parameterized but theres no < in the signature. int startOfParams = signature.indexOf('<'); - - if (startOfParams==-1) { + + 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); + return new UnresolvedType(signature, signatureErasure, typeParams); } else { - int endOfParams = locateMatchingEndBracket(signature,startOfParams);//signature.lastIndexOf('>'); + int endOfParams = locateMatchingEndBracket(signature, startOfParams);// signature.lastIndexOf('>'); StringBuffer erasureSig = new StringBuffer(signature); - while (startOfParams!=-1) { - erasureSig.delete(startOfParams,endOfParams+1); + while (startOfParams != -1) { + erasureSig.delete(startOfParams, endOfParams + 1); startOfParams = locateFirstBracket(erasureSig); - if (startOfParams!=-1) endOfParams = locateMatchingEndBracket(erasureSig,startOfParams); + 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); + if (nestedTypePosition != -1) + lastType = signature.substring(nestedTypePosition + 1); + else + lastType = new String(signature); startOfParams = lastType.indexOf("<"); - endOfParams = locateMatchingEndBracket(lastType,startOfParams); + endOfParams = locateMatchingEndBracket(lastType, startOfParams); UnresolvedType[] typeParams = UnresolvedType.NONE; - if (startOfParams!=-1) { - typeParams = createTypeParams(lastType.substring(startOfParams +1, endOfParams)); + if (startOfParams != -1) { + typeParams = createTypeParams(lastType.substring(startOfParams + 1, endOfParams)); } - return new UnresolvedType(signature,signatureErasure,typeParams); + 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=='+') { + return WildcardedUnresolvedType.QUESTIONMARK; + } else if (firstChar == '+') { // ? extends ... - UnresolvedType upperBound = convertSigToType(signature.substring(1)); - WildcardedUnresolvedType wildcardedUT = new WildcardedUnresolvedType(signature, upperBound, null); + UnresolvedType upperBound = convertSigToType(signature.substring(1)); + WildcardedUnresolvedType wildcardedUT = new WildcardedUnresolvedType(signature, upperBound, null); return wildcardedUT; - } else if (firstChar=='-') { + } else if (firstChar == '-') { // ? super ... - UnresolvedType lowerBound = convertSigToType(signature.substring(1)); - WildcardedUnresolvedType wildcardedUT = new WildcardedUnresolvedType(signature, null, lowerBound); - return wildcardedUT; - } else if (firstChar=='T') { + 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); + typeVariableName = typeVariableName.substring(0, typeVariableName.length() - 1); } return new UnresolvedTypeVariableReferenceType(new TypeVariable(typeVariableName)); - } else if (firstChar=='[') { + } else if (firstChar == '[') { int dims = 0; - while (signature.charAt(dims)=='[') dims++; + 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, 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; + if (startOfParams == -1) + return -1; + int count = 1; int idx = startOfParams; - while (count>0 && idx<signature.length()) { + while (count > 0 && idx < signature.length()) { idx++; - if (signature.charAt(idx)=='<') count++; - if (signature.charAt(idx)=='>') count--; + 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; + if (startOfParams == -1) + return -1; + int count = 1; int idx = startOfParams; - while (count>0 && idx<signature.length()) { + while (count > 0 && idx < signature.length()) { idx++; - if (signature.charAt(idx)=='<') count++; - if (signature.charAt(idx)=='>') count--; + 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; + while (idx < signature.length()) { + if (signature.charAt(idx) == '<') + return idx; idx++; } return -1; @@ -209,36 +227,42 @@ public class TypeFactory { private static UnresolvedType[] createTypeParams(String typeParameterSpecification) { String remainingToProcess = typeParameterSpecification; List types = new ArrayList(); - while(!remainingToProcess.equals("")) { + 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; - } + 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++; } - break; - case ';' : - if (anglies == 0) { + 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))); + types.add(createTypeFromSignature(remainingToProcess.substring(0, endOfSig))); remainingToProcess = remainingToProcess.substring(endOfSig); } UnresolvedType[] typeParams = new UnresolvedType[types.size()]; @@ -247,25 +271,23 @@ public class TypeFactory { } // 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;>;>;" + * 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)); + parameterizedSig.append(baseTypeSignature.substring(1, baseTypeSignature.length() - 1)); if (arguments.length > 0) { parameterizedSig.append("<"); - for (int i=0;i<arguments.length;i++) { + for (int i = 0; i < arguments.length; i++) { parameterizedSig.append(arguments[i].getSignature()); } parameterizedSig.append(">"); } parameterizedSig.append(";"); - return createUnresolvedParameterizedType(parameterizedSig.toString(),baseTypeSignature,arguments); + return createUnresolvedParameterizedType(parameterizedSig.toString(), baseTypeSignature, arguments); } } diff --git a/weaver/src/org/aspectj/weaver/WeaverStateInfo.java b/weaver/src/org/aspectj/weaver/WeaverStateInfo.java index f202f76cb..08fa79004 100644 --- a/weaver/src/org/aspectj/weaver/WeaverStateInfo.java +++ b/weaver/src/org/aspectj/weaver/WeaverStateInfo.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver; import java.io.ByteArrayInputStream; @@ -32,171 +31,163 @@ import org.aspectj.bridge.IMessage; import org.aspectj.weaver.bcel.BcelTypeMunger; /** - * 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: + * 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: 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 List/* Entry */typeMungers; private boolean oldStyle; - + private boolean reweavable; - private boolean reweavableCompressedMode; // If true, unwovenClassFile is uncompressed on read + 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 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 static byte[] key = { -51, 34, 105, 56, -34, 65, 45, 78, -26, 125, 114, 97, 98, 1, -1, -42 }; private boolean unwovenClassFileIsADiff = false; - - public WeaverStateInfo() { - this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault,reweavableDiffModeDefault); + + private WeaverStateInfo() { + // this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault,reweavableDiffModeDefault); } - + public WeaverStateInfo(boolean reweavable) { - this(new ArrayList(), false,reweavable,reweavableCompressedModeDefault,reweavableDiffModeDefault); + this(new ArrayList(), false, reweavable, reweavableCompressedModeDefault, reweavableDiffModeDefault); } - - private WeaverStateInfo(List typeMungers, boolean oldStyle,boolean reweavableMode,boolean reweavableCompressedMode,boolean reweavableDiffMode) { + + private WeaverStateInfo(List typeMungers, boolean oldStyle, boolean reweavableMode, boolean reweavableCompressedMode, + boolean reweavableDiffMode) { this.typeMungers = typeMungers; - this.oldStyle = oldStyle; - this.reweavable = reweavableMode; + this.oldStyle = oldStyle; + this.reweavable = reweavableMode; this.reweavableCompressedMode = reweavableCompressedMode; - this.reweavableDiffMode = reweavableMode?reweavableDiffMode:false; - this.aspectsAffectingType= new HashSet(); + 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; - + + 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; - + 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 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 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); + + 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())); + 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. + * 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){ + 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); + for (int i = 0; i < n; i++) { + Entry e = (Entry) typeMungers.get(i); e.aspectType.write(s); e.typeMunger.write(s); } - writeAnyReweavableData(this,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(); @@ -205,12 +196,11 @@ public class WeaverStateInfo { 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); + world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ASPECT_NEEDED, entry.aspectType, onType), + onType.getSourceLocation(), null); continue; } - + ret.add(new BcelTypeMunger(entry.typeMunger, aspectType)); } return ret; @@ -219,14 +209,14 @@ public class WeaverStateInfo { public boolean isOldStyle() { return oldStyle; } - + public byte[] getUnwovenClassFileData(byte wovenClassFile[]) { - if (unwovenClassFileIsADiff){ + if (unwovenClassFileIsADiff) { unwovenClassFile = applyDiff(wovenClassFile, unwovenClassFile); - unwovenClassFileIsADiff = false; + unwovenClassFileIsADiff = false; } return unwovenClassFile; - } + } public void setUnwovenClassFileData(byte[] data) { unwovenClassFile = data; @@ -235,54 +225,57 @@ public class WeaverStateInfo { public boolean isReweavable() { return reweavable; } - + public void setReweavable(boolean rw) { reweavable = rw; } - - public void addAspectsAffectingType(Collection /*String*/ aspects) { + + public void addAspectsAffectingType(Collection /* String */aspects) { aspectsAffectingType.addAll(aspects); } + public void addAspectAffectingType(String aspectType) { aspectsAffectingType.add(aspectType); } - public Set /*String*/ getAspectsAffectingType() { + + public Set /* String */getAspectsAffectingType() { return this.aspectsAffectingType; } - - private static void readAnyReweavableData(WeaverStateInfo wsi,DataInputStream s) throws IOException { - if (wsi.isReweavable()) { + 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());} - + for (int i = 0; i < numberAspectsAffectingType; i++) { + wsi.addAspectAffectingType(s.readUTF()); + } + int unwovenClassFileSize = s.readInt(); - byte[] classData = null; + byte[] classData = null; // the unwovenClassFile may have been compressed: if (wsi.reweavableCompressedMode) { - classData = new byte[unwovenClassFileSize]; + 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; + 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); + 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 (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; @@ -291,187 +284,187 @@ public class WeaverStateInfo { } /** - * 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. + * 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){ + + 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 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); + 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){} + } 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){ + } + + 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){ + 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; - } - + 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 + // 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){ - + // 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])){ + 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]; - + 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); + 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); - + 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]; - + + 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); - + 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); - + 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); - + System.arraycopy(diff, 6, unWovenClassFile, 10 + lengthInCommon, diff.length - 6); + return unWovenClassFile; } - - private byte [] serializeInt(int i){ + + private byte[] serializeInt(int i) { ByteArrayOutputStream bos = new ByteArrayOutputStream(4); DataOutputStream dos = new DataOutputStream(bos); try { dos.writeInt(i); - } catch(IOException e) {} + } catch (IOException e) { + } return bos.toByteArray(); } - - - - private static void writeAnyReweavableData(WeaverStateInfo wsi,DataOutputStream s) throws IOException { + 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) { + if (wsi.aspectsAffectingType.size() > 0) { for (Iterator iter = wsi.aspectsAffectingType.iterator(); iter.hasNext();) { String type = (String) iter.next(); - s.writeUTF(type); + 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) { diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 167d70b24..9360c9c4a 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -51,535 +51,504 @@ import org.aspectj.weaver.tools.TraceFactory; public abstract class World implements Dump.INode { /** handler for any messages produced during resolution etc. */ private IMessageHandler messageHandler = IMessageHandler.SYSTEM_ERR; - + /** handler for cross-reference information produced during the weaving process */ private ICrossReferenceHandler xrefHandler = null; /** Currently 'active' scope in which to lookup (resolve) typevariable references */ private TypeVariableDeclaringElement typeVariableLookupScope; - + /** The heart of the world, a map from type signatures to resolved types */ - protected TypeMap typeMap = new TypeMap(this); // Signature to ResolvedType - - /** New pointcut designators this world supports */ - private Set pointcutDesignators; - - // see pr145963 - /** Should we create the hierarchy for binary classes and aspects*/ - public static boolean createInjarHierarchy = true; - - /** Calculator for working out aspect precedence */ - private AspectPrecedenceCalculator precedenceCalculator; - - /** All of the type and shadow mungers known to us */ - private CrosscuttingMembersSet crosscuttingMembersSet = - new CrosscuttingMembersSet(this); - - /** Model holds ASM relationships */ - private IHierarchy model = null; - - /** for processing Xlint messages */ - private Lint lint = new Lint(this); - - /** XnoInline option setting passed down to weaver */ - private boolean XnoInline; - - /** XlazyTjp option setting passed down to weaver */ - private boolean XlazyTjp; - - /** XhasMember option setting passed down to weaver */ - private boolean XhasMember = false; - - /** Xpinpoint controls whether we put out developer info showing the source of messages */ - private boolean Xpinpoint = false; - - /** When behaving in a Java 5 way autoboxing is considered */ - private boolean behaveInJava5Way = false; - - /** Determines if this world could be used for multiple compiles */ - private boolean incrementalCompileCouldFollow = false; - - /** The level of the aspectjrt.jar the code we generate needs to run on */ - private String targetAspectjRuntimeLevel = Constants.RUNTIME_LEVEL_DEFAULT; - - /** Flags for the new joinpoints that are 'optional' */ - private boolean optionalJoinpoint_ArrayConstruction = false; // Command line flag: "-Xjoinpoints:arrayconstruction" - private boolean optionalJoinpoint_Synchronization = false; // Command line flag: "-Xjoinpoints:synchronization" - - private boolean addSerialVerUID = false; - - - private Properties extraConfiguration = null; - private boolean checkedAdvancedConfiguration=false; - private boolean synchronizationPointcutsInUse = false; - // Xset'table options - private boolean fastDelegateSupportEnabled = isASMAround; + protected TypeMap typeMap = new TypeMap(this); // Signature to ResolvedType + + /** New pointcut designators this world supports */ + private Set pointcutDesignators; + + // see pr145963 + /** Should we create the hierarchy for binary classes and aspects */ + public static boolean createInjarHierarchy = true; + + /** Calculator for working out aspect precedence */ + private AspectPrecedenceCalculator precedenceCalculator; + + /** All of the type and shadow mungers known to us */ + private CrosscuttingMembersSet crosscuttingMembersSet = new CrosscuttingMembersSet(this); + + /** Model holds ASM relationships */ + private IHierarchy model = null; + + /** for processing Xlint messages */ + private Lint lint = new Lint(this); + + /** XnoInline option setting passed down to weaver */ + private boolean XnoInline; + + /** XlazyTjp option setting passed down to weaver */ + private boolean XlazyTjp; + + /** XhasMember option setting passed down to weaver */ + private boolean XhasMember = false; + + /** Xpinpoint controls whether we put out developer info showing the source of messages */ + private boolean Xpinpoint = false; + + /** When behaving in a Java 5 way autoboxing is considered */ + private boolean behaveInJava5Way = false; + + /** Determines if this world could be used for multiple compiles */ + private boolean incrementalCompileCouldFollow = false; + + /** The level of the aspectjrt.jar the code we generate needs to run on */ + private String targetAspectjRuntimeLevel = Constants.RUNTIME_LEVEL_DEFAULT; + + /** Flags for the new joinpoints that are 'optional' */ + private boolean optionalJoinpoint_ArrayConstruction = false; // Command line flag: "-Xjoinpoints:arrayconstruction" + private boolean optionalJoinpoint_Synchronization = false; // Command line flag: "-Xjoinpoints:synchronization" + + private boolean addSerialVerUID = false; + + private Properties extraConfiguration = null; + private boolean checkedAdvancedConfiguration = false; + private boolean synchronizationPointcutsInUse = false; + // Xset'table options private boolean runMinimalMemory = false; private boolean shouldPipelineCompilation = true; protected boolean bcelRepositoryCaching = xsetBCEL_REPOSITORY_CACHING_DEFAULT.equalsIgnoreCase("true"); - private boolean fastMethodPacking = false; + private boolean fastMethodPacking = false; private boolean completeBinaryTypes = false; public boolean forDEBUG_structuralChangesCode = false; public boolean forDEBUG_bridgingCode = false; - + private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.class); - - // Records whether ASM is around ... so we might use it for delegates - protected static boolean isASMAround = false; - + private long errorThreshold; private long warningThreshold; - - -// static { -// try { -// Class c = Class.forName("org.aspectj.org.objectweb.asm.ClassVisitor"); -// isASMAround = true; -// } catch (ClassNotFoundException cnfe) { -// isASMAround = false; -// } -// } - - /** - * A list of RuntimeExceptions containing full stack information for every - * type we couldn't find. - */ - private List dumpState_cantFindTypeExceptions = null; - - /** - * Play God. - * On the first day, God created the primitive types and put them in the type - * map. - */ - protected World() { - super(); - if (trace.isTraceEnabled()) trace.enter("<init>", this); - Dump.registerNode(this.getClass(),this); - typeMap.put("B", ResolvedType.BYTE); - typeMap.put("S", ResolvedType.SHORT); - typeMap.put("I", ResolvedType.INT); - typeMap.put("J", ResolvedType.LONG); - typeMap.put("F", ResolvedType.FLOAT); - typeMap.put("D", ResolvedType.DOUBLE); - typeMap.put("C", ResolvedType.CHAR); - typeMap.put("Z", ResolvedType.BOOLEAN); - typeMap.put("V", ResolvedType.VOID); - precedenceCalculator = new AspectPrecedenceCalculator(this); - if (trace.isTraceEnabled()) trace.exit("<init>"); - } - - /** - * Dump processing when a fatal error occurs - */ - public void accept (Dump.IVisitor visitor) { -// visitor.visitObject("Extra configuration:"); -// visitor.visitList(extraConfiguration.); + + /** + * A list of RuntimeExceptions containing full stack information for every type we couldn't find. + */ + private List dumpState_cantFindTypeExceptions = null; + + /** + * Play God. On the first day, God created the primitive types and put them in the type map. + */ + protected World() { + super(); + if (trace.isTraceEnabled()) + trace.enter("<init>", this); + Dump.registerNode(this.getClass(), this); + typeMap.put("B", ResolvedType.BYTE); + typeMap.put("S", ResolvedType.SHORT); + typeMap.put("I", ResolvedType.INT); + typeMap.put("J", ResolvedType.LONG); + typeMap.put("F", ResolvedType.FLOAT); + typeMap.put("D", ResolvedType.DOUBLE); + typeMap.put("C", ResolvedType.CHAR); + typeMap.put("Z", ResolvedType.BOOLEAN); + typeMap.put("V", ResolvedType.VOID); + precedenceCalculator = new AspectPrecedenceCalculator(this); + if (trace.isTraceEnabled()) + trace.exit("<init>"); + } + + /** + * Dump processing when a fatal error occurs + */ + public void accept(Dump.IVisitor visitor) { + // visitor.visitObject("Extra configuration:"); + // visitor.visitList(extraConfiguration.); visitor.visitObject("Shadow mungers:"); visitor.visitList(crosscuttingMembersSet.getShadowMungers()); visitor.visitObject("Type mungers:"); visitor.visitList(crosscuttingMembersSet.getTypeMungers()); - visitor.visitObject("Late Type mungers:"); - visitor.visitList(crosscuttingMembersSet.getLateTypeMungers()); - if (dumpState_cantFindTypeExceptions!=null) { - visitor.visitObject("Cant find type problems:"); - visitor.visitList(dumpState_cantFindTypeExceptions); - dumpState_cantFindTypeExceptions = null; - } - } - - - // ============================================================================= - // T Y P E R E S O L U T I O N - // ============================================================================= - - /** - * Resolve a type that we require to be present in the world - */ - public ResolvedType resolve(UnresolvedType ty) { - return resolve(ty, false); - } - - /** - * Attempt to resolve a type - the source location gives you some context in which - * resolution is taking place. In the case of an error where we can't find the - * type - we can then at least report why (source location) we were trying to resolve it. - */ - public ResolvedType resolve(UnresolvedType ty,ISourceLocation isl) { - ResolvedType ret = resolve(ty,true); - if (ResolvedType.isMissing(ty)) { - //IMessage msg = null; - getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName()),isl); - //if (isl!=null) { - //msg = MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName()),isl); - //} else { - //msg = MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); - //} - //messageHandler.handleMessage(msg); - } - return ret; - } - - /** - * Convenience method for resolving an array of unresolved types - * in one hit. Useful for e.g. resolving type parameters in signatures. - */ - public ResolvedType[] resolve(UnresolvedType[] types) { - if (types == null) return new ResolvedType[0]; - - ResolvedType[] ret = new ResolvedType[types.length]; - for (int i=0; i<types.length; i++) { - ret[i] = resolve(types[i]); - } - return ret; - } - - /** - * Resolve a type. This the hub of type resolution. The resolved type is added - * to the type map by signature. - */ - public ResolvedType resolve(UnresolvedType ty, boolean allowMissing) { - - // special resolution processing for already resolved types. - if (ty instanceof ResolvedType) { - ResolvedType rty = (ResolvedType) ty; - rty = resolve(rty); - return rty; - } - - // dispatch back to the type variable reference to resolve its constituent parts - // don't do this for other unresolved types otherwise you'll end up in a loop - if (ty.isTypeVariableReference()) { - return ty.resolve(this); - } - - // if we've already got a resolved type for the signature, just return it - // after updating the world - String signature = ty.getSignature(); - ResolvedType ret = typeMap.get(signature); - if (ret != null) { - ret.world = this; // Set the world for the RTX - return ret; - } else if ( signature.equals("?") || signature.equals("*")) { - // might be a problem here, not sure '?' should make it to here as a signature, the - // proper signature for wildcard '?' is '*' - // fault in generic wildcard, can't be done earlier because of init issues - ResolvedType something = new BoundedReferenceType("?","Ljava/lang/Object",this); - typeMap.put("?",something); - return something; - } - - // no existing resolved type, create one - if (ty.isArray()) { - ResolvedType componentType = resolve(ty.getComponentType(),allowMissing); - //String brackets = signature.substring(0,signature.lastIndexOf("[")+1); - ret = new ArrayReferenceType(signature, "["+componentType.getErasureSignature(), - this, - componentType); - } else { - ret = resolveToReferenceType(ty,allowMissing); - if (!allowMissing && ret.isMissing()) { - ret = handleRequiredMissingTypeDuringResolution(ty); - } - if (completeBinaryTypes) { - completeBinaryType(ret); - } - } - + visitor.visitObject("Late Type mungers:"); + visitor.visitList(crosscuttingMembersSet.getLateTypeMungers()); + if (dumpState_cantFindTypeExceptions != null) { + visitor.visitObject("Cant find type problems:"); + visitor.visitList(dumpState_cantFindTypeExceptions); + dumpState_cantFindTypeExceptions = null; + } + } + + // ============================================================================= + // T Y P E R E S O L U T I O N + // ============================================================================= + + /** + * Resolve a type that we require to be present in the world + */ + public ResolvedType resolve(UnresolvedType ty) { + return resolve(ty, false); + } + + /** + * Attempt to resolve a type - the source location gives you some context in which resolution is taking place. In the case of an + * error where we can't find the type - we can then at least report why (source location) we were trying to resolve it. + */ + public ResolvedType resolve(UnresolvedType ty, ISourceLocation isl) { + ResolvedType ret = resolve(ty, true); + if (ResolvedType.isMissing(ty)) { + // IMessage msg = null; + getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE, ty.getName()), isl); + // if (isl!=null) { + // msg = MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName()),isl); + // } else { + // msg = MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); + // } + // messageHandler.handleMessage(msg); + } + return ret; + } + + /** + * Convenience method for resolving an array of unresolved types in one hit. Useful for e.g. resolving type parameters in + * signatures. + */ + public ResolvedType[] resolve(UnresolvedType[] types) { + if (types == null) + return new ResolvedType[0]; + + ResolvedType[] ret = new ResolvedType[types.length]; + for (int i = 0; i < types.length; i++) { + ret[i] = resolve(types[i]); + } + return ret; + } + + /** + * Resolve a type. This the hub of type resolution. The resolved type is added to the type map by signature. + */ + public ResolvedType resolve(UnresolvedType ty, boolean allowMissing) { + + // special resolution processing for already resolved types. + if (ty instanceof ResolvedType) { + ResolvedType rty = (ResolvedType) ty; + rty = resolve(rty); + return rty; + } + + // dispatch back to the type variable reference to resolve its constituent parts + // don't do this for other unresolved types otherwise you'll end up in a loop + if (ty.isTypeVariableReference()) { + return ty.resolve(this); + } + + // if we've already got a resolved type for the signature, just return it + // after updating the world + String signature = ty.getSignature(); + ResolvedType ret = typeMap.get(signature); + if (ret != null) { + ret.world = this; // Set the world for the RTX + return ret; + } else if (signature.equals("?") || signature.equals("*")) { + // might be a problem here, not sure '?' should make it to here as a signature, the + // proper signature for wildcard '?' is '*' + // fault in generic wildcard, can't be done earlier because of init issues + ResolvedType something = new BoundedReferenceType("?", "Ljava/lang/Object", this); + typeMap.put("?", something); + return something; + } + + // no existing resolved type, create one + if (ty.isArray()) { + ResolvedType componentType = resolve(ty.getComponentType(), allowMissing); + // String brackets = signature.substring(0,signature.lastIndexOf("[")+1); + ret = new ArrayReferenceType(signature, "[" + componentType.getErasureSignature(), this, componentType); + } else { + ret = resolveToReferenceType(ty, allowMissing); + if (!allowMissing && ret.isMissing()) { + ret = handleRequiredMissingTypeDuringResolution(ty); + } + if (completeBinaryTypes) { + completeBinaryType(ret); + } + } + // Pulling in the type may have already put the right entry in the map - if (typeMap.get(signature)==null && !ret.isMissing()) { - typeMap.put(signature, ret); + if (typeMap.get(signature) == null && !ret.isMissing()) { + typeMap.put(signature, ret); } - return ret; - } - + return ret; + } + /** - * Called when a type is resolved - enables its type hierarchy to be finished off before we - * proceed - */ - protected void completeBinaryType(ResolvedType ret) {} - - - /** - * Return true if the classloader relating to this world is definetly the one that will - * define the specified class. Return false otherwise or we don't know for certain. - */ - public boolean isLocallyDefined(String classname) { - return false; - } - - /** - * We tried to resolve a type and couldn't find it... - */ + * Called when a type is resolved - enables its type hierarchy to be finished off before we proceed + */ + protected void completeBinaryType(ResolvedType ret) { + } + + /** + * Return true if the classloader relating to this world is definetly the one that will define the specified class. Return false + * otherwise or we don't know for certain. + */ + public boolean isLocallyDefined(String classname) { + return false; + } + + /** + * We tried to resolve a type and couldn't find it... + */ private ResolvedType handleRequiredMissingTypeDuringResolution(UnresolvedType ty) { // defer the message until someone asks a question of the type that we can't answer // just from the signature. -// MessageUtil.error(messageHandler, -// WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); - if (dumpState_cantFindTypeExceptions==null) { - dumpState_cantFindTypeExceptions = new ArrayList(); + // MessageUtil.error(messageHandler, + // WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); + if (dumpState_cantFindTypeExceptions == null) { + dumpState_cantFindTypeExceptions = new ArrayList(); } if (dumpState_cantFindTypeExceptions.size() < 100) { // limit growth - dumpState_cantFindTypeExceptions.add(new RuntimeException("Can't find type " + ty.getName())); - } - return new MissingResolvedTypeWithKnownSignature(ty.getSignature(),this); - } - - /** - * Some TypeFactory operations create resolved types directly, but these won't be - * in the typeMap - this resolution process puts them there. Resolved types are - * also told their world which is needed for the special autoboxing resolved types. - */ - public ResolvedType resolve(ResolvedType ty) { - if (ty.isTypeVariableReference()) return ty; // until type variables have proper sigs... - ResolvedType resolved = typeMap.get(ty.getSignature()); - if (resolved == null) { - typeMap.put(ty.getSignature(), ty); - resolved = ty; - } - resolved.world = this; - return resolved; - } - - /** - * Convenience method for finding a type by name and resolving it in one step. - */ - public ResolvedType resolve(String name) { -// trace.enter("resolve", this, new Object[] {name}); - ResolvedType ret = resolve(UnresolvedType.forName(name)); -// trace.exit("resolve", ret); - return ret; - } - - public ResolvedType resolve(String name,boolean allowMissing) { - return resolve(UnresolvedType.forName(name),allowMissing); - } - + dumpState_cantFindTypeExceptions.add(new RuntimeException("Can't find type " + ty.getName())); + } + return new MissingResolvedTypeWithKnownSignature(ty.getSignature(), this); + } + /** - * Resolve to a ReferenceType - simple, raw, parameterized, or generic. - * Raw, parameterized, and generic versions of a type share a delegate. - */ - private final ResolvedType resolveToReferenceType(UnresolvedType ty,boolean allowMissing) { + * Some TypeFactory operations create resolved types directly, but these won't be in the typeMap - this resolution process puts + * them there. Resolved types are also told their world which is needed for the special autoboxing resolved types. + */ + public ResolvedType resolve(ResolvedType ty) { + if (ty.isTypeVariableReference()) + return ty; // until type variables have proper sigs... + ResolvedType resolved = typeMap.get(ty.getSignature()); + if (resolved == null) { + typeMap.put(ty.getSignature(), ty); + resolved = ty; + } + resolved.world = this; + return resolved; + } + + /** + * Convenience method for finding a type by name and resolving it in one step. + */ + public ResolvedType resolve(String name) { + // trace.enter("resolve", this, new Object[] {name}); + ResolvedType ret = resolve(UnresolvedType.forName(name)); + // trace.exit("resolve", ret); + return ret; + } + + public ResolvedType resolve(String name, boolean allowMissing) { + return resolve(UnresolvedType.forName(name), allowMissing); + } + + /** + * Resolve to a ReferenceType - simple, raw, parameterized, or generic. Raw, parameterized, and generic versions of a type share + * a delegate. + */ + private final ResolvedType resolveToReferenceType(UnresolvedType ty, boolean allowMissing) { if (ty.isParameterizedType()) { // ======= parameterized types ================ - ResolvedType rt = resolveGenericTypeFor(ty,allowMissing); - if (rt.isMissing()) return rt; - ReferenceType genericType = (ReferenceType)rt; - ReferenceType parameterizedType = - TypeFactory.createParameterizedType(genericType, ty.typeParameters, this); + ResolvedType rt = resolveGenericTypeFor(ty, allowMissing); + if (rt.isMissing()) + return rt; + ReferenceType genericType = (ReferenceType) rt; + ReferenceType parameterizedType = TypeFactory.createParameterizedType(genericType, ty.typeParameters, this); return parameterizedType; - + } else if (ty.isGenericType()) { // ======= generic types ====================== - ReferenceType genericType = (ReferenceType)resolveGenericTypeFor(ty,false); + ReferenceType genericType = (ReferenceType) resolveGenericTypeFor(ty, false); return genericType; - + } else if (ty.isGenericWildcard()) { // ======= generic wildcard types ============= return resolveGenericWildcardFor((WildcardedUnresolvedType) ty); - } else { + } else { // ======= simple and raw types =============== String erasedSignature = ty.getErasureSignature(); - ReferenceType simpleOrRawType = new ReferenceType(erasedSignature, this); - if (ty.needsModifiableDelegate()) simpleOrRawType.setNeedsModifiableDelegate(true); - ReferenceTypeDelegate delegate = resolveDelegate(simpleOrRawType); - // 117854 -// if (delegate == null) return ResolvedType.MISSING; - if (delegate == null) return new MissingResolvedTypeWithKnownSignature(ty.getSignature(),erasedSignature,this);//ResolvedType.MISSING; - - if (delegate.isGeneric() && behaveInJava5Way) { - // ======== raw type =========== - simpleOrRawType.typeKind = TypeKind.RAW; - ReferenceType genericType = makeGenericTypeFrom(delegate,simpleOrRawType); - // name = ReferenceType.fromTypeX(UnresolvedType.forRawTypeNames(ty.getName()),this); - simpleOrRawType.setDelegate(delegate); - genericType.setDelegate(delegate); - simpleOrRawType.setGenericType(genericType); - return simpleOrRawType; - - } else { - // ======== simple type ========= - simpleOrRawType.setDelegate(delegate); - return simpleOrRawType; - } + ReferenceType simpleOrRawType = new ReferenceType(erasedSignature, this); + if (ty.needsModifiableDelegate()) + simpleOrRawType.setNeedsModifiableDelegate(true); + ReferenceTypeDelegate delegate = resolveDelegate(simpleOrRawType); + // 117854 + // if (delegate == null) return ResolvedType.MISSING; + if (delegate == null) + return new MissingResolvedTypeWithKnownSignature(ty.getSignature(), erasedSignature, this);// ResolvedType.MISSING; + + if (delegate.isGeneric() && behaveInJava5Way) { + // ======== raw type =========== + simpleOrRawType.typeKind = TypeKind.RAW; + ReferenceType genericType = makeGenericTypeFrom(delegate, simpleOrRawType); + // name = ReferenceType.fromTypeX(UnresolvedType.forRawTypeNames(ty.getName()),this); + simpleOrRawType.setDelegate(delegate); + genericType.setDelegate(delegate); + simpleOrRawType.setGenericType(genericType); + return simpleOrRawType; + + } else { + // ======== simple type ========= + simpleOrRawType.setDelegate(delegate); + return simpleOrRawType; + } } - } - - /** - * Attempt to resolve a type that should be a generic type. - */ - public ResolvedType resolveGenericTypeFor(UnresolvedType anUnresolvedType, boolean allowMissing) { - // Look up the raw type by signature - String rawSignature = anUnresolvedType.getRawType().getSignature(); - ResolvedType rawType = typeMap.get(rawSignature); - if (rawType==null) { - rawType = resolve(UnresolvedType.forSignature(rawSignature),allowMissing); - typeMap.put(rawSignature,rawType); - } - if (rawType.isMissing()) return rawType; - - // Does the raw type know its generic form? (It will if we created the - // raw type from a source type, it won't if its been created just through - // being referenced, e.g. java.util.List - ResolvedType genericType = rawType.getGenericType(); - - // There is a special case to consider here (testGenericsBang_pr95993 highlights it) - // You may have an unresolvedType for a parameterized type but it - // is backed by a simple type rather than a generic type. This occurs for - // inner types of generic types that inherit their enclosing types - // type variables. - if (rawType.isSimpleType() && (anUnresolvedType.typeParameters==null || anUnresolvedType.typeParameters.length==0)) { - rawType.world = this; - return rawType; - } - - if (genericType != null) { - genericType.world = this; - return genericType; - } else { - // Fault in the generic that underpins the raw type ;) - ReferenceTypeDelegate delegate = resolveDelegate((ReferenceType)rawType); - ReferenceType genericRefType = makeGenericTypeFrom(delegate,((ReferenceType)rawType)); - ((ReferenceType)rawType).setGenericType(genericRefType); - genericRefType.setDelegate(delegate); - ((ReferenceType)rawType).setDelegate(delegate); - return genericRefType; - } - } - - private ReferenceType makeGenericTypeFrom(ReferenceTypeDelegate delegate, ReferenceType rawType) { - String genericSig = delegate.getDeclaredGenericSignature(); - if (genericSig != null) { - return new ReferenceType( - UnresolvedType.forGenericTypeSignature(rawType.getSignature(),delegate.getDeclaredGenericSignature()),this); - } else { - return new ReferenceType( - UnresolvedType.forGenericTypeVariables(rawType.getSignature(), delegate.getTypeVariables()),this); - } - } - - /** - * Go from an unresolved generic wildcard (represented by UnresolvedType) to a resolved version (BoundedReferenceType). - */ - private ReferenceType resolveGenericWildcardFor(WildcardedUnresolvedType aType) { - BoundedReferenceType ret = null; - // FIXME asc doesnt take account of additional interface bounds (e.g. ? super R & Serializable - can you do that?) - if (aType.isExtends()) { - ReferenceType upperBound = (ReferenceType)resolve(aType.getUpperBound()); - ret = new BoundedReferenceType(upperBound,true,this); - } else if (aType.isSuper()) { - ReferenceType lowerBound = (ReferenceType) resolve(aType.getLowerBound()); - ret = new BoundedReferenceType(lowerBound,false,this); - } else { - // must be ? on its own! - ret = new BoundedReferenceType("*", "Ljava/lang/Object", this); - } - return ret; - } - - /** - * Find the ReferenceTypeDelegate behind this reference type so that it can - * fulfill its contract. - */ - protected abstract ReferenceTypeDelegate resolveDelegate(ReferenceType ty); - - /** - * Special resolution for "core" types like OBJECT. These are resolved just like - * any other type, but if they are not found it is more serious and we issue an - * error message immediately. - */ - // OPTIMIZE streamline path for core types? They are just simple types, could look straight in the typemap? - public ResolvedType getCoreType(UnresolvedType tx) { - ResolvedType coreTy = resolve(tx,true); - if (coreTy.isMissing()) { - MessageUtil.error(messageHandler, - WeaverMessages.format(WeaverMessages.CANT_FIND_CORE_TYPE,tx.getName())); - } - return coreTy; - } - - /** - * Lookup a type by signature, if not found then build one and put it in the - * map. - */ + } + + /** + * Attempt to resolve a type that should be a generic type. + */ + public ResolvedType resolveGenericTypeFor(UnresolvedType anUnresolvedType, boolean allowMissing) { + // Look up the raw type by signature + String rawSignature = anUnresolvedType.getRawType().getSignature(); + ResolvedType rawType = typeMap.get(rawSignature); + if (rawType == null) { + rawType = resolve(UnresolvedType.forSignature(rawSignature), allowMissing); + typeMap.put(rawSignature, rawType); + } + if (rawType.isMissing()) + return rawType; + + // Does the raw type know its generic form? (It will if we created the + // raw type from a source type, it won't if its been created just through + // being referenced, e.g. java.util.List + ResolvedType genericType = rawType.getGenericType(); + + // There is a special case to consider here (testGenericsBang_pr95993 highlights it) + // You may have an unresolvedType for a parameterized type but it + // is backed by a simple type rather than a generic type. This occurs for + // inner types of generic types that inherit their enclosing types + // type variables. + if (rawType.isSimpleType() && (anUnresolvedType.typeParameters == null || anUnresolvedType.typeParameters.length == 0)) { + rawType.world = this; + return rawType; + } + + if (genericType != null) { + genericType.world = this; + return genericType; + } else { + // Fault in the generic that underpins the raw type ;) + ReferenceTypeDelegate delegate = resolveDelegate((ReferenceType) rawType); + ReferenceType genericRefType = makeGenericTypeFrom(delegate, ((ReferenceType) rawType)); + ((ReferenceType) rawType).setGenericType(genericRefType); + genericRefType.setDelegate(delegate); + ((ReferenceType) rawType).setDelegate(delegate); + return genericRefType; + } + } + + private ReferenceType makeGenericTypeFrom(ReferenceTypeDelegate delegate, ReferenceType rawType) { + String genericSig = delegate.getDeclaredGenericSignature(); + if (genericSig != null) { + return new ReferenceType(UnresolvedType.forGenericTypeSignature(rawType.getSignature(), delegate + .getDeclaredGenericSignature()), this); + } else { + return new ReferenceType(UnresolvedType.forGenericTypeVariables(rawType.getSignature(), delegate.getTypeVariables()), + this); + } + } + + /** + * Go from an unresolved generic wildcard (represented by UnresolvedType) to a resolved version (BoundedReferenceType). + */ + private ReferenceType resolveGenericWildcardFor(WildcardedUnresolvedType aType) { + BoundedReferenceType ret = null; + // FIXME asc doesnt take account of additional interface bounds (e.g. ? super R & Serializable - can you do that?) + if (aType.isExtends()) { + ReferenceType upperBound = (ReferenceType) resolve(aType.getUpperBound()); + ret = new BoundedReferenceType(upperBound, true, this); + } else if (aType.isSuper()) { + ReferenceType lowerBound = (ReferenceType) resolve(aType.getLowerBound()); + ret = new BoundedReferenceType(lowerBound, false, this); + } else { + // must be ? on its own! + ret = new BoundedReferenceType("*", "Ljava/lang/Object", this); + } + return ret; + } + + /** + * Find the ReferenceTypeDelegate behind this reference type so that it can fulfill its contract. + */ + protected abstract ReferenceTypeDelegate resolveDelegate(ReferenceType ty); + + /** + * Special resolution for "core" types like OBJECT. These are resolved just like any other type, but if they are not found it is + * more serious and we issue an error message immediately. + */ + // OPTIMIZE streamline path for core types? They are just simple types, could look straight in the typemap? + public ResolvedType getCoreType(UnresolvedType tx) { + ResolvedType coreTy = resolve(tx, true); + if (coreTy.isMissing()) { + MessageUtil.error(messageHandler, WeaverMessages.format(WeaverMessages.CANT_FIND_CORE_TYPE, tx.getName())); + } + return coreTy; + } + + /** + * Lookup a type by signature, if not found then build one and put it in the map. + */ public ReferenceType lookupOrCreateName(UnresolvedType ty) { String signature = ty.getSignature(); - ReferenceType ret = lookupBySignature(signature); - if (ret == null) { - ret = ReferenceType.fromTypeX(ty, this); - typeMap.put(signature, ret); - } + ReferenceType ret = lookupBySignature(signature); + if (ret == null) { + ret = ReferenceType.fromTypeX(ty, this); + typeMap.put(signature, ret); + } return ret; } /** - * Lookup a reference type in the world by its signature. Returns - * null if not found. + * Lookup a reference type in the world by its signature. Returns null if not found. */ public ReferenceType lookupBySignature(String signature) { return (ReferenceType) typeMap.get(signature); } - - - // ============================================================================= - // T Y P E R E S O L U T I O N -- E N D - // ============================================================================= - - /** - * Member resolution is achieved by resolving the declaring type and then - * looking up the member in the resolved declaring type. - */ - public ResolvedMember resolve(Member member) { - ResolvedType declaring = member.getDeclaringType().resolve(this); - if (declaring.isRawType()) declaring = declaring.getGenericType(); - ResolvedMember ret; - if (member.getKind() == Member.FIELD) { - ret = declaring.lookupField(member); - } else { - ret = declaring.lookupMethod(member); - } - - if (ret != null) return ret; - - return declaring.lookupSyntheticMember(member); - } - - // Methods for creating various cross-cutting members... - // =========================================================== - - /** - * Create an advice shadow munger from the given advice attribute - */ - public abstract Advice createAdviceMunger( - AjAttribute.AdviceAttribute attribute, - Pointcut pointcut, - Member signature); - - /** - * Create an advice shadow munger for the given advice kind - */ - public final Advice createAdviceMunger( - AdviceKind kind, - Pointcut p, - Member signature, - int extraParameterFlags, - IHasSourceLocation loc) - { - AjAttribute.AdviceAttribute attribute = - new AjAttribute.AdviceAttribute(kind, p, extraParameterFlags, loc.getStart(), loc.getEnd(), loc.getSourceContext()); + + // ============================================================================= + // T Y P E R E S O L U T I O N -- E N D + // ============================================================================= + + /** + * Member resolution is achieved by resolving the declaring type and then looking up the member in the resolved declaring type. + */ + public ResolvedMember resolve(Member member) { + ResolvedType declaring = member.getDeclaringType().resolve(this); + if (declaring.isRawType()) + declaring = declaring.getGenericType(); + ResolvedMember ret; + if (member.getKind() == Member.FIELD) { + ret = declaring.lookupField(member); + } else { + ret = declaring.lookupMethod(member); + } + + if (ret != null) + return ret; + + return declaring.lookupSyntheticMember(member); + } + + // Methods for creating various cross-cutting members... + // =========================================================== + + /** + * Create an advice shadow munger from the given advice attribute + */ + public abstract Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature); + + /** + * Create an advice shadow munger for the given advice kind + */ + public final Advice createAdviceMunger(AdviceKind kind, Pointcut p, Member signature, int extraParameterFlags, + IHasSourceLocation loc) { + AjAttribute.AdviceAttribute attribute = new AjAttribute.AdviceAttribute(kind, p, extraParameterFlags, loc.getStart(), loc + .getEnd(), loc.getSourceContext()); return createAdviceMunger(attribute, p, 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); + /** + * 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 abstract ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType); /** * Same signature as org.aspectj.util.PartialOrder.PartialComparable.compareTo @@ -587,24 +556,23 @@ public abstract class World implements Dump.INode { public int compareByPrecedence(ResolvedType aspect1, ResolvedType aspect2) { return precedenceCalculator.compareByPrecedence(aspect1, aspect2); } + public Integer getPrecedenceIfAny(ResolvedType aspect1, ResolvedType aspect2) { return precedenceCalculator.getPrecedenceIfAny(aspect1, aspect2); } - + /** - * compares by precedence with the additional rule that a super-aspect is - * sorted before its sub-aspects + * compares by precedence with the additional rule that a super-aspect is sorted before its sub-aspects */ public int compareByPrecedenceAndHierarchy(ResolvedType aspect1, ResolvedType aspect2) { return precedenceCalculator.compareByPrecedenceAndHierarchy(aspect1, aspect2); } - // simple property getter and setters - // =========================================================== - + // simple property getter and setters + // =========================================================== + /** - * Nobody should hold onto a copy of this message handler, or setMessageHandler won't - * work right. + * Nobody should hold onto a copy of this message handler, or setMessageHandler won't work right. */ public IMessageHandler getMessageHandler() { return messageHandler; @@ -614,66 +582,56 @@ public abstract class World implements Dump.INode { if (this.isInPinpointMode()) { this.messageHandler = new PinpointingMessageHandler(messageHandler); } else { - this.messageHandler = messageHandler; + this.messageHandler = messageHandler; } } /** - * convenenience method for creating and issuing messages via the message handler - - * if you supply two locations you will get two messages. + * convenenience method for creating and issuing messages via the message handler - if you supply two locations you will get two + * messages. */ - public void showMessage( - Kind kind, - String message, - ISourceLocation loc1, - ISourceLocation loc2) - { - if (loc1 != null) { - messageHandler.handleMessage(new Message(message, kind, null, loc1)); - if (loc2 != null) { - messageHandler.handleMessage(new Message(message, kind, null, loc2)); - } - } else { + public void showMessage(Kind kind, String message, ISourceLocation loc1, ISourceLocation loc2) { + if (loc1 != null) { + messageHandler.handleMessage(new Message(message, kind, null, loc1)); + if (loc2 != null) { messageHandler.handleMessage(new Message(message, kind, null, loc2)); } + } else { + messageHandler.handleMessage(new Message(message, kind, null, loc2)); } - - public boolean debug (String message) { - return MessageUtil.debug(messageHandler,message); } public void setCrossReferenceHandler(ICrossReferenceHandler xrefHandler) { this.xrefHandler = xrefHandler; } - /** - * Get the cross-reference handler for the world, may be null. - */ - public ICrossReferenceHandler getCrossReferenceHandler() { - return this.xrefHandler; - } - - public void setTypeVariableLookupScope(TypeVariableDeclaringElement scope) { - this.typeVariableLookupScope = scope; - } + /** + * Get the cross-reference handler for the world, may be null. + */ + public ICrossReferenceHandler getCrossReferenceHandler() { + return this.xrefHandler; + } - public TypeVariableDeclaringElement getTypeVariableLookupScope() { - return typeVariableLookupScope; - } + public void setTypeVariableLookupScope(TypeVariableDeclaringElement scope) { + this.typeVariableLookupScope = scope; + } + public TypeVariableDeclaringElement getTypeVariableLookupScope() { + return typeVariableLookupScope; + } public List getDeclareParents() { return crosscuttingMembersSet.getDeclareParents(); } - + public List getDeclareAnnotationOnTypes() { return crosscuttingMembersSet.getDeclareAnnotationOnTypes(); } - + public List getDeclareAnnotationOnFields() { return crosscuttingMembersSet.getDeclareAnnotationOnFields(); } - + public List getDeclareAnnotationOnMethods() { return crosscuttingMembersSet.getDeclareAnnotationOnMethods(); } @@ -709,7 +667,7 @@ public abstract class World implements Dump.INode { public void setXnoInline(boolean xnoInline) { XnoInline = xnoInline; } - + public boolean isXlazyTjp() { return XlazyTjp; } @@ -717,11 +675,11 @@ public abstract class World implements Dump.INode { public void setXlazyTjp(boolean b) { XlazyTjp = b; } - + public boolean isHasMemberSupportEnabled() { return XhasMember; } - + public void setXHasMemberSupportEnabled(boolean b) { XhasMember = b; } @@ -729,18 +687,17 @@ public abstract class World implements Dump.INode { public boolean isInPinpointMode() { return Xpinpoint; } - + public void setPinpointMode(boolean b) { this.Xpinpoint = b; } - + public void setBehaveInJava5Way(boolean b) { - behaveInJava5Way = b; - } - + behaveInJava5Way = b; + } + /** - * Set the error and warning threashold which can be taken from - * CompilerOptions (see bug 129282) + * Set the error and warning threashold which can be taken from CompilerOptions (see bug 129282) * * @param errorThreshold * @param warningThreshold @@ -749,125 +706,128 @@ public abstract class World implements Dump.INode { this.errorThreshold = errorThreshold; this.warningThreshold = warningThreshold; } - + /** - * @return true if ignoring the UnusedDeclaredThrownException and false if - * this compiler option is set to error or warning + * @return true if ignoring the UnusedDeclaredThrownException and false if this compiler option is set to error or warning */ public boolean isIgnoringUnusedDeclaredThrownException() { // the 0x800000 is CompilerOptions.UnusedDeclaredThrownException // which is ASTNode.bit24 - if((this.errorThreshold & 0x800000) != 0 - || (this.warningThreshold & 0x800000) != 0) + if ((this.errorThreshold & 0x800000) != 0 || (this.warningThreshold & 0x800000) != 0) return false; return true; } - + public void performExtraConfiguration(String config) { - if (config==null) return; + if (config == null) + return; // Bunch of name value pairs to split extraConfiguration = new Properties(); - int pos =-1; - while ((pos=config.indexOf(","))!=-1) { - String nvpair = config.substring(0,pos); + int pos = -1; + while ((pos = config.indexOf(",")) != -1) { + String nvpair = config.substring(0, pos); int pos2 = nvpair.indexOf("="); - if (pos2!=-1) { - String n = nvpair.substring(0,pos2); - String v = nvpair.substring(pos2+1); - extraConfiguration.setProperty(n,v); + if (pos2 != -1) { + String n = nvpair.substring(0, pos2); + String v = nvpair.substring(pos2 + 1); + extraConfiguration.setProperty(n, v); } - config = config.substring(pos+1); + config = config.substring(pos + 1); } - if (config.length()>0) { + if (config.length() > 0) { int pos2 = config.indexOf("="); - if (pos2!=-1) { - String n = config.substring(0,pos2); - String v = config.substring(pos2+1); - extraConfiguration.setProperty(n,v); + if (pos2 != -1) { + String n = config.substring(0, pos2); + String v = config.substring(pos2 + 1); + extraConfiguration.setProperty(n, v); } } ensureAdvancedConfigurationProcessed(); } - + /** * may return null */ public Properties getExtraConfiguration() { return extraConfiguration; } - public final static String xsetWEAVE_JAVA_PACKAGES = "weaveJavaPackages"; // default false - controls LTW - public final static String xsetWEAVE_JAVAX_PACKAGES = "weaveJavaxPackages"; // default false - controls LTW + + public final static String xsetWEAVE_JAVA_PACKAGES = "weaveJavaPackages"; // default false - controls LTW + public final static String xsetWEAVE_JAVAX_PACKAGES = "weaveJavaxPackages"; // default false - controls LTW public final static String xsetCAPTURE_ALL_CONTEXT = "captureAllContext"; // default false - public final static String xsetACTIVATE_LIGHTWEIGHT_DELEGATES = "activateLightweightDelegates"; // default true - public final static String xsetRUN_MINIMAL_MEMORY ="runMinimalMemory"; // default true + public final static String xsetRUN_MINIMAL_MEMORY = "runMinimalMemory"; // default true public final static String xsetDEBUG_STRUCTURAL_CHANGES_CODE = "debugStructuralChangesCode"; // default false public final static String xsetDEBUG_BRIDGING = "debugBridging"; // default false public final static String xsetBCEL_REPOSITORY_CACHING = "bcelRepositoryCaching"; public final static String xsetPIPELINE_COMPILATION = "pipelineCompilation"; - public final static String xsetPIPELINE_COMPILATION_DEFAULT = "true"; + public final static String xsetPIPELINE_COMPILATION_DEFAULT = "true"; public final static String xsetCOMPLETE_BINARY_TYPES = "completeBinaryTypes"; - public final static String xsetCOMPLETE_BINARY_TYPES_DEFAULT = "false"; - public final static String xsetBCEL_REPOSITORY_CACHING_DEFAULT = "true"; - public final static String xsetFAST_PACK_METHODS = "fastPackMethods"; // default TRUE - + public final static String xsetCOMPLETE_BINARY_TYPES_DEFAULT = "false"; + public final static String xsetBCEL_REPOSITORY_CACHING_DEFAULT = "true"; + public final static String xsetFAST_PACK_METHODS = "fastPackMethods"; // default TRUE + public boolean isInJava5Mode() { return behaveInJava5Way; } - + public void setTargetAspectjRuntimeLevel(String s) { targetAspectjRuntimeLevel = s; } - + public void setOptionalJoinpoints(String jps) { - if (jps==null) return; - if (jps.indexOf("arrayconstruction")!=-1) optionalJoinpoint_ArrayConstruction = true; - if (jps.indexOf("synchronization")!=-1) optionalJoinpoint_Synchronization = true; + if (jps == null) + return; + if (jps.indexOf("arrayconstruction") != -1) + optionalJoinpoint_ArrayConstruction = true; + if (jps.indexOf("synchronization") != -1) + optionalJoinpoint_Synchronization = true; } - + public boolean isJoinpointArrayConstructionEnabled() { return optionalJoinpoint_ArrayConstruction; } + public boolean isJoinpointSynchronizationEnabled() { return optionalJoinpoint_Synchronization; } - + public String getTargetAspectjRuntimeLevel() { return targetAspectjRuntimeLevel; } - + // OPTIMIZE are users falling foul of not supplying -1.5 and so targetting the old runtime? public boolean isTargettingAspectJRuntime12() { boolean b = false; // pr116679 - if (!isInJava5Mode()) b=true; - else b = getTargetAspectjRuntimeLevel().equals(org.aspectj.weaver.Constants.RUNTIME_LEVEL_12); - //System.err.println("Asked if targetting runtime 1.2 , returning: "+b); + if (!isInJava5Mode()) + b = true; + else + b = getTargetAspectjRuntimeLevel().equals(org.aspectj.weaver.Constants.RUNTIME_LEVEL_12); + // System.err.println("Asked if targetting runtime 1.2 , returning: "+b); return b; } - + /* - * Map of types in the world, can have 'references' to expendable ones which - * can be garbage collected to recover memory. - * An expendable type is a reference type that is not exposed to the weaver (ie - * just pulled in for type resolution purposes). + * Map of types in the world, can have 'references' to expendable ones which can be garbage collected to recover memory. An + * expendable type is a reference type that is not exposed to the weaver (ie just pulled in for type resolution purposes). */ protected static class TypeMap { - + private static boolean debug = false; // Strategy for entries in the expendable map public final static int DONT_USE_REFS = 0; // Hang around forever public final static int USE_WEAK_REFS = 1; // Collected asap public final static int USE_SOFT_REFS = 2; // Collected when short on memory - + // SECRETAPI - Can switch to a policy of choice ;) - public static int policy = USE_SOFT_REFS; + public static int policy = USE_SOFT_REFS; // Map of types that never get thrown away - private Map /* String -> ResolvedType */ tMap = new HashMap(); - + private Map /* String -> ResolvedType */tMap = new HashMap(); + // Map of types that may be ejected from the cache if we need space private Map expendableMap = Collections.synchronizedMap(new WeakHashMap()); - + private World w; // profiling tools... @@ -875,163 +835,173 @@ public abstract class World implements Dump.INode { private int maxExpendableMapSize = -1; private int collectedTypes = 0; private ReferenceQueue rq = new ReferenceQueue(); - + private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.TypeMap.class); - + TypeMap(World w) { - if (trace.isTraceEnabled()) trace.enter("<init>",this,w); + if (trace.isTraceEnabled()) + trace.enter("<init>", this, w); this.w = w; memoryProfiling = false;// !w.getMessageHandler().isIgnoring(Message.INFO); - if (trace.isTraceEnabled()) trace.exit("<init>"); + if (trace.isTraceEnabled()) + trace.exit("<init>"); } - - /** - * Add a new type into the map, the key is the type signature. - * Some types do *not* go in the map, these are ones involving - * *member* type variables. The reason is that when all you have is the - * signature which gives you a type variable name, you cannot - * guarantee you are using the type variable in the same way - * as someone previously working with a similarly - * named type variable. So, these do not go into the map: - * - TypeVariableReferenceType. - * - ParameterizedType where a member type variable is involved. - * - BoundedReferenceType when one of the bounds is a type variable. + + /** + * Add a new type into the map, the key is the type signature. Some types do *not* go in the map, these are ones involving + * *member* type variables. The reason is that when all you have is the signature which gives you a type variable name, you + * cannot guarantee you are using the type variable in the same way as someone previously working with a similarly named + * type variable. So, these do not go into the map: - TypeVariableReferenceType. - ParameterizedType where a member type + * variable is involved. - BoundedReferenceType when one of the bounds is a type variable. * - * definition: "member type variables" - a tvar declared on a generic - * method/ctor as opposed to those you see declared on a generic type. + * definition: "member type variables" - a tvar declared on a generic method/ctor as opposed to those you see declared on a + * generic type. */ - public ResolvedType put(String key, ResolvedType type) { + public ResolvedType put(String key, ResolvedType type) { if (type.isParameterizedType() && type.isParameterizedWithTypeVariable()) { - if (debug) - System.err.println("Not putting a parameterized type that utilises member declared type variables into the typemap: key="+key+" type="+type); + if (debug) + System.err + .println("Not putting a parameterized type that utilises member declared type variables into the typemap: key=" + + key + " type=" + type); return type; } if (type.isTypeVariableReference()) { - if (debug) - System.err.println("Not putting a type variable reference type into the typemap: key="+key+" type="+type); + if (debug) + System.err.println("Not putting a type variable reference type into the typemap: key=" + key + " type=" + type); return type; } // this test should be improved - only avoid putting them in if one of the // bounds is a member type variable if (type instanceof BoundedReferenceType) { - if (debug) - System.err.println("Not putting a bounded reference type into the typemap: key="+key+" type="+type); + if (debug) + System.err.println("Not putting a bounded reference type into the typemap: key=" + key + " type=" + type); return type; } if (type instanceof MissingResolvedTypeWithKnownSignature) { - if (debug) - System.err.println("Not putting a missing type into the typemap: key="+key+" type="+type); + if (debug) + System.err.println("Not putting a missing type into the typemap: key=" + key + " type=" + type); return type; } - - if ((type instanceof ReferenceType) && (((ReferenceType)type).getDelegate()==null) && w.isExpendable(type)) { - if (debug) - System.err.println("Not putting expendable ref type with null delegate into typemap: key="+key+" type="+type); + + if ((type instanceof ReferenceType) && (((ReferenceType) type).getDelegate() == null) && w.isExpendable(type)) { + if (debug) + System.err.println("Not putting expendable ref type with null delegate into typemap: key=" + key + " type=" + + type); return type; } - - if (w.isExpendable(type)) { + + if (w.isExpendable(type)) { // Dont use reference queue for tracking if not profiling... - if (policy==USE_WEAK_REFS) { - if (memoryProfiling) expendableMap.put(key,new WeakReference(type,rq)); - else expendableMap.put(key,new WeakReference(type)); - } else if (policy==USE_SOFT_REFS) { - if (memoryProfiling) expendableMap.put(key,new SoftReference(type,rq)); - else expendableMap.put(key,new SoftReference(type)); + if (policy == USE_WEAK_REFS) { + if (memoryProfiling) + expendableMap.put(key, new WeakReference(type, rq)); + else + expendableMap.put(key, new WeakReference(type)); + } else if (policy == USE_SOFT_REFS) { + if (memoryProfiling) + expendableMap.put(key, new SoftReference(type, rq)); + else + expendableMap.put(key, new SoftReference(type)); } else { - expendableMap.put(key,type); + expendableMap.put(key, type); } - if (memoryProfiling && expendableMap.size()>maxExpendableMapSize) { + if (memoryProfiling && expendableMap.size() > maxExpendableMapSize) { maxExpendableMapSize = expendableMap.size(); } - return type; + return type; } else { - return (ResolvedType) tMap.put(key,type); + return (ResolvedType) tMap.put(key, type); } } - + public void report() { - if (!memoryProfiling) return; + if (!memoryProfiling) + return; checkq(); - w.getMessageHandler().handleMessage(MessageUtil.info("MEMORY: world expendable type map reached maximum size of #"+maxExpendableMapSize+" entries")); - w.getMessageHandler().handleMessage(MessageUtil.info("MEMORY: types collected through garbage collection #"+collectedTypes+" entries")); + w.getMessageHandler().handleMessage( + MessageUtil.info("MEMORY: world expendable type map reached maximum size of #" + maxExpendableMapSize + + " entries")); + w.getMessageHandler().handleMessage( + MessageUtil.info("MEMORY: types collected through garbage collection #" + collectedTypes + " entries")); } - + public void checkq() { - if (!memoryProfiling) return; - while (rq.poll()!=null) collectedTypes++; + if (!memoryProfiling) + return; + while (rq.poll() != null) + collectedTypes++; } - - /** - * Lookup a type by its signature, always look - * in the real map before the expendable map + + /** + * Lookup a type by its signature, always look in the real map before the expendable map */ public ResolvedType get(String key) { checkq(); ResolvedType ret = (ResolvedType) tMap.get(key); if (ret == null) { - if (policy==USE_WEAK_REFS) { - WeakReference ref = (WeakReference)expendableMap.get(key); + if (policy == USE_WEAK_REFS) { + WeakReference ref = (WeakReference) expendableMap.get(key); if (ref != null) { ret = (ResolvedType) ref.get(); } - } else if (policy==USE_SOFT_REFS) { - SoftReference ref = (SoftReference)expendableMap.get(key); + } else if (policy == USE_SOFT_REFS) { + SoftReference ref = (SoftReference) expendableMap.get(key); if (ref != null) { ret = (ResolvedType) ref.get(); } } else { - return (ResolvedType)expendableMap.get(key); + return (ResolvedType) expendableMap.get(key); } } return ret; } - + /** Remove a type from the map */ public ResolvedType remove(String key) { ResolvedType ret = (ResolvedType) tMap.remove(key); if (ret == null) { - if (policy==USE_WEAK_REFS) { - WeakReference wref = (WeakReference)expendableMap.remove(key); - if (wref!=null) ret = (ResolvedType)wref.get(); - } else if (policy==USE_SOFT_REFS) { - SoftReference wref = (SoftReference)expendableMap.remove(key); - if (wref!=null) ret = (ResolvedType)wref.get(); + if (policy == USE_WEAK_REFS) { + WeakReference wref = (WeakReference) expendableMap.remove(key); + if (wref != null) + ret = (ResolvedType) wref.get(); + } else if (policy == USE_SOFT_REFS) { + SoftReference wref = (SoftReference) expendableMap.remove(key); + if (wref != null) + ret = (ResolvedType) wref.get(); } else { - ret = (ResolvedType)expendableMap.remove(key); + ret = (ResolvedType) expendableMap.remove(key); } } return ret; } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("types:\n"); - sb.append(dumpthem(tMap)); - sb.append("expendables:\n"); - sb.append(dumpthem(expendableMap)); - return sb.toString(); - } - - private String dumpthem(Map m) { - StringBuffer sb = new StringBuffer(); - - int otherTypes = 0; - int bcelDel = 0; - int refDel = 0; - - for (Iterator iter = m.entrySet().iterator(); iter.hasNext();) { + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("types:\n"); + sb.append(dumpthem(tMap)); + sb.append("expendables:\n"); + sb.append(dumpthem(expendableMap)); + return sb.toString(); + } + + private String dumpthem(Map m) { + StringBuffer sb = new StringBuffer(); + + int otherTypes = 0; + int bcelDel = 0; + int refDel = 0; + + for (Iterator iter = m.entrySet().iterator(); iter.hasNext();) { Map.Entry entry = (Map.Entry) iter.next(); Object val = entry.getValue(); if (val instanceof WeakReference) { - val = ((WeakReference)val).get(); - } else - if (val instanceof SoftReference) { - val = ((SoftReference)val).get(); - } - sb.append(entry.getKey()+"="+val).append("\n"); + val = ((WeakReference) val).get(); + } else if (val instanceof SoftReference) { + val = ((SoftReference) val).get(); + } + sb.append(entry.getKey() + "=" + val).append("\n"); if (val instanceof ReferenceType) { - ReferenceType refType = (ReferenceType)val; + ReferenceType refType = (ReferenceType) val; if (refType.getDelegate() instanceof BcelObjectType) { bcelDel++; } else if (refType.getDelegate() instanceof ReflectionBasedReferenceTypeDelegate) { @@ -1043,270 +1013,257 @@ public abstract class World implements Dump.INode { otherTypes++; } } - sb.append("# BCEL = "+bcelDel+", # REF = "+refDel+", # Other = "+otherTypes); - - return sb.toString(); - } - - public int totalSize() { - return tMap.size()+expendableMap.size(); - } - public int hardSize() { - return tMap.size(); - } - + sb.append("# BCEL = " + bcelDel + ", # REF = " + refDel + ", # Other = " + otherTypes); + + return sb.toString(); + } + public ResolvedType[] getAllTypes() { - List/*ResolvedType*/ results = new ArrayList(); + List/* ResolvedType */results = new ArrayList(); collectTypes(expendableMap, results); collectTypes(tMap, results); return (ResolvedType[]) results.toArray(new ResolvedType[results.size()]); } - private void collectTypes(Map map, List/*ResolvedType*/ results) { + private void collectTypes(Map map, List/* ResolvedType */results) { for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) { String key = (String) iterator.next(); ResolvedType type = get(key); - if (type!=null) results.add(type); - else System.err.println("null!:"+key); + if (type != null) + results.add(type); + else + System.err.println("null!:" + key); } } + } - } - - /** Reference types we don't intend to weave may be ejected from - * the cache if we need the space. + /** + * Reference types we don't intend to weave may be ejected from the cache if we need the space. */ protected boolean isExpendable(ResolvedType type) { - return ( - !type.equals(UnresolvedType.OBJECT) && - (!type.isExposedToWeaver()) && - (!type.isPrimitiveType()) - ); + return (!type.equals(UnresolvedType.OBJECT) && (!type.isExposedToWeaver()) && (!type.isPrimitiveType())); } /** - * This class is used to compute and store precedence relationships between - * aspects. + * This class is used to compute and store precedence relationships between aspects. */ private static class AspectPrecedenceCalculator { - + private World world; private Map cachedResults; - + public AspectPrecedenceCalculator(World forSomeWorld) { this.world = forSomeWorld; this.cachedResults = new HashMap(); } - + /** - * Ask every declare precedence in the world to order the two aspects. - * If more than one declare precedence gives an ordering, and the orderings - * conflict, then that's an error. + * Ask every declare precedence in the world to order the two aspects. If more than one declare precedence gives an + * ordering, and the orderings conflict, then that's an error. */ public int compareByPrecedence(ResolvedType firstAspect, ResolvedType secondAspect) { - PrecedenceCacheKey key = new PrecedenceCacheKey(firstAspect,secondAspect); + PrecedenceCacheKey key = new PrecedenceCacheKey(firstAspect, secondAspect); if (cachedResults.containsKey(key)) { return ((Integer) cachedResults.get(key)).intValue(); } else { int order = 0; DeclarePrecedence orderer = null; // Records the declare precedence statement that gives the first ordering - for (Iterator i = world.getCrosscuttingMembersSet().getDeclareDominates().iterator(); i.hasNext(); ) { - DeclarePrecedence d = (DeclarePrecedence)i.next(); + for (Iterator i = world.getCrosscuttingMembersSet().getDeclareDominates().iterator(); i.hasNext();) { + DeclarePrecedence d = (DeclarePrecedence) i.next(); int thisOrder = d.compare(firstAspect, secondAspect); if (thisOrder != 0) { - if (orderer==null) orderer = d; + if (orderer == null) + orderer = d; if (order != 0 && order != thisOrder) { ISourceLocation[] isls = new ISourceLocation[2]; - isls[0]=orderer.getSourceLocation(); - isls[1]=d.getSourceLocation(); - Message m = - new Message("conflicting declare precedence orderings for aspects: "+ - firstAspect.getName()+" and "+secondAspect.getName(),null,true,isls); + isls[0] = orderer.getSourceLocation(); + isls[1] = d.getSourceLocation(); + Message m = new Message("conflicting declare precedence orderings for aspects: " + + firstAspect.getName() + " and " + secondAspect.getName(), null, true, isls); world.getMessageHandler().handleMessage(m); } else { order = thisOrder; } } - } + } cachedResults.put(key, new Integer(order)); return order; } } - - public Integer getPrecedenceIfAny(ResolvedType aspect1,ResolvedType aspect2) { - return (Integer)cachedResults.get(new PrecedenceCacheKey(aspect1,aspect2)); + + public Integer getPrecedenceIfAny(ResolvedType aspect1, ResolvedType aspect2) { + return (Integer) cachedResults.get(new PrecedenceCacheKey(aspect1, aspect2)); } - + public int compareByPrecedenceAndHierarchy(ResolvedType firstAspect, ResolvedType secondAspect) { - if (firstAspect.equals(secondAspect)) return 0; - + if (firstAspect.equals(secondAspect)) + return 0; + int ret = compareByPrecedence(firstAspect, secondAspect); - if (ret != 0) return ret; - - if (firstAspect.isAssignableFrom(secondAspect)) return -1; - else if (secondAspect.isAssignableFrom(firstAspect)) return +1; + if (ret != 0) + return ret; + + if (firstAspect.isAssignableFrom(secondAspect)) + return -1; + else if (secondAspect.isAssignableFrom(firstAspect)) + return +1; return 0; } - - + private static class PrecedenceCacheKey { public ResolvedType aspect1; public ResolvedType aspect2; - + public PrecedenceCacheKey(ResolvedType a1, ResolvedType a2) { this.aspect1 = a1; this.aspect2 = a2; } - + public boolean equals(Object obj) { - if (!(obj instanceof PrecedenceCacheKey)) return false; + if (!(obj instanceof PrecedenceCacheKey)) + return false; PrecedenceCacheKey other = (PrecedenceCacheKey) obj; return (aspect1 == other.aspect1 && aspect2 == other.aspect2); } - + public int hashCode() { return aspect1.hashCode() + aspect2.hashCode(); } } } - public void validateType(UnresolvedType type) { } + public void validateType(UnresolvedType type) { + } + + // --- with java5 we can get into a recursive mess if we aren't careful when resolving types (*cough* java.lang.Enum) --- - // --- with java5 we can get into a recursive mess if we aren't careful when resolving types (*cough* java.lang.Enum) --- - - // --- this first map is for java15 delegates which may try and recursively access the same type variables. + // --- this first map is for java15 delegates which may try and recursively access the same type variables. // --- I would rather stash this against a reference type - but we don't guarantee referencetypes are unique for - // so we can't :( + // so we can't :( private Map workInProgress1 = new HashMap(); + public TypeVariable[] getTypeVariablesCurrentlyBeingProcessed(Class baseClass) { - return (TypeVariable[])workInProgress1.get(baseClass); + return (TypeVariable[]) workInProgress1.get(baseClass); } + public void recordTypeVariablesCurrentlyBeingProcessed(Class baseClass, TypeVariable[] typeVariables) { - workInProgress1.put(baseClass,typeVariables); + workInProgress1.put(baseClass, typeVariables); } + public void forgetTypeVariablesCurrentlyBeingProcessed(Class baseClass) { workInProgress1.remove(baseClass); } - public void setAddSerialVerUID(boolean b) { addSerialVerUID=b;} - public boolean isAddSerialVerUID() { return addSerialVerUID;} - - /** be careful calling this - pr152257 */ + public void setAddSerialVerUID(boolean b) { + addSerialVerUID = b; + } + + public boolean isAddSerialVerUID() { + return addSerialVerUID; + } + + /** be careful calling this - pr152257 */ public void flush() { typeMap.expendableMap.clear(); } - - public void ensureAdvancedConfigurationProcessed() { - // Check *once* whether the user has switched asm support off - if (!checkedAdvancedConfiguration) { - Properties p = getExtraConfiguration(); - if (p!=null) { - - if (isASMAround) { // dont bother if its not... - String s = p.getProperty(xsetACTIVATE_LIGHTWEIGHT_DELEGATES,"true"); - fastDelegateSupportEnabled = s.equalsIgnoreCase("true"); - if (!fastDelegateSupportEnabled) - getMessageHandler().handleMessage(MessageUtil.info("[activateLightweightDelegates=false] Disabling optimization to use lightweight delegates for non-woven types")); - } - - String s = p.getProperty(xsetBCEL_REPOSITORY_CACHING,xsetBCEL_REPOSITORY_CACHING_DEFAULT); + + public void ensureAdvancedConfigurationProcessed() { + // Check *once* whether the user has switched asm support off + if (!checkedAdvancedConfiguration) { + Properties p = getExtraConfiguration(); + if (p != null) { + + String s = p.getProperty(xsetBCEL_REPOSITORY_CACHING, xsetBCEL_REPOSITORY_CACHING_DEFAULT); bcelRepositoryCaching = s.equalsIgnoreCase("true"); if (!bcelRepositoryCaching) { - getMessageHandler().handleMessage(MessageUtil.info("[bcelRepositoryCaching=false] AspectJ will not use a bcel cache for class information")); + getMessageHandler().handleMessage( + MessageUtil + .info("[bcelRepositoryCaching=false] AspectJ will not use a bcel cache for class information")); } - s = p.getProperty(xsetFAST_PACK_METHODS,"true"); + s = p.getProperty(xsetFAST_PACK_METHODS, "true"); fastMethodPacking = s.equalsIgnoreCase("true"); - - s = p.getProperty(xsetPIPELINE_COMPILATION,xsetPIPELINE_COMPILATION_DEFAULT); + + s = p.getProperty(xsetPIPELINE_COMPILATION, xsetPIPELINE_COMPILATION_DEFAULT); shouldPipelineCompilation = s.equalsIgnoreCase("true"); - s = p.getProperty(xsetCOMPLETE_BINARY_TYPES,xsetCOMPLETE_BINARY_TYPES_DEFAULT); + s = p.getProperty(xsetCOMPLETE_BINARY_TYPES, xsetCOMPLETE_BINARY_TYPES_DEFAULT); completeBinaryTypes = s.equalsIgnoreCase("true"); if (completeBinaryTypes) { - getMessageHandler().handleMessage(MessageUtil.info("[completeBinaryTypes=true] Completion of binary types activated")); + getMessageHandler().handleMessage( + MessageUtil.info("[completeBinaryTypes=true] Completion of binary types activated")); } - - s = p.getProperty(xsetRUN_MINIMAL_MEMORY,"false"); - runMinimalMemory = s.equalsIgnoreCase("true"); -// if (runMinimalMemory) -// getMessageHandler().handleMessage(MessageUtil.info("[runMinimalMemory=true] Optimizing bcel processing (and cost of performance) to use less memory")); - - - s = p.getProperty(xsetDEBUG_STRUCTURAL_CHANGES_CODE,"false"); - forDEBUG_structuralChangesCode = s.equalsIgnoreCase("true"); - - s = p.getProperty(xsetDEBUG_BRIDGING,"false"); - forDEBUG_bridgingCode = s.equalsIgnoreCase("true"); - - } - checkedAdvancedConfiguration=true; - } - } - - public boolean isRunMinimalMemory() { - ensureAdvancedConfigurationProcessed(); - return runMinimalMemory; - } - - public boolean shouldFastPackMethods() { - ensureAdvancedConfigurationProcessed(); - return fastMethodPacking; - } - - public boolean shouldPipelineCompilation() { - ensureAdvancedConfigurationProcessed(); - return shouldPipelineCompilation; - } - - public void setFastDelegateSupport(boolean b) { - if (b && !isASMAround) { - throw new BCException("Unable to activate fast delegate support, ASM classes cannot be found"); - } - fastDelegateSupportEnabled = b; - } - - public boolean isFastDelegateSupportEnabled() { - return false; // ASM not currently being used -// ensureAdvancedConfigurationProcessed(); -// return fastDelegateSupportEnabled; - } - - public void setIncrementalCompileCouldFollow(boolean b) {incrementalCompileCouldFollow = b;} - public boolean couldIncrementalCompileFollow() {return incrementalCompileCouldFollow;} - - public void setSynchronizationPointcutsInUse() { - if (trace.isTraceEnabled()) trace.enter("setSynchronizationPointcutsInUse", this); - synchronizationPointcutsInUse =true; - if (trace.isTraceEnabled()) trace.exit("setSynchronizationPointcutsInUse"); - } - public boolean areSynchronizationPointcutsInUse() {return synchronizationPointcutsInUse;} - - public boolean isASMAround() { - return isASMAround; - } - - public ResolvedType[] getAllTypes() { - return typeMap.getAllTypes(); + + s = p.getProperty(xsetRUN_MINIMAL_MEMORY, "false"); + runMinimalMemory = s.equalsIgnoreCase("true"); + // if (runMinimalMemory) + // getMessageHandler().handleMessage(MessageUtil.info( + // "[runMinimalMemory=true] Optimizing bcel processing (and cost of performance) to use less memory")); + + s = p.getProperty(xsetDEBUG_STRUCTURAL_CHANGES_CODE, "false"); + forDEBUG_structuralChangesCode = s.equalsIgnoreCase("true"); + + s = p.getProperty(xsetDEBUG_BRIDGING, "false"); + forDEBUG_bridgingCode = s.equalsIgnoreCase("true"); + + } + checkedAdvancedConfiguration = true; } + } + + public boolean isRunMinimalMemory() { + ensureAdvancedConfigurationProcessed(); + return runMinimalMemory; + } + + public boolean shouldFastPackMethods() { + ensureAdvancedConfigurationProcessed(); + return fastMethodPacking; + } + + public boolean shouldPipelineCompilation() { + ensureAdvancedConfigurationProcessed(); + return shouldPipelineCompilation; + } + + public void setIncrementalCompileCouldFollow(boolean b) { + incrementalCompileCouldFollow = b; + } + + public boolean couldIncrementalCompileFollow() { + return incrementalCompileCouldFollow; + } + + public void setSynchronizationPointcutsInUse() { + if (trace.isTraceEnabled()) + trace.enter("setSynchronizationPointcutsInUse", this); + synchronizationPointcutsInUse = true; + if (trace.isTraceEnabled()) + trace.exit("setSynchronizationPointcutsInUse"); + } + + public boolean areSynchronizationPointcutsInUse() { + return synchronizationPointcutsInUse; + } + + /** + * Register a new pointcut designator handler with the world - this can be used by any pointcut parsers attached to the world. + * + * @param designatorHandler handler for the new pointcut + */ + public void registerPointcutHandler(PointcutDesignatorHandler designatorHandler) { + if (pointcutDesignators == null) + pointcutDesignators = new HashSet(); + pointcutDesignators.add(designatorHandler); + } + + public Set getRegisteredPointcutHandlers() { + if (pointcutDesignators == null) + return Collections.EMPTY_SET; + return pointcutDesignators; + } - /** - * Register a new pointcut designator handler with the world - this can be used by any pointcut parsers attached - * to the world. - * - * @param designatorHandler handler for the new pointcut - */ - public void registerPointcutHandler(PointcutDesignatorHandler designatorHandler) { - if (pointcutDesignators == null) pointcutDesignators = new HashSet(); - pointcutDesignators.add(designatorHandler); - } - - public Set getRegisteredPointcutHandlers() { - if (pointcutDesignators == null) return Collections.EMPTY_SET; - return pointcutDesignators; - } - }
\ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/ast/FieldGet.java b/weaver/src/org/aspectj/weaver/ast/FieldGet.java index b122d4ca4..2e145e3c2 100644 --- a/weaver/src/org/aspectj/weaver/ast/FieldGet.java +++ b/weaver/src/org/aspectj/weaver/ast/FieldGet.java @@ -10,23 +10,21 @@ * 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.field = field; this.resolvedType = resolvedType; } - + public ResolvedType getType() { return resolvedType; } @@ -34,16 +32,13 @@ public class FieldGet extends Expr { public String toString() { return "(FieldGet " + field + ")"; } - - public void accept(IExprVisitor v) { - v.visit(this); - } - public Member getField() { - return field; + + public void accept(IExprVisitor v) { + v.visit(this); } - public ResolvedType getResolvedType() { - return resolvedType; + public Member getField() { + return field; } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index 27727a7b4..43b211a71 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.bcel; import java.lang.reflect.Modifier; @@ -88,157 +87,142 @@ import org.aspectj.weaver.patterns.ExactTypePattern; import org.aspectj.weaver.tools.Trace; import org.aspectj.weaver.tools.TraceFactory; - class BcelClassWeaver implements IClassWeaver { - private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelClassWeaver.class); - - /** - * This is called from {@link BcelWeaver} to perform the per-class weaving process. - */ - public static boolean weave( - BcelWorld world, - LazyClassGen clazz, - List shadowMungers, - List typeMungers, - List lateTypeMungers) - { - boolean b = new BcelClassWeaver(world, clazz, shadowMungers, typeMungers, lateTypeMungers).weave(); - //System.out.println(clazz.getClassName() + ", " + clazz.getType().getWeaverState()); - //clazz.print(); + private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelClassWeaver.class); + + /** + * This is called from {@link BcelWeaver} to perform the per-class weaving process. + */ + public static boolean weave(BcelWorld world, LazyClassGen clazz, List shadowMungers, List typeMungers, List lateTypeMungers) { + boolean b = new BcelClassWeaver(world, clazz, shadowMungers, typeMungers, lateTypeMungers).weave(); + // System.out.println(clazz.getClassName() + ", " + clazz.getType().getWeaverState()); + // clazz.print(); return b; } - + // -------------------------------------------- - - private final LazyClassGen clazz; - private final List shadowMungers; - private final List typeMungers; - private final List lateTypeMungers; - - private final BcelObjectType ty; // alias of clazz.getType() - private final BcelWorld world; // alias of ty.getWorld() - private final ConstantPool cpg; // alias of clazz.getConstantPoolGen() - private final InstructionFactory fact; // alias of clazz.getFactory(); - - - private final List addedLazyMethodGens = new ArrayList(); - private final Set addedDispatchTargets = new HashSet(); - + + private final LazyClassGen clazz; + private final List shadowMungers; + private final List typeMungers; + private final List lateTypeMungers; + + private final BcelObjectType ty; // alias of clazz.getType() + private final BcelWorld world; // alias of ty.getWorld() + private final ConstantPool cpg; // alias of clazz.getConstantPoolGen() + private final InstructionFactory fact; // alias of clazz.getFactory(); + + private final List addedLazyMethodGens = new ArrayList(); + private final Set addedDispatchTargets = new HashSet(); // Static setting across BcelClassWeavers private static boolean inReweavableMode = false; - - - private List addedSuperInitializersAsList = null; // List<IfaceInitList> - private final Map addedSuperInitializers = new HashMap(); // Interface -> IfaceInitList - private List addedThisInitializers = new ArrayList(); // List<NewFieldMunger> - private List addedClassInitializers = new ArrayList(); // List<NewFieldMunger> - + + private List addedSuperInitializersAsList = null; // List<IfaceInitList> + private final Map addedSuperInitializers = new HashMap(); // Interface -> IfaceInitList + private List addedThisInitializers = new ArrayList(); // List<NewFieldMunger> + private List addedClassInitializers = new ArrayList(); // List<NewFieldMunger> + private Map mapToAnnotations = new HashMap(); - -// private BcelShadow clinitShadow = null; - - /** - * This holds the initialization and pre-initialization shadows for this class - * that were actually matched by mungers (if no match, then we don't even create the - * shadows really). - */ - private final List initializationShadows = new ArrayList(1); - - private BcelClassWeaver( - BcelWorld world, - LazyClassGen clazz, - List shadowMungers, - List typeMungers, - List lateTypeMungers) - { + + // private BcelShadow clinitShadow = null; + + /** + * This holds the initialization and pre-initialization shadows for this class that were actually matched by mungers (if no + * match, then we don't even create the shadows really). + */ + private final List initializationShadows = new ArrayList(1); + + private BcelClassWeaver(BcelWorld world, LazyClassGen clazz, List shadowMungers, List typeMungers, List lateTypeMungers) { super(); // assert world == clazz.getType().getWorld() this.world = world; this.clazz = clazz; this.shadowMungers = shadowMungers; this.typeMungers = typeMungers; - this.lateTypeMungers = lateTypeMungers; + this.lateTypeMungers = lateTypeMungers; this.ty = clazz.getBcelObjectType(); this.cpg = clazz.getConstantPool(); this.fact = clazz.getFactory(); - + fastMatchShadowMungers(shadowMungers); - + initializeSuperInitializerMap(ty.getResolvedTypeX()); if (!checkedXsetForLowLevelContextCapturing) { Properties p = world.getExtraConfiguration(); - if (p!=null) { - String s = p.getProperty(World.xsetCAPTURE_ALL_CONTEXT,"false"); - captureLowLevelContext = s.equalsIgnoreCase("true"); - if (captureLowLevelContext) - world.getMessageHandler().handleMessage(MessageUtil.info("["+World.xsetCAPTURE_ALL_CONTEXT+"=true] Enabling collection of low level context for debug/crash messages")); - } - checkedXsetForLowLevelContextCapturing=true; - } - } - - - private List[] perKindShadowMungers; - private boolean canMatchBodyShadows = false; -// private boolean canMatchInitialization = false; - private void fastMatchShadowMungers(List shadowMungers) { - // beware the annoying property that SHADOW_KINDS[i].getKey == (i+1) ! - - perKindShadowMungers = new List[Shadow.MAX_SHADOW_KIND + 1]; - for (int i = 0; i < perKindShadowMungers.length; i++) { + if (p != null) { + String s = p.getProperty(World.xsetCAPTURE_ALL_CONTEXT, "false"); + captureLowLevelContext = s.equalsIgnoreCase("true"); + if (captureLowLevelContext) + world.getMessageHandler().handleMessage( + MessageUtil.info("[" + World.xsetCAPTURE_ALL_CONTEXT + + "=true] Enabling collection of low level context for debug/crash messages")); + } + checkedXsetForLowLevelContextCapturing = true; + } + } + + private List[] perKindShadowMungers; + private boolean canMatchBodyShadows = false; + + // private boolean canMatchInitialization = false; + private void fastMatchShadowMungers(List shadowMungers) { + // beware the annoying property that SHADOW_KINDS[i].getKey == (i+1) ! + + perKindShadowMungers = new List[Shadow.MAX_SHADOW_KIND + 1]; + for (int i = 0; i < perKindShadowMungers.length; i++) { perKindShadowMungers[i] = new ArrayList(0); - } - for (Iterator iter = shadowMungers.iterator(); iter.hasNext();) { + } + for (Iterator iter = shadowMungers.iterator(); iter.hasNext();) { ShadowMunger munger = (ShadowMunger) iter.next(); - + int couldMatchKinds = munger.getPointcut().couldMatchKinds(); for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { Shadow.Kind kind = Shadow.SHADOW_KINDS[i]; - if (kind.isSet(couldMatchKinds)) perKindShadowMungers[kind.getKey()].add(munger); + if (kind.isSet(couldMatchKinds)) + perKindShadowMungers[kind.getKey()].add(munger); } - -// Set couldMatchKinds = munger.getPointcut().couldMatchKinds(); -// for (Iterator kindIterator = couldMatchKinds.iterator(); -// kindIterator.hasNext();) { -// Shadow.Kind aKind = (Shadow.Kind) kindIterator.next(); -// perKindShadowMungers[aKind.getKey()].add(munger); -// } - } - -// if (!perKindShadowMungers[Shadow.Initialization.getKey()].isEmpty()) -// canMatchInitialization = true; - - for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { + + // Set couldMatchKinds = munger.getPointcut().couldMatchKinds(); + // for (Iterator kindIterator = couldMatchKinds.iterator(); + // kindIterator.hasNext();) { + // Shadow.Kind aKind = (Shadow.Kind) kindIterator.next(); + // perKindShadowMungers[aKind.getKey()].add(munger); + // } + } + + // if (!perKindShadowMungers[Shadow.Initialization.getKey()].isEmpty()) + // canMatchInitialization = true; + + for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { Shadow.Kind kind = Shadow.SHADOW_KINDS[i]; - if (!kind.isEnclosingKind() && !perKindShadowMungers[i+1].isEmpty()) { + if (!kind.isEnclosingKind() && !perKindShadowMungers[i + 1].isEmpty()) { canMatchBodyShadows = true; } - if (perKindShadowMungers[i+1].isEmpty()) { - perKindShadowMungers[i+1] = null; + if (perKindShadowMungers[i + 1].isEmpty()) { + perKindShadowMungers[i + 1] = null; } - } - } - - private boolean canMatch(Shadow.Kind kind) { - return perKindShadowMungers[kind.getKey()] != null; - } - -// private void fastMatchShadowMungers(List shadowMungers, ArrayList mungers, Kind kind) { -// FastMatchInfo info = new FastMatchInfo(clazz.getType(), kind); -// for (Iterator i = shadowMungers.iterator(); i.hasNext();) { -// ShadowMunger munger = (ShadowMunger) i.next(); -// FuzzyBoolean fb = munger.getPointcut().fastMatch(info); -// WeaverMetrics.recordFastMatchResult(fb);// Could pass: munger.getPointcut().toString() -// if (fb.maybeTrue()) mungers.add(munger); -// } -// } + } + } + private boolean canMatch(Shadow.Kind kind) { + return perKindShadowMungers[kind.getKey()] != null; + } + + // private void fastMatchShadowMungers(List shadowMungers, ArrayList mungers, Kind kind) { + // FastMatchInfo info = new FastMatchInfo(clazz.getType(), kind); + // for (Iterator i = shadowMungers.iterator(); i.hasNext();) { + // ShadowMunger munger = (ShadowMunger) i.next(); + // FuzzyBoolean fb = munger.getPointcut().fastMatch(info); + // WeaverMetrics.recordFastMatchResult(fb);// Could pass: munger.getPointcut().toString() + // if (fb.maybeTrue()) mungers.add(munger); + // } + // } private void initializeSuperInitializerMap(ResolvedType child) { ResolvedType[] superInterfaces = child.getDeclaredInterfaces(); - for (int i=0, len=superInterfaces.length; i < len; i++) { + for (int i = 0, len = superInterfaces.length; i < len; i++) { if (ty.getResolvedTypeX().isTopmostImplementor(superInterfaces[i])) { if (addSuperInitializer(superInterfaces[i])) { initializeSuperInitializerMap(superInterfaces[i]); @@ -248,18 +232,21 @@ class BcelClassWeaver implements IClassWeaver { } private boolean addSuperInitializer(ResolvedType onType) { - if (onType.isRawType() || onType.isParameterizedType()) onType = onType.getGenericType(); + if (onType.isRawType() || onType.isParameterizedType()) + onType = onType.getGenericType(); IfaceInitList l = (IfaceInitList) addedSuperInitializers.get(onType); - if (l != null) return false; + if (l != null) + return false; l = new IfaceInitList(onType); addedSuperInitializers.put(onType, l); return true; } - + public void addInitializer(ConcreteTypeMunger cm) { NewFieldTypeMunger m = (NewFieldTypeMunger) cm.getMunger(); ResolvedType onType = m.getSignature().getDeclaringType().resolve(world); - if (onType.isRawType()) onType = onType.getGenericType(); + if (onType.isRawType()) + onType = onType.getGenericType(); if (m.getSignature().isStatic()) { addedClassInitializers.add(cm); @@ -272,40 +259,45 @@ class BcelClassWeaver implements IClassWeaver { } } } - - private static class IfaceInitList implements PartialOrder.PartialComparable { - final ResolvedType onType; - List list = new ArrayList(); - IfaceInitList(ResolvedType onType) { - this.onType = onType; - } - + + private static class IfaceInitList implements PartialOrder.PartialComparable { + final ResolvedType onType; + List list = new ArrayList(); + + IfaceInitList(ResolvedType onType) { + this.onType = onType; + } + public int compareTo(Object other) { - IfaceInitList o = (IfaceInitList)other; - if (onType.isAssignableFrom(o.onType)) return +1; - else if (o.onType.isAssignableFrom(onType)) return -1; - else return 0; + IfaceInitList o = (IfaceInitList) other; + if (onType.isAssignableFrom(o.onType)) + return +1; + else if (o.onType.isAssignableFrom(onType)) + return -1; + else + return 0; } public int fallbackCompareTo(Object other) { return 0; } - } - - // XXX this is being called, but the result doesn't seem to be being used - public boolean addDispatchTarget(ResolvedMember m) { - return addedDispatchTargets.add(m); - } - - public void addLazyMethodGen(LazyMethodGen gen) { - addedLazyMethodGens.add(gen); - } - + } + + // XXX this is being called, but the result doesn't seem to be being used + public boolean addDispatchTarget(ResolvedMember m) { + return addedDispatchTargets.add(m); + } + + public void addLazyMethodGen(LazyMethodGen gen) { + addedLazyMethodGens.add(gen); + } + public void addOrReplaceLazyMethodGen(LazyMethodGen mg) { - if (alreadyDefined(clazz, mg)) return; - - for (Iterator i = addedLazyMethodGens.iterator(); i.hasNext(); ) { - LazyMethodGen existing = (LazyMethodGen)i.next(); + if (alreadyDefined(clazz, mg)) + return; + + for (Iterator i = addedLazyMethodGens.iterator(); i.hasNext();) { + LazyMethodGen existing = (LazyMethodGen) i.next(); if (signaturesMatch(mg, existing)) { if (existing.definingType == null) { // this means existing was introduced on the class itself @@ -321,14 +313,14 @@ class BcelClassWeaver implements IClassWeaver { } else { throw new BCException("conflict between: " + mg + " and " + existing); } - } + } } addedLazyMethodGens.add(mg); } private boolean alreadyDefined(LazyClassGen clazz, LazyMethodGen mg) { - for (Iterator i = clazz.getMethodGens().iterator(); i.hasNext(); ) { - LazyMethodGen existing = (LazyMethodGen)i.next(); + for (Iterator i = clazz.getMethodGens().iterator(); i.hasNext();) { + LazyMethodGen existing = (LazyMethodGen) i.next(); if (signaturesMatch(mg, existing)) { if (!mg.isAbstract() && existing.isAbstract()) { i.remove(); @@ -341,384 +333,416 @@ class BcelClassWeaver implements IClassWeaver { } private boolean signaturesMatch(LazyMethodGen mg, LazyMethodGen existing) { - return mg.getName().equals(existing.getName()) && - mg.getSignature().equals(existing.getSignature()); - } - - + return mg.getName().equals(existing.getName()) && mg.getSignature().equals(existing.getSignature()); + } + protected static LazyMethodGen makeBridgeMethod(LazyClassGen gen, ResolvedMember member) { // remove abstract modifier int mods = member.getModifiers(); - if (Modifier.isAbstract(mods)) mods = mods - Modifier.ABSTRACT; - - LazyMethodGen ret = new LazyMethodGen( - mods, - BcelWorld.makeBcelType(member.getReturnType()), - member.getName(), - BcelWorld.makeBcelTypes(member.getParameterTypes()), - UnresolvedType.getNames(member.getExceptions()), - gen); - - // 43972 : Static crosscutting makes interfaces unusable for javac - // ret.makeSynthetic(); + if (Modifier.isAbstract(mods)) + mods = mods - Modifier.ABSTRACT; + + LazyMethodGen ret = new LazyMethodGen(mods, BcelWorld.makeBcelType(member.getReturnType()), member.getName(), BcelWorld + .makeBcelTypes(member.getParameterTypes()), UnresolvedType.getNames(member.getExceptions()), gen); + + // 43972 : Static crosscutting makes interfaces unusable for javac + // ret.makeSynthetic(); return ret; } - - + /** * Create a single bridge method called 'theBridgeMethod' that bridges to 'whatToBridgeTo' */ - private static void createBridgeMethod(BcelWorld world, LazyMethodGen whatToBridgeToMethodGen, LazyClassGen clazz,ResolvedMember theBridgeMethod) { + private static void createBridgeMethod(BcelWorld world, LazyMethodGen whatToBridgeToMethodGen, LazyClassGen clazz, + ResolvedMember theBridgeMethod) { InstructionList body; InstructionFactory fact; int pos = 0; ResolvedMember whatToBridgeTo = whatToBridgeToMethodGen.getMemberView(); - - if (whatToBridgeTo==null) { - whatToBridgeTo = - new ResolvedMemberImpl(Member.METHOD, - whatToBridgeToMethodGen.getEnclosingClass().getType(), - whatToBridgeToMethodGen.getAccessFlags(), - whatToBridgeToMethodGen.getName(), - whatToBridgeToMethodGen.getSignature()); - } - LazyMethodGen bridgeMethod = makeBridgeMethod(clazz,theBridgeMethod); // The bridge method in this type will have the same signature as the one in the supertype - int newflags = bridgeMethod.getAccessFlags() | 0x00000040;/*BRIDGE = 0x00000040*/ - if ((newflags & 0x00000100) !=0) newflags = newflags - 0x100;/* NATIVE = 0x00000100 - need to clear it */ - bridgeMethod.setAccessFlags(newflags ); - Type returnType = BcelWorld.makeBcelType(theBridgeMethod.getReturnType()); + + if (whatToBridgeTo == null) { + whatToBridgeTo = new ResolvedMemberImpl(Member.METHOD, whatToBridgeToMethodGen.getEnclosingClass().getType(), + whatToBridgeToMethodGen.getAccessFlags(), whatToBridgeToMethodGen.getName(), whatToBridgeToMethodGen + .getSignature()); + } + LazyMethodGen bridgeMethod = makeBridgeMethod(clazz, theBridgeMethod); // The bridge method in this type will have the same + // signature as the one in the supertype + int newflags = bridgeMethod.getAccessFlags() | 0x00000040;/* BRIDGE = 0x00000040 */ + if ((newflags & 0x00000100) != 0) + newflags = newflags - 0x100;/* NATIVE = 0x00000100 - need to clear it */ + bridgeMethod.setAccessFlags(newflags); + Type returnType = BcelWorld.makeBcelType(theBridgeMethod.getReturnType()); Type[] paramTypes = BcelWorld.makeBcelTypes(theBridgeMethod.getParameterTypes()); - Type[] newParamTypes=whatToBridgeToMethodGen.getArgumentTypes(); + Type[] newParamTypes = whatToBridgeToMethodGen.getArgumentTypes(); body = bridgeMethod.getBody(); fact = clazz.getFactory(); if (!whatToBridgeToMethodGen.isStatic()) { - body.append(InstructionFactory.createThis()); - pos++; + body.append(InstructionFactory.createThis()); + pos++; } for (int i = 0, len = paramTypes.length; i < len; i++) { - Type paramType = paramTypes[i]; - body.append(InstructionFactory.createLoad(paramType, pos)); - if (!newParamTypes[i].equals(paramTypes[i])) { - if (world.forDEBUG_bridgingCode) System.err.println("Bridging: Cast "+newParamTypes[i]+" from "+paramTypes[i]); - body.append(fact.createCast(paramTypes[i],newParamTypes[i])); - } - pos+=paramType.getSize(); + Type paramType = paramTypes[i]; + body.append(InstructionFactory.createLoad(paramType, pos)); + if (!newParamTypes[i].equals(paramTypes[i])) { + if (world.forDEBUG_bridgingCode) + System.err.println("Bridging: Cast " + newParamTypes[i] + " from " + paramTypes[i]); + body.append(fact.createCast(paramTypes[i], newParamTypes[i])); + } + pos += paramType.getSize(); } - body.append(Utility.createInvoke(fact, world,whatToBridgeTo)); + body.append(Utility.createInvoke(fact, world, whatToBridgeTo)); body.append(InstructionFactory.createReturn(returnType)); clazz.addMethodGen(bridgeMethod); } - - // ---- - - public boolean weave() { - if (clazz.isWoven() && !clazz.isReweavable()) { - world.showMessage(IMessage.ERROR, - WeaverMessages.format(WeaverMessages.ALREADY_WOVEN,clazz.getType().getName()), - ty.getSourceLocation(), null); - return false; - } - - - Set aspectsAffectingType = null; - if (inReweavableMode || clazz.getType().isAspect()) aspectsAffectingType = new HashSet(); - - boolean isChanged = false; - - // we want to "touch" all aspects - if (clazz.getType().isAspect()) isChanged = true; - - // start by munging all typeMungers - for (Iterator i = typeMungers.iterator(); i.hasNext(); ) { - Object o = i.next(); - if ( !(o instanceof BcelTypeMunger) ) { - //???System.err.println("surprising: " + o); - continue; - } - BcelTypeMunger munger = (BcelTypeMunger)o; - boolean typeMungerAffectedType = munger.munge(this); - if (typeMungerAffectedType) { - isChanged = true; - if (inReweavableMode || clazz.getType().isAspect()) aspectsAffectingType.add(munger.getAspectType().getName()); - } - } - - - - // Weave special half type/half shadow mungers... - isChanged = weaveDeclareAtMethodCtor(clazz) || isChanged; - isChanged = weaveDeclareAtField(clazz) || isChanged; - - // XXX do major sort of stuff - // sort according to: Major: type hierarchy - // within each list: dominates - // don't forget to sort addedThisInitialiers according to dominates - addedSuperInitializersAsList = new ArrayList(addedSuperInitializers.values()); - addedSuperInitializersAsList = PartialOrder.sort(addedSuperInitializersAsList); - if (addedSuperInitializersAsList == null) { - throw new BCException("circularity in inter-types"); - } - - // this will create a static initializer if there isn't one - // this is in just as bad taste as NOPs - LazyMethodGen staticInit = clazz.getStaticInitializer(); - staticInit.getBody().insert(genInitInstructions(addedClassInitializers, true)); - - // now go through each method, and match against each method. This - // sets up each method's {@link LazyMethodGen#matchedShadows} field, - // and it also possibly adds to {@link #initializationShadows}. - List methodGens = new ArrayList(clazz.getMethodGens()); - for (Iterator i = methodGens.iterator(); i.hasNext();) { - LazyMethodGen mg = (LazyMethodGen)i.next(); - if (! mg.hasBody()) continue; - if (world.isJoinpointSynchronizationEnabled() && - world.areSynchronizationPointcutsInUse() && - mg.getMethod().isSynchronized()) { + + // ---- + + public boolean weave() { + if (clazz.isWoven() && !clazz.isReweavable()) { + world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ALREADY_WOVEN, clazz.getType().getName()), ty + .getSourceLocation(), null); + return false; + } + + Set aspectsAffectingType = null; + if (inReweavableMode || clazz.getType().isAspect()) + aspectsAffectingType = new HashSet(); + + boolean isChanged = false; + + // we want to "touch" all aspects + if (clazz.getType().isAspect()) + isChanged = true; + + // start by munging all typeMungers + for (Iterator i = typeMungers.iterator(); i.hasNext();) { + Object o = i.next(); + if (!(o instanceof BcelTypeMunger)) { + // ???System.err.println("surprising: " + o); + continue; + } + BcelTypeMunger munger = (BcelTypeMunger) o; + boolean typeMungerAffectedType = munger.munge(this); + if (typeMungerAffectedType) { + isChanged = true; + if (inReweavableMode || clazz.getType().isAspect()) + aspectsAffectingType.add(munger.getAspectType().getName()); + } + } + + // Weave special half type/half shadow mungers... + isChanged = weaveDeclareAtMethodCtor(clazz) || isChanged; + isChanged = weaveDeclareAtField(clazz) || isChanged; + + // XXX do major sort of stuff + // sort according to: Major: type hierarchy + // within each list: dominates + // don't forget to sort addedThisInitialiers according to dominates + addedSuperInitializersAsList = new ArrayList(addedSuperInitializers.values()); + addedSuperInitializersAsList = PartialOrder.sort(addedSuperInitializersAsList); + if (addedSuperInitializersAsList == null) { + throw new BCException("circularity in inter-types"); + } + + // this will create a static initializer if there isn't one + // this is in just as bad taste as NOPs + LazyMethodGen staticInit = clazz.getStaticInitializer(); + staticInit.getBody().insert(genInitInstructions(addedClassInitializers, true)); + + // now go through each method, and match against each method. This + // sets up each method's {@link LazyMethodGen#matchedShadows} field, + // and it also possibly adds to {@link #initializationShadows}. + List methodGens = new ArrayList(clazz.getMethodGens()); + for (Iterator i = methodGens.iterator(); i.hasNext();) { + LazyMethodGen mg = (LazyMethodGen) i.next(); + if (!mg.hasBody()) + continue; + if (world.isJoinpointSynchronizationEnabled() && world.areSynchronizationPointcutsInUse() + && mg.getMethod().isSynchronized()) { transformSynchronizedMethod(mg); } boolean shadowMungerMatched = match(mg); if (shadowMungerMatched) { // For matching mungers, add their declaring aspects to the list that affected this type - if (inReweavableMode || clazz.getType().isAspect()) aspectsAffectingType.addAll(findAspectsForMungers(mg)); - isChanged = true; + if (inReweavableMode || clazz.getType().isAspect()) + aspectsAffectingType.addAll(findAspectsForMungers(mg)); + isChanged = true; } - } + } - // now we weave all but the initialization shadows + // now we weave all but the initialization shadows for (Iterator i = methodGens.iterator(); i.hasNext();) { - LazyMethodGen mg = (LazyMethodGen)i.next(); - if (! mg.hasBody()) continue; + LazyMethodGen mg = (LazyMethodGen) i.next(); + if (!mg.hasBody()) + continue; implement(mg); } - - // if we matched any initialization shadows, we inline and weave + + // if we matched any initialization shadows, we inline and weave if (!initializationShadows.isEmpty()) { - // Repeat next step until nothing left to inline...cant go on - // infinetly as compiler will have detected and reported + // Repeat next step until nothing left to inline...cant go on + // infinetly as compiler will have detected and reported // "Recursive constructor invocation" - while (inlineSelfConstructors(methodGens)); + while (inlineSelfConstructors(methodGens)) + ; positionAndImplement(initializationShadows); } - - // now proceed with late type mungers - if (lateTypeMungers != null) { - for (Iterator i = lateTypeMungers.iterator(); i.hasNext(); ) { - BcelTypeMunger munger = (BcelTypeMunger)i.next(); - if (munger.matches(clazz.getType())) { - boolean typeMungerAffectedType = munger.munge(this); - if (typeMungerAffectedType) { - isChanged = true; - if (inReweavableMode || clazz.getType().isAspect()) aspectsAffectingType.add(munger.getAspectType().getName()); - } - } - } - } - - //FIXME AV - see #75442, for now this is not enough to fix the bug, comment that out until we really fix it -// // flush to save some memory -// PerObjectInterfaceTypeMunger.unregisterFromAsAdvisedBy(clazz.getType()); + + // now proceed with late type mungers + if (lateTypeMungers != null) { + for (Iterator i = lateTypeMungers.iterator(); i.hasNext();) { + BcelTypeMunger munger = (BcelTypeMunger) i.next(); + if (munger.matches(clazz.getType())) { + boolean typeMungerAffectedType = munger.munge(this); + if (typeMungerAffectedType) { + isChanged = true; + if (inReweavableMode || clazz.getType().isAspect()) + aspectsAffectingType.add(munger.getAspectType().getName()); + } + } + } + } + + // FIXME AV - see #75442, for now this is not enough to fix the bug, comment that out until we really fix it + // // flush to save some memory + // PerObjectInterfaceTypeMunger.unregisterFromAsAdvisedBy(clazz.getType()); // finally, if we changed, we add in the introduced methods. - if (isChanged) { - clazz.getOrCreateWeaverStateInfo(inReweavableMode); + if (isChanged) { + clazz.getOrCreateWeaverStateInfo(inReweavableMode); weaveInAddedMethods(); // FIXME asc are these potentially affected by declare annotation? - } - - if (inReweavableMode) { - WeaverStateInfo wsi = clazz.getOrCreateWeaverStateInfo(true); - wsi.addAspectsAffectingType(aspectsAffectingType); - wsi.setUnwovenClassFileData(ty.getJavaClass().getBytes()); - wsi.setReweavable(true); - } else { - clazz.getOrCreateWeaverStateInfo(false).setReweavable(false); - } - - // tidyup, reduce ongoing memory usage of BcelMethods that hang around - for (Iterator i = methodGens.iterator(); i.hasNext();) { - LazyMethodGen mg = (LazyMethodGen) i.next(); - BcelMethod bM = mg.getMemberView(); - if (bM != null) bM.wipeJoinpointSignatures(); - } - - return isChanged; - } - - - - - // **************************** start of bridge method creation code ***************** - + } + + if (inReweavableMode) { + WeaverStateInfo wsi = clazz.getOrCreateWeaverStateInfo(true); + wsi.addAspectsAffectingType(aspectsAffectingType); + wsi.setUnwovenClassFileData(ty.getJavaClass().getBytes()); + wsi.setReweavable(true); + } else { + clazz.getOrCreateWeaverStateInfo(false).setReweavable(false); + } + + // tidyup, reduce ongoing memory usage of BcelMethods that hang around + for (Iterator i = methodGens.iterator(); i.hasNext();) { + LazyMethodGen mg = (LazyMethodGen) i.next(); + BcelMethod bM = mg.getMemberView(); + if (bM != null) + bM.wipeJoinpointSignatures(); + } + + return isChanged; + } + + // **************************** start of bridge method creation code ***************** + // FIXME asc tidy this lot up !! - - // FIXME asc refactor into ResolvedType or even ResolvedMember? - /** - * Check if a particular method is overriding another - refactored into this helper so it - * can be used from multiple places. - */ - private static ResolvedMember isOverriding(ResolvedType typeToCheck,ResolvedMember methodThatMightBeGettingOverridden,String mname,String mrettype,int mmods,boolean inSamePackage,UnresolvedType[] methodParamsArray) { + + // FIXME asc refactor into ResolvedType or even ResolvedMember? + /** + * Check if a particular method is overriding another - refactored into this helper so it can be used from multiple places. + */ + private static ResolvedMember isOverriding(ResolvedType typeToCheck, ResolvedMember methodThatMightBeGettingOverridden, + String mname, String mrettype, int mmods, boolean inSamePackage, UnresolvedType[] methodParamsArray) { // Check if we can be an override... - if (methodThatMightBeGettingOverridden.isStatic()) return null; // we can't be overriding a static method - if (methodThatMightBeGettingOverridden.isPrivate()) return null; // we can't be overriding a private method - if (!methodThatMightBeGettingOverridden.getName().equals(mname)) return null; // names dont match (this will also skip <init> and <clinit> too) - if (methodThatMightBeGettingOverridden.getParameterTypes().length!=methodParamsArray.length) return null; // check same number of parameters - if (!isVisibilityOverride(mmods,methodThatMightBeGettingOverridden,inSamePackage)) return null; - - if (typeToCheck.getWorld().forDEBUG_bridgingCode) System.err.println(" Bridging:seriously considering this might be getting overridden '"+methodThatMightBeGettingOverridden+"'"); - + if (methodThatMightBeGettingOverridden.isStatic()) + return null; // we can't be overriding a static method + if (methodThatMightBeGettingOverridden.isPrivate()) + return null; // we can't be overriding a private method + if (!methodThatMightBeGettingOverridden.getName().equals(mname)) + return null; // names dont match (this will also skip <init> and <clinit> too) + if (methodThatMightBeGettingOverridden.getParameterTypes().length != methodParamsArray.length) + return null; // check same number of parameters + if (!isVisibilityOverride(mmods, methodThatMightBeGettingOverridden, inSamePackage)) + return null; + + if (typeToCheck.getWorld().forDEBUG_bridgingCode) + System.err.println(" Bridging:seriously considering this might be getting overridden '" + + methodThatMightBeGettingOverridden + "'"); + // Look at erasures of parameters (List<String> erased is List) boolean sameParams = true; - for (int p = 0;p<methodThatMightBeGettingOverridden.getParameterTypes().length;p++) { - if (!methodThatMightBeGettingOverridden.getParameterTypes()[p].getErasureSignature().equals(methodParamsArray[p].getErasureSignature())) sameParams = false; + for (int p = 0; p < methodThatMightBeGettingOverridden.getParameterTypes().length; p++) { + if (!methodThatMightBeGettingOverridden.getParameterTypes()[p].getErasureSignature().equals( + methodParamsArray[p].getErasureSignature())) + sameParams = false; } - + // If the 'typeToCheck' represents a parameterized type then the method will be the parameterized form of the - // generic method in the generic type. So if the method was 'void m(List<T> lt, T t)' and the parameterized type here + // generic method in the generic type. So if the method was 'void m(List<T> lt, T t)' and the parameterized type here // is I<String> then the method we are looking at will be 'void m(List<String> lt, String t)' which when erased // is 'void m(List lt,String t)' - so if the parameters *do* match then there is a generic method we are // overriding - - if (sameParams) { - // check for covariance - if (typeToCheck.isParameterizedType()) { + + if (sameParams) { + // check for covariance + if (typeToCheck.isParameterizedType()) { return methodThatMightBeGettingOverridden.getBackingGenericMember(); - } else if (!methodThatMightBeGettingOverridden.getReturnType().getErasureSignature().equals(mrettype)) { - // addressing the wierd situation from bug 147801 - // just check whether these things are in the right relationship for covariance... - ResolvedType superReturn = typeToCheck.getWorld().resolve(UnresolvedType.forSignature(methodThatMightBeGettingOverridden.getReturnType().getErasureSignature())); - ResolvedType subReturn = typeToCheck.getWorld().resolve(UnresolvedType.forSignature(mrettype)); - if (superReturn.isAssignableFrom(subReturn)) - return methodThatMightBeGettingOverridden; - } - } - return null; - } - - /** - * Looks at the visibility modifiers between two methods, and knows whether they are from classes in - * the same package, and decides whether one overrides the other. - * @return true if there is an overrides rather than a 'hides' relationship - */ - static boolean isVisibilityOverride(int methodMods, ResolvedMember inheritedMethod,boolean inSamePackage) { - if (inheritedMethod.isStatic()) return false; - if (methodMods == inheritedMethod.getModifiers()) return true; - - if (inheritedMethod.isPrivate()) return false; - - boolean isPackageVisible = !inheritedMethod.isPrivate() && !inheritedMethod.isProtected() - && !inheritedMethod.isPublic(); - if (isPackageVisible && !inSamePackage) return false; - - return true; - } - - /** - * This method recurses up a specified type looking for a method that overrides the one passed in. - * - * @return the method being overridden or null if none is found - */ - public static ResolvedMember checkForOverride(ResolvedType typeToCheck,String mname,String mparams,String mrettype,int mmods,String mpkg,UnresolvedType[] methodParamsArray) { - - if (typeToCheck==null) return null; - if (typeToCheck instanceof MissingResolvedTypeWithKnownSignature) return null; // we just can't tell ! - - if (typeToCheck.getWorld().forDEBUG_bridgingCode) System.err.println(" Bridging:checking for override of "+mname+" in "+typeToCheck); - - String packageName = typeToCheck.getPackageName(); - if (packageName==null) packageName=""; - boolean inSamePackage = packageName.equals(mpkg); // used when looking at visibility rules - - ResolvedMember [] methods = typeToCheck.getDeclaredMethods(); - for (int ii=0;ii<methods.length;ii++) { - ResolvedMember methodThatMightBeGettingOverridden = methods[ii]; // the method we are going to check - ResolvedMember isOverriding = isOverriding(typeToCheck,methodThatMightBeGettingOverridden,mname,mrettype,mmods,inSamePackage,methodParamsArray); - if (isOverriding!=null) return isOverriding; + } else if (!methodThatMightBeGettingOverridden.getReturnType().getErasureSignature().equals(mrettype)) { + // addressing the wierd situation from bug 147801 + // just check whether these things are in the right relationship for covariance... + ResolvedType superReturn = typeToCheck.getWorld().resolve( + UnresolvedType.forSignature(methodThatMightBeGettingOverridden.getReturnType().getErasureSignature())); + ResolvedType subReturn = typeToCheck.getWorld().resolve(UnresolvedType.forSignature(mrettype)); + if (superReturn.isAssignableFrom(subReturn)) + return methodThatMightBeGettingOverridden; + } + } + return null; + } + + /** + * Looks at the visibility modifiers between two methods, and knows whether they are from classes in the same package, and + * decides whether one overrides the other. + * + * @return true if there is an overrides rather than a 'hides' relationship + */ + static boolean isVisibilityOverride(int methodMods, ResolvedMember inheritedMethod, boolean inSamePackage) { + if (inheritedMethod.isStatic()) + return false; + if (methodMods == inheritedMethod.getModifiers()) + return true; + + if (inheritedMethod.isPrivate()) + return false; + + boolean isPackageVisible = !inheritedMethod.isPrivate() && !inheritedMethod.isProtected() && !inheritedMethod.isPublic(); + if (isPackageVisible && !inSamePackage) + return false; + + return true; + } + + /** + * This method recurses up a specified type looking for a method that overrides the one passed in. + * + * @return the method being overridden or null if none is found + */ + public static ResolvedMember checkForOverride(ResolvedType typeToCheck, String mname, String mparams, String mrettype, + int mmods, String mpkg, UnresolvedType[] methodParamsArray) { + + if (typeToCheck == null) + return null; + if (typeToCheck instanceof MissingResolvedTypeWithKnownSignature) + return null; // we just can't tell ! + + if (typeToCheck.getWorld().forDEBUG_bridgingCode) + System.err.println(" Bridging:checking for override of " + mname + " in " + typeToCheck); + + String packageName = typeToCheck.getPackageName(); + if (packageName == null) + packageName = ""; + boolean inSamePackage = packageName.equals(mpkg); // used when looking at visibility rules + + ResolvedMember[] methods = typeToCheck.getDeclaredMethods(); + for (int ii = 0; ii < methods.length; ii++) { + ResolvedMember methodThatMightBeGettingOverridden = methods[ii]; // the method we are going to check + ResolvedMember isOverriding = isOverriding(typeToCheck, methodThatMightBeGettingOverridden, mname, mrettype, mmods, + inSamePackage, methodParamsArray); + if (isOverriding != null) + return isOverriding; } List l = typeToCheck.getInterTypeMungers(); for (Iterator iterator = l.iterator(); iterator.hasNext();) { Object o = iterator.next(); // FIXME asc if its not a BcelTypeMunger then its an EclipseTypeMunger ... do I need to worry about that? if (o instanceof BcelTypeMunger) { - BcelTypeMunger element = (BcelTypeMunger)o; + BcelTypeMunger element = (BcelTypeMunger) o; if (element.getMunger() instanceof NewMethodTypeMunger) { - if (typeToCheck.getWorld().forDEBUG_bridgingCode) System.err.println("Possible ITD candidate "+element); + if (typeToCheck.getWorld().forDEBUG_bridgingCode) + System.err.println("Possible ITD candidate " + element); ResolvedMember aMethod = element.getSignature(); - ResolvedMember isOverriding = isOverriding(typeToCheck,aMethod,mname,mrettype,mmods,inSamePackage,methodParamsArray); - if (isOverriding!=null) return isOverriding; + ResolvedMember isOverriding = isOverriding(typeToCheck, aMethod, mname, mrettype, mmods, inSamePackage, + methodParamsArray); + if (isOverriding != null) + return isOverriding; } } } - - - if (typeToCheck.equals(UnresolvedType.OBJECT)) return null; - - ResolvedType superclass = typeToCheck.getSuperclass(); - ResolvedMember overriddenMethod = checkForOverride(superclass,mname,mparams,mrettype,mmods,mpkg,methodParamsArray); - if (overriddenMethod!=null) return overriddenMethod; - + + if (typeToCheck.equals(UnresolvedType.OBJECT)) + return null; + + ResolvedType superclass = typeToCheck.getSuperclass(); + ResolvedMember overriddenMethod = checkForOverride(superclass, mname, mparams, mrettype, mmods, mpkg, methodParamsArray); + if (overriddenMethod != null) + return overriddenMethod; + ResolvedType[] interfaces = typeToCheck.getDeclaredInterfaces(); for (int i = 0; i < interfaces.length; i++) { ResolvedType anInterface = interfaces[i]; - overriddenMethod = checkForOverride(anInterface,mname,mparams,mrettype,mmods,mpkg,methodParamsArray); - if (overriddenMethod!=null) return overriddenMethod; + overriddenMethod = checkForOverride(anInterface, mname, mparams, mrettype, mmods, mpkg, methodParamsArray); + if (overriddenMethod != null) + return overriddenMethod; } return null; - } - - /** - * We need to determine if any methods in this type require bridge methods - this method should only - * be called if necessary to do this calculation, i.e. we are on a 1.5 VM (where covariance/generics exist) and - * the type hierarchy for the specified class has changed (via decp/itd). - * - * See pr108101 - */ - public static boolean calculateAnyRequiredBridgeMethods(BcelWorld world,LazyClassGen clazz) { - world.ensureAdvancedConfigurationProcessed(); - if (!world.isInJava5Mode()) return false; // just double check... the caller should have already verified this - if (clazz.isInterface()) return false; // dont bother if we're an interface - boolean didSomething=false; // set if we build any bridge methods - + } + + /** + * We need to determine if any methods in this type require bridge methods - this method should only be called if necessary to + * do this calculation, i.e. we are on a 1.5 VM (where covariance/generics exist) and the type hierarchy for the specified class + * has changed (via decp/itd). + * + * See pr108101 + */ + public static boolean calculateAnyRequiredBridgeMethods(BcelWorld world, LazyClassGen clazz) { + world.ensureAdvancedConfigurationProcessed(); + if (!world.isInJava5Mode()) + return false; // just double check... the caller should have already verified this + if (clazz.isInterface()) + return false; // dont bother if we're an interface + boolean didSomething = false; // set if we build any bridge methods + // So what methods do we have right now in this class? - List /*LazyMethodGen*/ methods = clazz.getMethodGens(); + List /* LazyMethodGen */methods = clazz.getMethodGens(); - // Keep a set of all methods from this type - it'll help us to check if bridge methods + // Keep a set of all methods from this type - it'll help us to check if bridge methods // have already been created, we don't want to do it twice! Set methodsSet = new HashSet(); for (int i = 0; i < methods.size(); i++) { - LazyMethodGen aMethod = (LazyMethodGen)methods.get(i); - methodsSet.add(aMethod.getName()+aMethod.getSignature()); // e.g. "foo(Ljava/lang/String;)V" + LazyMethodGen aMethod = (LazyMethodGen) methods.get(i); + methodsSet.add(aMethod.getName() + aMethod.getSignature()); // e.g. "foo(Ljava/lang/String;)V" } - + // Now go through all the methods in this type for (int i = 0; i < methods.size(); i++) { - + // This is the local method that we *might* have to bridge to - LazyMethodGen bridgeToCandidate = (LazyMethodGen)methods.get(i); - if (bridgeToCandidate.isBridgeMethod()) continue; // Doh! - String name = bridgeToCandidate.getName(); - String psig = bridgeToCandidate.getParameterSignature(); - String rsig = bridgeToCandidate.getReturnType().getSignature(); - - //if (bridgeToCandidate.isAbstract()) continue; - if (bridgeToCandidate.isStatic()) continue; // ignore static methods - if (name.endsWith("init>")) continue; // Skip constructors and static initializers - - if (world.forDEBUG_bridgingCode) System.err.println("Bridging: Determining if we have to bridge to "+clazz.getName()+"."+name+""+bridgeToCandidate.getSignature()); - + LazyMethodGen bridgeToCandidate = (LazyMethodGen) methods.get(i); + if (bridgeToCandidate.isBridgeMethod()) + continue; // Doh! + String name = bridgeToCandidate.getName(); + String psig = bridgeToCandidate.getParameterSignature(); + String rsig = bridgeToCandidate.getReturnType().getSignature(); + + // if (bridgeToCandidate.isAbstract()) continue; + if (bridgeToCandidate.isStatic()) + continue; // ignore static methods + if (name.endsWith("init>")) + continue; // Skip constructors and static initializers + + if (world.forDEBUG_bridgingCode) + System.err.println("Bridging: Determining if we have to bridge to " + clazz.getName() + "." + name + "" + + bridgeToCandidate.getSignature()); + // Let's take a look at the superclass - ResolvedType theSuperclass= clazz.getSuperClass(); - if (world.forDEBUG_bridgingCode) System.err.println("Bridging: Checking supertype "+theSuperclass); + ResolvedType theSuperclass = clazz.getSuperClass(); + if (world.forDEBUG_bridgingCode) + System.err.println("Bridging: Checking supertype " + theSuperclass); String pkgName = clazz.getPackageName(); UnresolvedType[] bm = BcelWorld.fromBcel(bridgeToCandidate.getArgumentTypes()); - ResolvedMember overriddenMethod = checkForOverride(theSuperclass,name,psig,rsig,bridgeToCandidate.getAccessFlags(),pkgName,bm); - if (overriddenMethod!=null) { - String key = new StringBuffer().append(overriddenMethod.getName()).append(overriddenMethod.getSignatureErased()).toString(); // pr 237419 + ResolvedMember overriddenMethod = checkForOverride(theSuperclass, name, psig, rsig, bridgeToCandidate.getAccessFlags(), + pkgName, bm); + if (overriddenMethod != null) { + String key = new StringBuffer().append(overriddenMethod.getName()).append(overriddenMethod.getSignatureErased()) + .toString(); // pr 237419 boolean alreadyHaveABridgeMethod = methodsSet.contains(key); - if (!alreadyHaveABridgeMethod) { - if (world.forDEBUG_bridgingCode) System.err.println("Bridging:bridging to '"+overriddenMethod+"'"); + if (!alreadyHaveABridgeMethod) { + if (world.forDEBUG_bridgingCode) + System.err.println("Bridging:bridging to '" + overriddenMethod + "'"); createBridgeMethod(world, bridgeToCandidate, clazz, overriddenMethod); methodsSet.add(key); didSomething = true; @@ -729,153 +753,175 @@ class BcelClassWeaver implements IClassWeaver { // Check superinterfaces String[] interfaces = clazz.getInterfaceNames(); for (int j = 0; j < interfaces.length; j++) { - if (world.forDEBUG_bridgingCode) System.err.println("Bridging:checking superinterface "+interfaces[j]); + if (world.forDEBUG_bridgingCode) + System.err.println("Bridging:checking superinterface " + interfaces[j]); ResolvedType interfaceType = world.resolve(interfaces[j]); - overriddenMethod = checkForOverride(interfaceType,name,psig,rsig,bridgeToCandidate.getAccessFlags(),clazz.getPackageName(),bm); - if (overriddenMethod!=null) { - String key = new StringBuffer().append(overriddenMethod.getName()).append(overriddenMethod.getSignatureErased()).toString(); // pr 237419 + overriddenMethod = checkForOverride(interfaceType, name, psig, rsig, bridgeToCandidate.getAccessFlags(), clazz + .getPackageName(), bm); + if (overriddenMethod != null) { + String key = new StringBuffer().append(overriddenMethod.getName()) + .append(overriddenMethod.getSignatureErased()).toString(); // pr 237419 boolean alreadyHaveABridgeMethod = methodsSet.contains(key); if (!alreadyHaveABridgeMethod) { createBridgeMethod(world, bridgeToCandidate, clazz, overriddenMethod); methodsSet.add(key); - didSomething=true; - if (world.forDEBUG_bridgingCode) System.err.println("Bridging:bridging to "+overriddenMethod); + didSomething = true; + if (world.forDEBUG_bridgingCode) + System.err.println("Bridging:bridging to " + overriddenMethod); continue; // look at the next method - } + } } } } return didSomething; } - - // **************************** end of bridge method creation code ***************** - /** - * Weave any declare @method/@ctor statements into the members of the supplied class - */ - private boolean weaveDeclareAtMethodCtor(LazyClassGen clazz) { + // **************************** end of bridge method creation code ***************** + + /** + * Weave any declare @method/@ctor statements into the members of the supplied class + */ + private boolean weaveDeclareAtMethodCtor(LazyClassGen clazz) { List reportedProblems = new ArrayList(); - + List allDecams = world.getDeclareAnnotationOnMethods(); - if (allDecams.isEmpty()) return false; // nothing to do - + if (allDecams.isEmpty()) + return false; // nothing to do + boolean isChanged = false; // deal with ITDs - List itdMethodsCtors = getITDSubset(clazz,ResolvedTypeMunger.Method); - itdMethodsCtors.addAll(getITDSubset(clazz,ResolvedTypeMunger.Constructor)); + List itdMethodsCtors = getITDSubset(clazz, ResolvedTypeMunger.Method); + itdMethodsCtors.addAll(getITDSubset(clazz, ResolvedTypeMunger.Constructor)); if (!itdMethodsCtors.isEmpty()) { // Can't use the subset called 'decaMs' as it won't be right for ITDs... - isChanged = weaveAtMethodOnITDSRepeatedly(allDecams,itdMethodsCtors,reportedProblems); + isChanged = weaveAtMethodOnITDSRepeatedly(allDecams, itdMethodsCtors, reportedProblems); } - + // deal with all the other methods... - List members = clazz.getMethodGens(); - List decaMs = getMatchingSubset(allDecams,clazz.getType()); - if (decaMs.isEmpty()) return false; // nothing to do + List members = clazz.getMethodGens(); + List decaMs = getMatchingSubset(allDecams, clazz.getType()); + if (decaMs.isEmpty()) + return false; // nothing to do if (!members.isEmpty()) { - Set unusedDecams = new HashSet(); - unusedDecams.addAll(decaMs); - for (int memberCounter = 0;memberCounter<members.size();memberCounter++) { - LazyMethodGen mg = (LazyMethodGen)members.get(memberCounter); - if (!mg.getName().startsWith(NameMangler.PREFIX)) { - - // Single first pass - List worthRetrying = new ArrayList(); - boolean modificationOccured = false; - List /*AnnotationGen*/ annotationsToAdd = null; - for (Iterator iter = decaMs.iterator(); iter.hasNext();) { - DeclareAnnotation decaM = (DeclareAnnotation) iter.next(); - - if (decaM.matches(mg.getMemberView(),world)) { - if (doesAlreadyHaveAnnotation(mg.getMemberView(),decaM,reportedProblems)) { - // remove the declare @method since don't want an error when - // the annotation is already there - unusedDecams.remove(decaM); - continue; // skip this one... - } - - if (annotationsToAdd==null) annotationsToAdd = new ArrayList(); - AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation(); - AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true); - annotationsToAdd.add(ag); - mg.addAnnotation(decaM.getAnnotationX()); - - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod()); - reportMethodCtorWeavingMessage(clazz, mg.getMemberView(), decaM,mg.getDeclarationLineNumber()); - isChanged = true; - modificationOccured = true; - // remove the declare @method since have matched against it - unusedDecams.remove(decaM); - } else { - if (!decaM.isStarredAnnotationPattern()) - worthRetrying.add(decaM); // an annotation is specified that might be put on by a subsequent decaf - } - } - - // Multiple secondary passes - while (!worthRetrying.isEmpty() && modificationOccured) { - modificationOccured = false; - // lets have another go - List forRemoval = new ArrayList(); - for (Iterator iter = worthRetrying.iterator(); iter.hasNext();) { - DeclareAnnotation decaM = (DeclareAnnotation) iter.next(); - if (decaM.matches(mg.getMemberView(),world)) { - if (doesAlreadyHaveAnnotation(mg.getMemberView(),decaM,reportedProblems)) { - // remove the declare @method since don't want an error when - // the annotation is already there - unusedDecams.remove(decaM); - continue; // skip this one... - } - - if (annotationsToAdd==null) annotationsToAdd = new ArrayList(); - AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation(); - //CUSTARD superfluous? - //AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true); - annotationsToAdd.add(a); - - mg.addAnnotation(decaM.getAnnotationX()); - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod()); - isChanged = true; - modificationOccured = true; - forRemoval.add(decaM); - // remove the declare @method since have matched against it - unusedDecams.remove(decaM); - } - } - worthRetrying.removeAll(forRemoval); - } - if (annotationsToAdd!=null) { - Method oldMethod = mg.getMethod(); - MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPool(),false);// dont use tags, they won't get repaired like for woven methods. - for (Iterator iter = annotationsToAdd.iterator(); iter.hasNext();) { - AnnotationGen a = (AnnotationGen) iter.next(); - myGen.addAnnotation(a); + Set unusedDecams = new HashSet(); + unusedDecams.addAll(decaMs); + for (int memberCounter = 0; memberCounter < members.size(); memberCounter++) { + LazyMethodGen mg = (LazyMethodGen) members.get(memberCounter); + if (!mg.getName().startsWith(NameMangler.PREFIX)) { + + // Single first pass + List worthRetrying = new ArrayList(); + boolean modificationOccured = false; + List /* AnnotationGen */annotationsToAdd = null; + for (Iterator iter = decaMs.iterator(); iter.hasNext();) { + DeclareAnnotation decaM = (DeclareAnnotation) iter.next(); + + if (decaM.matches(mg.getMemberView(), world)) { + if (doesAlreadyHaveAnnotation(mg.getMemberView(), decaM, reportedProblems)) { + // remove the declare @method since don't want an error when + // the annotation is already there + unusedDecams.remove(decaM); + continue; // skip this one... + } + + if (annotationsToAdd == null) + annotationsToAdd = new ArrayList(); + AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation(); + AnnotationGen ag = new AnnotationGen(a, clazz.getConstantPool(), true); + annotationsToAdd.add(ag); + mg.addAnnotation(decaM.getAnnotationX()); + + AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(), + clazz.getName(), mg.getMethod()); + reportMethodCtorWeavingMessage(clazz, mg.getMemberView(), decaM, mg.getDeclarationLineNumber()); + isChanged = true; + modificationOccured = true; + // remove the declare @method since have matched against it + unusedDecams.remove(decaM); + } else { + if (!decaM.isStarredAnnotationPattern()) + worthRetrying.add(decaM); // an annotation is specified that might be put on by a subsequent decaf + } } - Method newMethod = myGen.getMethod(); - members.set(memberCounter,new LazyMethodGen(newMethod,clazz)); - } - - } - } - checkUnusedDeclareAtTypes(unusedDecams, false); - } + + // Multiple secondary passes + while (!worthRetrying.isEmpty() && modificationOccured) { + modificationOccured = false; + // lets have another go + List forRemoval = new ArrayList(); + for (Iterator iter = worthRetrying.iterator(); iter.hasNext();) { + DeclareAnnotation decaM = (DeclareAnnotation) iter.next(); + if (decaM.matches(mg.getMemberView(), world)) { + if (doesAlreadyHaveAnnotation(mg.getMemberView(), decaM, reportedProblems)) { + // remove the declare @method since don't want an error when + // the annotation is already there + unusedDecams.remove(decaM); + continue; // skip this one... + } + + if (annotationsToAdd == null) + annotationsToAdd = new ArrayList(); + AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation(); + // CUSTARD superfluous? + // AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true); + annotationsToAdd.add(a); + + mg.addAnnotation(decaM.getAnnotationX()); + AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(), + clazz.getName(), mg.getMethod()); + isChanged = true; + modificationOccured = true; + forRemoval.add(decaM); + // remove the declare @method since have matched against it + unusedDecams.remove(decaM); + } + } + worthRetrying.removeAll(forRemoval); + } + if (annotationsToAdd != null) { + Method oldMethod = mg.getMethod(); + MethodGen myGen = new MethodGen(oldMethod, clazz.getClassName(), clazz.getConstantPool(), false);// dont use + // tags, + // they + // won't + // get + // repaired + // like + // for + // woven + // methods + // . + for (Iterator iter = annotationsToAdd.iterator(); iter.hasNext();) { + AnnotationGen a = (AnnotationGen) iter.next(); + myGen.addAnnotation(a); + } + Method newMethod = myGen.getMethod(); + members.set(memberCounter, new LazyMethodGen(newMethod, clazz)); + } + + } + } + checkUnusedDeclareAtTypes(unusedDecams, false); + } return isChanged; - } + } - - // TAG: WeavingMessage - private void reportMethodCtorWeavingMessage(LazyClassGen clazz, ResolvedMember member, DeclareAnnotation decaM,int memberLineNumber) { - if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)){ + // TAG: WeavingMessage + private void reportMethodCtorWeavingMessage(LazyClassGen clazz, ResolvedMember member, DeclareAnnotation decaM, + int memberLineNumber) { + if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) { StringBuffer parmString = new StringBuffer("("); UnresolvedType[] paramTypes = member.getParameterTypes(); for (int i = 0; i < paramTypes.length; i++) { UnresolvedType type = paramTypes[i]; String s = org.aspectj.apache.bcel.classfile.Utility.signatureToString(type.getSignature()); - if (s.lastIndexOf('.')!=-1) s =s.substring(s.lastIndexOf('.')+1); + if (s.lastIndexOf('.') != -1) + s = s.substring(s.lastIndexOf('.') + 1); parmString.append(s); - if ((i+1)<paramTypes.length) parmString.append(","); + if ((i + 1) < paramTypes.length) + parmString.append(","); } parmString.append(")"); String methodName = member.getName(); @@ -886,38 +932,33 @@ class BcelClassWeaver implements IClassWeaver { sig.append(" "); sig.append(member.getDeclaringType().toString()); sig.append("."); - sig.append(methodName.equals("<init>")?"new":methodName); + sig.append(methodName.equals("<init>") ? "new" : methodName); sig.append(parmString); - + StringBuffer loc = new StringBuffer(); - if (clazz.getFileName()==null) { + if (clazz.getFileName() == null) { loc.append("no debug info available"); } else { loc.append(clazz.getFileName()); - if (memberLineNumber!=-1) { - loc.append(":"+memberLineNumber); + if (memberLineNumber != -1) { + loc.append(":" + memberLineNumber); } } getWorld().getMessageHandler().handleMessage( - WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES, - new String[]{ - sig.toString(), - loc.toString(), - decaM.getAnnotationString(), - methodName.startsWith("<init>")?"constructor":"method", - decaM.getAspect().toString(), - Utility.beautifyLocation(decaM.getSourceLocation()) - })); - } - } - + WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES, new String[] { sig.toString(), + loc.toString(), decaM.getAnnotationString(), + methodName.startsWith("<init>") ? "constructor" : "method", decaM.getAspect().toString(), + Utility.beautifyLocation(decaM.getSourceLocation()) })); + } + } + /** - * Looks through a list of declare annotation statements and only returns - * those that could possibly match on a field/method/ctor in type. + * Looks through a list of declare annotation statements and only returns those that could possibly match on a field/method/ctor + * in type. */ private List getMatchingSubset(List declareAnnotations, ResolvedType type) { - List subset = new ArrayList(); - for (Iterator iter = declareAnnotations.iterator(); iter.hasNext();) { + List subset = new ArrayList(); + for (Iterator iter = declareAnnotations.iterator(); iter.hasNext();) { DeclareAnnotation da = (DeclareAnnotation) iter.next(); if (da.couldEverMatch(type)) { subset.add(da); @@ -926,427 +967,433 @@ class BcelClassWeaver implements IClassWeaver { return subset; } - - /** - * Get a subset of all the type mungers defined on this aspect - */ - private List getITDSubset(LazyClassGen clazz,ResolvedTypeMunger.Kind wantedKind) { + /** + * Get a subset of all the type mungers defined on this aspect + */ + private List getITDSubset(LazyClassGen clazz, ResolvedTypeMunger.Kind wantedKind) { List subset = new ArrayList(); Collection c = clazz.getBcelObjectType().getTypeMungers(); - for (Iterator iter = c.iterator();iter.hasNext();) { - BcelTypeMunger typeMunger = (BcelTypeMunger)iter.next(); - if (typeMunger.getMunger().getKind()==wantedKind) + for (Iterator iter = c.iterator(); iter.hasNext();) { + BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next(); + if (typeMunger.getMunger().getKind() == wantedKind) subset.add(typeMunger); } return subset; } - - public LazyMethodGen locateAnnotationHolderForFieldMunger(LazyClassGen clazz,BcelTypeMunger fieldMunger) { - NewFieldTypeMunger nftm = (NewFieldTypeMunger)fieldMunger.getMunger(); - ResolvedMember lookingFor =AjcMemberMaker.interFieldInitializer(nftm.getSignature(),clazz.getType()); + + public LazyMethodGen locateAnnotationHolderForFieldMunger(LazyClassGen clazz, BcelTypeMunger fieldMunger) { + NewFieldTypeMunger nftm = (NewFieldTypeMunger) fieldMunger.getMunger(); + ResolvedMember lookingFor = AjcMemberMaker.interFieldInitializer(nftm.getSignature(), clazz.getType()); List meths = clazz.getMethodGens(); for (Iterator iter = meths.iterator(); iter.hasNext();) { LazyMethodGen element = (LazyMethodGen) iter.next(); - if (element.getName().equals(lookingFor.getName())) return element; + if (element.getName().equals(lookingFor.getName())) + return element; } return null; } - + // FIXME asc refactor this to neaten it up - public LazyMethodGen locateAnnotationHolderForMethodCtorMunger(LazyClassGen clazz,BcelTypeMunger methodCtorMunger) { + public LazyMethodGen locateAnnotationHolderForMethodCtorMunger(LazyClassGen clazz, BcelTypeMunger methodCtorMunger) { if (methodCtorMunger.getMunger() instanceof NewMethodTypeMunger) { - NewMethodTypeMunger nftm = (NewMethodTypeMunger)methodCtorMunger.getMunger(); - - ResolvedMember lookingFor = AjcMemberMaker.interMethodDispatcher(nftm.getSignature(),methodCtorMunger.getAspectType()); - + NewMethodTypeMunger nftm = (NewMethodTypeMunger) methodCtorMunger.getMunger(); + + ResolvedMember lookingFor = AjcMemberMaker.interMethodDispatcher(nftm.getSignature(), methodCtorMunger.getAspectType()); + List meths = clazz.getMethodGens(); for (Iterator iter = meths.iterator(); iter.hasNext();) { LazyMethodGen element = (LazyMethodGen) iter.next(); - if (element.getName().equals(lookingFor.getName()) && element.getParameterSignature().equals(lookingFor.getParameterSignature())) return element; + if (element.getName().equals(lookingFor.getName()) + && element.getParameterSignature().equals(lookingFor.getParameterSignature())) + return element; } return null; } else if (methodCtorMunger.getMunger() instanceof NewConstructorTypeMunger) { - NewConstructorTypeMunger nftm = (NewConstructorTypeMunger)methodCtorMunger.getMunger(); - ResolvedMember lookingFor =AjcMemberMaker.postIntroducedConstructor(methodCtorMunger.getAspectType(),nftm.getSignature().getDeclaringType(),nftm.getSignature().getParameterTypes()); + NewConstructorTypeMunger nftm = (NewConstructorTypeMunger) methodCtorMunger.getMunger(); + ResolvedMember lookingFor = AjcMemberMaker.postIntroducedConstructor(methodCtorMunger.getAspectType(), nftm + .getSignature().getDeclaringType(), nftm.getSignature().getParameterTypes()); List meths = clazz.getMethodGens(); for (Iterator iter = meths.iterator(); iter.hasNext();) { LazyMethodGen element = (LazyMethodGen) iter.next(); - if (element.getName().equals(lookingFor.getName()) && element.getParameterSignature().equals(lookingFor.getParameterSignature())) return element; + if (element.getName().equals(lookingFor.getName()) + && element.getParameterSignature().equals(lookingFor.getParameterSignature())) + return element; } return null; } else { - throw new BCException("Not sure what this is: "+methodCtorMunger); + throw new BCException("Not sure what this is: " + methodCtorMunger); } } - - /** - * Applies some set of declare @field constructs (List<DeclareAnnotation>) to some bunch - * of ITDfields (List<BcelTypeMunger>. It will iterate over the fields repeatedly until - * everything has been applied. - * - */ - private boolean weaveAtFieldRepeatedly(List decaFs, List itdFields,List reportedErrors) { + + /** + * Applies some set of declare @field constructs (List<DeclareAnnotation>) to some bunch of ITDfields (List<BcelTypeMunger>. It + * will iterate over the fields repeatedly until everything has been applied. + * + */ + private boolean weaveAtFieldRepeatedly(List decaFs, List itdFields, List reportedErrors) { boolean isChanged = false; for (Iterator iter = itdFields.iterator(); iter.hasNext();) { BcelTypeMunger fieldMunger = (BcelTypeMunger) iter.next(); ResolvedMember itdIsActually = fieldMunger.getSignature(); List worthRetrying = new ArrayList(); boolean modificationOccured = false; - + for (Iterator iter2 = decaFs.iterator(); iter2.hasNext();) { DeclareAnnotation decaF = (DeclareAnnotation) iter2.next(); - - if (decaF.matches(itdIsActually,world)) { - LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz,fieldMunger); - if (doesAlreadyHaveAnnotation(annotationHolder,itdIsActually,decaF,reportedErrors)) continue; // skip this one... + + if (decaF.matches(itdIsActually, world)) { + LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, fieldMunger); + if (doesAlreadyHaveAnnotation(annotationHolder, itdIsActually, decaF, reportedErrors)) + continue; // skip this one... annotationHolder.addAnnotation(decaF.getAnnotationX()); - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),itdIsActually.getSourceLocation()); + AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(), + itdIsActually.getSourceLocation()); isChanged = true; modificationOccured = true; - + } else { - if (!decaF.isStarredAnnotationPattern()) + if (!decaF.isStarredAnnotationPattern()) worthRetrying.add(decaF); // an annotation is specified that might be put on by a subsequent decaf } } - - while (!worthRetrying.isEmpty() && modificationOccured) { + + while (!worthRetrying.isEmpty() && modificationOccured) { modificationOccured = false; - List forRemoval = new ArrayList(); - for (Iterator iter2 = worthRetrying.iterator(); iter2.hasNext();) { - DeclareAnnotation decaF = (DeclareAnnotation) iter2.next(); - if (decaF.matches(itdIsActually,world)) { - LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz,fieldMunger); - if (doesAlreadyHaveAnnotation(annotationHolder,itdIsActually,decaF,reportedErrors)) continue; // skip this one... - annotationHolder.addAnnotation(decaF.getAnnotationX()); - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),itdIsActually.getSourceLocation()); - isChanged = true; - modificationOccured = true; - forRemoval.add(decaF); - } - worthRetrying.removeAll(forRemoval); - } - } - } - return isChanged; - } - - + List forRemoval = new ArrayList(); + for (Iterator iter2 = worthRetrying.iterator(); iter2.hasNext();) { + DeclareAnnotation decaF = (DeclareAnnotation) iter2.next(); + if (decaF.matches(itdIsActually, world)) { + LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, fieldMunger); + if (doesAlreadyHaveAnnotation(annotationHolder, itdIsActually, decaF, reportedErrors)) + continue; // skip this one... + annotationHolder.addAnnotation(decaF.getAnnotationX()); + AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(), + itdIsActually.getSourceLocation()); + isChanged = true; + modificationOccured = true; + forRemoval.add(decaF); + } + worthRetrying.removeAll(forRemoval); + } + } + } + return isChanged; + } + /** - * Applies some set of declare @method/@ctor constructs (List<DeclareAnnotation>) to some bunch - * of ITDmembers (List<BcelTypeMunger>. It will iterate over the fields repeatedly until - * everything has been applied. - */ - private boolean weaveAtMethodOnITDSRepeatedly(List decaMCs, List itdMethodsCtors,List reportedErrors) { + * Applies some set of declare @method/@ctor constructs (List<DeclareAnnotation>) to some bunch of ITDmembers + * (List<BcelTypeMunger>. It will iterate over the fields repeatedly until everything has been applied. + */ + private boolean weaveAtMethodOnITDSRepeatedly(List decaMCs, List itdMethodsCtors, List reportedErrors) { boolean isChanged = false; for (Iterator iter = itdMethodsCtors.iterator(); iter.hasNext();) { BcelTypeMunger methodctorMunger = (BcelTypeMunger) iter.next(); ResolvedMember unMangledInterMethod = methodctorMunger.getSignature(); List worthRetrying = new ArrayList(); boolean modificationOccured = false; - + for (Iterator iter2 = decaMCs.iterator(); iter2.hasNext();) { DeclareAnnotation decaMC = (DeclareAnnotation) iter2.next(); - if (decaMC.matches(unMangledInterMethod,world)) { - LazyMethodGen annotationHolder = locateAnnotationHolderForMethodCtorMunger(clazz,methodctorMunger); - if (annotationHolder == null || doesAlreadyHaveAnnotation(annotationHolder,unMangledInterMethod,decaMC,reportedErrors)){ + if (decaMC.matches(unMangledInterMethod, world)) { + LazyMethodGen annotationHolder = locateAnnotationHolderForMethodCtorMunger(clazz, methodctorMunger); + if (annotationHolder == null + || doesAlreadyHaveAnnotation(annotationHolder, unMangledInterMethod, decaMC, reportedErrors)) { continue; // skip this one... } annotationHolder.addAnnotation(decaMC.getAnnotationX()); - isChanged=true; - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaMC.getSourceLocation(),unMangledInterMethod.getSourceLocation()); - reportMethodCtorWeavingMessage(clazz, unMangledInterMethod, decaMC,-1); - modificationOccured = true; + isChanged = true; + AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaMC.getSourceLocation(), + unMangledInterMethod.getSourceLocation()); + reportMethodCtorWeavingMessage(clazz, unMangledInterMethod, decaMC, -1); + modificationOccured = true; } else { - if (!decaMC.isStarredAnnotationPattern()) + if (!decaMC.isStarredAnnotationPattern()) worthRetrying.add(decaMC); // an annotation is specified that might be put on by a subsequent decaf } } - - while (!worthRetrying.isEmpty() && modificationOccured) { + + while (!worthRetrying.isEmpty() && modificationOccured) { modificationOccured = false; - List forRemoval = new ArrayList(); - for (Iterator iter2 = worthRetrying.iterator(); iter2.hasNext();) { - DeclareAnnotation decaMC = (DeclareAnnotation) iter2.next(); - if (decaMC.matches(unMangledInterMethod,world)) { - LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz,methodctorMunger); - if (doesAlreadyHaveAnnotation(annotationHolder,unMangledInterMethod,decaMC,reportedErrors)) continue; // skip this one... - annotationHolder.addAnnotation(decaMC.getAnnotationX()); - unMangledInterMethod.addAnnotation(decaMC.getAnnotationX()); - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaMC.getSourceLocation(),unMangledInterMethod.getSourceLocation()); - isChanged = true; - modificationOccured = true; - forRemoval.add(decaMC); - } - worthRetrying.removeAll(forRemoval); - } - } - } - return isChanged; - } - - private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX [] dontAddMeTwice){ - for (int i = 0; i < dontAddMeTwice.length; i++){ + List forRemoval = new ArrayList(); + for (Iterator iter2 = worthRetrying.iterator(); iter2.hasNext();) { + DeclareAnnotation decaMC = (DeclareAnnotation) iter2.next(); + if (decaMC.matches(unMangledInterMethod, world)) { + LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz, methodctorMunger); + if (doesAlreadyHaveAnnotation(annotationHolder, unMangledInterMethod, decaMC, reportedErrors)) + continue; // skip this one... + annotationHolder.addAnnotation(decaMC.getAnnotationX()); + unMangledInterMethod.addAnnotation(decaMC.getAnnotationX()); + AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaMC.getSourceLocation(), + unMangledInterMethod.getSourceLocation()); + isChanged = true; + modificationOccured = true; + forRemoval.add(decaMC); + } + worthRetrying.removeAll(forRemoval); + } + } + } + return isChanged; + } + + private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX[] dontAddMeTwice) { + for (int i = 0; i < dontAddMeTwice.length; i++) { AnnotationX ann = dontAddMeTwice[i]; - if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())){ - //dontAddMeTwice[i] = null; // incase it really has been added twice! + if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())) { + // dontAddMeTwice[i] = null; // incase it really has been added twice! return true; } } return false; } - + /** * Weave any declare @field statements into the fields of the supplied class * - * Interesting case relating to public ITDd fields. The annotations are really stored against - * the interfieldinit method in the aspect, but the public field is placed in the target - * type and then is processed in the 2nd pass over fields that occurs. I think it would be - * more expensive to avoid putting the annotation on that inserted public field than just to - * have it put there as well as on the interfieldinit method. + * Interesting case relating to public ITDd fields. The annotations are really stored against the interfieldinit method in the + * aspect, but the public field is placed in the target type and then is processed in the 2nd pass over fields that occurs. I + * think it would be more expensive to avoid putting the annotation on that inserted public field than just to have it put there + * as well as on the interfieldinit method. */ private boolean weaveDeclareAtField(LazyClassGen clazz) { - - // BUGWARNING not getting enough warnings out on declare @field ? - // There is a potential problem here with warnings not coming out - this - // will occur if they are created on the second iteration round this loop. - // We currently deactivate error reporting for the second time round. - // A possible solution is to record what annotations were added by what - // decafs and check that to see if an error needs to be reported - this - // would be expensive so lets skip it for now + + // BUGWARNING not getting enough warnings out on declare @field ? + // There is a potential problem here with warnings not coming out - this + // will occur if they are created on the second iteration round this loop. + // We currently deactivate error reporting for the second time round. + // A possible solution is to record what annotations were added by what + // decafs and check that to see if an error needs to be reported - this + // would be expensive so lets skip it for now List reportedProblems = new ArrayList(); List allDecafs = world.getDeclareAnnotationOnFields(); - if (allDecafs.isEmpty()) return false; // nothing to do - - + if (allDecafs.isEmpty()) + return false; // nothing to do + boolean isChanged = false; - List itdFields = getITDSubset(clazz,ResolvedTypeMunger.Field); - if (itdFields!=null) { - isChanged = weaveAtFieldRepeatedly(allDecafs,itdFields,reportedProblems); + List itdFields = getITDSubset(clazz, ResolvedTypeMunger.Field); + if (itdFields != null) { + isChanged = weaveAtFieldRepeatedly(allDecafs, itdFields, reportedProblems); } - - List decaFs = getMatchingSubset(allDecafs,clazz.getType()); - if (decaFs.isEmpty()) return false; // nothing more to do + + List decaFs = getMatchingSubset(allDecafs, clazz.getType()); + if (decaFs.isEmpty()) + return false; // nothing more to do List fields = clazz.getFieldGens(); - if (fields!=null) { - Set unusedDecafs = new HashSet(); - unusedDecafs.addAll(decaFs); - for (int fieldCounter = 0;fieldCounter<fields.size();fieldCounter++) { - BcelField aBcelField = (BcelField)fields.get(fieldCounter);//new BcelField(clazz.getBcelObjectType(),fields[fieldCounter]); - if (!aBcelField.getName().startsWith(NameMangler.PREFIX)) { - // Single first pass - List worthRetrying = new ArrayList(); - boolean modificationOccured = false; - - AnnotationX[] dontAddMeTwice = aBcelField.getAnnotations(); - - // go through all the declare @field statements - for (Iterator iter = decaFs.iterator(); iter.hasNext();) { - DeclareAnnotation decaF = (DeclareAnnotation) iter.next(); - if (decaF.matches(aBcelField,world)) { - - if (!dontAddTwice(decaF,dontAddMeTwice)){ - if (doesAlreadyHaveAnnotation(aBcelField,decaF,reportedProblems)){ - // remove the declare @field since don't want an error when - // the annotation is already there - unusedDecafs.remove(decaF); - continue; - } - - if(decaF.getAnnotationX().isRuntimeVisible()){ // isAnnotationWithRuntimeRetention(clazz.getJavaClass(world))){ - //if(decaF.getAnnotationTypeX().isAnnotationWithRuntimeRetention(world)){ - // it should be runtime visible, so put it on the Field -// Annotation a = decaF.getAnnotationX().getBcelAnnotation(); -// AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true); -// FieldGen myGen = new FieldGen(fields[fieldCounter],clazz.getConstantPoolGen()); -// myGen.addAnnotation(ag); -// Field newField = myGen.getField(); - - aBcelField.addAnnotation(decaF.getAnnotationX()); -// clazz.replaceField(fields[fieldCounter],newField); -// fields[fieldCounter]=newField; - - } else{ - aBcelField.addAnnotation(decaF.getAnnotationX()); + if (fields != null) { + Set unusedDecafs = new HashSet(); + unusedDecafs.addAll(decaFs); + for (int fieldCounter = 0; fieldCounter < fields.size(); fieldCounter++) { + BcelField aBcelField = (BcelField) fields.get(fieldCounter);// new + // BcelField(clazz.getBcelObjectType(),fields[fieldCounter + // ]); + if (!aBcelField.getName().startsWith(NameMangler.PREFIX)) { + // Single first pass + List worthRetrying = new ArrayList(); + boolean modificationOccured = false; + + AnnotationX[] dontAddMeTwice = aBcelField.getAnnotations(); + + // go through all the declare @field statements + for (Iterator iter = decaFs.iterator(); iter.hasNext();) { + DeclareAnnotation decaF = (DeclareAnnotation) iter.next(); + if (decaF.matches(aBcelField, world)) { + + if (!dontAddTwice(decaF, dontAddMeTwice)) { + if (doesAlreadyHaveAnnotation(aBcelField, decaF, reportedProblems)) { + // remove the declare @field since don't want an error when + // the annotation is already there + unusedDecafs.remove(decaF); + continue; + } + + if (decaF.getAnnotationX().isRuntimeVisible()) { // isAnnotationWithRuntimeRetention(clazz. + // getJavaClass(world))){ + // if(decaF.getAnnotationTypeX().isAnnotationWithRuntimeRetention(world)){ + // it should be runtime visible, so put it on the Field + // Annotation a = decaF.getAnnotationX().getBcelAnnotation(); + // AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true); + // FieldGen myGen = new FieldGen(fields[fieldCounter],clazz.getConstantPoolGen()); + // myGen.addAnnotation(ag); + // Field newField = myGen.getField(); + + aBcelField.addAnnotation(decaF.getAnnotationX()); + // clazz.replaceField(fields[fieldCounter],newField); + // fields[fieldCounter]=newField; + + } else { + aBcelField.addAnnotation(decaF.getAnnotationX()); + } + } + + AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(), + clazz.getName(), aBcelField.getFieldAsIs()); + reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF); + isChanged = true; + modificationOccured = true; + // remove the declare @field since have matched against it + unusedDecafs.remove(decaF); + } else { + if (!decaF.isStarredAnnotationPattern()) + worthRetrying.add(decaF); // an annotation is specified that might be put on by a subsequent decaf } } - - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs()); - reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF); - isChanged = true; - modificationOccured = true; - // remove the declare @field since have matched against it - unusedDecafs.remove(decaF); - } else { - if (!decaF.isStarredAnnotationPattern()) - worthRetrying.add(decaF); // an annotation is specified that might be put on by a subsequent decaf - } - } - - // Multiple secondary passes - while (!worthRetrying.isEmpty() && modificationOccured) { - modificationOccured = false; - // lets have another go - List forRemoval = new ArrayList(); - for (Iterator iter = worthRetrying.iterator(); iter.hasNext();) { - DeclareAnnotation decaF = (DeclareAnnotation) iter.next(); - if (decaF.matches(aBcelField,world)) { - // below code is for recursive things - if (doesAlreadyHaveAnnotation(aBcelField,decaF,reportedProblems)) { - // remove the declare @field since don't want an error when - // the annotation is already there - unusedDecafs.remove(decaF); - continue; // skip this one... + + // Multiple secondary passes + while (!worthRetrying.isEmpty() && modificationOccured) { + modificationOccured = false; + // lets have another go + List forRemoval = new ArrayList(); + for (Iterator iter = worthRetrying.iterator(); iter.hasNext();) { + DeclareAnnotation decaF = (DeclareAnnotation) iter.next(); + if (decaF.matches(aBcelField, world)) { + // below code is for recursive things + if (doesAlreadyHaveAnnotation(aBcelField, decaF, reportedProblems)) { + // remove the declare @field since don't want an error when + // the annotation is already there + unusedDecafs.remove(decaF); + continue; // skip this one... + } + aBcelField.addAnnotation(decaF.getAnnotationX()); + AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(), + clazz.getName(), aBcelField.getFieldAsIs()); + isChanged = true; + modificationOccured = true; + forRemoval.add(decaF); + // remove the declare @field since have matched against it + unusedDecafs.remove(decaF); + } + } + worthRetrying.removeAll(forRemoval); } - aBcelField.addAnnotation(decaF.getAnnotationX()); - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs()); - isChanged = true; - modificationOccured = true; - forRemoval.add(decaF); - // remove the declare @field since have matched against it - unusedDecafs.remove(decaF); } - } - worthRetrying.removeAll(forRemoval); - } } - } - checkUnusedDeclareAtTypes(unusedDecafs,true); - } + checkUnusedDeclareAtTypes(unusedDecafs, true); + } return isChanged; } // bug 99191 - put out an error message if the type doesn't exist /** - * Report an error if the reason a "declare @method/ctor/field" was not used was because the member - * specified does not exist. This method is passed some set of declare statements that didn't - * match and a flag indicating whether the set contains declare @field or declare @method/ctor - * entries. + * Report an error if the reason a "declare @method/ctor/field" was not used was because the member specified does not exist. + * This method is passed some set of declare statements that didn't match and a flag indicating whether the set contains declare @field + * or declare @method/ctor entries. */ private void checkUnusedDeclareAtTypes(Set unusedDecaTs, boolean isDeclareAtField) { for (Iterator iter = unusedDecaTs.iterator(); iter.hasNext();) { - DeclareAnnotation declA = (DeclareAnnotation) iter.next(); - - // Error if an exact type pattern was specified - if ((declA.isExactPattern() || - (declA.getSignaturePattern().getDeclaringType() instanceof ExactTypePattern)) - && (!declA.getSignaturePattern().getName().isAny() - || (declA.getKind() == DeclareAnnotation.AT_CONSTRUCTOR))) { - - // Quickly check if an ITD meets supplies the 'missing' member - boolean itdMatch = false; - List lst = clazz.getType().getInterTypeMungers(); - for (Iterator iterator = lst.iterator(); iterator.hasNext() && !itdMatch;) { + DeclareAnnotation declA = (DeclareAnnotation) iter.next(); + + // Error if an exact type pattern was specified + if ((declA.isExactPattern() || (declA.getSignaturePattern().getDeclaringType() instanceof ExactTypePattern)) + && (!declA.getSignaturePattern().getName().isAny() || (declA.getKind() == DeclareAnnotation.AT_CONSTRUCTOR))) { + + // Quickly check if an ITD meets supplies the 'missing' member + boolean itdMatch = false; + List lst = clazz.getType().getInterTypeMungers(); + for (Iterator iterator = lst.iterator(); iterator.hasNext() && !itdMatch;) { BcelTypeMunger element = (BcelTypeMunger) iterator.next(); - if (element.getMunger() instanceof NewFieldTypeMunger) { - NewFieldTypeMunger nftm = (NewFieldTypeMunger)element.getMunger(); - itdMatch = declA.getSignaturePattern().matches(nftm.getSignature(),world,false); - }else if (element.getMunger() instanceof NewMethodTypeMunger) { - NewMethodTypeMunger nmtm = (NewMethodTypeMunger)element.getMunger(); - itdMatch = declA.getSignaturePattern().matches(nmtm.getSignature(),world,false); + if (element.getMunger() instanceof NewFieldTypeMunger) { + NewFieldTypeMunger nftm = (NewFieldTypeMunger) element.getMunger(); + itdMatch = declA.getSignaturePattern().matches(nftm.getSignature(), world, false); + } else if (element.getMunger() instanceof NewMethodTypeMunger) { + NewMethodTypeMunger nmtm = (NewMethodTypeMunger) element.getMunger(); + itdMatch = declA.getSignaturePattern().matches(nmtm.getSignature(), world, false); } else if (element.getMunger() instanceof NewConstructorTypeMunger) { - NewConstructorTypeMunger nctm = (NewConstructorTypeMunger)element.getMunger(); - itdMatch = declA.getSignaturePattern().matches(nctm.getSignature(),world,false); + NewConstructorTypeMunger nctm = (NewConstructorTypeMunger) element.getMunger(); + itdMatch = declA.getSignaturePattern().matches(nctm.getSignature(), world, false); } } - if (!itdMatch) { - IMessage message = null; - if (isDeclareAtField) { - message = new Message( - "The field '"+ declA.getSignaturePattern().toString() + - "' does not exist", declA.getSourceLocation() , true); - } else { - message = new Message( - "The method '"+ declA.getSignaturePattern().toString() + - "' does not exist", declA.getSourceLocation() , true); + if (!itdMatch) { + IMessage message = null; + if (isDeclareAtField) { + message = new Message("The field '" + declA.getSignaturePattern().toString() + "' does not exist", declA + .getSourceLocation(), true); + } else { + message = new Message("The method '" + declA.getSignaturePattern().toString() + "' does not exist", declA + .getSourceLocation(), true); } - world.getMessageHandler().handleMessage(message); + world.getMessageHandler().handleMessage(message); } - } - } + } + } } - + // TAG: WeavingMessage private void reportFieldAnnotationWeavingMessage(LazyClassGen clazz, List fields, int fieldCounter, DeclareAnnotation decaF) { - if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)){ - BcelField theField = (BcelField)fields.get(fieldCounter); - world.getMessageHandler().handleMessage( - WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES, - new String[]{ - theField.getFieldAsIs().toString() + "' of type '" + clazz.getName(), - clazz.getFileName(), - decaF.getAnnotationString(), - "field", - decaF.getAspect().toString(), - Utility.beautifyLocation(decaF.getSourceLocation())})); - } - } - - /** - * Check if a resolved member (field/method/ctor) already has an annotation, if it - * does then put out a warning and return true - */ - private boolean doesAlreadyHaveAnnotation(ResolvedMember rm,DeclareAnnotation deca,List reportedProblems) { - if (rm.hasAnnotation(deca.getAnnotationTypeX())) { - if (world.getLint().elementAlreadyAnnotated.isEnabled()) { - Integer uniqueID = new Integer(rm.hashCode()*deca.hashCode()); - if (!reportedProblems.contains(uniqueID)) { - reportedProblems.add(uniqueID); - world.getLint().elementAlreadyAnnotated.signal( - new String[]{rm.toString(),deca.getAnnotationTypeX().toString()}, - rm.getSourceLocation(),new ISourceLocation[]{deca.getSourceLocation()}); - } - } - return true; - } - return false; - } - - private boolean doesAlreadyHaveAnnotation(LazyMethodGen rm,ResolvedMember itdfieldsig,DeclareAnnotation deca,List reportedProblems) { - if (rm != null && rm.hasAnnotation(deca.getAnnotationTypeX())) { - if (world.getLint().elementAlreadyAnnotated.isEnabled()) { - Integer uniqueID = new Integer(rm.hashCode()*deca.hashCode()); - if (!reportedProblems.contains(uniqueID)) { - reportedProblems.add(uniqueID); - reportedProblems.add(new Integer(itdfieldsig.hashCode()*deca.hashCode())); - world.getLint().elementAlreadyAnnotated.signal( - new String[]{itdfieldsig.toString(),deca.getAnnotationTypeX().toString()}, - rm.getSourceLocation(),new ISourceLocation[]{deca.getSourceLocation()}); - } - } - return true; - } - return false; - } - + if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) { + BcelField theField = (BcelField) fields.get(fieldCounter); + world.getMessageHandler().handleMessage( + WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES, new String[] { + theField.getFieldAsIs().toString() + "' of type '" + clazz.getName(), clazz.getFileName(), + decaF.getAnnotationString(), "field", decaF.getAspect().toString(), + Utility.beautifyLocation(decaF.getSourceLocation()) })); + } + } + + /** + * Check if a resolved member (field/method/ctor) already has an annotation, if it does then put out a warning and return true + */ + private boolean doesAlreadyHaveAnnotation(ResolvedMember rm, DeclareAnnotation deca, List reportedProblems) { + if (rm.hasAnnotation(deca.getAnnotationTypeX())) { + if (world.getLint().elementAlreadyAnnotated.isEnabled()) { + Integer uniqueID = new Integer(rm.hashCode() * deca.hashCode()); + if (!reportedProblems.contains(uniqueID)) { + reportedProblems.add(uniqueID); + world.getLint().elementAlreadyAnnotated.signal(new String[] { rm.toString(), + deca.getAnnotationTypeX().toString() }, rm.getSourceLocation(), new ISourceLocation[] { deca + .getSourceLocation() }); + } + } + return true; + } + return false; + } + + private boolean doesAlreadyHaveAnnotation(LazyMethodGen rm, ResolvedMember itdfieldsig, DeclareAnnotation deca, + List reportedProblems) { + if (rm != null && rm.hasAnnotation(deca.getAnnotationTypeX())) { + if (world.getLint().elementAlreadyAnnotated.isEnabled()) { + Integer uniqueID = new Integer(rm.hashCode() * deca.hashCode()); + if (!reportedProblems.contains(uniqueID)) { + reportedProblems.add(uniqueID); + reportedProblems.add(new Integer(itdfieldsig.hashCode() * deca.hashCode())); + world.getLint().elementAlreadyAnnotated.signal(new String[] { itdfieldsig.toString(), + deca.getAnnotationTypeX().toString() }, rm.getSourceLocation(), new ISourceLocation[] { deca + .getSourceLocation() }); + } + } + return true; + } + return false; + } + private Set findAspectsForMungers(LazyMethodGen mg) { Set aspectsAffectingType = new HashSet(); for (Iterator iter = mg.matchedShadows.iterator(); iter.hasNext();) { - BcelShadow aShadow = (BcelShadow) iter.next(); + BcelShadow aShadow = (BcelShadow) iter.next(); // Mungers in effect on that shadow - for (Iterator iter2 = aShadow.getMungers().iterator();iter2.hasNext();) { + for (Iterator iter2 = aShadow.getMungers().iterator(); iter2.hasNext();) { ShadowMunger aMunger = (ShadowMunger) iter2.next(); if (aMunger instanceof BcelAdvice) { - BcelAdvice bAdvice = (BcelAdvice)aMunger; - if(bAdvice.getConcreteAspect() != null){ + BcelAdvice bAdvice = (BcelAdvice) aMunger; + if (bAdvice.getConcreteAspect() != null) { aspectsAffectingType.add(bAdvice.getConcreteAspect().getName()); } } else { - // It is a 'Checker' - we don't need to remember aspects that only contributed Checkers... - } + // It is a 'Checker' - we don't need to remember aspects that only contributed Checkers... + } } } return aspectsAffectingType; } - private boolean inlineSelfConstructors(List methodGens) { boolean inlinedSomething = false; for (Iterator i = methodGens.iterator(); i.hasNext();) { LazyMethodGen mg = (LazyMethodGen) i.next(); - if (! mg.getName().equals("<init>")) continue; + if (!mg.getName().equals("<init>")) + continue; InstructionHandle ih = findSuperOrThisCall(mg); if (ih != null && isThisCall(ih)) { LazyMethodGen donor = getCalledMethod(ih); @@ -1358,32 +1405,28 @@ class BcelClassWeaver implements IClassWeaver { } private void positionAndImplement(List initializationShadows) { - for (Iterator i = initializationShadows.iterator(); i.hasNext(); ) { + for (Iterator i = initializationShadows.iterator(); i.hasNext();) { BcelShadow s = (BcelShadow) i.next(); positionInitializationShadow(s); - //s.getEnclosingMethod().print(); + // s.getEnclosingMethod().print(); s.implement(); - } - } + } + } private void positionInitializationShadow(BcelShadow s) { LazyMethodGen mg = s.getEnclosingMethod(); InstructionHandle call = findSuperOrThisCall(mg); InstructionList body = mg.getBody(); ShadowRange r = new ShadowRange(body); - r.associateWithShadow( s); + r.associateWithShadow(s); if (s.getKind() == Shadow.PreInitialization) { // XXX assert first instruction is an ALOAD_0. // a pre shadow goes from AFTER the first instruction (which we believe to // be an ALOAD_0) to just before the call to super - r.associateWithTargets( - Range.genStart(body, body.getStart().getNext()), - Range.genEnd(body, call.getPrev())); + r.associateWithTargets(Range.genStart(body, body.getStart().getNext()), Range.genEnd(body, call.getPrev())); } else { // assert s.getKind() == Shadow.Initialization - r.associateWithTargets( - Range.genStart(body, call.getNext()), - Range.genEnd(body)); + r.associateWithTargets(Range.genStart(body, call.getNext()), Range.genEnd(body)); } } @@ -1392,132 +1435,119 @@ class BcelClassWeaver implements IClassWeaver { return inst.getClassName(cpg).equals(clazz.getName()); } - - /** inline a particular call in bytecode. + /** + * inline a particular call in bytecode. * * @param donor the method we want to inline - * @param recipient the method containing the call we want to inline - * @param call the instructionHandle in recipient's body holding the call we want to - * inline. + * @param recipient the method containing the call we want to inline + * @param call the instructionHandle in recipient's body holding the call we want to inline. */ - public static void inlineMethod( - LazyMethodGen donor, - LazyMethodGen recipient, - InstructionHandle call) - { + public static void inlineMethod(LazyMethodGen donor, LazyMethodGen recipient, InstructionHandle call) { // assert recipient.contains(call) - - /* Implementation notes: - * - * We allocate two slots for every tempvar so we don't screw up - * longs and doubles which may share space. This could be conservatively avoided - * (no reference to a long/double instruction, don't do it) or packed later. - * Right now we don't bother to pack. + + /* + * Implementation notes: + * + * We allocate two slots for every tempvar so we don't screw up longs and doubles which may share space. This could be + * conservatively avoided (no reference to a long/double instruction, don't do it) or packed later. Right now we don't + * bother to pack. * - * Allocate a new var for each formal param of the inlined. Fill with stack - * contents. Then copy the inlined instructions in with the appropriate remap - * table. Any framelocs used by locals in inlined are reallocated to top of - * frame, + * Allocate a new var for each formal param of the inlined. Fill with stack contents. Then copy the inlined instructions in + * with the appropriate remap table. Any framelocs used by locals in inlined are reallocated to top of frame, */ final InstructionFactory fact = recipient.getEnclosingClass().getFactory(); IntMap frameEnv = new IntMap(); // this also sets up the initial environment - InstructionList argumentStores = - genArgumentStores(donor, recipient, frameEnv, fact); + InstructionList argumentStores = genArgumentStores(donor, recipient, frameEnv, fact); - InstructionList inlineInstructions = - genInlineInstructions(donor, recipient, frameEnv, fact, false); + InstructionList inlineInstructions = genInlineInstructions(donor, recipient, frameEnv, fact, false); inlineInstructions.insert(argumentStores); - + recipient.getBody().append(call, inlineInstructions); Utility.deleteInstruction(call, recipient); } - -// public BcelVar genTempVar(UnresolvedType typeX) { -// return new BcelVar(typeX.resolve(world), genTempVarIndex(typeX.getSize())); -// } -// -// private int genTempVarIndex(int size) { -// return enclosingMethod.allocateLocal(size); -// } - - - + + // public BcelVar genTempVar(UnresolvedType typeX) { + // return new BcelVar(typeX.resolve(world), genTempVarIndex(typeX.getSize())); + // } + // + // private int genTempVarIndex(int size) { + // return enclosingMethod.allocateLocal(size); + // } + /** - * Input method is a synchronized method, we remove the bit flag for synchronized and - * then insert a try..finally block + * Input method is a synchronized method, we remove the bit flag for synchronized and then insert a try..finally block * - * Some jumping through firey hoops required - depending on the input code level (1.5 or not) - * we may or may not be able to use the LDC instruction that takes a class literal (doesnt on - * <1.5). + * Some jumping through firey hoops required - depending on the input code level (1.5 or not) we may or may not be able to use + * the LDC instruction that takes a class literal (doesnt on <1.5). * - * FIXME asc Before promoting -Xjoinpoints:synchronization to be a standard option, this needs a bunch of - * tidying up - there is some duplication that can be removed. + * FIXME asc Before promoting -Xjoinpoints:synchronization to be a standard option, this needs a bunch of tidying up - there is + * some duplication that can be removed. */ public static void transformSynchronizedMethod(LazyMethodGen synchronizedMethod) { - if (trace.isTraceEnabled()) trace.enter("transformSynchronizedMethod",synchronizedMethod); -// System.err.println("DEBUG: Transforming synchronized method: "+synchronizedMethod.getName()); - final InstructionFactory fact = synchronizedMethod.getEnclosingClass().getFactory(); - InstructionList body = synchronizedMethod.getBody(); + if (trace.isTraceEnabled()) + trace.enter("transformSynchronizedMethod", synchronizedMethod); + // System.err.println("DEBUG: Transforming synchronized method: "+synchronizedMethod.getName()); + final InstructionFactory fact = synchronizedMethod.getEnclosingClass().getFactory(); + InstructionList body = synchronizedMethod.getBody(); InstructionList prepend = new InstructionList(); Type enclosingClassType = BcelWorld.makeBcelType(synchronizedMethod.getEnclosingClass().getType()); - - + // STATIC METHOD TRANSFORMATION if (synchronizedMethod.isStatic()) { - + // What to do here depends on the level of the class file! // LDC can handle class literals in Java5 and above *sigh* if (synchronizedMethod.getEnclosingClass().isAtLeastJava5()) { // MONITORENTER logic: - // 0: ldc #2; //class C - // 2: dup - // 3: astore_0 - // 4: monitorenter + // 0: ldc #2; //class C + // 2: dup + // 3: astore_0 + // 4: monitorenter int slotForLockObject = synchronizedMethod.allocateLocal(enclosingClassType); prepend.append(fact.createConstant(enclosingClassType)); prepend.append(InstructionFactory.createDup(1)); prepend.append(InstructionFactory.createStore(enclosingClassType, slotForLockObject)); prepend.append(InstructionFactory.MONITORENTER); - + // MONITOREXIT logic: - + // We basically need to wrap the code from the method in a finally block that - // will ensure monitorexit is called. Content on the finally block seems to + // will ensure monitorexit is called. Content on the finally block seems to // be always: // // E1: ALOAD_1 - // MONITOREXIT - // ATHROW + // MONITOREXIT + // ATHROW // // so lets build that: InstructionList finallyBlock = new InstructionList(); - finallyBlock.append(InstructionFactory.createLoad(Type.getType(java.lang.Class.class),slotForLockObject)); + finallyBlock.append(InstructionFactory.createLoad(Type.getType(java.lang.Class.class), slotForLockObject)); finallyBlock.append(InstructionConstants.MONITOREXIT); finallyBlock.append(InstructionConstants.ATHROW); - -// finally -> E1 -// | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 21) -// | LDC "hello" -// | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V -// | ALOAD_1 (line 20) -// | MONITOREXIT -// finally -> E1 -// GOTO L0 -// finally -> E1 -// | E1: ALOAD_1 -// | MONITOREXIT -// finally -> E1 -// ATHROW -// L0: RETURN (line 23) - + + // finally -> E1 + // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 21) + // | LDC "hello" + // | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V + // | ALOAD_1 (line 20) + // | MONITOREXIT + // finally -> E1 + // GOTO L0 + // finally -> E1 + // | E1: ALOAD_1 + // | MONITOREXIT + // finally -> E1 + // ATHROW + // L0: RETURN (line 23) + // search for 'returns' and make them jump to the aload_<n>,monitorexit InstructionHandle walker = body.getStart(); List rets = new ArrayList(); - while (walker!=null) { + while (walker != null) { if (walker.getInstruction().isReturnInstruction()) { rets.add(walker); } @@ -1526,285 +1556,293 @@ class BcelClassWeaver implements IClassWeaver { if (!rets.isEmpty()) { // need to ensure targeters for 'return' now instead target the load instruction // (so we never jump over the monitorexit logic) - + for (Iterator iter = rets.iterator(); iter.hasNext();) { InstructionHandle element = (InstructionHandle) iter.next(); InstructionList monitorExitBlock = new InstructionList(); - monitorExitBlock.append(InstructionFactory.createLoad(enclosingClassType,slotForLockObject)); + monitorExitBlock.append(InstructionFactory.createLoad(enclosingClassType, slotForLockObject)); monitorExitBlock.append(InstructionConstants.MONITOREXIT); - //monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); - //element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); - InstructionHandle monitorExitBlockStart = body.insert(element,monitorExitBlock); - + // monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); + // element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); + InstructionHandle monitorExitBlockStart = body.insert(element, monitorExitBlock); + // now move the targeters from the RET to the start of the monitorexit block InstructionTargeter[] targeters = element.getTargetersArray(); - if (targeters!=null) { + if (targeters != null) { for (int i = 0; i < targeters.length; i++) { - + InstructionTargeter targeter = targeters[i]; // what kinds are there? if (targeter instanceof LocalVariableTag) { // ignore } else if (targeter instanceof LineNumberTag) { // ignore -// } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) { -// // move it... -// targeter.updateTarget(element, monitorExitBlockStart); + // } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) { + // // move it... + // targeter.updateTarget(element, monitorExitBlockStart); } else if (targeter instanceof InstructionBranch) { // move it targeter.updateTarget(element, monitorExitBlockStart); } else { - throw new BCException("Unexpected targeter encountered during transform: "+targeter); + throw new BCException("Unexpected targeter encountered during transform: " + targeter); } - } + } } } } - + // now the magic, putting the finally block around the code - InstructionHandle finallyStart = finallyBlock.getStart(); + InstructionHandle finallyStart = finallyBlock.getStart(); - InstructionHandle tryPosition = body.getStart(); + InstructionHandle tryPosition = body.getStart(); InstructionHandle catchPosition = body.getEnd(); - body.insert(body.getStart(),prepend); // now we can put the monitorenter stuff on - synchronizedMethod.getBody().append(finallyBlock); - synchronizedMethod.addExceptionHandler(tryPosition, catchPosition,finallyStart,null/*==finally*/,false); - synchronizedMethod.addExceptionHandler(finallyStart,finallyStart.getNext(),finallyStart,null,false); + body.insert(body.getStart(), prepend); // now we can put the monitorenter stuff on + synchronizedMethod.getBody().append(finallyBlock); + synchronizedMethod.addExceptionHandler(tryPosition, catchPosition, finallyStart, null/* ==finally */, false); + synchronizedMethod.addExceptionHandler(finallyStart, finallyStart.getNext(), finallyStart, null, false); } else { // TRANSFORMING STATIC METHOD ON PRE JAVA5 - + // Hideous nightmare, class literal references prior to Java5 - - // YIKES! this is just the code for MONITORENTER ! -// 0: getstatic #59; //Field class$1:Ljava/lang/Class; -// 3: dup -// 4: ifnonnull 32 -// 7: pop -// try -// 8: ldc #61; //String java.lang.String -// 10: invokestatic #44; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; -// 13: dup -// catch -// 14: putstatic #59; //Field class$1:Ljava/lang/Class; -// 17: goto 32 -// 20: new #46; //class java/lang/NoClassDefFoundError -// 23: dup_x1 -// 24: swap -// 25: invokevirtual #52; //Method java/lang/Throwable.getMessage:()Ljava/lang/String; -// 28: invokespecial #54; //Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V -// 31: athrow -// 32: dup <-- partTwo (branch target) -// 33: astore_0 -// 34: monitorenter -// -// plus exceptiontable entry! -// 8 13 20 Class java/lang/ClassNotFoundException - Type classType = BcelWorld.makeBcelType(synchronizedMethod.getEnclosingClass().getType()); - Type clazzType = Type.getType(Class.class); - - InstructionList parttwo = new InstructionList(); - parttwo.append(InstructionFactory.createDup(1)); - int slotForThis = synchronizedMethod.allocateLocal(classType); - parttwo.append(InstructionFactory.createStore(clazzType, slotForThis)); // ? should be the real type ? String or something? - parttwo.append(InstructionFactory.MONITORENTER); - - String fieldname = synchronizedMethod.getEnclosingClass().allocateField("class$"); - FieldGen f = new FieldGen(Modifier.STATIC | Modifier.PRIVATE, - Type.getType(Class.class),fieldname,synchronizedMethod.getEnclosingClass().getConstantPool()); - synchronizedMethod.getEnclosingClass().addField(f, null); - -// 10: invokestatic #44; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; -// 13: dup -// 14: putstatic #59; //Field class$1:Ljava/lang/Class; -// 17: goto 32 -// 20: new #46; //class java/lang/NoClassDefFoundError -// 23: dup_x1 -// 24: swap -// 25: invokevirtual #52; //Method java/lang/Throwable.getMessage:()Ljava/lang/String; -// 28: invokespecial #54; //Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V -// 31: athrow - String name = synchronizedMethod.getEnclosingClass().getName(); - - prepend.append(fact.createGetStatic(name, fieldname, Type.getType(Class.class))); - prepend.append(InstructionFactory.createDup(1)); - prepend.append(InstructionFactory.createBranchInstruction(Constants.IFNONNULL, parttwo.getStart())); - prepend.append(InstructionFactory.POP); - - prepend.append(fact.createConstant(name)); - InstructionHandle tryInstruction = prepend.getEnd(); - prepend.append(fact.createInvoke("java.lang.Class", "forName", clazzType,new Type[]{ Type.getType(String.class)}, Constants.INVOKESTATIC)); - InstructionHandle catchInstruction = prepend.getEnd(); - prepend.append(InstructionFactory.createDup(1)); - - prepend.append(fact.createPutStatic(synchronizedMethod.getEnclosingClass().getType().getName(), fieldname, Type.getType(Class.class))); - prepend.append(InstructionFactory.createBranchInstruction(Constants.GOTO, parttwo.getStart())); - - // start of catch block - InstructionList catchBlockForLiteralLoadingFail = new InstructionList(); - catchBlockForLiteralLoadingFail.append(fact.createNew((ObjectType)Type.getType(NoClassDefFoundError.class))); - catchBlockForLiteralLoadingFail.append(InstructionFactory.createDup_1(1)); - catchBlockForLiteralLoadingFail.append(InstructionFactory.SWAP); - catchBlockForLiteralLoadingFail.append(fact.createInvoke("java.lang.Throwable", "getMessage", Type.getType(String.class),new Type[]{}, Constants.INVOKEVIRTUAL)); - catchBlockForLiteralLoadingFail.append(fact.createInvoke("java.lang.NoClassDefFoundError", "<init>", Type.VOID,new Type[]{ Type.getType(String.class)}, Constants.INVOKESPECIAL)); - catchBlockForLiteralLoadingFail.append(InstructionFactory.ATHROW); - InstructionHandle catchBlockStart = catchBlockForLiteralLoadingFail.getStart(); - prepend.append(catchBlockForLiteralLoadingFail); - prepend.append(parttwo); -// MONITORENTER - // pseudocode: load up 'this' (var0), dup it, store it in a new local var (for use with monitorexit) and call monitorenter: - // ALOAD_0, DUP, ASTORE_<n>, MONITORENTER -// prepend.append(InstructionFactory.createLoad(classType,0)); -// prepend.append(InstructionFactory.createDup(1)); -// int slotForThis = synchronizedMethod.allocateLocal(classType); -// prepend.append(InstructionFactory.createStore(classType, slotForThis)); -// prepend.append(InstructionFactory.MONITORENTER); - - // MONITOREXIT - // here be dragons - - // We basically need to wrap the code from the method in a finally block that - // will ensure monitorexit is called. Content on the finally block seems to - // be always: - // - // E1: ALOAD_1 - // MONITOREXIT - // ATHROW - // - // so lets build that: - InstructionList finallyBlock = new InstructionList(); - finallyBlock.append(InstructionFactory.createLoad(Type.getType(java.lang.Class.class),slotForThis)); - finallyBlock.append(InstructionConstants.MONITOREXIT); - finallyBlock.append(InstructionConstants.ATHROW); - -// finally -> E1 -// | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 21) -// | LDC "hello" -// | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V -// | ALOAD_1 (line 20) -// | MONITOREXIT -// finally -> E1 -// GOTO L0 -// finally -> E1 -// | E1: ALOAD_1 -// | MONITOREXIT -// finally -> E1 -// ATHROW -// L0: RETURN (line 23) - //frameEnv.put(donorFramePos, thisSlot); - - // search for 'returns' and make them to the aload_<n>,monitorexit - InstructionHandle walker = body.getStart(); - List rets = new ArrayList(); - while (walker!=null) { //!walker.equals(body.getEnd())) { - if (walker.getInstruction().isReturnInstruction()) { - rets.add(walker); + + // YIKES! this is just the code for MONITORENTER ! + // 0: getstatic #59; //Field class$1:Ljava/lang/Class; + // 3: dup + // 4: ifnonnull 32 + // 7: pop + // try + // 8: ldc #61; //String java.lang.String + // 10: invokestatic #44; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; + // 13: dup + // catch + // 14: putstatic #59; //Field class$1:Ljava/lang/Class; + // 17: goto 32 + // 20: new #46; //class java/lang/NoClassDefFoundError + // 23: dup_x1 + // 24: swap + // 25: invokevirtual #52; //Method java/lang/Throwable.getMessage:()Ljava/lang/String; + // 28: invokespecial #54; //Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V + // 31: athrow + // 32: dup <-- partTwo (branch target) + // 33: astore_0 + // 34: monitorenter + // + // plus exceptiontable entry! + // 8 13 20 Class java/lang/ClassNotFoundException + Type classType = BcelWorld.makeBcelType(synchronizedMethod.getEnclosingClass().getType()); + Type clazzType = Type.getType(Class.class); + + InstructionList parttwo = new InstructionList(); + parttwo.append(InstructionFactory.createDup(1)); + int slotForThis = synchronizedMethod.allocateLocal(classType); + parttwo.append(InstructionFactory.createStore(clazzType, slotForThis)); // ? should be the real type ? String or + // something? + parttwo.append(InstructionFactory.MONITORENTER); + + String fieldname = synchronizedMethod.getEnclosingClass().allocateField("class$"); + FieldGen f = new FieldGen(Modifier.STATIC | Modifier.PRIVATE, Type.getType(Class.class), fieldname, + synchronizedMethod.getEnclosingClass().getConstantPool()); + synchronizedMethod.getEnclosingClass().addField(f, null); + + // 10: invokestatic #44; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; + // 13: dup + // 14: putstatic #59; //Field class$1:Ljava/lang/Class; + // 17: goto 32 + // 20: new #46; //class java/lang/NoClassDefFoundError + // 23: dup_x1 + // 24: swap + // 25: invokevirtual #52; //Method java/lang/Throwable.getMessage:()Ljava/lang/String; + // 28: invokespecial #54; //Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V + // 31: athrow + String name = synchronizedMethod.getEnclosingClass().getName(); + + prepend.append(fact.createGetStatic(name, fieldname, Type.getType(Class.class))); + prepend.append(InstructionFactory.createDup(1)); + prepend.append(InstructionFactory.createBranchInstruction(Constants.IFNONNULL, parttwo.getStart())); + prepend.append(InstructionFactory.POP); + + prepend.append(fact.createConstant(name)); + InstructionHandle tryInstruction = prepend.getEnd(); + prepend.append(fact.createInvoke("java.lang.Class", "forName", clazzType, + new Type[] { Type.getType(String.class) }, Constants.INVOKESTATIC)); + InstructionHandle catchInstruction = prepend.getEnd(); + prepend.append(InstructionFactory.createDup(1)); + + prepend.append(fact.createPutStatic(synchronizedMethod.getEnclosingClass().getType().getName(), fieldname, Type + .getType(Class.class))); + prepend.append(InstructionFactory.createBranchInstruction(Constants.GOTO, parttwo.getStart())); + + // start of catch block + InstructionList catchBlockForLiteralLoadingFail = new InstructionList(); + catchBlockForLiteralLoadingFail.append(fact.createNew((ObjectType) Type.getType(NoClassDefFoundError.class))); + catchBlockForLiteralLoadingFail.append(InstructionFactory.createDup_1(1)); + catchBlockForLiteralLoadingFail.append(InstructionFactory.SWAP); + catchBlockForLiteralLoadingFail.append(fact.createInvoke("java.lang.Throwable", "getMessage", Type + .getType(String.class), new Type[] {}, Constants.INVOKEVIRTUAL)); + catchBlockForLiteralLoadingFail.append(fact.createInvoke("java.lang.NoClassDefFoundError", "<init>", Type.VOID, + new Type[] { Type.getType(String.class) }, Constants.INVOKESPECIAL)); + catchBlockForLiteralLoadingFail.append(InstructionFactory.ATHROW); + InstructionHandle catchBlockStart = catchBlockForLiteralLoadingFail.getStart(); + prepend.append(catchBlockForLiteralLoadingFail); + prepend.append(parttwo); + // MONITORENTER + // pseudocode: load up 'this' (var0), dup it, store it in a new local var (for use with monitorexit) and call + // monitorenter: + // ALOAD_0, DUP, ASTORE_<n>, MONITORENTER + // prepend.append(InstructionFactory.createLoad(classType,0)); + // prepend.append(InstructionFactory.createDup(1)); + // int slotForThis = synchronizedMethod.allocateLocal(classType); + // prepend.append(InstructionFactory.createStore(classType, slotForThis)); + // prepend.append(InstructionFactory.MONITORENTER); + + // MONITOREXIT + // here be dragons + + // We basically need to wrap the code from the method in a finally block that + // will ensure monitorexit is called. Content on the finally block seems to + // be always: + // + // E1: ALOAD_1 + // MONITOREXIT + // ATHROW + // + // so lets build that: + InstructionList finallyBlock = new InstructionList(); + finallyBlock.append(InstructionFactory.createLoad(Type.getType(java.lang.Class.class), slotForThis)); + finallyBlock.append(InstructionConstants.MONITOREXIT); + finallyBlock.append(InstructionConstants.ATHROW); + + // finally -> E1 + // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 21) + // | LDC "hello" + // | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V + // | ALOAD_1 (line 20) + // | MONITOREXIT + // finally -> E1 + // GOTO L0 + // finally -> E1 + // | E1: ALOAD_1 + // | MONITOREXIT + // finally -> E1 + // ATHROW + // L0: RETURN (line 23) + // frameEnv.put(donorFramePos, thisSlot); + + // search for 'returns' and make them to the aload_<n>,monitorexit + InstructionHandle walker = body.getStart(); + List rets = new ArrayList(); + while (walker != null) { // !walker.equals(body.getEnd())) { + if (walker.getInstruction().isReturnInstruction()) { + rets.add(walker); + } + walker = walker.getNext(); } - walker = walker.getNext(); - } - if (rets.size()>0) { - // need to ensure targeters for 'return' now instead target the load instruction - // (so we never jump over the monitorexit logic) - - for (Iterator iter = rets.iterator(); iter.hasNext();) { - InstructionHandle element = (InstructionHandle) iter.next(); -// System.err.println("Adding monitor exit block at "+element); - InstructionList monitorExitBlock = new InstructionList(); - monitorExitBlock.append(InstructionFactory.createLoad(classType,slotForThis)); - monitorExitBlock.append(InstructionConstants.MONITOREXIT); - //monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); - //element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); - InstructionHandle monitorExitBlockStart = body.insert(element,monitorExitBlock); - - // now move the targeters from the RET to the start of the monitorexit block - InstructionTargeter[] targeters = element.getTargetersArray(); - if (targeters!=null) { - for (int i = 0; i < targeters.length; i++) { - - InstructionTargeter targeter = targeters[i]; - // what kinds are there? - if (targeter instanceof LocalVariableTag) { - // ignore - } else if (targeter instanceof LineNumberTag) { - // ignore -// } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { -// // move it... -// targeter.updateTarget(element, monitorExitBlockStart); - } else if (targeter instanceof InstructionBranch) { - // move it - targeter.updateTarget(element, monitorExitBlockStart); - } else { - throw new BCException("Unexpected targeter encountered during transform: "+targeter); + if (rets.size() > 0) { + // need to ensure targeters for 'return' now instead target the load instruction + // (so we never jump over the monitorexit logic) + + for (Iterator iter = rets.iterator(); iter.hasNext();) { + InstructionHandle element = (InstructionHandle) iter.next(); + // System.err.println("Adding monitor exit block at "+element); + InstructionList monitorExitBlock = new InstructionList(); + monitorExitBlock.append(InstructionFactory.createLoad(classType, slotForThis)); + monitorExitBlock.append(InstructionConstants.MONITOREXIT); + // monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); + // element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); + InstructionHandle monitorExitBlockStart = body.insert(element, monitorExitBlock); + + // now move the targeters from the RET to the start of the monitorexit block + InstructionTargeter[] targeters = element.getTargetersArray(); + if (targeters != null) { + for (int i = 0; i < targeters.length; i++) { + + InstructionTargeter targeter = targeters[i]; + // what kinds are there? + if (targeter instanceof LocalVariableTag) { + // ignore + } else if (targeter instanceof LineNumberTag) { + // ignore + // } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { + // // move it... + // targeter.updateTarget(element, monitorExitBlockStart); + } else if (targeter instanceof InstructionBranch) { + // move it + targeter.updateTarget(element, monitorExitBlockStart); + } else { + throw new BCException("Unexpected targeter encountered during transform: " + targeter); + } } - } + } } } - } -// body = rewriteWithMonitorExitCalls(body,fact,true,slotForThis,classType); -// synchronizedMethod.setBody(body); - - // now the magic, putting the finally block around the code - InstructionHandle finallyStart = finallyBlock.getStart(); + // body = rewriteWithMonitorExitCalls(body,fact,true,slotForThis,classType); + // synchronizedMethod.setBody(body); - InstructionHandle tryPosition = body.getStart(); - InstructionHandle catchPosition = body.getEnd(); - body.insert(body.getStart(),prepend); // now we can put the monitorenter stuff on + // now the magic, putting the finally block around the code + InstructionHandle finallyStart = finallyBlock.getStart(); + + InstructionHandle tryPosition = body.getStart(); + InstructionHandle catchPosition = body.getEnd(); + body.insert(body.getStart(), prepend); // now we can put the monitorenter stuff on - synchronizedMethod.getBody().append(finallyBlock); - synchronizedMethod.addExceptionHandler(tryPosition, catchPosition,finallyStart,null/*==finally*/,false); - synchronizedMethod.addExceptionHandler(tryInstruction, catchInstruction,catchBlockStart,(ObjectType)Type.getType(ClassNotFoundException.class),true); - synchronizedMethod.addExceptionHandler(finallyStart,finallyStart.getNext(),finallyStart,null,false); + synchronizedMethod.getBody().append(finallyBlock); + synchronizedMethod.addExceptionHandler(tryPosition, catchPosition, finallyStart, null/* ==finally */, false); + synchronizedMethod.addExceptionHandler(tryInstruction, catchInstruction, catchBlockStart, (ObjectType) Type + .getType(ClassNotFoundException.class), true); + synchronizedMethod.addExceptionHandler(finallyStart, finallyStart.getNext(), finallyStart, null, false); } } else { - - // TRANSFORMING NON STATIC METHOD + + // TRANSFORMING NON STATIC METHOD Type classType = BcelWorld.makeBcelType(synchronizedMethod.getEnclosingClass().getType()); // MONITORENTER - // pseudocode: load up 'this' (var0), dup it, store it in a new local var (for use with monitorexit) and call monitorenter: + // pseudocode: load up 'this' (var0), dup it, store it in a new local var (for use with monitorexit) and call + // monitorenter: // ALOAD_0, DUP, ASTORE_<n>, MONITORENTER - prepend.append(InstructionFactory.createLoad(classType,0)); + prepend.append(InstructionFactory.createLoad(classType, 0)); prepend.append(InstructionFactory.createDup(1)); int slotForThis = synchronizedMethod.allocateLocal(classType); prepend.append(InstructionFactory.createStore(classType, slotForThis)); prepend.append(InstructionFactory.MONITORENTER); -// body.insert(body.getStart(),prepend); - + // body.insert(body.getStart(),prepend); + // MONITOREXIT - + // We basically need to wrap the code from the method in a finally block that - // will ensure monitorexit is called. Content on the finally block seems to + // will ensure monitorexit is called. Content on the finally block seems to // be always: // // E1: ALOAD_1 - // MONITOREXIT - // ATHROW + // MONITOREXIT + // ATHROW // // so lets build that: InstructionList finallyBlock = new InstructionList(); - finallyBlock.append(InstructionFactory.createLoad(classType,slotForThis)); + finallyBlock.append(InstructionFactory.createLoad(classType, slotForThis)); finallyBlock.append(InstructionConstants.MONITOREXIT); finallyBlock.append(InstructionConstants.ATHROW); - -// finally -> E1 -// | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 21) -// | LDC "hello" -// | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V -// | ALOAD_1 (line 20) -// | MONITOREXIT -// finally -> E1 -// GOTO L0 -// finally -> E1 -// | E1: ALOAD_1 -// | MONITOREXIT -// finally -> E1 -// ATHROW -// L0: RETURN (line 23) - //frameEnv.put(donorFramePos, thisSlot); - + + // finally -> E1 + // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 21) + // | LDC "hello" + // | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V + // | ALOAD_1 (line 20) + // | MONITOREXIT + // finally -> E1 + // GOTO L0 + // finally -> E1 + // | E1: ALOAD_1 + // | MONITOREXIT + // finally -> E1 + // ATHROW + // L0: RETURN (line 23) + // frameEnv.put(donorFramePos, thisSlot); + // search for 'returns' and make them to the aload_<n>,monitorexit InstructionHandle walker = body.getStart(); List rets = new ArrayList(); - while (walker!=null) { //!walker.equals(body.getEnd())) { + while (walker != null) { // !walker.equals(body.getEnd())) { if (walker.getInstruction().isReturnInstruction()) { rets.add(walker); } @@ -1813,114 +1851,101 @@ class BcelClassWeaver implements IClassWeaver { if (!rets.isEmpty()) { // need to ensure targeters for 'return' now instead target the load instruction // (so we never jump over the monitorexit logic) - + for (Iterator iter = rets.iterator(); iter.hasNext();) { InstructionHandle element = (InstructionHandle) iter.next(); -// System.err.println("Adding monitor exit block at "+element); + // System.err.println("Adding monitor exit block at "+element); InstructionList monitorExitBlock = new InstructionList(); - monitorExitBlock.append(InstructionFactory.createLoad(classType,slotForThis)); + monitorExitBlock.append(InstructionFactory.createLoad(classType, slotForThis)); monitorExitBlock.append(InstructionConstants.MONITOREXIT); - //monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); - //element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); - InstructionHandle monitorExitBlockStart = body.insert(element,monitorExitBlock); - + // monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); + // element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); + InstructionHandle monitorExitBlockStart = body.insert(element, monitorExitBlock); + // now move the targeters from the RET to the start of the monitorexit block InstructionTargeter[] targeters = element.getTargetersArray(); - if (targeters!=null) { + if (targeters != null) { for (int i = 0; i < targeters.length; i++) { - + InstructionTargeter targeter = targeters[i]; // what kinds are there? if (targeter instanceof LocalVariableTag) { // ignore } else if (targeter instanceof LineNumberTag) { // ignore -// } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { -// // move it... -// targeter.updateTarget(element, monitorExitBlockStart); + // } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { + // // move it... + // targeter.updateTarget(element, monitorExitBlockStart); } else if (targeter instanceof InstructionBranch) { // move it targeter.updateTarget(element, monitorExitBlockStart); } else { - throw new BCException("Unexpected targeter encountered during transform: "+targeter); + throw new BCException("Unexpected targeter encountered during transform: " + targeter); } - } + } } } } - + // now the magic, putting the finally block around the code - InstructionHandle finallyStart = finallyBlock.getStart(); + InstructionHandle finallyStart = finallyBlock.getStart(); - InstructionHandle tryPosition = body.getStart(); + InstructionHandle tryPosition = body.getStart(); InstructionHandle catchPosition = body.getEnd(); - body.insert(body.getStart(),prepend); // now we can put the monitorenter stuff on - synchronizedMethod.getBody().append(finallyBlock); - synchronizedMethod.addExceptionHandler(tryPosition, catchPosition,finallyStart,null/*==finally*/,false); - synchronizedMethod.addExceptionHandler(finallyStart,finallyStart.getNext(),finallyStart,null,false); + body.insert(body.getStart(), prepend); // now we can put the monitorenter stuff on + synchronizedMethod.getBody().append(finallyBlock); + synchronizedMethod.addExceptionHandler(tryPosition, catchPosition, finallyStart, null/* ==finally */, false); + synchronizedMethod.addExceptionHandler(finallyStart, finallyStart.getNext(), finallyStart, null, false); // also the exception handling for the finally block jumps to itself - + // max locals will already have been modified in the allocateLocal() call - -// synchronized bit is removed on LazyMethodGen.pack() + + // synchronized bit is removed on LazyMethodGen.pack() } - + // gonna have to go through and change all aload_0s to load the var from a variable, // going to add a new variable for the this var - if (trace.isTraceEnabled()) trace.exit("transformSynchronizedMethod"); + if (trace.isTraceEnabled()) + trace.exit("transformSynchronizedMethod"); } - - - /** generate the instructions to be inlined. + /** + * generate the instructions to be inlined. * - * @param donor the method from which we will copy (and adjust frame and jumps) - * instructions. - * @param recipient the method the instructions will go into. Used to get the frame - * size so we can allocate new frame locations for locals in donor. - * @param frameEnv an environment to map from donor frame to recipient frame, - * initially populated with argument locations. + * @param donor the method from which we will copy (and adjust frame and jumps) instructions. + * @param recipient the method the instructions will go into. Used to get the frame size so we can allocate new frame locations + * for locals in donor. + * @param frameEnv an environment to map from donor frame to recipient frame, initially populated with argument locations. * @param fact an instruction factory for recipient */ - static InstructionList genInlineInstructions( - LazyMethodGen donor, - LazyMethodGen recipient, - IntMap frameEnv, - InstructionFactory fact, - boolean keepReturns) - { + static InstructionList genInlineInstructions(LazyMethodGen donor, LazyMethodGen recipient, IntMap frameEnv, + InstructionFactory fact, boolean keepReturns) { InstructionList footer = new InstructionList(); InstructionHandle end = footer.append(InstructionConstants.NOP); InstructionList ret = new InstructionList(); InstructionList sourceList = donor.getBody(); - Map srcToDest = new HashMap(); + Map srcToDest = new HashMap(); ConstantPool donorCpg = donor.getEnclosingClass().getConstantPool(); ConstantPool recipientCpg = recipient.getEnclosingClass().getConstantPool(); - + boolean isAcrossClass = donorCpg != recipientCpg; - + // first pass: copy the instructions directly, populate the srcToDest map, // fix frame instructions - for (InstructionHandle src = sourceList.getStart(); - src != null; - src = src.getNext()) - { + for (InstructionHandle src = sourceList.getStart(); src != null; src = src.getNext()) { Instruction fresh = Utility.copyInstruction(src.getInstruction()); InstructionHandle dest; - + // OPTIMIZE optimize this stuff? if (fresh.isConstantPoolInstruction()) { - // need to reset index to go to new constant pool. This is totally - // a computation leak... we're testing this LOTS of times. Sigh. + // need to reset index to go to new constant pool. This is totally + // a computation leak... we're testing this LOTS of times. Sigh. if (isAcrossClass) { InstructionCP cpi = (InstructionCP) fresh; - cpi.setIndex( - recipientCpg.addConstant( - donorCpg.getConstant(cpi.getIndex()), - donorCpg)); + cpi.setIndex(recipientCpg.addConstant(donorCpg.getConstant(cpi.getIndex()), donorCpg)); } } if (src.getInstruction() == Range.RANGEINSTRUCTION) { @@ -1929,15 +1954,13 @@ class BcelClassWeaver implements IClassWeaver { if (keepReturns) { dest = ret.append(fresh); } else { - dest = - ret.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end)); + dest = ret.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end)); } } else if (fresh instanceof InstructionBranch) { dest = ret.append((InstructionBranch) fresh); - } else if ( - fresh.isLocalVariableInstruction() || fresh instanceof RET) { - -// IndexedInstruction indexed = (IndexedInstruction) fresh; + } else if (fresh.isLocalVariableInstruction() || fresh instanceof RET) { + + // IndexedInstruction indexed = (IndexedInstruction) fresh; int oldIndex = fresh.getIndex(); int freshIndex; if (!frameEnv.hasKey(oldIndex)) { @@ -1949,7 +1972,7 @@ class BcelClassWeaver implements IClassWeaver { if (fresh instanceof RET) { fresh.setIndex(freshIndex); } else { - fresh = ((InstructionLV)fresh).setIndexAndCopyIfNecessary(freshIndex); + fresh = ((InstructionLV) fresh).setIndexAndCopyIfNecessary(freshIndex); } dest = ret.append(fresh); } else { @@ -1957,21 +1980,19 @@ class BcelClassWeaver implements IClassWeaver { } srcToDest.put(src, dest); } - + // second pass: retarget branch instructions, copy ranges and tags Map tagMap = new HashMap(); - Map shadowMap = new HashMap(); - for (InstructionHandle dest = ret.getStart(), src = sourceList.getStart(); - dest != null; - dest = dest.getNext(), src = src.getNext()) { + Map shadowMap = new HashMap(); + for (InstructionHandle dest = ret.getStart(), src = sourceList.getStart(); dest != null; dest = dest.getNext(), src = src + .getNext()) { Instruction inst = dest.getInstruction(); - + // retarget branches if (inst instanceof InstructionBranch) { InstructionBranch branch = (InstructionBranch) inst; InstructionHandle oldTarget = branch.getTarget(); - InstructionHandle newTarget = - (InstructionHandle) srcToDest.get(oldTarget); + InstructionHandle newTarget = (InstructionHandle) srcToDest.get(oldTarget); if (newTarget == null) { // assert this is a GOTO // this was a return instruction we previously replaced @@ -1981,223 +2002,207 @@ class BcelClassWeaver implements IClassWeaver { InstructionSelect select = (InstructionSelect) branch; InstructionHandle[] oldTargets = select.getTargets(); for (int k = oldTargets.length - 1; k >= 0; k--) { - select.setTarget( - k, - (InstructionHandle) srcToDest.get(oldTargets[k])); + select.setTarget(k, (InstructionHandle) srcToDest.get(oldTargets[k])); } } } - } - - //copy over tags and range attributes - + } + + // copy over tags and range attributes + Iterator tIter = src.getTargeters().iterator(); while (tIter.hasNext()) { - InstructionTargeter old = (InstructionTargeter)tIter.next(); - if (old instanceof Tag) { - Tag oldTag = (Tag) old; - Tag fresh = (Tag) tagMap.get(oldTag); - if (fresh == null) { - fresh = oldTag.copy(); - tagMap.put(oldTag, fresh); - } - dest.addTargeter(fresh); - } else if (old instanceof ExceptionRange) { - ExceptionRange er = (ExceptionRange) old; - if (er.getStart() == src) { - ExceptionRange freshEr = - new ExceptionRange( - recipient.getBody(), - er.getCatchType(), - er.getPriority()); - freshEr.associateWithTargets( - dest, - (InstructionHandle)srcToDest.get(er.getEnd()), - (InstructionHandle)srcToDest.get(er.getHandler())); - } + InstructionTargeter old = (InstructionTargeter) tIter.next(); + if (old instanceof Tag) { + Tag oldTag = (Tag) old; + Tag fresh = (Tag) tagMap.get(oldTag); + if (fresh == null) { + fresh = oldTag.copy(); + tagMap.put(oldTag, fresh); + } + dest.addTargeter(fresh); + } else if (old instanceof ExceptionRange) { + ExceptionRange er = (ExceptionRange) old; + if (er.getStart() == src) { + ExceptionRange freshEr = new ExceptionRange(recipient.getBody(), er.getCatchType(), er.getPriority()); + freshEr.associateWithTargets(dest, (InstructionHandle) srcToDest.get(er.getEnd()), + (InstructionHandle) srcToDest.get(er.getHandler())); + } } else if (old instanceof ShadowRange) { ShadowRange oldRange = (ShadowRange) old; if (oldRange.getStart() == src) { BcelShadow oldShadow = oldRange.getShadow(); - BcelShadow freshEnclosing = - oldShadow.getEnclosingShadow() == null - ? null - : (BcelShadow) shadowMap.get(oldShadow.getEnclosingShadow()); - BcelShadow freshShadow = - oldShadow.copyInto(recipient, freshEnclosing); + BcelShadow freshEnclosing = oldShadow.getEnclosingShadow() == null ? null : (BcelShadow) shadowMap + .get(oldShadow.getEnclosingShadow()); + BcelShadow freshShadow = oldShadow.copyInto(recipient, freshEnclosing); ShadowRange freshRange = new ShadowRange(recipient.getBody()); freshRange.associateWithShadow(freshShadow); - freshRange.associateWithTargets( - dest, - (InstructionHandle) srcToDest.get(oldRange.getEnd())); + freshRange.associateWithTargets(dest, (InstructionHandle) srcToDest.get(oldRange.getEnd())); shadowMap.put(oldRange, freshRange); - //recipient.matchedShadows.add(freshShadow); + // recipient.matchedShadows.add(freshShadow); // XXX should go through the NEW copied shadow and update // the thisVar, targetVar, and argsVar // ??? Might want to also go through at this time and add - // "extra" vars to the shadow. + // "extra" vars to the shadow. } - } - } + } + } } - if (!keepReturns) ret.append(footer); + if (!keepReturns) + ret.append(footer); return ret; } - static InstructionList rewriteWithMonitorExitCalls(InstructionList sourceList,InstructionFactory fact,boolean keepReturns,int monitorVarSlot,Type monitorVarType) - { - InstructionList footer = new InstructionList(); - InstructionHandle end = footer.append(InstructionConstants.NOP); - - InstructionList newList = new InstructionList(); - - Map srcToDest = new HashMap(); - - // first pass: copy the instructions directly, populate the srcToDest map, - // fix frame instructions - for (InstructionHandle src = sourceList.getStart(); src != null; src = src.getNext()) { - Instruction fresh = Utility.copyInstruction(src.getInstruction()); - InstructionHandle dest; - if (src.getInstruction() == Range.RANGEINSTRUCTION) { - dest = newList.append(Range.RANGEINSTRUCTION); - } else if (fresh.isReturnInstruction()) { - if (keepReturns) { - newList.append(InstructionFactory.createLoad(monitorVarType,monitorVarSlot)); - newList.append(InstructionConstants.MONITOREXIT); - dest = newList.append(fresh); - } else { - dest = - newList.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end)); - } - } else if (fresh instanceof InstructionBranch) { - dest = newList.append((InstructionBranch) fresh); - } else if ( - fresh.isLocalVariableInstruction() || fresh instanceof RET) { - //IndexedInstruction indexed = (IndexedInstruction) fresh; - int oldIndex = fresh.getIndex(); - int freshIndex; -// if (!frameEnv.hasKey(oldIndex)) { -// freshIndex = recipient.allocateLocal(2); -// frameEnv.put(oldIndex, freshIndex); -// } else { - freshIndex = oldIndex;//frameEnv.get(oldIndex); -// } - if (fresh instanceof RET) { - fresh.setIndex(freshIndex); - } else { - fresh = ((InstructionLV)fresh).setIndexAndCopyIfNecessary(freshIndex); - } - dest = newList.append(fresh); - } else { - dest = newList.append(fresh); - } - srcToDest.put(src, dest); - } - - // second pass: retarget branch instructions, copy ranges and tags - Map tagMap = new HashMap(); - for (InstructionHandle dest = newList.getStart(), src = sourceList.getStart(); - dest != null; - dest = dest.getNext(), src = src.getNext()) { - Instruction inst = dest.getInstruction(); - - // retarget branches - if (inst instanceof InstructionBranch) { - InstructionBranch branch = (InstructionBranch) inst; - InstructionHandle oldTarget = branch.getTarget(); - InstructionHandle newTarget = - (InstructionHandle) srcToDest.get(oldTarget); - if (newTarget == null) { - // assert this is a GOTO - // this was a return instruction we previously replaced - } else { - branch.setTarget(newTarget); - if (branch instanceof InstructionSelect) { - InstructionSelect select = (InstructionSelect) branch; - InstructionHandle[] oldTargets = select.getTargets(); - for (int k = oldTargets.length - 1; k >= 0; k--) { - select.setTarget( - k, - (InstructionHandle) srcToDest.get(oldTargets[k])); - } - } - } - } - - //copy over tags and range attributes - Iterator tIter = src.getTargeters().iterator(); - - while (tIter.hasNext()) { - InstructionTargeter old = (InstructionTargeter)tIter.next(); - if (old instanceof Tag) { - Tag oldTag = (Tag) old; - Tag fresh = (Tag) tagMap.get(oldTag); - if (fresh == null) { - fresh = oldTag.copy(); - tagMap.put(oldTag, fresh); - } - dest.addTargeter(fresh); - } else if (old instanceof ExceptionRange) { - ExceptionRange er = (ExceptionRange) old; - if (er.getStart() == src) { - ExceptionRange freshEr = - new ExceptionRange(newList/*recipient.getBody()*/,er.getCatchType(),er.getPriority()); - freshEr.associateWithTargets( - dest, - (InstructionHandle)srcToDest.get(er.getEnd()), - (InstructionHandle)srcToDest.get(er.getHandler())); - } - } -/*else if (old instanceof ShadowRange) { - ShadowRange oldRange = (ShadowRange) old; - if (oldRange.getStart() == src) { - BcelShadow oldShadow = oldRange.getShadow(); - BcelShadow freshEnclosing = - oldShadow.getEnclosingShadow() == null - ? null - : (BcelShadow) shadowMap.get(oldShadow.getEnclosingShadow()); - BcelShadow freshShadow = - oldShadow.copyInto(recipient, freshEnclosing); - ShadowRange freshRange = new ShadowRange(recipient.getBody()); - freshRange.associateWithShadow(freshShadow); - freshRange.associateWithTargets( - dest, - (InstructionHandle) srcToDest.get(oldRange.getEnd())); - shadowMap.put(oldRange, freshRange); - //recipient.matchedShadows.add(freshShadow); - // XXX should go through the NEW copied shadow and update - // the thisVar, targetVar, and argsVar - // ??? Might want to also go through at this time and add - // "extra" vars to the shadow. - } - }*/ - } - } - if (!keepReturns) newList.append(footer); - return newList; - } + // static InstructionList rewriteWithMonitorExitCalls(InstructionList sourceList,InstructionFactory fact,boolean keepReturns,int + // monitorVarSlot,Type monitorVarType) + // { + // InstructionList footer = new InstructionList(); + // InstructionHandle end = footer.append(InstructionConstants.NOP); + // + // InstructionList newList = new InstructionList(); + // + // Map srcToDest = new HashMap(); + // + // // first pass: copy the instructions directly, populate the srcToDest map, + // // fix frame instructions + // for (InstructionHandle src = sourceList.getStart(); src != null; src = src.getNext()) { + // Instruction fresh = Utility.copyInstruction(src.getInstruction()); + // InstructionHandle dest; + // if (src.getInstruction() == Range.RANGEINSTRUCTION) { + // dest = newList.append(Range.RANGEINSTRUCTION); + // } else if (fresh.isReturnInstruction()) { + // if (keepReturns) { + // newList.append(InstructionFactory.createLoad(monitorVarType,monitorVarSlot)); + // newList.append(InstructionConstants.MONITOREXIT); + // dest = newList.append(fresh); + // } else { + // dest = + // newList.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end)); + // } + // } else if (fresh instanceof InstructionBranch) { + // dest = newList.append((InstructionBranch) fresh); + // } else if ( + // fresh.isLocalVariableInstruction() || fresh instanceof RET) { + // //IndexedInstruction indexed = (IndexedInstruction) fresh; + // int oldIndex = fresh.getIndex(); + // int freshIndex; + // // if (!frameEnv.hasKey(oldIndex)) { + // // freshIndex = recipient.allocateLocal(2); + // // frameEnv.put(oldIndex, freshIndex); + // // } else { + // freshIndex = oldIndex;//frameEnv.get(oldIndex); + // // } + // if (fresh instanceof RET) { + // fresh.setIndex(freshIndex); + // } else { + // fresh = ((InstructionLV)fresh).setIndexAndCopyIfNecessary(freshIndex); + // } + // dest = newList.append(fresh); + // } else { + // dest = newList.append(fresh); + // } + // srcToDest.put(src, dest); + // } + // + // // second pass: retarget branch instructions, copy ranges and tags + // Map tagMap = new HashMap(); + // for (InstructionHandle dest = newList.getStart(), src = sourceList.getStart(); + // dest != null; + // dest = dest.getNext(), src = src.getNext()) { + // Instruction inst = dest.getInstruction(); + // + // // retarget branches + // if (inst instanceof InstructionBranch) { + // InstructionBranch branch = (InstructionBranch) inst; + // InstructionHandle oldTarget = branch.getTarget(); + // InstructionHandle newTarget = + // (InstructionHandle) srcToDest.get(oldTarget); + // if (newTarget == null) { + // // assert this is a GOTO + // // this was a return instruction we previously replaced + // } else { + // branch.setTarget(newTarget); + // if (branch instanceof InstructionSelect) { + // InstructionSelect select = (InstructionSelect) branch; + // InstructionHandle[] oldTargets = select.getTargets(); + // for (int k = oldTargets.length - 1; k >= 0; k--) { + // select.setTarget( + // k, + // (InstructionHandle) srcToDest.get(oldTargets[k])); + // } + // } + // } + // } + // + // //copy over tags and range attributes + // Iterator tIter = src.getTargeters().iterator(); + // + // while (tIter.hasNext()) { + // InstructionTargeter old = (InstructionTargeter)tIter.next(); + // if (old instanceof Tag) { + // Tag oldTag = (Tag) old; + // Tag fresh = (Tag) tagMap.get(oldTag); + // if (fresh == null) { + // fresh = oldTag.copy(); + // tagMap.put(oldTag, fresh); + // } + // dest.addTargeter(fresh); + // } else if (old instanceof ExceptionRange) { + // ExceptionRange er = (ExceptionRange) old; + // if (er.getStart() == src) { + // ExceptionRange freshEr = + // new ExceptionRange(newList/*recipient.getBody()*/,er.getCatchType(),er.getPriority()); + // freshEr.associateWithTargets( + // dest, + // (InstructionHandle)srcToDest.get(er.getEnd()), + // (InstructionHandle)srcToDest.get(er.getHandler())); + // } + // } + // /*else if (old instanceof ShadowRange) { + // ShadowRange oldRange = (ShadowRange) old; + // if (oldRange.getStart() == src) { + // BcelShadow oldShadow = oldRange.getShadow(); + // BcelShadow freshEnclosing = + // oldShadow.getEnclosingShadow() == null + // ? null + // : (BcelShadow) shadowMap.get(oldShadow.getEnclosingShadow()); + // BcelShadow freshShadow = + // oldShadow.copyInto(recipient, freshEnclosing); + // ShadowRange freshRange = new ShadowRange(recipient.getBody()); + // freshRange.associateWithShadow(freshShadow); + // freshRange.associateWithTargets( + // dest, + // (InstructionHandle) srcToDest.get(oldRange.getEnd())); + // shadowMap.put(oldRange, freshRange); + // //recipient.matchedShadows.add(freshShadow); + // // XXX should go through the NEW copied shadow and update + // // the thisVar, targetVar, and argsVar + // // ??? Might want to also go through at this time and add + // // "extra" vars to the shadow. + // } + // }*/ + // } + // } + // if (!keepReturns) newList.append(footer); + // return newList; + // } - /** generate the argument stores in preparation for inlining. + /** + * generate the argument stores in preparation for inlining. * - * @param donor the method we will inline from. Used to get the signature. - * @param recipient the method we will inline into. Used to get the frame size - * so we can allocate fresh locations. - * @param frameEnv an empty environment we populate with a map from donor frame to - * recipient frame. + * @param donor the method we will inline from. Used to get the signature. + * @param recipient the method we will inline into. Used to get the frame size so we can allocate fresh locations. + * @param frameEnv an empty environment we populate with a map from donor frame to recipient frame. * @param fact an instruction factory for recipient */ - private static InstructionList genArgumentStores( - LazyMethodGen donor, - LazyMethodGen recipient, - IntMap frameEnv, - InstructionFactory fact) - { + private static InstructionList genArgumentStores(LazyMethodGen donor, LazyMethodGen recipient, IntMap frameEnv, + InstructionFactory fact) { InstructionList ret = new InstructionList(); int donorFramePos = 0; - // writing ret back to front because we're popping. - if (! donor.isStatic()) { + // writing ret back to front because we're popping. + if (!donor.isStatic()) { int targetSlot = recipient.allocateLocal(Type.OBJECT); ret.insert(InstructionFactory.createStore(Type.OBJECT, targetSlot)); frameEnv.put(donorFramePos, targetSlot); @@ -2214,14 +2219,12 @@ class BcelClassWeaver implements IClassWeaver { return ret; } - /** get a called method: Assumes the called method is in this class, - * and the reference to it is exact (a la INVOKESPECIAL). + /** + * get a called method: Assumes the called method is in this class, and the reference to it is exact (a la INVOKESPECIAL). * * @param ih The InvokeInstruction instructionHandle pointing to the called method. */ - private LazyMethodGen getCalledMethod( - InstructionHandle ih) - { + private LazyMethodGen getCalledMethod(InstructionHandle ih) { InvokeInstruction inst = (InvokeInstruction) ih.getInstruction(); String methodName = inst.getName(cpg); @@ -2231,26 +2234,25 @@ class BcelClassWeaver implements IClassWeaver { } private void weaveInAddedMethods() { - Collections.sort(addedLazyMethodGens, - new Comparator() { - public int compare(Object a, Object b) { - LazyMethodGen aa = (LazyMethodGen) a; - LazyMethodGen bb = (LazyMethodGen) b; - int i = aa.getName().compareTo(bb.getName()); - if (i != 0) return i; - return aa.getSignature().compareTo(bb.getSignature()); - } + Collections.sort(addedLazyMethodGens, new Comparator() { + public int compare(Object a, Object b) { + LazyMethodGen aa = (LazyMethodGen) a; + LazyMethodGen bb = (LazyMethodGen) b; + int i = aa.getName().compareTo(bb.getName()); + if (i != 0) + return i; + return aa.getSignature().compareTo(bb.getSignature()); } - ); - - for (Iterator i = addedLazyMethodGens.iterator(); i.hasNext(); ) { - clazz.addMethodGen((LazyMethodGen)i.next()); + }); + + for (Iterator i = addedLazyMethodGens.iterator(); i.hasNext();) { + clazz.addMethodGen((LazyMethodGen) i.next()); } } - void addPerSingletonField(Member field) { - ObjectType aspectType = (ObjectType) BcelWorld.makeBcelType(field.getReturnType()); - String aspectName = field.getReturnType().getName(); + void addPerSingletonField(Member field) { + ObjectType aspectType = (ObjectType) BcelWorld.makeBcelType(field.getReturnType()); + String aspectName = field.getReturnType().getName(); LazyMethodGen clinit = clazz.getStaticInitializer(); InstructionList setup = new InstructionList(); @@ -2258,60 +2260,50 @@ class BcelClassWeaver implements IClassWeaver { setup.append(fact.createNew(aspectType)); setup.append(InstructionFactory.createDup(1)); - setup.append(fact.createInvoke( - aspectName, - "<init>", - Type.VOID, - new Type[0], - Constants.INVOKESPECIAL)); - setup.append( - fact.createFieldAccess( - aspectName, - field.getName(), - aspectType, - Constants.PUTSTATIC)); + setup.append(fact.createInvoke(aspectName, "<init>", Type.VOID, new Type[0], Constants.INVOKESPECIAL)); + setup.append(fact.createFieldAccess(aspectName, field.getName(), aspectType, Constants.PUTSTATIC)); clinit.getBody().insert(setup); - } + } /** - * Returns null if this is not a Java constructor, and then we won't - * weave into it at all + * Returns null if this is not a Java constructor, and then we won't weave into it at all */ private InstructionHandle findSuperOrThisCall(LazyMethodGen mg) { int depth = 1; InstructionHandle start = mg.getBody().getStart(); while (true) { - if (start == null) return null; - + if (start == null) + return null; + Instruction inst = start.getInstruction(); - if (inst.opcode==Constants.INVOKESPECIAL - && ((InvokeInstruction) inst).getName(cpg).equals("<init>")) { + if (inst.opcode == Constants.INVOKESPECIAL && ((InvokeInstruction) inst).getName(cpg).equals("<init>")) { depth--; - if (depth == 0) return start; - } else if (inst.opcode==Constants.NEW) { + if (depth == 0) + return start; + } else if (inst.opcode == Constants.NEW) { depth++; - } + } start = start.getNext(); } } // ---- - + private boolean match(LazyMethodGen mg) { BcelShadow enclosingShadow; List shadowAccumulator = new ArrayList(); - - boolean startsAngly = mg.getName().charAt(0)=='<'; + + boolean startsAngly = mg.getName().charAt(0) == '<'; // we want to match ajsynthetic constructors... if (startsAngly && mg.getName().equals("<init>")) { return matchInit(mg, shadowAccumulator); - } else if (!shouldWeaveBody(mg)) { //.isAjSynthetic()) { - return false; + } else if (!shouldWeaveBody(mg)) { // .isAjSynthetic()) { + return false; } else { if (startsAngly && mg.getName().equals("<clinit>")) { -// clinitShadow = - enclosingShadow = BcelShadow.makeStaticInitialization(world, mg); - //System.err.println(enclosingShadow); + // clinitShadow = + enclosingShadow = BcelShadow.makeStaticInitialization(world, mg); + // System.err.println(enclosingShadow); } else if (mg.isAdviceMethod()) { enclosingShadow = BcelShadow.makeAdviceExecution(world, mg); } else { @@ -2319,30 +2311,28 @@ class BcelClassWeaver implements IClassWeaver { if (effective == null) { enclosingShadow = BcelShadow.makeMethodExecution(world, mg, !canMatchBodyShadows); } else if (effective.isWeaveBody()) { - ResolvedMember rm = effective.getEffectiveSignature(); - - // Annotations for things with effective signatures are never stored in the effective - // signature itself - we have to hunt for them. Storing them in the effective signature - // would mean keeping two sets up to date (no way!!) - - fixAnnotationsForResolvedMember(rm,mg.getMemberView()); - - enclosingShadow = - BcelShadow.makeShadowForMethod(world,mg,effective.getShadowKind(),rm); + ResolvedMember rm = effective.getEffectiveSignature(); + + // Annotations for things with effective signatures are never stored in the effective + // signature itself - we have to hunt for them. Storing them in the effective signature + // would mean keeping two sets up to date (no way!!) + + fixAnnotationsForResolvedMember(rm, mg.getMemberView()); + + enclosingShadow = BcelShadow.makeShadowForMethod(world, mg, effective.getShadowKind(), rm); } else { return false; } } if (canMatchBodyShadows) { - for (InstructionHandle h = mg.getBody().getStart(); - h != null; - h = h.getNext()) { + for (InstructionHandle h = mg.getBody().getStart(); h != null; h = h.getNext()) { match(mg, h, enclosingShadow, shadowAccumulator); } } - // FIXME asc change from string match if we can, rather brittle. this check actually prevents field-exec jps - if (canMatch(enclosingShadow.getKind()) && !(mg.getName().charAt(0)=='a' && mg.getName().startsWith("ajc$interFieldInit"))) { + // FIXME asc change from string match if we can, rather brittle. this check actually prevents field-exec jps + if (canMatch(enclosingShadow.getKind()) + && !(mg.getName().charAt(0) == 'a' && mg.getName().startsWith("ajc$interFieldInit"))) { if (match(enclosingShadow, shadowAccumulator)) { enclosingShadow.init(); } @@ -2358,20 +2348,19 @@ class BcelClassWeaver implements IClassWeaver { InstructionHandle superOrThisCall = findSuperOrThisCall(mg); // we don't walk bodies of things where it's a wrong constructor thingie - if (superOrThisCall == null) return false; + if (superOrThisCall == null) + return false; enclosingShadow = BcelShadow.makeConstructorExecution(world, mg, superOrThisCall); if (mg.getEffectiveSignature() != null) { enclosingShadow.setMatchingSignature(mg.getEffectiveSignature().getEffectiveSignature()); } - + // walk the body boolean beforeSuperOrThisCall = true; if (shouldWeaveBody(mg)) { if (canMatchBodyShadows) { - for (InstructionHandle h = mg.getBody().getStart(); - h != null; - h = h.getNext()) { + for (InstructionHandle h = mg.getBody().getStart(); h != null; h = h.getNext()) { if (h == superOrThisCall) { beforeSuperOrThisCall = false; continue; @@ -2382,20 +2371,19 @@ class BcelClassWeaver implements IClassWeaver { if (canMatch(Shadow.ConstructorExecution)) match(enclosingShadow, shadowAccumulator); } - + // XXX we don't do pre-inits of interfaces - + // now add interface inits - if (! isThisCall(superOrThisCall)) { + if (!isThisCall(superOrThisCall)) { InstructionHandle curr = enclosingShadow.getRange().getStart(); - for (Iterator i = addedSuperInitializersAsList.iterator(); i.hasNext(); ) { + for (Iterator i = addedSuperInitializersAsList.iterator(); i.hasNext();) { IfaceInitList l = (IfaceInitList) i.next(); Member ifaceInitSig = AjcMemberMaker.interfaceConstructor(l.onType); - - BcelShadow initShadow = - BcelShadow.makeIfaceInitialization(world, mg, ifaceInitSig); - + + BcelShadow initShadow = BcelShadow.makeIfaceInitialization(world, mg, ifaceInitSig); + // insert code in place InstructionList inits = genInitInstructions(l.list, false); if (match(initShadow, shadowAccumulator) || !inits.isEmpty()) { @@ -2403,123 +2391,106 @@ class BcelClassWeaver implements IClassWeaver { initShadow.getRange().insert(inits, Range.OutsideBefore); } } - + // now we add our initialization code InstructionList inits = genInitInstructions(addedThisInitializers, false); - enclosingShadow.getRange().insert(inits, Range.OutsideBefore); + enclosingShadow.getRange().insert(inits, Range.OutsideBefore); } - // actually, you only need to inline the self constructors that are + // actually, you only need to inline the self constructors that are // in a particular group (partition the constructors into groups where members - // call or are called only by those in the group). Then only inline + // call or are called only by those in the group). Then only inline // constructors - // in groups where at least one initialization jp matched. Future work. - boolean addedInitialization = - match( - BcelShadow.makeUnfinishedInitialization(world, mg), - initializationShadows); - addedInitialization |= - match( - BcelShadow.makeUnfinishedPreinitialization(world, mg), - initializationShadows); + // in groups where at least one initialization jp matched. Future work. + boolean addedInitialization = match(BcelShadow.makeUnfinishedInitialization(world, mg), initializationShadows); + addedInitialization |= match(BcelShadow.makeUnfinishedPreinitialization(world, mg), initializationShadows); mg.matchedShadows = shadowAccumulator; return addedInitialization || !shadowAccumulator.isEmpty(); } - private boolean shouldWeaveBody(LazyMethodGen mg) { - if (mg.isBridgeMethod()) return false; - if (mg.isAjSynthetic()) return mg.getName().equals("<clinit>"); + private boolean shouldWeaveBody(LazyMethodGen mg) { + if (mg.isBridgeMethod()) + return false; + if (mg.isAjSynthetic()) + return mg.getName().equals("<clinit>"); AjAttribute.EffectiveSignatureAttribute a = mg.getEffectiveSignature(); - if (a != null) return a.isWeaveBody(); + if (a != null) + return a.isWeaveBody(); return true; } - /** * first sorts the mungers, then gens the initializers in the right order */ private InstructionList genInitInstructions(List list, boolean isStatic) { list = PartialOrder.sort(list); - if (list == null) { - throw new BCException("circularity in inter-types"); - } - + if (list == null) { + throw new BCException("circularity in inter-types"); + } + InstructionList ret = new InstructionList(); - + for (Iterator i = list.iterator(); i.hasNext();) { ConcreteTypeMunger cmunger = (ConcreteTypeMunger) i.next(); NewFieldTypeMunger munger = (NewFieldTypeMunger) cmunger.getMunger(); ResolvedMember initMethod = munger.getInitMethod(cmunger.getAspectType()); - if (!isStatic) ret.append(InstructionConstants.ALOAD_0); + if (!isStatic) + ret.append(InstructionConstants.ALOAD_0); ret.append(Utility.createInvoke(fact, world, initMethod)); } return ret; } - - private void match( - LazyMethodGen mg, - InstructionHandle ih, - BcelShadow enclosingShadow, - List shadowAccumulator) - { - Instruction i = ih.getInstruction(); - - // Exception handlers (pr230817) - if (canMatch(Shadow.ExceptionHandler) && !Range.isRangeHandle(ih)) { - InstructionTargeter[] targeters = ih.getTargetersArray(); - if (targeters != null) { - for (int j = 0; j < targeters.length; j++) { - InstructionTargeter t = targeters[j]; - if (t instanceof ExceptionRange) { - // assert t.getHandler() == ih - ExceptionRange er = (ExceptionRange) t; - if (er.getCatchType() == null) continue; - if (isInitFailureHandler(ih)) return; - - if (!ih.getInstruction().isStoreInstruction() && ih.getInstruction().getOpcode()!=Constants.NOP) { - // If using cobertura, the catch block stats with INVOKESTATIC rather than ASTORE, in order that the ranges - // for the methodcall and exceptionhandler shadows that occur at this same - // line, we need to modify the instruction list to split them - adding a - // NOP before the invokestatic that gets all the targeters - // that were aimed at the INVOKESTATIC - mg.getBody().insert(ih,InstructionConstants.NOP); - InstructionHandle newNOP = ih.getPrev(); - // what about a try..catch that starts at the start of the exception handler? need to only include certain targeters really. - er.updateTarget(ih, newNOP,mg.getBody()); - for (int ii=0;ii<targeters.length;ii++) { - newNOP.addTargeter(targeters[ii]); - } - ih.removeAllTargeters(); - match( - BcelShadow.makeExceptionHandler( - world, - er, - mg, newNOP, enclosingShadow), - shadowAccumulator); - } else { - match( - BcelShadow.makeExceptionHandler( - world, - er, - mg, ih, enclosingShadow), - shadowAccumulator); - } - } - } - } - } - - if ((i instanceof FieldInstruction) && - (canMatch(Shadow.FieldGet) || canMatch(Shadow.FieldSet)) - ) { + private void match(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List shadowAccumulator) { + Instruction i = ih.getInstruction(); + + // Exception handlers (pr230817) + if (canMatch(Shadow.ExceptionHandler) && !Range.isRangeHandle(ih)) { + InstructionTargeter[] targeters = ih.getTargetersArray(); + if (targeters != null) { + for (int j = 0; j < targeters.length; j++) { + InstructionTargeter t = targeters[j]; + if (t instanceof ExceptionRange) { + // assert t.getHandler() == ih + ExceptionRange er = (ExceptionRange) t; + if (er.getCatchType() == null) + continue; + if (isInitFailureHandler(ih)) + return; + + if (!ih.getInstruction().isStoreInstruction() && ih.getInstruction().getOpcode() != Constants.NOP) { + // If using cobertura, the catch block stats with INVOKESTATIC rather than ASTORE, in order that the + // ranges + // for the methodcall and exceptionhandler shadows that occur at this same + // line, we need to modify the instruction list to split them - adding a + // NOP before the invokestatic that gets all the targeters + // that were aimed at the INVOKESTATIC + mg.getBody().insert(ih, InstructionConstants.NOP); + InstructionHandle newNOP = ih.getPrev(); + // what about a try..catch that starts at the start of the exception handler? need to only include + // certain targeters really. + er.updateTarget(ih, newNOP, mg.getBody()); + for (int ii = 0; ii < targeters.length; ii++) { + newNOP.addTargeter(targeters[ii]); + } + ih.removeAllTargeters(); + match(BcelShadow.makeExceptionHandler(world, er, mg, newNOP, enclosingShadow), shadowAccumulator); + } else { + match(BcelShadow.makeExceptionHandler(world, er, mg, ih, enclosingShadow), shadowAccumulator); + } + } + } + } + } + + if ((i instanceof FieldInstruction) && (canMatch(Shadow.FieldGet) || canMatch(Shadow.FieldSet))) { FieldInstruction fi = (FieldInstruction) i; - - if (fi.opcode==Constants.PUTFIELD || fi.opcode==Constants.PUTSTATIC) { - // check for sets of constant fields. We first check the previous - // instruction. If the previous instruction is a LD_WHATEVER (push + + if (fi.opcode == Constants.PUTFIELD || fi.opcode == Constants.PUTSTATIC) { + // check for sets of constant fields. We first check the previous + // instruction. If the previous instruction is a LD_WHATEVER (push // constant on the stack) then we must resolve the field to determine - // if it's final. If it is final, then we don't generate a shadow. + // if it's final. If it is final, then we don't generate a shadow. InstructionHandle prevHandle = ih.getPrev(); Instruction prevI = prevHandle.getInstruction(); if (Utility.isConstantPushInstruction(prevI)) { @@ -2533,7 +2504,7 @@ class BcelClassWeaver implements IClassWeaver { } else { if (canMatch(Shadow.FieldSet)) matchSetInstruction(mg, ih, enclosingShadow, shadowAccumulator); - } + } } else { if (canMatch(Shadow.FieldSet)) matchSetInstruction(mg, ih, enclosingShadow, shadowAccumulator); @@ -2546,10 +2517,8 @@ class BcelClassWeaver implements IClassWeaver { InvokeInstruction ii = (InvokeInstruction) i; if (ii.getMethodName(clazz.getConstantPool()).equals("<init>")) { if (canMatch(Shadow.ConstructorCall)) - match( - BcelShadow.makeConstructorCall(world, mg, ih, enclosingShadow), - shadowAccumulator); - } else if (ii.opcode==Constants.INVOKESPECIAL) { + match(BcelShadow.makeConstructorCall(world, mg, ih, enclosingShadow), shadowAccumulator); + } else if (ii.opcode == Constants.INVOKESPECIAL) { String onTypeName = ii.getClassName(cpg); if (onTypeName.equals(mg.getEnclosingClass().getName())) { // we are private @@ -2558,86 +2527,86 @@ class BcelClassWeaver implements IClassWeaver { // we are a super call, and this is not a join point in AspectJ-1.{0,1} } } else { - matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator); + matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator); } } else if (world.isJoinpointArrayConstructionEnabled() && i.isArrayCreationInstruction()) { if (canMatch(Shadow.ConstructorCall)) { boolean debug = false; - if (debug) System.err.println("Found new array instruction: "+i); - if (i.opcode==Constants.ANEWARRAY) { -// ANEWARRAY arrayInstruction = (ANEWARRAY)i; + if (debug) + System.err.println("Found new array instruction: " + i); + if (i.opcode == Constants.ANEWARRAY) { + // ANEWARRAY arrayInstruction = (ANEWARRAY)i; ObjectType arrayType = i.getLoadClassType(clazz.getConstantPool()); - if (debug) System.err.println("Array type is "+arrayType); - BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); - match(ctorCallShadow,shadowAccumulator); - } else if (i.opcode==Constants.NEWARRAY) { -// NEWARRAY arrayInstruction = (NEWARRAY)i; + if (debug) + System.err.println("Array type is " + arrayType); + BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world, mg, ih, enclosingShadow); + match(ctorCallShadow, shadowAccumulator); + } else if (i.opcode == Constants.NEWARRAY) { + // NEWARRAY arrayInstruction = (NEWARRAY)i; Type arrayType = i.getType(); - if (debug) System.err.println("Array type is "+arrayType); - BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); - match(ctorCallShadow,shadowAccumulator); + if (debug) + System.err.println("Array type is " + arrayType); + BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world, mg, ih, enclosingShadow); + match(ctorCallShadow, shadowAccumulator); } else if (i instanceof MULTIANEWARRAY) { - MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY)i; + MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY) i; ObjectType arrayType = arrayInstruction.getLoadClassType(clazz.getConstantPool()); - if (debug) System.err.println("Array type is "+arrayType); - BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world,mg,ih,enclosingShadow); - match(ctorCallShadow,shadowAccumulator); + if (debug) + System.err.println("Array type is " + arrayType); + BcelShadow ctorCallShadow = BcelShadow.makeArrayConstructorCall(world, mg, ih, enclosingShadow); + match(ctorCallShadow, shadowAccumulator); } } -// see pr77166 if you are thinking about implementing this -// } else if (i instanceof AALOAD ) { -// AALOAD arrayLoad = (AALOAD)i; -// Type arrayType = arrayLoad.getType(clazz.getConstantPoolGen()); -// BcelShadow arrayLoadShadow = BcelShadow.makeArrayLoadCall(world,mg,ih,enclosingShadow); -// match(arrayLoadShadow,shadowAccumulator); -// } else if (i instanceof AASTORE) { -// // ... magic required - } else if ( world.isJoinpointSynchronizationEnabled() && - ((i.getOpcode()==Constants.MONITORENTER) || (i.getOpcode()==Constants.MONITOREXIT))) { + // see pr77166 if you are thinking about implementing this + // } else if (i instanceof AALOAD ) { + // AALOAD arrayLoad = (AALOAD)i; + // Type arrayType = arrayLoad.getType(clazz.getConstantPoolGen()); + // BcelShadow arrayLoadShadow = BcelShadow.makeArrayLoadCall(world,mg,ih,enclosingShadow); + // match(arrayLoadShadow,shadowAccumulator); + // } else if (i instanceof AASTORE) { + // // ... magic required + } else if (world.isJoinpointSynchronizationEnabled() + && ((i.getOpcode() == Constants.MONITORENTER) || (i.getOpcode() == Constants.MONITOREXIT))) { // if (canMatch(Shadow.Monitoring)) { - if (i.getOpcode()==Constants.MONITORENTER) { - BcelShadow monitorEntryShadow = BcelShadow.makeMonitorEnter(world,mg,ih,enclosingShadow); - match(monitorEntryShadow,shadowAccumulator); - } else { - BcelShadow monitorExitShadow = BcelShadow.makeMonitorExit(world,mg,ih,enclosingShadow); - match(monitorExitShadow,shadowAccumulator); - } + if (i.getOpcode() == Constants.MONITORENTER) { + BcelShadow monitorEntryShadow = BcelShadow.makeMonitorEnter(world, mg, ih, enclosingShadow); + match(monitorEntryShadow, shadowAccumulator); + } else { + BcelShadow monitorExitShadow = BcelShadow.makeMonitorExit(world, mg, ih, enclosingShadow); + match(monitorExitShadow, shadowAccumulator); + } // } } - + } private boolean isInitFailureHandler(InstructionHandle ih) { - // Skip the astore_0 and aload_0 at the start of the handler and - // then check if the instruction following these is - // 'putstatic ajc$initFailureCause'. If it is then we are + // Skip the astore_0 and aload_0 at the start of the handler and + // then check if the instruction following these is + // 'putstatic ajc$initFailureCause'. If it is then we are // in the handler we created in AspectClinit.generatePostSyntheticCode() InstructionHandle twoInstructionsAway = ih.getNext().getNext(); - if (twoInstructionsAway.getInstruction().opcode==Constants.PUTSTATIC) { - String name = ((FieldInstruction)twoInstructionsAway.getInstruction()).getFieldName(cpg); - if (name.equals(NameMangler.INITFAILURECAUSE_FIELD_NAME)) return true; + if (twoInstructionsAway.getInstruction().opcode == Constants.PUTSTATIC) { + String name = ((FieldInstruction) twoInstructionsAway.getInstruction()).getFieldName(cpg); + if (name.equals(NameMangler.INITFAILURECAUSE_FIELD_NAME)) + return true; } return false; } - - private void matchSetInstruction( - LazyMethodGen mg, - InstructionHandle ih, - BcelShadow enclosingShadow, - List shadowAccumulator) { + private void matchSetInstruction(LazyMethodGen mg, InstructionHandle ih, BcelShadow enclosingShadow, List shadowAccumulator) { FieldInstruction fi = (FieldInstruction) ih.getInstruction(); Member field = BcelWorld.makeFieldJoinPointSignature(clazz, fi); - + // synthetic fields are never join points - if (field.getName().startsWith(NameMangler.PREFIX)) return; - + if (field.getName().startsWith(NameMangler.PREFIX)) + return; + ResolvedMember resolvedField = field.resolve(world); if (resolvedField == null) { // we can't find the field, so it's not a join point. return; - } else if ( - Modifier.isFinal(resolvedField.getModifiers()) + } else if (Modifier.isFinal(resolvedField.getModifiers()) && Utility.isConstantPushInstruction(ih.getPrev().getInstruction())) { // it's the set of a final constant, so it's // not a join point according to 1.0.6 and 1.1. @@ -2647,8 +2616,7 @@ class BcelClassWeaver implements IClassWeaver { return; } else { // Fix for bug 172107 (similar the "get" fix for bug 109728) - BcelShadow bs= - BcelShadow.makeFieldSet(world, resolvedField, mg, ih, enclosingShadow); + BcelShadow bs = BcelShadow.makeFieldSet(world, resolvedField, mg, ih, enclosingShadow); String cname = fi.getClassName(cpg); if (!resolvedField.getDeclaringType().getName().equals(cname)) { bs.setActualTargetType(cname); @@ -2662,8 +2630,9 @@ class BcelClassWeaver implements IClassWeaver { Member field = BcelWorld.makeFieldJoinPointSignature(clazz, fi); // synthetic fields are never join points - if (field.getName().startsWith(NameMangler.PREFIX)) return; - + if (field.getName().startsWith(NameMangler.PREFIX)) + return; + ResolvedMember resolvedField = field.resolve(world); if (resolvedField == null) { // we can't find the field, so it's not a join point. @@ -2672,7 +2641,7 @@ class BcelClassWeaver implements IClassWeaver { // sets of synthetics aren't join points in 1.1 return; } else { - BcelShadow bs = BcelShadow.makeFieldGet(world,resolvedField,mg,ih,enclosingShadow); + BcelShadow bs = BcelShadow.makeFieldGet(world, resolvedField, mg, ih, enclosingShadow); String cname = fi.getClassName(cpg); if (!resolvedField.getDeclaringType().getName().equals(cname)) { bs.setActualTargetType(cname); @@ -2680,97 +2649,95 @@ class BcelClassWeaver implements IClassWeaver { match(bs, shadowAccumulator); } } - + /** - * For some named resolved type, this method looks for a member with a particular name - - * it should only be used when you truly believe there is only one member with that - * name in the type as it returns the first one it finds. - */ - private ResolvedMember findResolvedMemberNamed(ResolvedType type,String methodName) { + * For some named resolved type, this method looks for a member with a particular name - it should only be used when you truly + * believe there is only one member with that name in the type as it returns the first one it finds. + */ + private ResolvedMember findResolvedMemberNamed(ResolvedType type, String methodName) { ResolvedMember[] allMethods = type.getDeclaredMethods(); for (int i = 0; i < allMethods.length; i++) { ResolvedMember member = allMethods[i]; - if (member.getName().equals(methodName)) return member; + if (member.getName().equals(methodName)) + return member; } return null; } - + /** - * For a given resolvedmember, this will discover the real annotations for it. - * <b>Should only be used when the resolvedmember is the contents of an effective signature - * attribute, as thats the only time when the annotations aren't stored directly in the + * For a given resolvedmember, this will discover the real annotations for it. <b>Should only be used when the resolvedmember is + * the contents of an effective signature attribute, as thats the only time when the annotations aren't stored directly in the * resolvedMember</b> + * * @param rm the sig we want it to pretend to be 'int A.m()' or somesuch ITD like thing * @param declaredSig the real sig 'blah.ajc$xxx' */ - private void fixAnnotationsForResolvedMember(ResolvedMember rm,ResolvedMember declaredSig) { - try { - UnresolvedType memberHostType = declaredSig.getDeclaringType(); - ResolvedType[] annotations = (ResolvedType[])mapToAnnotations.get(rm); - String methodName = declaredSig.getName(); - // FIXME asc shouldnt really rely on string names ! - if (annotations == null) { - if (rm.getKind()==Member.FIELD) { - if (methodName.startsWith("ajc$inlineAccessField")) { - ResolvedMember resolvedDooberry = world.resolve(rm); - annotations = resolvedDooberry.getAnnotationTypes(); - } else { - ResolvedMember realthing = AjcMemberMaker.interFieldInitializer(rm,memberHostType); - ResolvedMember resolvedDooberry = world.resolve(realthing); - annotations = resolvedDooberry.getAnnotationTypes(); - } - } else if (rm.getKind()==Member.METHOD && !rm.isAbstract()) { - if (methodName.startsWith("ajc$inlineAccessMethod") || methodName.startsWith("ajc$superDispatch")) { - ResolvedMember resolvedDooberry = world.resolve(declaredSig); - annotations = resolvedDooberry.getAnnotationTypes(); - } else { - ResolvedMember realthing = AjcMemberMaker.interMethodDispatcher(rm.resolve(world),memberHostType).resolve(world); - // ResolvedMember resolvedDooberry = world.resolve(realthing); - ResolvedMember theRealMember = findResolvedMemberNamed(memberHostType.resolve(world),realthing.getName()); + private void fixAnnotationsForResolvedMember(ResolvedMember rm, ResolvedMember declaredSig) { + try { + UnresolvedType memberHostType = declaredSig.getDeclaringType(); + ResolvedType[] annotations = (ResolvedType[]) mapToAnnotations.get(rm); + String methodName = declaredSig.getName(); + // FIXME asc shouldnt really rely on string names ! + if (annotations == null) { + if (rm.getKind() == Member.FIELD) { + if (methodName.startsWith("ajc$inlineAccessField")) { + ResolvedMember resolvedDooberry = world.resolve(rm); + annotations = resolvedDooberry.getAnnotationTypes(); + } else { + ResolvedMember realthing = AjcMemberMaker.interFieldInitializer(rm, memberHostType); + ResolvedMember resolvedDooberry = world.resolve(realthing); + annotations = resolvedDooberry.getAnnotationTypes(); + } + } else if (rm.getKind() == Member.METHOD && !rm.isAbstract()) { + if (methodName.startsWith("ajc$inlineAccessMethod") || methodName.startsWith("ajc$superDispatch")) { + ResolvedMember resolvedDooberry = world.resolve(declaredSig); + annotations = resolvedDooberry.getAnnotationTypes(); + } else { + ResolvedMember realthing = AjcMemberMaker.interMethodDispatcher(rm.resolve(world), memberHostType).resolve( + world); + // ResolvedMember resolvedDooberry = world.resolve(realthing); + ResolvedMember theRealMember = findResolvedMemberNamed(memberHostType.resolve(world), realthing.getName()); + // AMC temp guard for M4 + if (theRealMember == null) { + throw new UnsupportedOperationException( + "Known limitation in M4 - can't find ITD members when type variable is used as an argument and has upper bound specified"); + } + annotations = theRealMember.getAnnotationTypes(); + } + } else if (rm.getKind() == Member.CONSTRUCTOR) { + ResolvedMember realThing = AjcMemberMaker.postIntroducedConstructor(memberHostType.resolve(world), rm + .getDeclaringType(), rm.getParameterTypes()); + ResolvedMember resolvedDooberry = world.resolve(realThing); // AMC temp guard for M4 - if (theRealMember == null) { - throw new UnsupportedOperationException("Known limitation in M4 - can't find ITD members when type variable is used as an argument and has upper bound specified"); + if (resolvedDooberry == null) { + throw new UnsupportedOperationException( + "Known limitation in M4 - can't find ITD members when type variable is used as an argument and has upper bound specified"); } - annotations = theRealMember.getAnnotationTypes(); - } - } else if (rm.getKind()==Member.CONSTRUCTOR) { - ResolvedMember realThing = AjcMemberMaker.postIntroducedConstructor(memberHostType.resolve(world),rm.getDeclaringType(),rm.getParameterTypes()); - ResolvedMember resolvedDooberry = world.resolve(realThing); - // AMC temp guard for M4 - if (resolvedDooberry == null) { - throw new UnsupportedOperationException("Known limitation in M4 - can't find ITD members when type variable is used as an argument and has upper bound specified"); + annotations = resolvedDooberry.getAnnotationTypes(); } - annotations = resolvedDooberry.getAnnotationTypes(); + if (annotations == null) + annotations = new ResolvedType[0]; + mapToAnnotations.put(rm, annotations); } - if (annotations == null) - annotations = new ResolvedType[0]; - mapToAnnotations.put(rm,annotations); - } - rm.setAnnotationTypes(annotations); - } - catch (UnsupportedOperationException ex) { - throw ex; - } catch (Throwable t) { - //FIXME asc remove this catch after more testing has confirmed the above stuff is OK - throw new BCException("Unexpectedly went bang when searching for annotations on "+rm,t); + rm.setAnnotationTypes(annotations); + } catch (UnsupportedOperationException ex) { + throw ex; + } catch (Throwable t) { + // FIXME asc remove this catch after more testing has confirmed the above stuff is OK + throw new BCException("Unexpectedly went bang when searching for annotations on " + rm, t); } } - - private void matchInvokeInstruction(LazyMethodGen mg, - InstructionHandle ih, - InvokeInstruction invoke, - BcelShadow enclosingShadow, - List shadowAccumulator) - { + private void matchInvokeInstruction(LazyMethodGen mg, InstructionHandle ih, InvokeInstruction invoke, + BcelShadow enclosingShadow, List shadowAccumulator) { String methodName = invoke.getName(cpg); if (methodName.startsWith(NameMangler.PREFIX)) { - Member jpSig = - world.makeJoinPointSignatureForMethodInvocation(clazz, invoke); + Member jpSig = world.makeJoinPointSignatureForMethodInvocation(clazz, invoke); ResolvedMember declaredSig = jpSig.resolve(world); - //System.err.println(method + ", declaredSig: " +declaredSig); - if (declaredSig == null) return; - + // System.err.println(method + ", declaredSig: " +declaredSig); + if (declaredSig == null) + return; + if (declaredSig.getKind() == Member.FIELD) { Shadow.Kind kind; if (jpSig.getReturnType().equals(ResolvedType.VOID)) { @@ -2778,103 +2745,105 @@ class BcelClassWeaver implements IClassWeaver { } else { kind = Shadow.FieldGet; } - + if (canMatch(Shadow.FieldGet) || canMatch(Shadow.FieldSet)) - match(BcelShadow.makeShadowForMethodCall(world, mg, ih, enclosingShadow, - kind, declaredSig), - shadowAccumulator); + match(BcelShadow.makeShadowForMethodCall(world, mg, ih, enclosingShadow, kind, declaredSig), shadowAccumulator); } else { - AjAttribute.EffectiveSignatureAttribute effectiveSig = - declaredSig.getEffectiveSignature(); - if (effectiveSig == null) return; - //System.err.println("call to inter-type member: " + effectiveSig); - if (effectiveSig.isWeaveBody()) return; - - - ResolvedMember rm = effectiveSig.getEffectiveSignature(); - - fixAnnotationsForResolvedMember(rm,declaredSig); // abracadabra - - if (canMatch(effectiveSig.getShadowKind())) - match(BcelShadow.makeShadowForMethodCall(world, mg, ih, enclosingShadow, - effectiveSig.getShadowKind(), rm), shadowAccumulator); + AjAttribute.EffectiveSignatureAttribute effectiveSig = declaredSig.getEffectiveSignature(); + if (effectiveSig == null) + return; + // System.err.println("call to inter-type member: " + effectiveSig); + if (effectiveSig.isWeaveBody()) + return; + + ResolvedMember rm = effectiveSig.getEffectiveSignature(); + + fixAnnotationsForResolvedMember(rm, declaredSig); // abracadabra + + if (canMatch(effectiveSig.getShadowKind())) + match(BcelShadow.makeShadowForMethodCall(world, mg, ih, enclosingShadow, effectiveSig.getShadowKind(), rm), + shadowAccumulator); } } else { if (canMatch(Shadow.MethodCall)) - match( - BcelShadow.makeMethodCall(world, mg, ih, enclosingShadow), - shadowAccumulator); - } + match(BcelShadow.makeMethodCall(world, mg, ih, enclosingShadow), shadowAccumulator); } - + } + // static ... so all worlds will share the config for the first one created... private static boolean checkedXsetForLowLevelContextCapturing = false; private static boolean captureLowLevelContext = false; - - private boolean match(BcelShadow shadow, List shadowAccumulator) { - //System.err.println("match: " + shadow); - if (captureLowLevelContext) { // duplicate blocks - one with context capture, one without, seems faster than multiple 'ifs()' - ContextToken shadowMatchToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MATCHING_SHADOW, shadow); - boolean isMatched = false; - for (Iterator i = shadowMungers.iterator(); i.hasNext(); ) { - ShadowMunger munger = (ShadowMunger)i.next(); - ContextToken mungerMatchToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MATCHING_POINTCUT, munger.getPointcut()); - if (munger.match(shadow, world)) { - shadow.addMunger(munger); - isMatched = true; - if (shadow.getKind() == Shadow.StaticInitialization) { - clazz.warnOnAddedStaticInitializer(shadow,munger.getSourceLocation()); - } - } - CompilationAndWeavingContext.leavingPhase(mungerMatchToken); - } - - if (isMatched) shadowAccumulator.add(shadow); - CompilationAndWeavingContext.leavingPhase(shadowMatchToken); - return isMatched; - } else { - boolean isMatched = false; - int max = shadowMungers.size(); - for (int i=0;i<max;i++) { - ShadowMunger munger = (ShadowMunger)shadowMungers.get(i); - if (munger.match(shadow, world)) { - shadow.addMunger(munger); - isMatched = true; - if (shadow.getKind() == Shadow.StaticInitialization) { - clazz.warnOnAddedStaticInitializer(shadow,munger.getSourceLocation()); - } - } - } - if (isMatched) { - shadowAccumulator.add(shadow); - } - return isMatched; - } - } - - // ---- - - private void implement(LazyMethodGen mg) { - List shadows = mg.matchedShadows; - if (shadows == null) return; - // We depend on a partial order such that inner shadows are earlier on the list - // than outer shadows. That's fine. This order is preserved if: - - // A preceeds B iff B.getStart() is LATER THAN A.getStart(). - - for (Iterator i = shadows.iterator(); i.hasNext(); ) { - BcelShadow shadow = (BcelShadow)i.next(); - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.IMPLEMENTING_ON_SHADOW,shadow); - shadow.implement(); - CompilationAndWeavingContext.leavingPhase(tok); - } -// int ii = + + private boolean match(BcelShadow shadow, List shadowAccumulator) { + // System.err.println("match: " + shadow); + if (captureLowLevelContext) { // duplicate blocks - one with context capture, one without, seems faster than multiple + // 'ifs()' + ContextToken shadowMatchToken = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.MATCHING_SHADOW, shadow); + boolean isMatched = false; + for (Iterator i = shadowMungers.iterator(); i.hasNext();) { + ShadowMunger munger = (ShadowMunger) i.next(); + ContextToken mungerMatchToken = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.MATCHING_POINTCUT, munger.getPointcut()); + if (munger.match(shadow, world)) { + shadow.addMunger(munger); + isMatched = true; + if (shadow.getKind() == Shadow.StaticInitialization) { + clazz.warnOnAddedStaticInitializer(shadow, munger.getSourceLocation()); + } + } + CompilationAndWeavingContext.leavingPhase(mungerMatchToken); + } + + if (isMatched) + shadowAccumulator.add(shadow); + CompilationAndWeavingContext.leavingPhase(shadowMatchToken); + return isMatched; + } else { + boolean isMatched = false; + int max = shadowMungers.size(); + for (int i = 0; i < max; i++) { + ShadowMunger munger = (ShadowMunger) shadowMungers.get(i); + if (munger.match(shadow, world)) { + shadow.addMunger(munger); + isMatched = true; + if (shadow.getKind() == Shadow.StaticInitialization) { + clazz.warnOnAddedStaticInitializer(shadow, munger.getSourceLocation()); + } + } + } + if (isMatched) { + shadowAccumulator.add(shadow); + } + return isMatched; + } + } + + // ---- + + private void implement(LazyMethodGen mg) { + List shadows = mg.matchedShadows; + if (shadows == null) + return; + // We depend on a partial order such that inner shadows are earlier on the list + // than outer shadows. That's fine. This order is preserved if: + + // A preceeds B iff B.getStart() is LATER THAN A.getStart(). + + for (Iterator i = shadows.iterator(); i.hasNext();) { + BcelShadow shadow = (BcelShadow) i.next(); + ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.IMPLEMENTING_ON_SHADOW, + shadow); + shadow.implement(); + CompilationAndWeavingContext.leavingPhase(tok); + } + // int ii = mg.getMaxLocals(); mg.matchedShadows = null; - } - - // ---- - + } + + // ---- + public LazyClassGen getLazyClassGen() { return clazz; } @@ -2886,19 +2855,18 @@ class BcelClassWeaver implements IClassWeaver { public BcelWorld getWorld() { return world; } - + // Called by the BcelWeaver to let us know all BcelClassWeavers need to collect reweavable info public static void setReweavableMode(boolean mode) { inReweavableMode = mode; } - - public static boolean getReweavableMode() { + + public static boolean getReweavableMode() { return inReweavableMode; } - + public String toString() { - return "BcelClassWeaver instance for : "+clazz; + return "BcelClassWeaver instance for : " + clazz; } - } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java index 4716ceede..3fcc0ab02 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.AttributeUtils; import org.aspectj.apache.bcel.classfile.Field; import org.aspectj.apache.bcel.classfile.JavaClass; @@ -61,27 +60,27 @@ import org.aspectj.weaver.patterns.IScope; import org.aspectj.weaver.patterns.PerClause; public class BcelObjectType extends AbstractReferenceTypeDelegate { - public JavaClass javaClass; - private LazyClassGen lazyClassGen = null; // set lazily if it's an aspect + public JavaClass javaClass; + private LazyClassGen lazyClassGen = null; // set lazily if it's an aspect private int modifiers; private String className; - + private String superclassSignature; private String superclassName; private String[] interfaceSignatures; - - private ResolvedMember[] fields = null; - private ResolvedMember[] methods = null; - private ResolvedType[] annotationTypes = null; - private AnnotationX[] annotations = null; - private TypeVariable[] typeVars = null; - private String retentionPolicy; + + private ResolvedMember[] fields = null; + private ResolvedMember[] methods = null; + private ResolvedType[] annotationTypes = null; + private AnnotationX[] annotations = null; + private TypeVariable[] typeVars = null; + private String retentionPolicy; private AnnotationTargetKind[] annotationTargetKinds; - // Aspect related stuff (pointcuts *could* be in a java class) + // Aspect related stuff (pointcuts *could* be in a java class) private AjAttribute.WeaverVersionInfo wvInfo = AjAttribute.WeaverVersionInfo.UNKNOWN; - private ResolvedPointcutDefinition[] pointcuts = null; + private ResolvedPointcutDefinition[] pointcuts = null; private ResolvedMember[] privilegedAccess = null; private WeaverStateInfo weaverState = null; private PerClause perClause = null; @@ -90,7 +89,6 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { private Signature.FormalTypeParameter[] formalsForResolution = null; private String declaredSignature = null; - private boolean hasBeenWoven = false; private boolean isGenericType = false; @@ -99,253 +97,263 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { private boolean isAnnotation; private boolean isAnonymous; private boolean isNested; - private boolean isObject = false; // set upon construction - private boolean isAnnotationStyleAspect = false;// set upon construction + private boolean isObject = false; // set upon construction + private boolean isAnnotationStyleAspect = false;// set upon construction private boolean isCodeStyleAspect = false; // not redundant with field above! private int bitflag = 0x0000; - + // discovery bits private static final int DISCOVERED_ANNOTATION_RETENTION_POLICY = 0x0001; - private static final int UNPACKED_GENERIC_SIGNATURE = 0x0002; - private static final int UNPACKED_AJATTRIBUTES = 0x0004; // see note(1) below - private static final int DISCOVERED_ANNOTATION_TARGET_KINDS = 0x0008; - private static final int DISCOVERED_DECLARED_SIGNATURE = 0x0010; - private static final int DISCOVERED_WHETHER_ANNOTATION_STYLE = 0x0020; - private static final int DAMAGED = 0x0040; // see note(2) below - - private static final String[] NO_INTERFACE_SIGS = new String[]{}; - + private static final int UNPACKED_GENERIC_SIGNATURE = 0x0002; + private static final int UNPACKED_AJATTRIBUTES = 0x0004; // see note(1) below + private static final int DISCOVERED_ANNOTATION_TARGET_KINDS = 0x0008; + private static final int DISCOVERED_DECLARED_SIGNATURE = 0x0010; + private static final int DISCOVERED_WHETHER_ANNOTATION_STYLE = 0x0020; + private static final int DAMAGED = 0x0040; // see note(2) below + + private static final String[] NO_INTERFACE_SIGS = new String[] {}; + /* - * Notes: - * note(1): - * in some cases (perclause inheritance) we encounter unpacked state when calling getPerClause + * Notes: note(1): in some cases (perclause inheritance) we encounter unpacked state when calling getPerClause * - * note(2): - * A BcelObjectType is 'damaged' if it has been modified from what was original constructed from - * the bytecode. This currently happens if the parents are modified or an annotation is added - - * ideally BcelObjectType should be immutable but that's a bigger piece of work. XXX + * note(2): A BcelObjectType is 'damaged' if it has been modified from what was original constructed from the bytecode. This + * currently happens if the parents are modified or an annotation is added - ideally BcelObjectType should be immutable but + * that's a bigger piece of work. XXX */ - // ------------------ construction and initialization - - BcelObjectType(ReferenceType resolvedTypeX, JavaClass javaClass, boolean exposedToWeaver) { - super(resolvedTypeX, exposedToWeaver); - this.javaClass = javaClass; - initializeFromJavaclass(); - - //ATAJ: set the delegate right now for @AJ pointcut, else it is done too late to lookup - // @AJ pc refs annotation in class hierarchy - resolvedTypeX.setDelegate(this); - - ISourceContext sourceContext = resolvedTypeX.getSourceContext(); - if (sourceContext==SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) { - sourceContext = new SourceContextImpl(this); - setSourceContext(sourceContext); - } - - // this should only ever be java.lang.Object which is - // the only class in Java-1.4 with no superclasses - isObject = (javaClass.getSuperclassNameIndex() == 0); - ensureAspectJAttributesUnpacked(); -// if (sourceContext instanceof SourceContextImpl) { -// ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.getSourceFileName()); -// } - setSourcefilename(javaClass.getSourceFileName()); - } - - // repeat initialization - public void setJavaClass(JavaClass newclass) { - this.javaClass = newclass; - resetState(); - initializeFromJavaclass(); - } - - private void initializeFromJavaclass() { - isInterface = javaClass.isInterface(); - isEnum = javaClass.isEnum(); - isAnnotation = javaClass.isAnnotation(); - isAnonymous = javaClass.isAnonymous(); - isNested = javaClass.isNested(); - modifiers = javaClass.getModifiers(); - superclassName = javaClass.getSuperclassName(); - className = javaClass.getClassName(); + BcelObjectType(ReferenceType resolvedTypeX, JavaClass javaClass, boolean exposedToWeaver) { + super(resolvedTypeX, exposedToWeaver); + this.javaClass = javaClass; + initializeFromJavaclass(); + + // ATAJ: set the delegate right now for @AJ pointcut, else it is done too late to lookup + // @AJ pc refs annotation in class hierarchy + resolvedTypeX.setDelegate(this); + + ISourceContext sourceContext = resolvedTypeX.getSourceContext(); + if (sourceContext == SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) { + sourceContext = new SourceContextImpl(this); + setSourceContext(sourceContext); + } + + // this should only ever be java.lang.Object which is + // the only class in Java-1.4 with no superclasses + isObject = (javaClass.getSuperclassNameIndex() == 0); + ensureAspectJAttributesUnpacked(); + // if (sourceContext instanceof SourceContextImpl) { + // ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.getSourceFileName()); + // } + setSourcefilename(javaClass.getSourceFileName()); + } + + // repeat initialization + public void setJavaClass(JavaClass newclass) { + this.javaClass = newclass; + resetState(); + initializeFromJavaclass(); + } + + private void initializeFromJavaclass() { + isInterface = javaClass.isInterface(); + isEnum = javaClass.isEnum(); + isAnnotation = javaClass.isAnnotation(); + isAnonymous = javaClass.isAnonymous(); + isNested = javaClass.isNested(); + modifiers = javaClass.getModifiers(); + superclassName = javaClass.getSuperclassName(); + className = javaClass.getClassName(); cachedGenericClassTypeSignature = null; - } - - - - - // --- getters - - // Java related - public boolean isInterface() {return isInterface;} - public boolean isEnum() {return isEnum;} - public boolean isAnnotation() {return isAnnotation;} - public boolean isAnonymous() {return isAnonymous;} - public boolean isNested() {return isNested;} - public int getModifiers() {return modifiers;} - - - - - /** - * Must take into account generic signature - */ - public ResolvedType getSuperclass() { - if (isObject) return null; - ensureGenericSignatureUnpacked(); - if (superclassSignature == null) { - if (superclassName==null) superclassName = javaClass.getSuperclassName(); - superclassSignature = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(superclassName)).getSignature(); - } - World world = getResolvedTypeX().getWorld(); - ResolvedType res = world.resolve(UnresolvedType.forSignature(superclassSignature)); - return res; - } - - public World getWorld() { - return getResolvedTypeX().getWorld(); - } - - /** - * Retrieves the declared interfaces - this allows for the generic signature on a type. If specified - * then the generic signature is used to work out the types - this gets around the results of - * erasure when the class was originally compiled. - */ - public ResolvedType[] getDeclaredInterfaces() { - ensureGenericSignatureUnpacked(); - ResolvedType[] interfaceTypes = null; - if (interfaceSignatures == null) { - String[] names = javaClass.getInterfaceNames(); - if (names.length==0) { - interfaceSignatures = NO_INTERFACE_SIGS; - interfaceTypes = ResolvedType.NONE; - } else { - interfaceSignatures = new String[names.length]; - interfaceTypes = new ResolvedType[names.length]; - for (int i = 0, len = names.length; i < len; i++) { - interfaceTypes[i] = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(names[i])); - interfaceSignatures[i] = interfaceTypes[i].getSignature(); - } - } - } else { - interfaceTypes = new ResolvedType[interfaceSignatures.length]; - for (int i = 0, len = interfaceSignatures.length; i < len; i++) { - interfaceTypes[i] = getResolvedTypeX().getWorld().resolve(UnresolvedType.forSignature(interfaceSignatures[i])); - } - } - - return interfaceTypes; - } - - public ResolvedMember[] getDeclaredMethods() { - ensureGenericSignatureUnpacked(); - if (methods == null) { - Method[] ms = javaClass.getMethods(); + } + + // --- getters + + // Java related + public boolean isInterface() { + return isInterface; + } + + public boolean isEnum() { + return isEnum; + } + + public boolean isAnnotation() { + return isAnnotation; + } + + public boolean isAnonymous() { + return isAnonymous; + } + + public boolean isNested() { + return isNested; + } + + public int getModifiers() { + return modifiers; + } + + /** + * Must take into account generic signature + */ + public ResolvedType getSuperclass() { + if (isObject) + return null; + ensureGenericSignatureUnpacked(); + if (superclassSignature == null) { + if (superclassName == null) + superclassName = javaClass.getSuperclassName(); + superclassSignature = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(superclassName)).getSignature(); + } + World world = getResolvedTypeX().getWorld(); + ResolvedType res = world.resolve(UnresolvedType.forSignature(superclassSignature)); + return res; + } + + public World getWorld() { + return getResolvedTypeX().getWorld(); + } + + /** + * Retrieves the declared interfaces - this allows for the generic signature on a type. If specified then the generic signature + * is used to work out the types - this gets around the results of erasure when the class was originally compiled. + */ + public ResolvedType[] getDeclaredInterfaces() { + ensureGenericSignatureUnpacked(); + ResolvedType[] interfaceTypes = null; + if (interfaceSignatures == null) { + String[] names = javaClass.getInterfaceNames(); + if (names.length == 0) { + interfaceSignatures = NO_INTERFACE_SIGS; + interfaceTypes = ResolvedType.NONE; + } else { + interfaceSignatures = new String[names.length]; + interfaceTypes = new ResolvedType[names.length]; + for (int i = 0, len = names.length; i < len; i++) { + interfaceTypes[i] = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(names[i])); + interfaceSignatures[i] = interfaceTypes[i].getSignature(); + } + } + } else { + interfaceTypes = new ResolvedType[interfaceSignatures.length]; + for (int i = 0, len = interfaceSignatures.length; i < len; i++) { + interfaceTypes[i] = getResolvedTypeX().getWorld().resolve(UnresolvedType.forSignature(interfaceSignatures[i])); + } + } + + return interfaceTypes; + } + + public ResolvedMember[] getDeclaredMethods() { + ensureGenericSignatureUnpacked(); + if (methods == null) { + Method[] ms = javaClass.getMethods(); methods = new ResolvedMember[ms.length]; for (int i = ms.length - 1; i >= 0; i--) { methods[i] = new BcelMethod(this, ms[i]); } - } - return methods; - } - - public ResolvedMember[] getDeclaredFields() { - ensureGenericSignatureUnpacked(); - if (fields == null) { - Field[] fs = javaClass.getFields(); - fields = new ResolvedMember[fs.length]; - for (int i = 0, len = fs.length; i < len; i++) { - fields[i] = new BcelField(this, fs[i]); - } - } - return fields; - } - - - public TypeVariable[] getTypeVariables() { - if (!isGeneric()) return TypeVariable.NONE; - - if (typeVars == null) { - Signature.ClassSignature classSig = getGenericClassTypeSignature();//cachedGenericClassTypeSignature;//javaClass.getGenericClassTypeSignature(); - typeVars = new TypeVariable[classSig.formalTypeParameters.length]; - for (int i = 0; i < typeVars.length; i++) { + } + return methods; + } + + public ResolvedMember[] getDeclaredFields() { + ensureGenericSignatureUnpacked(); + if (fields == null) { + Field[] fs = javaClass.getFields(); + fields = new ResolvedMember[fs.length]; + for (int i = 0, len = fs.length; i < len; i++) { + fields[i] = new BcelField(this, fs[i]); + } + } + return fields; + } + + public TypeVariable[] getTypeVariables() { + if (!isGeneric()) + return TypeVariable.NONE; + + if (typeVars == null) { + Signature.ClassSignature classSig = getGenericClassTypeSignature();// cachedGenericClassTypeSignature;//javaClass. + // getGenericClassTypeSignature(); + typeVars = new TypeVariable[classSig.formalTypeParameters.length]; + for (int i = 0; i < typeVars.length; i++) { Signature.FormalTypeParameter ftp = classSig.formalTypeParameters[i]; try { - typeVars[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable( - ftp, - classSig.formalTypeParameters, - getResolvedTypeX().getWorld()); + typeVars[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable(ftp, + classSig.formalTypeParameters, getResolvedTypeX().getWorld()); } catch (GenericSignatureFormatException e) { // this is a development bug, so fail fast with good info - throw new IllegalStateException( - "While getting the type variables for type " + this.toString() - + " with generic signature " + classSig + - " the following error condition was detected: " + e.getMessage()); + throw new IllegalStateException("While getting the type variables for type " + this.toString() + + " with generic signature " + classSig + " the following error condition was detected: " + + e.getMessage()); } } - } - return typeVars; - } + } + return typeVars; + } - // Aspect related - public Collection getTypeMungers() {return typeMungers;} - public Collection getDeclares() {return declares;} - + public Collection getTypeMungers() { + return typeMungers; + } + + public Collection getDeclares() { + return declares; + } + public Collection getPrivilegedAccesses() { - if (privilegedAccess == null) return Collections.EMPTY_LIST; + if (privilegedAccess == null) + return Collections.EMPTY_LIST; return Arrays.asList(privilegedAccess); } public ResolvedMember[] getDeclaredPointcuts() { - return pointcuts; - } - + return pointcuts; + } - public boolean isAspect() { + public boolean isAspect() { return perClause != null; - } - - /** - * Check if the type is an @AJ aspect (no matter if used from an LTW point of view). - * Such aspects are annotated with @Aspect - * - * @return true for @AJ aspect - */ - public boolean isAnnotationStyleAspect() { - if ((bitflag&DISCOVERED_WHETHER_ANNOTATION_STYLE)==0) { - bitflag|=DISCOVERED_WHETHER_ANNOTATION_STYLE; + } + + /** + * Check if the type is an @AJ aspect (no matter if used from an LTW point of view). Such aspects are annotated with @Aspect + * + * @return true for @AJ aspect + */ + public boolean isAnnotationStyleAspect() { + if ((bitflag & DISCOVERED_WHETHER_ANNOTATION_STYLE) == 0) { + bitflag |= DISCOVERED_WHETHER_ANNOTATION_STYLE; isAnnotationStyleAspect = !isCodeStyleAspect && hasAnnotation(AjcMemberMaker.ASPECT_ANNOTATION); } - return isAnnotationStyleAspect; - } + return isAnnotationStyleAspect; + } - /** - * Process any org.aspectj.weaver attributes stored against the class. - */ + /** + * Process any org.aspectj.weaver attributes stored against the class. + */ private void ensureAspectJAttributesUnpacked() { - if ((bitflag&UNPACKED_AJATTRIBUTES)!=0) return; - bitflag|=UNPACKED_AJATTRIBUTES; + if ((bitflag & UNPACKED_AJATTRIBUTES) != 0) + return; + bitflag |= UNPACKED_AJATTRIBUTES; IMessageHandler msgHandler = getResolvedTypeX().getWorld().getMessageHandler(); // Pass in empty list that can store things for readAj5 to process - List l = BcelAttributes.readAjAttributes(className,javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld(),AjAttribute.WeaverVersionInfo.UNKNOWN); + List l = BcelAttributes.readAjAttributes(className, javaClass.getAttributes(), getResolvedTypeX().getSourceContext(), + getResolvedTypeX().getWorld(), AjAttribute.WeaverVersionInfo.UNKNOWN); List pointcuts = new ArrayList(); typeMungers = new ArrayList(); declares = new ArrayList(); - processAttributes(l,pointcuts,false); - l = AtAjAttributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), msgHandler,isCodeStyleAspect); - AjAttribute.Aspect deferredAspectAttribute = processAttributes(l,pointcuts,true); - - if (pointcuts.size()==0) { + processAttributes(l, pointcuts, false); + l = AtAjAttributes.readAj5ClassAttributes(javaClass, getResolvedTypeX(), getResolvedTypeX().getSourceContext(), msgHandler, + isCodeStyleAspect); + AjAttribute.Aspect deferredAspectAttribute = processAttributes(l, pointcuts, true); + + if (pointcuts.size() == 0) { this.pointcuts = ResolvedPointcutDefinition.NO_POINTCUTS; } else { - this.pointcuts = (ResolvedPointcutDefinition[]) - pointcuts.toArray(new ResolvedPointcutDefinition[pointcuts.size()]); + this.pointcuts = (ResolvedPointcutDefinition[]) pointcuts.toArray(new ResolvedPointcutDefinition[pointcuts.size()]); } - + resolveAnnotationDeclares(l); if (deferredAspectAttribute != null) { @@ -353,129 +361,128 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { perClause = deferredAspectAttribute.reifyFromAtAspectJ(this.getResolvedTypeX()); } if (isAspect() && !Modifier.isAbstract(getModifiers()) && isGeneric()) { - msgHandler.handleMessage(MessageUtil.error("The generic aspect '"+getResolvedTypeX().getName()+"' must be declared abstract",getResolvedTypeX().getSourceLocation())); + msgHandler.handleMessage(MessageUtil.error("The generic aspect '" + getResolvedTypeX().getName() + + "' must be declared abstract", getResolvedTypeX().getSourceLocation())); } } - - private AjAttribute.Aspect processAttributes(List attributeList, List pointcuts, boolean fromAnnotations) { - AjAttribute.Aspect deferredAspectAttribute = null; + private AjAttribute.Aspect processAttributes(List attributeList, List pointcuts, boolean fromAnnotations) { + AjAttribute.Aspect deferredAspectAttribute = null; for (Iterator iter = attributeList.iterator(); iter.hasNext();) { AjAttribute a = (AjAttribute) iter.next(); - //System.err.println("unpacking: " + this + " and " + a); + // System.err.println("unpacking: " + this + " and " + a); if (a instanceof AjAttribute.Aspect) { if (fromAnnotations) { deferredAspectAttribute = (AjAttribute.Aspect) a; } else { - perClause = ((AjAttribute.Aspect)a).reify(this.getResolvedTypeX()); + perClause = ((AjAttribute.Aspect) a).reify(this.getResolvedTypeX()); isCodeStyleAspect = true; } } else if (a instanceof AjAttribute.PointcutDeclarationAttribute) { - pointcuts.add(((AjAttribute.PointcutDeclarationAttribute)a).reify()); + pointcuts.add(((AjAttribute.PointcutDeclarationAttribute) a).reify()); } else if (a instanceof AjAttribute.WeaverState) { - weaverState = ((AjAttribute.WeaverState)a).reify(); + weaverState = ((AjAttribute.WeaverState) a).reify(); } else if (a instanceof AjAttribute.TypeMunger) { - typeMungers.add(((AjAttribute.TypeMunger)a).reify(getResolvedTypeX().getWorld(), getResolvedTypeX())); + typeMungers.add(((AjAttribute.TypeMunger) a).reify(getResolvedTypeX().getWorld(), getResolvedTypeX())); } else if (a instanceof AjAttribute.DeclareAttribute) { - declares.add(((AjAttribute.DeclareAttribute)a).getDeclare()); + declares.add(((AjAttribute.DeclareAttribute) a).getDeclare()); } else if (a instanceof AjAttribute.PrivilegedAttribute) { - privilegedAccess = ((AjAttribute.PrivilegedAttribute)a).getAccessedMembers(); + privilegedAccess = ((AjAttribute.PrivilegedAttribute) a).getAccessedMembers(); } else if (a instanceof AjAttribute.SourceContextAttribute) { if (getResolvedTypeX().getSourceContext() instanceof SourceContextImpl) { - AjAttribute.SourceContextAttribute sca = (AjAttribute.SourceContextAttribute)a; - ((SourceContextImpl)getResolvedTypeX().getSourceContext()).configureFromAttribute(sca.getSourceFileName(),sca.getLineBreaks()); - + AjAttribute.SourceContextAttribute sca = (AjAttribute.SourceContextAttribute) a; + ((SourceContextImpl) getResolvedTypeX().getSourceContext()).configureFromAttribute(sca.getSourceFileName(), sca + .getLineBreaks()); + setSourcefilename(sca.getSourceFileName()); } } else if (a instanceof AjAttribute.WeaverVersionInfo) { - wvInfo = (AjAttribute.WeaverVersionInfo)a; // Set the weaver version used to build this type + wvInfo = (AjAttribute.WeaverVersionInfo) a; // Set the weaver version used to build this type } else { throw new BCException("bad attribute " + a); } } return deferredAspectAttribute; } - - /** - * Extra processing step needed because declares that come from annotations are not pre-resolved. - * We can't do the resolution until *after* the pointcuts have been resolved. - * @param attributeList - */ - private void resolveAnnotationDeclares(List attributeList) { - FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0]; - IScope bindingScope = new BindingScope( - getResolvedTypeX(), - getResolvedTypeX().getSourceContext(), - bindings - ); + + /** + * Extra processing step needed because declares that come from annotations are not pre-resolved. We can't do the resolution + * until *after* the pointcuts have been resolved. + * + * @param attributeList + */ + private void resolveAnnotationDeclares(List attributeList) { + FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0]; + IScope bindingScope = new BindingScope(getResolvedTypeX(), getResolvedTypeX().getSourceContext(), bindings); for (Iterator iter = attributeList.iterator(); iter.hasNext();) { AjAttribute a = (AjAttribute) iter.next(); if (a instanceof AjAttribute.DeclareAttribute) { - Declare decl = (((AjAttribute.DeclareAttribute)a).getDeclare()); - if (decl instanceof DeclareErrorOrWarning || - decl instanceof DeclarePrecedence) { - decl.resolve(bindingScope); + Declare decl = (((AjAttribute.DeclareAttribute) a).getDeclare()); + if (decl instanceof DeclareErrorOrWarning || decl instanceof DeclarePrecedence) { + decl.resolve(bindingScope); } } - } - } + } + } public PerClause getPerClause() { - ensureAspectJAttributesUnpacked(); + ensureAspectJAttributesUnpacked(); return perClause; } - - public JavaClass getJavaClass() { - return javaClass; - } - - public void ensureDelegateConsistent() { - if ((bitflag&DAMAGED)!=0) {resetState();} - } - - public void resetState() { - if (javaClass == null) { - // we might store the classname and allow reloading? - // At this point we are relying on the world to not evict if it might want to reweave multiple times - throw new BCException("can't weave evicted type"); - } - - bitflag=0x0000; - - this.annotationTypes = null; - this.annotations = null; - this.interfaceSignatures=null; - this.superclassSignature = null; - this.superclassName = null; - this.fields = null; - this.methods = null; - this.pointcuts = null; - this.perClause = null; - this.weaverState = null; - this.lazyClassGen = null; - hasBeenWoven=false; - - isObject = (javaClass.getSuperclassNameIndex() == 0); - isAnnotationStyleAspect=false; - ensureAspectJAttributesUnpacked(); - } - - public void finishedWith() { - // memory usage experiments.... -// this.interfaces = null; -// this.superClass = null; -// this.fields = null; -// this.methods = null; -// this.pointcuts = null; -// this.perClause = null; -// this.weaverState = null; -// this.lazyClassGen = null; - // this next line frees up memory, but need to understand incremental implications - // before leaving it in. -// getResolvedTypeX().setSourceContext(null); - } - + + public JavaClass getJavaClass() { + return javaClass; + } + + public void ensureDelegateConsistent() { + if ((bitflag & DAMAGED) != 0) { + resetState(); + } + } + + public void resetState() { + if (javaClass == null) { + // we might store the classname and allow reloading? + // At this point we are relying on the world to not evict if it might want to reweave multiple times + throw new BCException("can't weave evicted type"); + } + + bitflag = 0x0000; + + this.annotationTypes = null; + this.annotations = null; + this.interfaceSignatures = null; + this.superclassSignature = null; + this.superclassName = null; + this.fields = null; + this.methods = null; + this.pointcuts = null; + this.perClause = null; + this.weaverState = null; + this.lazyClassGen = null; + hasBeenWoven = false; + + isObject = (javaClass.getSuperclassNameIndex() == 0); + isAnnotationStyleAspect = false; + ensureAspectJAttributesUnpacked(); + } + + public void finishedWith() { + // memory usage experiments.... + // this.interfaces = null; + // this.superClass = null; + // this.fields = null; + // this.methods = null; + // this.pointcuts = null; + // this.perClause = null; + // this.weaverState = null; + // this.lazyClassGen = null; + // this next line frees up memory, but need to understand incremental implications + // before leaving it in. + // getResolvedTypeX().setSourceContext(null); + } + public WeaverStateInfo getWeaverState() { return weaverState; } @@ -483,32 +490,32 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { void setWeaverState(WeaverStateInfo weaverState) { this.weaverState = weaverState; } - - public void printWackyStuff(PrintStream out) { - if (typeMungers.size() > 0) out.println(" TypeMungers: " + typeMungers); - if (declares.size() > 0) out.println(" declares: " + declares); - } - - /** - * Return the lazyClassGen associated with this type. For aspect types, this - * value will be cached, since it is used to inline advice. For non-aspect - * types, this lazyClassGen is always newly constructed. - */ - public LazyClassGen getLazyClassGen() { - LazyClassGen ret = lazyClassGen; - if (ret == null) { - //System.err.println("creating lazy class gen for: " + this); - ret = new LazyClassGen(this); - //ret.print(System.err); - //System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName ); - if (isAspect()) { - lazyClassGen = ret; - } - } - return ret; - } - - + + public void printWackyStuff(PrintStream out) { + if (typeMungers.size() > 0) + out.println(" TypeMungers: " + typeMungers); + if (declares.size() > 0) + out.println(" declares: " + declares); + } + + /** + * Return the lazyClassGen associated with this type. For aspect types, this value will be cached, since it is used to inline + * advice. For non-aspect types, this lazyClassGen is always newly constructed. + */ + public LazyClassGen getLazyClassGen() { + LazyClassGen ret = lazyClassGen; + if (ret == null) { + // System.err.println("creating lazy class gen for: " + this); + ret = new LazyClassGen(this); + // ret.print(System.err); + // System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName ); + if (isAspect()) { + lazyClassGen = ret; + } + } + return ret; + } + public boolean isSynthetic() { return getResolvedTypeX().isSynthetic(); } @@ -518,39 +525,40 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { } public void addParent(ResolvedType newParent) { - bitflag|=DAMAGED; + bitflag |= DAMAGED; if (newParent.isClass()) { superclassSignature = newParent.getSignature(); superclassName = newParent.getName(); -// superClass = newParent; + // superClass = newParent; } else { ResolvedType[] oldInterfaceNames = getDeclaredInterfaces(); int exists = -1; for (int i = 0; i < oldInterfaceNames.length; i++) { ResolvedType type = oldInterfaceNames[i]; - if (type.equals(newParent)) {exists = i;break; } + if (type.equals(newParent)) { + exists = i; + break; + } } - if (exists==-1) { - + if (exists == -1) { + int len = interfaceSignatures.length; - String[] newInterfaceSignatures = new String[len+1]; + String[] newInterfaceSignatures = new String[len + 1]; System.arraycopy(interfaceSignatures, 0, newInterfaceSignatures, 0, len); - newInterfaceSignatures[len]=newParent.getSignature(); + newInterfaceSignatures[len] = newParent.getSignature(); interfaceSignatures = newInterfaceSignatures; } } - //System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + superclassName); - //if (lazyClassGen != null) lazyClassGen.print(); + // System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + superclassName); + // if (lazyClassGen != null) lazyClassGen.print(); } - - // -- annotation related public ResolvedType[] getAnnotationTypes() { - ensureAnnotationsUnpacked(); - return annotationTypes; - } + ensureAnnotationsUnpacked(); + return annotationTypes; + } public AnnotationX[] getAnnotations() { ensureAnnotationsUnpacked(); @@ -561,57 +569,59 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { ensureAnnotationsUnpacked(); for (int i = 0; i < annotationTypes.length; i++) { ResolvedType ax = annotationTypes[i]; - if (ax.equals(ofType)) return true; + if (ax.equals(ofType)) + return true; } return false; } - + // evil mutator - adding state not stored in the java class public void addAnnotation(AnnotationX annotation) { - bitflag|=DAMAGED; + bitflag |= DAMAGED; int len = annotations.length; - AnnotationX[] ret = new AnnotationX[len+1]; + AnnotationX[] ret = new AnnotationX[len + 1]; System.arraycopy(annotations, 0, ret, 0, len); ret[len] = annotation; annotations = ret; - + len = annotationTypes.length; - ResolvedType[] ret2 = new ResolvedType[len+1]; - System.arraycopy(annotationTypes,0,ret2,0,len); + ResolvedType[] ret2 = new ResolvedType[len + 1]; + System.arraycopy(annotationTypes, 0, ret2, 0, len); ret2[len] = getResolvedTypeX().getWorld().resolve(UnresolvedType.forName(annotation.getTypeName())); annotationTypes = ret2; } - + public boolean isAnnotationWithRuntimeRetention() { - return (getRetentionPolicy()==null?false:getRetentionPolicy().equals("RUNTIME")); + return (getRetentionPolicy() == null ? false : getRetentionPolicy().equals("RUNTIME")); } - + public String getRetentionPolicy() { - if ((bitflag&DISCOVERED_ANNOTATION_RETENTION_POLICY)==0) { - bitflag|=DISCOVERED_ANNOTATION_RETENTION_POLICY; - retentionPolicy=null; // null means we have no idea + if ((bitflag & DISCOVERED_ANNOTATION_RETENTION_POLICY) == 0) { + bitflag |= DISCOVERED_ANNOTATION_RETENTION_POLICY; + retentionPolicy = null; // null means we have no idea if (isAnnotation()) { ensureAnnotationsUnpacked(); - for (int i = annotations.length-1; i>=0; i--) { + for (int i = annotations.length - 1; i >= 0; i--) { AnnotationX ax = annotations[i]; if (ax.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) { - List values = ax.getBcelAnnotation().getValues(); - for (Iterator it = values.iterator(); it.hasNext();) { - ElementNameValuePairGen element = (ElementNameValuePairGen) it.next(); - EnumElementValueGen v = (EnumElementValueGen)element.getValue(); - retentionPolicy = v.getEnumValueString(); - return retentionPolicy; - } + List values = ax.getBcelAnnotation().getValues(); + for (Iterator it = values.iterator(); it.hasNext();) { + ElementNameValuePairGen element = (ElementNameValuePairGen) it.next(); + EnumElementValueGen v = (EnumElementValueGen) element.getValue(); + retentionPolicy = v.getEnumValueString(); + return retentionPolicy; + } } } } } - return retentionPolicy; + return retentionPolicy; } - + public boolean canAnnotationTargetType() { AnnotationTargetKind[] targetKinds = getAnnotationTargetKinds(); - if (targetKinds == null) return true; + if (targetKinds == null) + return true; for (int i = 0; i < targetKinds.length; i++) { if (targetKinds[i].equals(AnnotationTargetKind.TYPE)) { return true; @@ -619,76 +629,87 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { } return false; } - + public AnnotationTargetKind[] getAnnotationTargetKinds() { - if ((bitflag&DISCOVERED_ANNOTATION_TARGET_KINDS)!=0) return annotationTargetKinds; - bitflag|=DISCOVERED_ANNOTATION_TARGET_KINDS; + if ((bitflag & DISCOVERED_ANNOTATION_TARGET_KINDS) != 0) + return annotationTargetKinds; + bitflag |= DISCOVERED_ANNOTATION_TARGET_KINDS; annotationTargetKinds = null; // null means we have no idea or the @Target annotation hasn't been used List targetKinds = new ArrayList(); if (isAnnotation()) { - AnnotationGen[] annotationsOnThisType = javaClass.getAnnotations(); - for (int i = 0; i < annotationsOnThisType.length; i++) { - AnnotationGen a = annotationsOnThisType[i]; - if (a.getTypeName().equals(UnresolvedType.AT_TARGET.getName())) { - ArrayElementValueGen arrayValue = (ArrayElementValueGen)((ElementNameValuePairGen)a.getValues().get(0)).getValue(); - ElementValueGen[] evs = arrayValue.getElementValuesArray(); - if (evs!=null) { - for (int j = 0; j < evs.length; j++) { - String targetKind = ((EnumElementValueGen)evs[j]).getEnumValueString(); - if (targetKind.equals("ANNOTATION_TYPE")) { targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE); - } else if (targetKind.equals("CONSTRUCTOR")) { targetKinds.add(AnnotationTargetKind.CONSTRUCTOR); - } else if (targetKind.equals("FIELD")) { targetKinds.add(AnnotationTargetKind.FIELD); - } else if (targetKind.equals("LOCAL_VARIABLE")) { targetKinds.add(AnnotationTargetKind.LOCAL_VARIABLE); - } else if (targetKind.equals("METHOD")) { targetKinds.add(AnnotationTargetKind.METHOD); - } else if (targetKind.equals("PACKAGE")) { targetKinds.add(AnnotationTargetKind.PACKAGE); - } else if (targetKind.equals("PARAMETER")) { targetKinds.add(AnnotationTargetKind.PARAMETER); - } else if (targetKind.equals("TYPE")) { targetKinds.add(AnnotationTargetKind.TYPE);} - } + AnnotationGen[] annotationsOnThisType = javaClass.getAnnotations(); + for (int i = 0; i < annotationsOnThisType.length; i++) { + AnnotationGen a = annotationsOnThisType[i]; + if (a.getTypeName().equals(UnresolvedType.AT_TARGET.getName())) { + ArrayElementValueGen arrayValue = (ArrayElementValueGen) ((ElementNameValuePairGen) a.getValues().get(0)) + .getValue(); + ElementValueGen[] evs = arrayValue.getElementValuesArray(); + if (evs != null) { + for (int j = 0; j < evs.length; j++) { + String targetKind = ((EnumElementValueGen) evs[j]).getEnumValueString(); + if (targetKind.equals("ANNOTATION_TYPE")) { + targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE); + } else if (targetKind.equals("CONSTRUCTOR")) { + targetKinds.add(AnnotationTargetKind.CONSTRUCTOR); + } else if (targetKind.equals("FIELD")) { + targetKinds.add(AnnotationTargetKind.FIELD); + } else if (targetKind.equals("LOCAL_VARIABLE")) { + targetKinds.add(AnnotationTargetKind.LOCAL_VARIABLE); + } else if (targetKind.equals("METHOD")) { + targetKinds.add(AnnotationTargetKind.METHOD); + } else if (targetKind.equals("PACKAGE")) { + targetKinds.add(AnnotationTargetKind.PACKAGE); + } else if (targetKind.equals("PARAMETER")) { + targetKinds.add(AnnotationTargetKind.PARAMETER); + } else if (targetKind.equals("TYPE")) { + targetKinds.add(AnnotationTargetKind.TYPE); + } + } } - } - } + } + } if (!targetKinds.isEmpty()) { annotationTargetKinds = new AnnotationTargetKind[targetKinds.size()]; - return (AnnotationTargetKind[]) targetKinds.toArray(annotationTargetKinds); + return (AnnotationTargetKind[]) targetKinds.toArray(annotationTargetKinds); } } return annotationTargetKinds; } - + // --- unpacking methods - + private void ensureAnnotationsUnpacked() { if (annotationTypes == null) { - AnnotationGen annos[] = javaClass.getAnnotations(); - if (annos==null || annos.length==0) { - annotationTypes = ResolvedType.NONE; - annotations = AnnotationX.NONE; - } else { - World w = getResolvedTypeX().getWorld(); - annotationTypes = new ResolvedType[annos.length]; - annotations = new AnnotationX[annos.length]; - for (int i = 0; i < annos.length; i++) { + AnnotationGen annos[] = javaClass.getAnnotations(); + if (annos == null || annos.length == 0) { + annotationTypes = ResolvedType.NONE; + annotations = AnnotationX.NONE; + } else { + World w = getResolvedTypeX().getWorld(); + annotationTypes = new ResolvedType[annos.length]; + annotations = new AnnotationX[annos.length]; + for (int i = 0; i < annos.length; i++) { AnnotationGen annotation = annos[i]; annotationTypes[i] = w.resolve(UnresolvedType.forSignature(annotation.getTypeSignature())); - annotations[i] = new AnnotationX(annotation,w); + annotations[i] = new AnnotationX(annotation, w); } - } - } + } + } } - - // --- + // --- public String getDeclaredGenericSignature() { ensureGenericInfoProcessed(); return declaredSignature; } - - + private void ensureGenericSignatureUnpacked() { - if ((bitflag&UNPACKED_GENERIC_SIGNATURE)!=0) return; - bitflag|=UNPACKED_GENERIC_SIGNATURE; - if (!getResolvedTypeX().getWorld().isInJava5Mode()) return; + if ((bitflag & UNPACKED_GENERIC_SIGNATURE) != 0) + return; + bitflag |= UNPACKED_GENERIC_SIGNATURE; + if (!getResolvedTypeX().getWorld().isInJava5Mode()) + return; Signature.ClassSignature cSig = getGenericClassTypeSignature(); if (cSig != null) { formalsForResolution = cSig.formalTypeParameters; @@ -709,46 +730,41 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { } Signature.ClassTypeSignature superSig = cSig.superclassSignature; try { -// this.superClass = -// BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( -// superSig, formalsForResolution, getResolvedTypeX().getWorld()); - - ResolvedType rt = - BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( - superSig, formalsForResolution, getResolvedTypeX().getWorld()); + // this.superClass = + // BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( + // superSig, formalsForResolution, getResolvedTypeX().getWorld()); + + ResolvedType rt = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(superSig, formalsForResolution, + getResolvedTypeX().getWorld()); this.superclassSignature = rt.getSignature(); this.superclassName = rt.getName(); - + } catch (GenericSignatureFormatException e) { // development bug, fail fast with good info - throw new IllegalStateException( - "While determining the generic superclass of " + this.className - + " with generic signature " + getDeclaredGenericSignature()+ " the following error was detected: " + throw new IllegalStateException("While determining the generic superclass of " + this.className + + " with generic signature " + getDeclaredGenericSignature() + " the following error was detected: " + e.getMessage()); } -// this.interfaces = new ResolvedType[cSig.superInterfaceSignatures.length]; - if (cSig.superInterfaceSignatures.length==0) { + // this.interfaces = new ResolvedType[cSig.superInterfaceSignatures.length]; + if (cSig.superInterfaceSignatures.length == 0) { this.interfaceSignatures = NO_INTERFACE_SIGS; } else { this.interfaceSignatures = new String[cSig.superInterfaceSignatures.length]; for (int i = 0; i < cSig.superInterfaceSignatures.length; i++) { try { - // this.interfaces[i] = - // BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( - // cSig.superInterfaceSignatures[i], - // formalsForResolution, - // getResolvedTypeX().getWorld()); - this.interfaceSignatures[i] = - BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( - cSig.superInterfaceSignatures[i], - formalsForResolution, - getResolvedTypeX().getWorld()).getSignature(); + // this.interfaces[i] = + // BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( + // cSig.superInterfaceSignatures[i], + // formalsForResolution, + // getResolvedTypeX().getWorld()); + this.interfaceSignatures[i] = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( + cSig.superInterfaceSignatures[i], formalsForResolution, getResolvedTypeX().getWorld()) + .getSignature(); } catch (GenericSignatureFormatException e) { // development bug, fail fast with good info - throw new IllegalStateException( - "While determing the generic superinterfaces of " + this.className - + " with generic signature " + getDeclaredGenericSignature() +" the following error was detected: " - + e.getMessage()); + throw new IllegalStateException("While determing the generic superinterfaces of " + this.className + + " with generic signature " + getDeclaredGenericSignature() + + " the following error was detected: " + e.getMessage()); } } } @@ -756,12 +772,12 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { if (isGeneric()) { // update resolved typex to point at generic type not raw type. ReferenceType genericType = (ReferenceType) this.resolvedTypeX.getGenericType(); - //genericType.setSourceContext(this.resolvedTypeX.getSourceContext()); + // genericType.setSourceContext(this.resolvedTypeX.getSourceContext()); genericType.setStartPos(this.resolvedTypeX.getStartPos()); this.resolvedTypeX = genericType; } } - + public Signature.FormalTypeParameter[] getAllFormals() { ensureGenericSignatureUnpacked(); if (formalsForResolution == null) { @@ -770,42 +786,44 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { return formalsForResolution; } } - - + public ResolvedType getOuterClass() { - if (!isNested()) throw new IllegalStateException("Can't get the outer class of a non-nested type"); + if (!isNested()) + throw new IllegalStateException("Can't get the outer class of a non-nested type"); int lastDollar = className.lastIndexOf('$'); - String superClassName = className.substring(0,lastDollar); + String superClassName = className.substring(0, lastDollar); UnresolvedType outer = UnresolvedType.forName(superClassName); return outer.resolve(getResolvedTypeX().getWorld()); } - - - private void ensureGenericInfoProcessed() { - if ((bitflag & DISCOVERED_DECLARED_SIGNATURE)!=0) return; + + private void ensureGenericInfoProcessed() { + if ((bitflag & DISCOVERED_DECLARED_SIGNATURE) != 0) + return; bitflag |= DISCOVERED_DECLARED_SIGNATURE; Signature sigAttr = AttributeUtils.getSignatureAttribute(javaClass.getAttributes()); - declaredSignature = (sigAttr==null?null:sigAttr.getSignature()); - if (declaredSignature!=null) isGenericType= (declaredSignature.charAt(0)=='<'); + declaredSignature = (sigAttr == null ? null : sigAttr.getSignature()); + if (declaredSignature != null) + isGenericType = (declaredSignature.charAt(0) == '<'); } - + public boolean isGeneric() { - ensureGenericInfoProcessed(); - return isGenericType; + ensureGenericInfoProcessed(); + return isGenericType; } - + public String toString() { - return (javaClass==null?"BcelObjectType":"BcelObjectTypeFor:"+className); + return (javaClass == null ? "BcelObjectType" : "BcelObjectTypeFor:" + className); } - + // --- state management - + public void evictWeavingState() { - // Can't chuck all this away - if (getResolvedTypeX().getWorld().couldIncrementalCompileFollow()) return; - + // Can't chuck all this away + if (getResolvedTypeX().getWorld().couldIncrementalCompileFollow()) + return; + if (javaClass != null) { - // Force retrieval of any lazy information + // Force retrieval of any lazy information ensureAnnotationsUnpacked(); ensureGenericInfoProcessed(); @@ -813,72 +831,75 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { getDeclaredFields(); getDeclaredMethods(); // The lazyClassGen is preserved for aspects - it exists to enable around advice - // inlining since the method will need 'injecting' into the affected class. If + // inlining since the method will need 'injecting' into the affected class. If // XnoInline is on, we can chuck away the lazyClassGen since it won't be required // later. - if (getResolvedTypeX().getWorld().isXnoInline()) lazyClassGen=null; - + if (getResolvedTypeX().getWorld().isXnoInline()) + lazyClassGen = null; + // discard expensive bytecode array containing reweavable info if (weaverState != null) { weaverState.setReweavable(false); weaverState.setUnwovenClassFileData(null); } - for (int i = methods.length - 1; i >= 0; i--) methods[i].evictWeavingState(); - for (int i = fields.length - 1; i >= 0; i--) fields[i].evictWeavingState(); + for (int i = methods.length - 1; i >= 0; i--) + methods[i].evictWeavingState(); + for (int i = fields.length - 1; i >= 0; i--) + fields[i].evictWeavingState(); javaClass = null; -// setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); // bit naughty -// interfaces=null; // force reinit - may get us the right instances! -// superClass=null; + // setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); // bit naughty + // interfaces=null; // force reinit - may get us the right instances! + // superClass=null; } } - + public void weavingCompleted() { hasBeenWoven = true; - if (getResolvedTypeX().getWorld().isRunMinimalMemory()) evictWeavingState(); - if (getSourceContext()!=null && !getResolvedTypeX().isAspect()) getSourceContext().tidy(); + if (getResolvedTypeX().getWorld().isRunMinimalMemory()) + evictWeavingState(); + if (getSourceContext() != null && !getResolvedTypeX().isAspect()) + getSourceContext().tidy(); } - + // --- methods for testing + // for testing - if we have this attribute, return it - will return null if it doesnt know anything + // public AjAttribute[] getAttributes(String name) { + // List results = new ArrayList(); + // List l = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), + // getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld(),AjAttribute.WeaverVersionInfo.UNKNOWN); + // for (Iterator iter = l.iterator(); iter.hasNext();) { + // AjAttribute element = (AjAttribute) iter.next(); + // if (element.getNameString().equals(name)) results.add(element); + // } + // if (results.size()>0) { + // return (AjAttribute[])results.toArray(new AjAttribute[]{}); + // } + // return null; + // } + // + // // for testing - use with the method above - this returns *all* including those that are not Aj attributes + // public String[] getAttributeNames() { + // Attribute[] as = javaClass.getAttributes(); + // String[] strs = new String[as.length]; + // for (int j = 0; j < as.length; j++) { + // strs[j] = as[j].getName(); + // } + // return strs; + // } - // for testing - if we have this attribute, return it - will return null if it doesnt know anything - public AjAttribute[] getAttributes(String name) { - List results = new ArrayList(); - List l = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld(),AjAttribute.WeaverVersionInfo.UNKNOWN); - for (Iterator iter = l.iterator(); iter.hasNext();) { - AjAttribute element = (AjAttribute) iter.next(); - if (element.getNameString().equals(name)) results.add(element); - } - if (results.size()>0) { - return (AjAttribute[])results.toArray(new AjAttribute[]{}); - } - return null; - } - - // for testing - use with the method above - this returns *all* including those that are not Aj attributes - public String[] getAttributeNames() { - Attribute[] as = javaClass.getAttributes(); - String[] strs = new String[as.length]; - for (int j = 0; j < as.length; j++) { - strs[j] = as[j].getName(); - } - return strs; - } - // for testing public void addPointcutDefinition(ResolvedPointcutDefinition d) { - bitflag|=DAMAGED; + bitflag |= DAMAGED; int len = pointcuts.length; - ResolvedPointcutDefinition[] ret = new ResolvedPointcutDefinition[len+1]; + ResolvedPointcutDefinition[] ret = new ResolvedPointcutDefinition[len + 1]; System.arraycopy(pointcuts, 0, ret, 0, len); ret[len] = d; pointcuts = ret; } - - public boolean hasBeenWoven() { + + public boolean hasBeenWoven() { return hasBeenWoven; } - -} - -
\ No newline at end of file + +} diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java index 421c3e700..346f2c1f4 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java @@ -11,26 +11,21 @@ * Alexandre Vasseur perClause support for @AJ aspects * ******************************************************************/ - package org.aspectj.weaver.bcel; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Properties; import java.util.StringTokenizer; import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.ClassParser; import org.aspectj.apache.bcel.classfile.ConstantPool; import org.aspectj.apache.bcel.classfile.JavaClass; import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; import org.aspectj.apache.bcel.generic.FieldInstruction; import org.aspectj.apache.bcel.generic.INVOKEINTERFACE; import org.aspectj.apache.bcel.generic.Instruction; @@ -65,7 +60,6 @@ import org.aspectj.weaver.ResolvedTypeMunger; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.WeakClassLoaderReference; import org.aspectj.weaver.World; -import org.aspectj.weaver.AjAttribute.Aspect; import org.aspectj.weaver.patterns.DeclareAnnotation; import org.aspectj.weaver.patterns.DeclareParents; import org.aspectj.weaver.patterns.PerClause; @@ -76,459 +70,408 @@ import org.aspectj.weaver.tools.TraceFactory; public class BcelWorld extends World implements Repository { private ClassPathManager classPath; - protected Repository delegate; - private WeakClassLoaderReference loaderRef; - - - //private ClassPathManager aspectPath = null; + protected Repository delegate; + private WeakClassLoaderReference loaderRef; + + // private ClassPathManager aspectPath = null; // private List aspectPathEntries; - private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWorld.class); - - // ---- constructors + private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWorld.class); + + // ---- constructors public BcelWorld() { - this(""); + this(""); } - + public BcelWorld(String cp) { this(makeDefaultClasspath(cp), IMessageHandler.THROW, null); } - + private static List makeDefaultClasspath(String cp) { List classPath = new ArrayList(); classPath.addAll(getPathEntries(cp)); classPath.addAll(getPathEntries(ClassPath.getClassPath())); - //System.err.println("classpath: " + classPath); + // System.err.println("classpath: " + classPath); return classPath; - + } - + private static List getPathEntries(String s) { List ret = new ArrayList(); StringTokenizer tok = new StringTokenizer(s, File.pathSeparator); - while(tok.hasMoreTokens()) ret.add(tok.nextToken()); - - return ret; + while (tok.hasMoreTokens()) + ret.add(tok.nextToken()); + + return ret; } - + public BcelWorld(List classPath, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { - //this.aspectPath = new ClassPathManager(aspectPath, handler); + // this.aspectPath = new ClassPathManager(aspectPath, handler); this.classPath = new ClassPathManager(classPath, handler); - setMessageHandler(handler); + setMessageHandler(handler); setCrossReferenceHandler(xrefHandler); // Tell BCEL to use us for resolving any classes - delegate = this; + delegate = this; // TODO Alex do we need to call org.aspectj.apache.bcel.Repository.setRepository(delegate); - // if so, how can that be safe in J2EE ?? (static stuff in Bcel) + // if so, how can that be safe in J2EE ?? (static stuff in Bcel) } - + public BcelWorld(ClassPathManager cpm, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { this.classPath = cpm; setMessageHandler(handler); setCrossReferenceHandler(xrefHandler); // Tell BCEL to use us for resolving any classes - delegate = this; - // TODO Alex do we need to call org.aspectj.apache.bcel.Repository.setRepository(delegate); - // if so, how can that be safe in J2EE ?? (static stuff in Bcel) - } - - /** - * Build a World from a ClassLoader, for LTW support - * - * @param loader - * @param handler - * @param xrefHandler - */ - public BcelWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { - this.classPath = null; - this.loaderRef = new WeakClassLoaderReference(loader); - setMessageHandler(handler); - setCrossReferenceHandler(xrefHandler); - // Tell BCEL to use us for resolving any classes - // delegate = getClassLoaderRepositoryFor(loader); - } - - public void ensureRepositorySetup() { - if (delegate==null) { - delegate = getClassLoaderRepositoryFor(loaderRef); - } - } - - public Repository getClassLoaderRepositoryFor(ClassLoaderReference loader) { - if (bcelRepositoryCaching) { - return new ClassLoaderRepository(loader); - } else { - return new NonCachingClassLoaderRepository(loader); - } - } - - public void addPath (String name) { + delegate = this; + // TODO Alex do we need to call org.aspectj.apache.bcel.Repository.setRepository(delegate); + // if so, how can that be safe in J2EE ?? (static stuff in Bcel) + } + + /** + * Build a World from a ClassLoader, for LTW support + * + * @param loader + * @param handler + * @param xrefHandler + */ + public BcelWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { + this.classPath = null; + this.loaderRef = new WeakClassLoaderReference(loader); + setMessageHandler(handler); + setCrossReferenceHandler(xrefHandler); + // Tell BCEL to use us for resolving any classes + // delegate = getClassLoaderRepositoryFor(loader); + } + + public void ensureRepositorySetup() { + if (delegate == null) { + delegate = getClassLoaderRepositoryFor(loaderRef); + } + } + + public Repository getClassLoaderRepositoryFor(ClassLoaderReference loader) { + if (bcelRepositoryCaching) { + return new ClassLoaderRepository(loader); + } else { + return new NonCachingClassLoaderRepository(loader); + } + } + + public void addPath(String name) { classPath.addPath(name, this.getMessageHandler()); } - // ---- various interactions with bcel - - public static Type makeBcelType(UnresolvedType type) { - return Type.getType(type.getErasureSignature()); - } - - static Type[] makeBcelTypes(UnresolvedType[] types) { - Type[] ret = new Type[types.length]; - for (int i = 0, len = types.length; i < len; i++) { - ret[i] = makeBcelType(types[i]); - } - return ret; - } - - static String[] makeBcelTypesAsClassNames(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; - } - - public static UnresolvedType fromBcel(Type t) { - return UnresolvedType.forSignature(t.getSignature()); - } - - static UnresolvedType[] fromBcel(Type[] ts) { - UnresolvedType[] ret = new UnresolvedType[ts.length]; - for (int i = 0, len = ts.length; i < len; i++) { - ret[i] = fromBcel(ts[i]); - } - return ret; - } - - public ResolvedType resolve(Type t) { - return resolve(fromBcel(t)); - } - - // SECRETAPI: used for testing ASM loading of delegates... - public boolean fallbackToLoadingBcelDelegatesForAspects = true; - - private int packageRestrictionsForFastDelegates = 0; // 0=dontknow 1=no 2=yes - private List packagePrefixRestrictionList = null; - - public boolean isNotOnPackageRestrictedList(String s) { - if (packageRestrictionsForFastDelegates==0) { - Properties p = getExtraConfiguration(); - String possiblePackageRestrictions = (p==null?null:p.getProperty("fastDelegateRestrictions")); - if (possiblePackageRestrictions==null) { - packageRestrictionsForFastDelegates=1; - } else { - packageRestrictionsForFastDelegates=2; - packagePrefixRestrictionList=new ArrayList(); - StringTokenizer st = new StringTokenizer(possiblePackageRestrictions,":"); - while (st.hasMoreTokens()) { - packagePrefixRestrictionList.add(st.nextToken()); - } - } - } - if (packageRestrictionsForFastDelegates==1) return true; - if (packageRestrictionsForFastDelegates==2) { - for (Iterator iter = packagePrefixRestrictionList.iterator(); iter.hasNext();) { - String element = (String) iter.next(); - if (s.startsWith(element)) { -// System.err.println("Not creating fast delegate for "+s); - return false; - } - } - } - return true; - } + // ---- various interactions with bcel + + public static Type makeBcelType(UnresolvedType type) { + return Type.getType(type.getErasureSignature()); + } + + static Type[] makeBcelTypes(UnresolvedType[] types) { + Type[] ret = new Type[types.length]; + for (int i = 0, len = types.length; i < len; i++) { + ret[i] = makeBcelType(types[i]); + } + return ret; + } + + static String[] makeBcelTypesAsClassNames(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; + } + + public static UnresolvedType fromBcel(Type t) { + return UnresolvedType.forSignature(t.getSignature()); + } + + static UnresolvedType[] fromBcel(Type[] ts) { + UnresolvedType[] ret = new UnresolvedType[ts.length]; + for (int i = 0, len = ts.length; i < len; i++) { + ret[i] = fromBcel(ts[i]); + } + return ret; + } + + public ResolvedType resolve(Type t) { + return resolve(fromBcel(t)); + } protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { - String name = ty.getName(); - ensureAdvancedConfigurationProcessed(); - JavaClass jc = lookupJavaClass(classPath, name); - if (jc == null) { - return null; - } else { - return buildBcelDelegate(ty, jc, false); - } - } - + String name = ty.getName(); + ensureAdvancedConfigurationProcessed(); + JavaClass jc = lookupJavaClass(classPath, name); + if (jc == null) { + return null; + } else { + return buildBcelDelegate(ty, jc, false); + } + } + public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX, JavaClass jc, boolean exposedToWeaver) { BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, exposedToWeaver); return ret; } - - + private JavaClass lookupJavaClass(ClassPathManager classPath, String name) { - if (classPath == null) { - try { - ensureRepositorySetup(); - JavaClass jc = delegate.loadClass(name); - if (trace.isTraceEnabled()) trace.event("lookupJavaClass",this,new Object[] { name, jc }); - return jc; - } catch (ClassNotFoundException e) { - if (trace.isTraceEnabled()) trace.error("Unable to find class '"+name+"' in repository",e); - return null; - } - } + if (classPath == null) { + try { + ensureRepositorySetup(); + JavaClass jc = delegate.loadClass(name); + if (trace.isTraceEnabled()) + trace.event("lookupJavaClass", this, new Object[] { name, jc }); + return jc; + } catch (ClassNotFoundException e) { + if (trace.isTraceEnabled()) + trace.error("Unable to find class '" + name + "' in repository", e); + return null; + } + } try { - ClassPathManager.ClassFile file = classPath.find(UnresolvedType.forName(name)); - if (file == null) return null; - - ClassParser parser = new ClassParser(file.getInputStream(), file.getPath()); - - JavaClass jc = parser.parse(); + ClassPathManager.ClassFile file = classPath.find(UnresolvedType.forName(name)); + if (file == null) + return null; + + ClassParser parser = new ClassParser(file.getInputStream(), file.getPath()); + + JavaClass jc = parser.parse(); file.close(); return jc; } catch (IOException ioe) { return null; } } - - + public BcelObjectType addSourceObjectType(JavaClass jc) { BcelObjectType ret = null; String signature = UnresolvedType.forName(jc.getClassName()).getSignature(); - + Object fromTheMap = typeMap.get(signature); - - if (fromTheMap!=null && !(fromTheMap instanceof ReferenceType)) { + + if (fromTheMap != null && !(fromTheMap instanceof ReferenceType)) { // what on earth is it then? See pr 112243 StringBuffer exceptionText = new StringBuffer(); exceptionText.append("Found invalid (not a ReferenceType) entry in the type map. "); - exceptionText.append("Signature=["+signature+"] Found=["+fromTheMap+"] Class=["+fromTheMap.getClass()+"]"); + exceptionText.append("Signature=[" + signature + "] Found=[" + fromTheMap + "] Class=[" + fromTheMap.getClass() + "]"); throw new BCException(exceptionText.toString()); } - - ReferenceType nameTypeX = (ReferenceType)fromTheMap; - - if (nameTypeX == null) { - if (jc.isGeneric() && isInJava5Mode()) { - - nameTypeX = ReferenceType.fromTypeX(UnresolvedType.forRawTypeName(jc.getClassName()),this); - ret = buildBcelDelegate(nameTypeX, jc, true); - ReferenceType genericRefType = new ReferenceType( - UnresolvedType.forGenericTypeSignature(signature,ret.getDeclaredGenericSignature()),this); + + ReferenceType nameTypeX = (ReferenceType) fromTheMap; + + if (nameTypeX == null) { + if (jc.isGeneric() && isInJava5Mode()) { + + nameTypeX = ReferenceType.fromTypeX(UnresolvedType.forRawTypeName(jc.getClassName()), this); + ret = buildBcelDelegate(nameTypeX, jc, true); + ReferenceType genericRefType = new ReferenceType(UnresolvedType.forGenericTypeSignature(signature, ret + .getDeclaredGenericSignature()), this); nameTypeX.setDelegate(ret); - genericRefType.setDelegate(ret); - nameTypeX.setGenericType(genericRefType); - typeMap.put(signature, nameTypeX); - } else { - nameTypeX = new ReferenceType(signature, this); - ret = buildBcelDelegate(nameTypeX, jc, true); - typeMap.put(signature, nameTypeX); - } - } else { - ret = buildBcelDelegate(nameTypeX, jc, true); - } + genericRefType.setDelegate(ret); + nameTypeX.setGenericType(genericRefType); + typeMap.put(signature, nameTypeX); + } else { + nameTypeX = new ReferenceType(signature, this); + ret = buildBcelDelegate(nameTypeX, jc, true); + typeMap.put(signature, nameTypeX); + } + } else { + ret = buildBcelDelegate(nameTypeX, jc, true); + } return ret; } - + void deleteSourceObjectType(UnresolvedType ty) { typeMap.remove(ty.getSignature()); } - public static Member makeFieldJoinPointSignature(LazyClassGen cg, FieldInstruction fi) { - ConstantPool cpg = cg.getConstantPool(); - return - MemberImpl.field( - fi.getClassName(cpg), - (fi.opcode==Constants.GETSTATIC || fi.opcode==Constants.PUTSTATIC) - ? Modifier.STATIC: 0, - fi.getName(cpg), - fi.getSignature(cpg)); - } + public static Member makeFieldJoinPointSignature(LazyClassGen cg, FieldInstruction fi) { + ConstantPool cpg = cg.getConstantPool(); + return MemberImpl.field(fi.getClassName(cpg), + (fi.opcode == Constants.GETSTATIC || fi.opcode == Constants.PUTSTATIC) ? Modifier.STATIC : 0, fi.getName(cpg), fi + .getSignature(cpg)); + } - public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberKind kind) { Member ret = mg.getMemberView(); if (ret == null) { - int mods = mg.getAccessFlags(); - if (mg.getEnclosingClass().isInterface()) { - mods |= Modifier.INTERFACE; - } - return new ResolvedMemberImpl(kind, - UnresolvedType.forName(mg.getClassName()), - mods, - fromBcel(mg.getReturnType()), - mg.getName(), - fromBcel(mg.getArgumentTypes()) - ); + int mods = mg.getAccessFlags(); + if (mg.getEnclosingClass().isInterface()) { + mods |= Modifier.INTERFACE; + } + return new ResolvedMemberImpl(kind, UnresolvedType.forName(mg.getClassName()), mods, fromBcel(mg.getReturnType()), mg + .getName(), fromBcel(mg.getArgumentTypes())); } else { return ret; } - - } - - public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg,InstructionHandle h) { + + } + + public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg, InstructionHandle h) { return MemberImpl.monitorEnter(); } - public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg,InstructionHandle h) { + public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg, InstructionHandle h) { return MemberImpl.monitorExit(); } - + public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg, InstructionHandle handle) { Instruction i = handle.getInstruction(); ConstantPool cpg = cg.getConstantPool(); Member retval = null; - if (i.opcode==Constants.ANEWARRAY) { -// ANEWARRAY arrayInstruction = (ANEWARRAY)i; + if (i.opcode == Constants.ANEWARRAY) { + // ANEWARRAY arrayInstruction = (ANEWARRAY)i; Type ot = i.getType(cpg); UnresolvedType ut = fromBcel(ot); - ut = UnresolvedType.makeArray(ut,1); - retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", new ResolvedType[]{ResolvedType.INT}); + ut = UnresolvedType.makeArray(ut, 1); + retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", new ResolvedType[] { ResolvedType.INT }); } else if (i instanceof MULTIANEWARRAY) { - MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY)i; + MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY) i; UnresolvedType ut = null; short dimensions = arrayInstruction.getDimensions(); ObjectType ot = arrayInstruction.getLoadClassType(cpg); - if (ot!=null) { + if (ot != null) { ut = fromBcel(ot); - ut = UnresolvedType.makeArray(ut,dimensions); + ut = UnresolvedType.makeArray(ut, dimensions); } else { Type t = arrayInstruction.getType(cpg); ut = fromBcel(t); } ResolvedType[] parms = new ResolvedType[dimensions]; - for (int ii=0;ii<dimensions;ii++) parms[ii] = ResolvedType.INT; + for (int ii = 0; ii < dimensions; ii++) + parms[ii] = ResolvedType.INT; retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", parms); - - } else if (i.opcode==Constants.NEWARRAY) { -// NEWARRAY arrayInstruction = (NEWARRAY)i; + + } else if (i.opcode == Constants.NEWARRAY) { + // NEWARRAY arrayInstruction = (NEWARRAY)i; Type ot = i.getType(); UnresolvedType ut = fromBcel(ot); - retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", new ResolvedType[]{ResolvedType.INT}); + retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "<init>", new ResolvedType[] { ResolvedType.INT }); } else { - throw new BCException("Cannot create array construction signature for this non-array instruction:"+i); + throw new BCException("Cannot create array construction signature for this non-array instruction:" + i); } return retval; } - public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, InvokeInstruction ii) { - ConstantPool cpg = cg.getConstantPool(); - String name = ii.getName(cpg); - String declaring = ii.getClassName(cpg); - UnresolvedType declaringType = null; - - String signature = ii.getSignature(cpg); - - int modifier = - (ii instanceof INVOKEINTERFACE) - ? Modifier.INTERFACE - : (ii.opcode==Constants.INVOKESTATIC) - ? Modifier.STATIC - : (ii.opcode==Constants.INVOKESPECIAL && ! name.equals("<init>")) - ? Modifier.PRIVATE - : 0; - - // in Java 1.4 and after, static method call of super class within subclass method appears - // as declared by the subclass in the bytecode - but they are not - // see #104212 - if (ii.opcode==Constants.INVOKESTATIC) { - ResolvedType appearsDeclaredBy = resolve(declaring); - // look for the method there - for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator.hasNext();) { - ResolvedMember method = (ResolvedMember) iterator.next(); - if (method.isStatic()) { - if (name.equals(method.getName()) && signature.equals(method.getSignature())) { - // we found it - declaringType = method.getDeclaringType(); - break; - } - } - - } - } - - if (declaringType == null) { - if (declaring.charAt(0)=='[') declaringType = UnresolvedType.forSignature(declaring); - else declaringType = UnresolvedType.forName(declaring); - } - return MemberImpl.method(declaringType, modifier, name, signature); - } - - public static Member makeMungerMethodSignature(JavaClass javaClass, Method method) { - int mods = 0; - if (method.isStatic()) mods = Modifier.STATIC; - else if (javaClass.isInterface()) mods = Modifier.INTERFACE; - else if (method.isPrivate()) mods = Modifier.PRIVATE; - return MemberImpl.method( - UnresolvedType.forName(javaClass.getClassName()), mods, method.getName(), method.getSignature()); - } - + public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, InvokeInstruction ii) { + ConstantPool cpg = cg.getConstantPool(); + String name = ii.getName(cpg); + String declaring = ii.getClassName(cpg); + UnresolvedType declaringType = null; + + String signature = ii.getSignature(cpg); + + int modifier = (ii instanceof INVOKEINTERFACE) ? Modifier.INTERFACE + : (ii.opcode == Constants.INVOKESTATIC) ? Modifier.STATIC : (ii.opcode == Constants.INVOKESPECIAL && !name + .equals("<init>")) ? Modifier.PRIVATE : 0; + + // in Java 1.4 and after, static method call of super class within subclass method appears + // as declared by the subclass in the bytecode - but they are not + // see #104212 + if (ii.opcode == Constants.INVOKESTATIC) { + ResolvedType appearsDeclaredBy = resolve(declaring); + // look for the method there + for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator.hasNext();) { + ResolvedMember method = (ResolvedMember) iterator.next(); + if (method.isStatic()) { + if (name.equals(method.getName()) && signature.equals(method.getSignature())) { + // we found it + declaringType = method.getDeclaringType(); + break; + } + } + + } + } + + if (declaringType == null) { + if (declaring.charAt(0) == '[') + declaringType = UnresolvedType.forSignature(declaring); + else + declaringType = UnresolvedType.forName(declaring); + } + return MemberImpl.method(declaringType, modifier, name, signature); + } + + public static Member makeMungerMethodSignature(JavaClass javaClass, Method method) { + int mods = 0; + if (method.isStatic()) + mods = Modifier.STATIC; + else if (javaClass.isInterface()) + mods = Modifier.INTERFACE; + else if (method.isPrivate()) + mods = Modifier.PRIVATE; + return MemberImpl.method(UnresolvedType.forName(javaClass.getClassName()), mods, method.getName(), method.getSignature()); + } + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("BcelWorld("); - //buf.append(shadowMungerMap); + // buf.append(shadowMungerMap); buf.append(")"); return buf.toString(); } - public Advice createAdviceMunger( - AjAttribute.AdviceAttribute attribute, - Pointcut pointcut, - Member signature) - { - //System.err.println("concrete advice: " + signature + " context " + sourceContext); - return new BcelAdvice(attribute, pointcut, signature, null); - } - - public ConcreteTypeMunger concreteTypeMunger( - ResolvedTypeMunger munger, ResolvedType aspectType) - { - return new BcelTypeMunger(munger, aspectType); - } - + public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature) { + // System.err.println("concrete advice: " + signature + " context " + sourceContext); + return new BcelAdvice(attribute, pointcut, signature, null); + } + + public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) { + return new BcelTypeMunger(munger, aspectType); + } + public ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField) { return new BcelCflowStackFieldAdder(cflowField); } - + public ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField) { return new BcelCflowCounterFieldAdder(cflowField); } - /** - * Register a munger for perclause @AJ aspect so that we add aspectOf(..) to them as needed - * - * @param aspect - * @param kind - * @return munger - */ - public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind) { - return new BcelPerClauseAspectAdder(aspect, kind); - } - - /** - * Retrieve a bcel delegate for an aspect - this will return NULL if the - * delegate is an EclipseSourceType and not a BcelObjectType - this happens - * quite often when incrementally compiling. - */ + /** + * Register a munger for perclause @AJ aspect so that we add aspectOf(..) to them as needed + * + * @param aspect + * @param kind + * @return munger + */ + public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind) { + return new BcelPerClauseAspectAdder(aspect, kind); + } + + /** + * Retrieve a bcel delegate for an aspect - this will return NULL if the delegate is an EclipseSourceType and not a + * BcelObjectType - this happens quite often when incrementally compiling. + */ public static BcelObjectType getBcelObjectType(ResolvedType concreteAspect) { - ReferenceTypeDelegate rtDelegate = ((ReferenceType)concreteAspect).getDelegate(); + ReferenceTypeDelegate rtDelegate = ((ReferenceType) concreteAspect).getDelegate(); if (rtDelegate instanceof BcelObjectType) { - return (BcelObjectType)rtDelegate; + return (BcelObjectType) rtDelegate; } else { return null; } } public void tidyUp() { - // At end of compile, close any open files so deletion of those archives is possible + // At end of compile, close any open files so deletion of those archives is possible classPath.closeArchives(); typeMap.report(); ResolvedType.resetPrimitives(); } - - /// The repository interface methods + // / The repository interface methods public JavaClass findClass(String className) { - return lookupJavaClass(classPath,className); + return lookupJavaClass(classPath, className); } public JavaClass loadClass(String className) throws ClassNotFoundException { - return lookupJavaClass(classPath,className); + return lookupJavaClass(classPath, className); } public void storeClass(JavaClass clazz) { @@ -545,122 +488,81 @@ public class BcelWorld extends World implements Repository { public void clear() { delegate.clear(); -// throw new RuntimeException("Not implemented"); + // throw new RuntimeException("Not implemented"); } - // @Override - /** - * The aim of this method is to make sure a particular type is 'ok'. Some - * operations on the delegate for a type modify it and this method is - * intended to undo that... see pr85132 - */ + // @Override + /** + * The aim of this method is to make sure a particular type is 'ok'. Some operations on the delegate for a type modify it and + * this method is intended to undo that... see pr85132 + */ public void validateType(UnresolvedType type) { ResolvedType result = typeMap.get(type.getSignature()); - if (result==null) return; // We haven't heard of it yet - if (!result.isExposedToWeaver()) return; // cant need resetting - ReferenceType rt = (ReferenceType)result; + if (result == null) + return; // We haven't heard of it yet + if (!result.isExposedToWeaver()) + return; // cant need resetting + ReferenceType rt = (ReferenceType) result; rt.getDelegate().ensureDelegateConsistent(); // If we want to rebuild it 'from scratch' then: -// ClassParser cp = new ClassParser(new ByteArrayInputStream(newbytes),new String(cs)); -// try { -// rt.setDelegate(makeBcelObjectType(rt,cp.parse(),true)); -// } catch (ClassFormatException e) { -// e.printStackTrace(); -// } catch (IOException e) { -// e.printStackTrace(); -// } - } - - /** - * Checks if given bytecode is an @AspectJ aspect - * - * @param name - * @param bytes - * @return true if so - */ - public boolean isAnnotationStyleAspect(String name, byte[] bytes) { - try { - ClassParser cp = new ClassParser(new ByteArrayInputStream(bytes), null); - JavaClass jc = cp.parse(); - if (!jc.isClass()) { - return false; - } - AnnotationGen anns[] = jc.getAnnotations(); - if (anns.length == 0) { - return false; - } - boolean couldBeAtAspectJStyle = false; - for (int i = 0; i < anns.length; i++) { - AnnotationGen ann = anns[i]; - if ("Lorg/aspectj/lang/annotation/Aspect;".equals(ann.getTypeSignature())) { - couldBeAtAspectJStyle = true; - } - } - - if (!couldBeAtAspectJStyle) return false; - - // ok, so it has the annotation, but it could have been put - // on a code style aspect by the annotation visitor - Attribute[] attributes = jc.getAttributes(); - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].getName().equals(Aspect.AttributeName)) { - return false; - } - } - return true; - } catch (IOException e) { - // assume it is one as a best effort - return true; - } - } - - /** + // ClassParser cp = new ClassParser(new ByteArrayInputStream(newbytes),new String(cs)); + // try { + // rt.setDelegate(makeBcelObjectType(rt,cp.parse(),true)); + // } catch (ClassFormatException e) { + // e.printStackTrace(); + // } catch (IOException e) { + // e.printStackTrace(); + // } + } + + /** * Apply a single declare parents - return true if we change the type */ private boolean applyDeclareParents(DeclareParents p, ResolvedType onType) { boolean didSomething = false; - List newParents = p.findMatchingNewParents(onType,true); + List newParents = p.findMatchingNewParents(onType, true); if (!newParents.isEmpty()) { - didSomething=true; + didSomething = true; BcelObjectType classType = BcelWorld.getBcelObjectType(onType); - //System.err.println("need to do declare parents for: " + onType); - for (Iterator j = newParents.iterator(); j.hasNext(); ) { - ResolvedType newParent = (ResolvedType)j.next(); - - // We set it here so that the imminent matching for ITDs can succeed - we - // still haven't done the necessary changes to the class file itself - // (like transform super calls) - that is done in BcelTypeMunger.mungeNewParent() + // System.err.println("need to do declare parents for: " + onType); + for (Iterator j = newParents.iterator(); j.hasNext();) { + ResolvedType newParent = (ResolvedType) j.next(); + + // We set it here so that the imminent matching for ITDs can succeed - we + // still haven't done the necessary changes to the class file itself + // (like transform super calls) - that is done in BcelTypeMunger.mungeNewParent() classType.addParent(newParent); ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(newParent); - newParentMunger.setSourceLocation(p.getSourceLocation()); - onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, getCrosscuttingMembersSet().findAspectDeclaringParents(p))); + newParentMunger.setSourceLocation(p.getSourceLocation()); + onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, getCrosscuttingMembersSet() + .findAspectDeclaringParents(p))); } } return didSomething; } - + /** * Apply a declare @type - return true if we change the type */ - private boolean applyDeclareAtType(DeclareAnnotation decA, ResolvedType onType,boolean reportProblems) { + private boolean applyDeclareAtType(DeclareAnnotation decA, ResolvedType onType, boolean reportProblems) { boolean didSomething = false; if (decA.matches(onType)) { - - if (onType.hasAnnotation(decA.getAnnotationX().getSignature())) { - // already has it - return false; - } - + + if (onType.hasAnnotation(decA.getAnnotationX().getSignature())) { + // already has it + return false; + } + AnnotationX annoX = decA.getAnnotationX(); - + // check the annotation is suitable for the target - boolean isOK = checkTargetOK(decA,onType,annoX); + boolean isOK = checkTargetOK(decA, onType, annoX); if (isOK) { didSomething = true; ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger(annoX); newAnnotationTM.setSourceLocation(decA.getSourceLocation()); - onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM,decA.getAspect().resolve(this))); + onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, decA.getAspect().resolve(this))); decA.copyAnnotationTo(onType); } } @@ -668,73 +570,74 @@ public class BcelWorld extends World implements Repository { } /** - * Checks for an @target() on the annotation and if found ensures it allows the annotation - * to be attached to the target type that matched. + * Checks for an @target() on the annotation and if found ensures it allows the annotation to be attached to the target type + * that matched. */ private boolean checkTargetOK(DeclareAnnotation decA, ResolvedType onType, AnnotationX annoX) { if (annoX.specifiesTarget()) { - if ( (onType.isAnnotation() && !annoX.allowedOnAnnotationType()) || - (!annoX.allowedOnRegularType())) { - return false; - } + if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) || (!annoX.allowedOnRegularType())) { + return false; + } } return true; } - + // Hmmm - very similar to the code in BcelWeaver.weaveParentTypeMungers - this code // doesn't need to produce errors/warnings though as it won't really be weaving. protected void weaveInterTypeDeclarations(ResolvedType onType) { - + List declareParentsList = getCrosscuttingMembersSet().getDeclareParents(); - if (onType.isRawType()) onType = onType.getGenericType(); - onType.clearInterTypeMungers(); - + if (onType.isRawType()) + onType = onType.getGenericType(); + onType.clearInterTypeMungers(); + List decpToRepeat = new ArrayList(); - boolean aParentChangeOccurred = false; + boolean aParentChangeOccurred = false; boolean anAnnotationChangeOccurred = false; // First pass - apply all decp mungers - for (Iterator i = declareParentsList.iterator(); i.hasNext(); ) { - DeclareParents decp = (DeclareParents)i.next(); - boolean typeChanged = applyDeclareParents(decp,onType); + for (Iterator i = declareParentsList.iterator(); i.hasNext();) { + DeclareParents decp = (DeclareParents) i.next(); + boolean typeChanged = applyDeclareParents(decp, onType); if (typeChanged) { aParentChangeOccurred = true; } else { // Perhaps it would have matched if a 'dec @type' had modified the type - if (!decp.getChild().isStarAnnotation()) decpToRepeat.add(decp); + if (!decp.getChild().isStarAnnotation()) + decpToRepeat.add(decp); } } // Still first pass - apply all dec @type mungers - for (Iterator i = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator();i.hasNext();) { - DeclareAnnotation decA = (DeclareAnnotation)i.next(); - boolean typeChanged = applyDeclareAtType(decA,onType,true); + for (Iterator i = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator(); i.hasNext();) { + DeclareAnnotation decA = (DeclareAnnotation) i.next(); + boolean typeChanged = applyDeclareAtType(decA, onType, true); if (typeChanged) { anAnnotationChangeOccurred = true; } } - + while ((aParentChangeOccurred || anAnnotationChangeOccurred) && !decpToRepeat.isEmpty()) { anAnnotationChangeOccurred = aParentChangeOccurred = false; List decpToRepeatNextTime = new ArrayList(); for (Iterator iter = decpToRepeat.iterator(); iter.hasNext();) { DeclareParents decp = (DeclareParents) iter.next(); - boolean typeChanged = applyDeclareParents(decp,onType); + boolean typeChanged = applyDeclareParents(decp, onType); if (typeChanged) { aParentChangeOccurred = true; } else { decpToRepeatNextTime.add(decp); } } - + for (Iterator iter = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator(); iter.hasNext();) { DeclareAnnotation decA = (DeclareAnnotation) iter.next(); - boolean typeChanged = applyDeclareAtType(decA,onType,false); + boolean typeChanged = applyDeclareAtType(decA, onType, false); if (typeChanged) { anAnnotationChangeOccurred = true; } } decpToRepeat = decpToRepeatNextTime; } - } + } }
\ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java b/weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java index 6b163ab38..7e6b69ca5 100644 --- a/weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java +++ b/weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.bcel; import java.io.File; @@ -33,58 +32,60 @@ import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.tools.Trace; import org.aspectj.weaver.tools.TraceFactory; - public class ClassPathManager { - + private List entries; - + // In order to control how many open files we have, we maintain a list. // The max number is configured through the property: - // org.aspectj.weaver.openarchives + // org.aspectj.weaver.openarchives // and it defaults to 1000 - private List openArchives = new ArrayList(); - private static int maxOpenArchives = -1; - private static final int MAXOPEN_DEFAULT = 1000; + private List openArchives = new ArrayList(); + private static int maxOpenArchives = -1; + private static final int MAXOPEN_DEFAULT = 1000; + + private static Trace trace = TraceFactory.getTraceFactory().getTrace(ClassPathManager.class); - private static Trace trace = TraceFactory.getTraceFactory().getTrace(ClassPathManager.class); - static { - String openzipsString = getSystemPropertyWithoutSecurityException("org.aspectj.weaver.openarchives",Integer.toString(MAXOPEN_DEFAULT)); - maxOpenArchives=Integer.parseInt(openzipsString); - if (maxOpenArchives<20) maxOpenArchives=1000; + String openzipsString = getSystemPropertyWithoutSecurityException("org.aspectj.weaver.openarchives", Integer + .toString(MAXOPEN_DEFAULT)); + maxOpenArchives = Integer.parseInt(openzipsString); + if (maxOpenArchives < 20) + maxOpenArchives = 1000; } - - - + public ClassPathManager(List classpath, IMessageHandler handler) { - if (trace.isTraceEnabled()) trace.enter("<init>",this,new Object[] { classpath, handler }); + if (trace.isTraceEnabled()) + trace.enter("<init>", this, new Object[] { classpath, handler }); entries = new ArrayList(); for (Iterator i = classpath.iterator(); i.hasNext();) { String name = (String) i.next(); addPath(name, handler); } - if (trace.isTraceEnabled()) trace.exit("<init>"); + if (trace.isTraceEnabled()) + trace.exit("<init>"); + } + + protected ClassPathManager() { } - protected ClassPathManager() {} - - public void addPath (String name, IMessageHandler handler) { + public void addPath(String name, IMessageHandler handler) { File f = new File(name); String lc = name.toLowerCase(); if (!f.isDirectory()) { if (!f.isFile()) { if (!lc.endsWith(".jar") || lc.endsWith(".zip")) { // heuristic-only: ending with .jar or .zip means probably a zip file - MessageUtil.info(handler, WeaverMessages.format(WeaverMessages.ZIPFILE_ENTRY_MISSING,name)); - } else { - MessageUtil.info(handler, WeaverMessages.format(WeaverMessages.DIRECTORY_ENTRY_MISSING,name)); + MessageUtil.info(handler, WeaverMessages.format(WeaverMessages.ZIPFILE_ENTRY_MISSING, name)); + } else { + MessageUtil.info(handler, WeaverMessages.format(WeaverMessages.DIRECTORY_ENTRY_MISSING, name)); } return; } try { entries.add(new ZipFileEntry(f)); } catch (IOException ioe) { - MessageUtil.warn(handler, WeaverMessages.format(WeaverMessages.ZIPFILE_ENTRY_INVALID,name,ioe.getMessage())); + MessageUtil.warn(handler, WeaverMessages.format(WeaverMessages.ZIPFILE_ENTRY_INVALID, name, ioe.getMessage())); return; } } else { @@ -92,14 +93,14 @@ public class ClassPathManager { } } - public ClassFile find(UnresolvedType type) { String name = type.getName(); - for (Iterator i = entries.iterator(); i.hasNext(); ) { - Entry entry = (Entry)i.next(); + for (Iterator i = entries.iterator(); i.hasNext();) { + Entry entry = (Entry) i.next(); try { ClassFile ret = entry.find(name); - if (ret != null) return ret; + if (ret != null) + return ret; } catch (IOException ioe) { // this is NOT an error: it's valid to have missing classpath entries i.remove(); @@ -108,186 +109,210 @@ public class ClassPathManager { } return null; } - + public String toString() { StringBuffer buf = new StringBuffer(); boolean start = true; - for (Iterator i = entries.iterator(); i.hasNext(); ) { - if (start) { start = false; } - else {buf.append(File.pathSeparator); } + for (Iterator i = entries.iterator(); i.hasNext();) { + if (start) { + start = false; + } else { + buf.append(File.pathSeparator); + } buf.append(i.next()); } return buf.toString(); } - - /** - * This method is extremely expensive and should only be called rarely - */ - public List getAllClassFiles() { - List ret = new ArrayList(); - for (Iterator i = entries.iterator(); i.hasNext(); ) { - Entry entry = (Entry)i.next(); - try { - ret.addAll(entry.getAllClassFiles()); - } catch (IOException e) { - i.remove(); - } - } - return ret; - } - - - + + // /** + // * This method is extremely expensive and should only be called rarely + // */ + // public List getAllClassFiles() { + // List ret = new ArrayList(); + // for (Iterator i = entries.iterator(); i.hasNext(); ) { + // Entry entry = (Entry)i.next(); + // try { + // ret.addAll(entry.getAllClassFiles()); + // } catch (IOException e) { + // i.remove(); + // } + // } + // return ret; + // } + // + public abstract static class ClassFile { public abstract InputStream getInputStream() throws IOException; + public abstract String getPath(); + public abstract void close(); } public abstract static class Entry { public abstract ClassFile find(String name) throws IOException; + public abstract List getAllClassFiles() throws IOException; } - + private static class FileClassFile extends ClassFile { private File file; private FileInputStream fis; - + public FileClassFile(File file) { this.file = file; } - + public InputStream getInputStream() throws IOException { fis = new FileInputStream(file); return fis; } - + public void close() { try { - if (fis!=null) fis.close(); + if (fis != null) + fis.close(); } catch (IOException ioe) { - throw new BCException("Can't close class file : "+file.getName(),ioe); - } finally { + throw new BCException("Can't close class file : " + file.getName(), ioe); + } finally { fis = null; } - } - - public String getPath() { return file.getPath(); } + } + + public String getPath() { + return file.getPath(); + } } - + public class DirEntry extends Entry { private String dirPath; - - public DirEntry(File dir) { this.dirPath = dir.getPath(); } - public DirEntry(String dirPath) { this.dirPath = dirPath; } - + + public DirEntry(File dir) { + this.dirPath = dir.getPath(); + } + + public DirEntry(String dirPath) { + this.dirPath = dirPath; + } + public ClassFile find(String name) { File f = new File(dirPath + File.separator + name.replace('.', File.separatorChar) + ".class"); - if (f.isFile()) return new FileClassFile(f); - else return null; + if (f.isFile()) + return new FileClassFile(f); + else + return null; } - + public List getAllClassFiles() { throw new RuntimeException("unimplemented"); } - - public String toString() { return dirPath; } + + public String toString() { + return dirPath; + } } - + private static class ZipEntryClassFile extends ClassFile { private ZipEntry entry; private ZipFileEntry zipFile; private InputStream is; - + public ZipEntryClassFile(ZipFileEntry zipFile, ZipEntry entry) { this.zipFile = zipFile; this.entry = entry; } - + public InputStream getInputStream() throws IOException { is = zipFile.getZipFile().getInputStream(entry); return is; } - + public void close() { try { - if (is!=null) is.close(); + if (is != null) + is.close(); } catch (IOException e) { e.printStackTrace(); } finally { is = null; } - } - - public String getPath() { return entry.getName(); } - + } + + public String getPath() { + return entry.getName(); + } + } - + public class ZipFileEntry extends Entry { private File file; private ZipFile zipFile; - + public ZipFileEntry(File file) throws IOException { this.file = file; } - + public ZipFileEntry(ZipFile zipFile) { this.zipFile = zipFile; } - + public ZipFile getZipFile() { return zipFile; } - + public ClassFile find(String name) throws IOException { ensureOpen(); String key = name.replace('.', '/') + ".class"; ZipEntry entry = zipFile.getEntry(key); - if (entry != null) return new ZipEntryClassFile(this, entry); - else return null; // This zip will be closed when necessary... + if (entry != null) + return new ZipEntryClassFile(this, entry); + else + return null; // This zip will be closed when necessary... } - + public List getAllClassFiles() throws IOException { ensureOpen(); List ret = new ArrayList(); - for (Enumeration e = zipFile.entries(); e.hasMoreElements(); ) { - ZipEntry entry = (ZipEntry)e.nextElement(); + for (Enumeration e = zipFile.entries(); e.hasMoreElements();) { + ZipEntry entry = (ZipEntry) e.nextElement(); String name = entry.getName(); - if (hasClassExtension(name)) ret.add(new ZipEntryClassFile(this, entry)); + if (hasClassExtension(name)) + ret.add(new ZipEntryClassFile(this, entry)); } -// if (ret.isEmpty()) close(); + // if (ret.isEmpty()) close(); return ret; } - + private void ensureOpen() throws IOException { if (zipFile != null && openArchives.contains(zipFile)) { - if (isReallyOpen()) return; + if (isReallyOpen()) + return; } - if (openArchives.size()>=maxOpenArchives) { - closeSomeArchives(openArchives.size()/10); // Close 10% of those open + if (openArchives.size() >= maxOpenArchives) { + closeSomeArchives(openArchives.size() / 10); // Close 10% of those open } zipFile = new ZipFile(file); if (!isReallyOpen()) { - throw new FileNotFoundException("Can't open archive: "+file.getName()+" (size() check failed)"); + throw new FileNotFoundException("Can't open archive: " + file.getName() + " (size() check failed)"); } openArchives.add(zipFile); } - + private boolean isReallyOpen() { try { zipFile.size(); // this will fail if the file has been closed for - // some reason; + // some reason; return true; } catch (IllegalStateException ex) { // this means the zip file is closed... return false; } - + } - + public void closeSomeArchives(int n) { - for (int i=n-1;i>=0;i--) { - ZipFile zf = (ZipFile)openArchives.get(i); + for (int i = n - 1; i >= 0; i--) { + ZipFile zf = (ZipFile) openArchives.get(i); try { zf.close(); } catch (IOException e) { @@ -296,40 +321,41 @@ public class ClassPathManager { openArchives.remove(i); } } - + public void close() { - if (zipFile == null) return; + if (zipFile == null) + return; try { openArchives.remove(zipFile); zipFile.close(); } catch (IOException ioe) { - throw new BCException("Can't close archive: "+file.getName(),ioe); + throw new BCException("Can't close archive: " + file.getName(), ioe); } finally { zipFile = null; } } - - public String toString() { return file.getName(); } - } + public String toString() { + return file.getName(); + } + } - /* private */ static boolean hasClassExtension(String name) { + /* private */static boolean hasClassExtension(String name) { return name.toLowerCase().endsWith((".class")); } - public void closeArchives() { - for (Iterator i = entries.iterator(); i.hasNext(); ) { - Entry entry = (Entry)i.next(); + for (Iterator i = entries.iterator(); i.hasNext();) { + Entry entry = (Entry) i.next(); if (entry instanceof ZipFileEntry) { - ((ZipFileEntry)entry).close(); + ((ZipFileEntry) entry).close(); } openArchives.clear(); } } - - // Copes with the security manager - private static String getSystemPropertyWithoutSecurityException (String aPropertyName, String aDefaultValue) { + + // Copes with the security manager + private static String getSystemPropertyWithoutSecurityException(String aPropertyName, String aDefaultValue) { try { return System.getProperty(aPropertyName, aDefaultValue); } catch (SecurityException ex) { diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java index ce789252b..dcf553ce3 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java @@ -11,7 +11,6 @@ * Andy Clement 6Jul05 generics - signature attribute * ******************************************************************/ - package org.aspectj.weaver.bcel; import java.io.ByteArrayOutputStream; @@ -67,58 +66,54 @@ import org.aspectj.weaver.World; import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; import org.aspectj.weaver.UnresolvedType.TypeKind; - - /** - * Lazy lazy lazy. - * We don't unpack the underlying class unless necessary. Things - * like new methods and annotations accumulate in here until they - * must be written out, don't add them to the underlying MethodGen! - * Things are slightly different if this represents an Aspect. + * Lazy lazy lazy. We don't unpack the underlying class unless necessary. Things like new methods and annotations accumulate in here + * until they must be written out, don't add them to the underlying MethodGen! Things are slightly different if this represents an + * Aspect. */ public final class LazyClassGen { - - private static final int ACC_SYNTHETIC = 0x1000; - - private static final String[] NO_STRINGS = new String[0]; + + private static final int ACC_SYNTHETIC = 0x1000; + + private static final String[] NO_STRINGS = new String[0]; int highestLineNumber = 0; // ---- JSR 45 info - - private SortedMap /* <String, InlinedSourceFileInfo> */ inlinedFiles = new TreeMap(); - - private boolean regenerateGenericSignatureAttribute = false; - + + private SortedMap /* <String, InlinedSourceFileInfo> */inlinedFiles = new TreeMap(); + + private boolean regenerateGenericSignatureAttribute = false; + private BcelObjectType myType; // XXX is not set for types we create private ClassGen myGen; private ConstantPool cp; private World world; - private String packageName = null; - - private List /*BcelField*/ fields = new ArrayList(); - private List /*LazyMethodGen*/ methodGens = new ArrayList(); - private List /*LazyClassGen*/ classGens = new ArrayList(); - private List /*AnnotationGen*/ annotations = new ArrayList(); - private int childCounter = 0; - - private InstructionFactory fact; - + private String packageName = null; + + private List /* BcelField */fields = new ArrayList(); + private List /* LazyMethodGen */methodGens = new ArrayList(); + private List /* LazyClassGen */classGens = new ArrayList(); + private List /* AnnotationGen */annotations = new ArrayList(); + private int childCounter = 0; + + private InstructionFactory fact; + private boolean isSerializable = false; private boolean hasSerialVersionUIDField = false; private boolean serialVersionUIDRequiresInitialization = false; - private long calculatedSerialVersionUID; + private long calculatedSerialVersionUID; private boolean hasClinit = false; - + // --- - + static class InlinedSourceFileInfo { int highestLineNumber; - int offset; // calculated - + int offset; // calculated + InlinedSourceFileInfo(int highestLineNumber) { this.highestLineNumber = highestLineNumber; } - } - + } + void addInlinedSourceFileInfo(String fullpath, int highestLineNumber) { Object o = inlinedFiles.get(fullpath); if (o != null) { @@ -130,7 +125,7 @@ public final class LazyClassGen { inlinedFiles.put(fullpath, new InlinedSourceFileInfo(highestLineNumber)); } } - + void calculateSourceDebugExtensionOffsets() { int i = roundUpToHundreds(highestLineNumber); for (Iterator iter = inlinedFiles.values().iterator(); iter.hasNext();) { @@ -143,460 +138,438 @@ public final class LazyClassGen { private static int roundUpToHundreds(int i) { return ((i / 100) + 1) * 100; } - + int getSourceDebugExtensionOffset(String fullpath) { return ((InlinedSourceFileInfo) inlinedFiles.get(fullpath)).offset; } - -// private Unknown getSourceDebugExtensionAttribute() { -// int nameIndex = cp.addUtf8("SourceDebugExtension"); -// String data = getSourceDebugExtensionString(); -// //System.err.println(data); -// byte[] bytes = Utility.stringToUTF(data); -// int length = bytes.length; -// -// return new Unknown(nameIndex, length, bytes, cp); -// } - -// private LazyClassGen() {} -// public static void main(String[] args) { -// LazyClassGen m = new LazyClassGen(); -// m.highestLineNumber = 37; -// m.inlinedFiles.put("boo/baz/foo.java", new InlinedSourceFileInfo( 83)); -// m.inlinedFiles.put("boo/barz/foo.java", new InlinedSourceFileInfo(292)); -// m.inlinedFiles.put("boo/baz/moo.java", new InlinedSourceFileInfo(128)); -// m.calculateSourceDebugExtensionOffsets(); -// System.err.println(m.getSourceDebugExtensionString()); -// } - - // For the entire pathname, we're using package names. This is probably wrong. -// private String getSourceDebugExtensionString() { -// StringBuffer out = new StringBuffer(); -// String myFileName = getFileName(); -// // header section -// out.append("SMAP\n"); -// out.append(myFileName); -// out.append("\nAspectJ\n"); -// // stratum section -// out.append("*S AspectJ\n"); -// // file section -// out.append("*F\n"); -// out.append("1 "); -// out.append(myFileName); -// out.append("\n"); -// int i = 2; -// for (Iterator iter = inlinedFiles.keySet().iterator(); iter.hasNext();) { -// String element = (String) iter.next(); -// int ii = element.lastIndexOf('/'); -// if (ii == -1) { -// out.append(i++); out.append(' '); -// out.append(element); out.append('\n'); -// } else { -// out.append("+ "); out.append(i++); out.append(' '); -// out.append(element.substring(ii+1)); out.append('\n'); -// out.append(element); out.append('\n'); -// } -// } -// // emit line section -// out.append("*L\n"); -// out.append("1#1,"); -// out.append(highestLineNumber); -// out.append(":1,1\n"); -// i = 2; -// for (Iterator iter = inlinedFiles.values().iterator(); iter.hasNext();) { -// InlinedSourceFileInfo element = (InlinedSourceFileInfo) iter.next(); -// out.append("1#"); -// out.append(i++); out.append(','); -// out.append(element.highestLineNumber); out.append(":"); -// out.append(element.offset + 1); out.append(",1\n"); -// } -// // end section -// out.append("*E\n"); -// // and finish up... -// return out.toString(); -// } - + + // private Unknown getSourceDebugExtensionAttribute() { + // int nameIndex = cp.addUtf8("SourceDebugExtension"); + // String data = getSourceDebugExtensionString(); + // //System.err.println(data); + // byte[] bytes = Utility.stringToUTF(data); + // int length = bytes.length; + // + // return new Unknown(nameIndex, length, bytes, cp); + // } + + // private LazyClassGen() {} + // public static void main(String[] args) { + // LazyClassGen m = new LazyClassGen(); + // m.highestLineNumber = 37; + // m.inlinedFiles.put("boo/baz/foo.java", new InlinedSourceFileInfo( 83)); + // m.inlinedFiles.put("boo/barz/foo.java", new InlinedSourceFileInfo(292)); + // m.inlinedFiles.put("boo/baz/moo.java", new InlinedSourceFileInfo(128)); + // m.calculateSourceDebugExtensionOffsets(); + // System.err.println(m.getSourceDebugExtensionString()); + // } + + // For the entire pathname, we're using package names. This is probably wrong. + // private String getSourceDebugExtensionString() { + // StringBuffer out = new StringBuffer(); + // String myFileName = getFileName(); + // // header section + // out.append("SMAP\n"); + // out.append(myFileName); + // out.append("\nAspectJ\n"); + // // stratum section + // out.append("*S AspectJ\n"); + // // file section + // out.append("*F\n"); + // out.append("1 "); + // out.append(myFileName); + // out.append("\n"); + // int i = 2; + // for (Iterator iter = inlinedFiles.keySet().iterator(); iter.hasNext();) { + // String element = (String) iter.next(); + // int ii = element.lastIndexOf('/'); + // if (ii == -1) { + // out.append(i++); out.append(' '); + // out.append(element); out.append('\n'); + // } else { + // out.append("+ "); out.append(i++); out.append(' '); + // out.append(element.substring(ii+1)); out.append('\n'); + // out.append(element); out.append('\n'); + // } + // } + // // emit line section + // out.append("*L\n"); + // out.append("1#1,"); + // out.append(highestLineNumber); + // out.append(":1,1\n"); + // i = 2; + // for (Iterator iter = inlinedFiles.values().iterator(); iter.hasNext();) { + // InlinedSourceFileInfo element = (InlinedSourceFileInfo) iter.next(); + // out.append("1#"); + // out.append(i++); out.append(','); + // out.append(element.highestLineNumber); out.append(":"); + // out.append(element.offset + 1); out.append(",1\n"); + // } + // // end section + // out.append("*E\n"); + // // and finish up... + // return out.toString(); + // } + // ---- end JSR45-related stuff - - /** Emit disassembled class and newline to out */ - public static void disassemble(String path, String name, PrintStream out) - throws IOException { - if (null == out) { - return; - } - //out.println("classPath: " + classPath); - - BcelWorld world = new BcelWorld(path); - - UnresolvedType ut = UnresolvedType.forName(name); - ut.setNeedsModifiableDelegate(true); - LazyClassGen clazz = new LazyClassGen(BcelWorld.getBcelObjectType(world.resolve(ut))); - clazz.print(out); - out.println(); - } - - - public int getNewGeneratedNameTag() { - return childCounter++; - } - - // ---- - - public LazyClassGen( - String class_name, - String super_class_name, - String file_name, - int access_flags, - String[] interfaces, - World world) - { - myGen = new ClassGen(class_name, super_class_name, file_name, access_flags, interfaces); + + /** Emit disassembled class and newline to out */ + public static void disassemble(String path, String name, PrintStream out) throws IOException { + if (null == out) { + return; + } + // out.println("classPath: " + classPath); + + BcelWorld world = new BcelWorld(path); + + UnresolvedType ut = UnresolvedType.forName(name); + ut.setNeedsModifiableDelegate(true); + LazyClassGen clazz = new LazyClassGen(BcelWorld.getBcelObjectType(world.resolve(ut))); + clazz.print(out); + out.println(); + } + + public int getNewGeneratedNameTag() { + return childCounter++; + } + + // ---- + + public LazyClassGen(String class_name, String super_class_name, String file_name, int access_flags, String[] interfaces, + World world) { + myGen = new ClassGen(class_name, super_class_name, file_name, access_flags, interfaces); cp = myGen.getConstantPool(); - fact = new InstructionFactory(myGen, cp); - regenerateGenericSignatureAttribute = true; - this.world = world; - } - - //Non child type, so it comes from a real type in the world. - public LazyClassGen(BcelObjectType myType) { - myGen = new ClassGen(myType.getJavaClass()); - cp = myGen.getConstantPool(); - fact = new InstructionFactory(myGen, cp); + fact = new InstructionFactory(myGen, cp); + regenerateGenericSignatureAttribute = true; + this.world = world; + } + + // Non child type, so it comes from a real type in the world. + public LazyClassGen(BcelObjectType myType) { + myGen = new ClassGen(myType.getJavaClass()); + cp = myGen.getConstantPool(); + fact = new InstructionFactory(myGen, cp); this.myType = myType; this.world = myType.getResolvedTypeX().getWorld(); /* Does this class support serialization */ if (implementsSerializable(getType())) { - isSerializable = true; - -// ResolvedMember[] fields = getType().getDeclaredFields(); -// for (int i = 0; i < fields.length; i++) { -// ResolvedMember field = fields[i]; -// if (field.getName().equals("serialVersionUID") -// && field.isStatic() && field.getType().equals(ResolvedType.LONG)) { -// hasSerialVersionUIDField = true; -// } -// } - hasSerialVersionUIDField = hasSerialVersionUIDField(getType()); + isSerializable = true; + + // ResolvedMember[] fields = getType().getDeclaredFields(); + // for (int i = 0; i < fields.length; i++) { + // ResolvedMember field = fields[i]; + // if (field.getName().equals("serialVersionUID") + // && field.isStatic() && field.getType().equals(ResolvedType.LONG)) { + // hasSerialVersionUIDField = true; + // } + // } + hasSerialVersionUIDField = hasSerialVersionUIDField(getType()); ResolvedMember[] methods = getType().getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { ResolvedMember method = methods[i]; if (method.getName().equals("<clinit>")) { - if (method.getKind()!=Member.STATIC_INITIALIZATION) { + if (method.getKind() != Member.STATIC_INITIALIZATION) { throw new RuntimeException("qui?"); } - hasClinit = true; + hasClinit = true; } } - + // Do we need to calculate an SUID and add it? if (!hasSerialVersionUIDField && world.isAddSerialVerUID()) { - calculatedSerialVersionUID = myGen.getSUID(); - FieldGen fg = new FieldGen( - Constants.ACC_PRIVATE|Constants.ACC_FINAL|Constants.ACC_STATIC, - BasicType.LONG,"serialVersionUID",getConstantPool()); - addField(fg); - hasSerialVersionUIDField=true; - serialVersionUIDRequiresInitialization=true; - // warn about what we've done? - if (world.getLint().calculatingSerialVersionUID.isEnabled()) - world.getLint().calculatingSerialVersionUID.signal( - new String[]{getClassName(),Long.toString(calculatedSerialVersionUID)+"L"},null,null); - } + calculatedSerialVersionUID = myGen.getSUID(); + FieldGen fg = new FieldGen(Constants.ACC_PRIVATE | Constants.ACC_FINAL | Constants.ACC_STATIC, BasicType.LONG, + "serialVersionUID", getConstantPool()); + addField(fg); + hasSerialVersionUIDField = true; + serialVersionUIDRequiresInitialization = true; + // warn about what we've done? + if (world.getLint().calculatingSerialVersionUID.isEnabled()) + world.getLint().calculatingSerialVersionUID.signal(new String[] { getClassName(), + Long.toString(calculatedSerialVersionUID) + "L" }, null, null); + } } - ResolvedMember[] methods = myType.getDeclaredMethods(); - for (int i=0; i<methods.length; i++) { - addMethodGen(new LazyMethodGen((BcelMethod)methods[i],this)); + for (int i = 0; i < methods.length; i++) { + addMethodGen(new LazyMethodGen((BcelMethod) methods[i], this)); } - - // Method[] methods = myGen.getMethods(); - // for (int i = 0; i < methods.length; i++) { - // addMethodGen(new LazyMethodGen(methods[i], this)); - // } - - ResolvedMember[] fields = myType.getDeclaredFields(); - for (int i=0; i<fields.length; i++) { + + // Method[] methods = myGen.getMethods(); + // for (int i = 0; i < methods.length; i++) { + // addMethodGen(new LazyMethodGen(methods[i], this)); + // } + + ResolvedMember[] fields = myType.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { this.fields.add(fields[i]); - } - } + } + } - public static boolean hasSerialVersionUIDField (ResolvedType type) { + public static boolean hasSerialVersionUIDField(ResolvedType type) { ResolvedMember[] fields = type.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { ResolvedMember field = fields[i]; - if (field.getName().equals("serialVersionUID") - && field.isStatic() && field.getType().equals(ResolvedType.LONG)) { - return true; + if (field.getName().equals("serialVersionUID") && field.isStatic() && field.getType().equals(ResolvedType.LONG)) { + return true; } } - + return false; } -// public void addAttribute(Attribute i) { -// myGen.addAttribute(i); -// } + // public void addAttribute(Attribute i) { + // myGen.addAttribute(i); + // } - // ---- + // ---- - public String getInternalClassName() { - return getConstantPool().getConstantString_CONSTANTClass(myGen.getClassNameIndex()); - //getConstantPool().getConstantString( - // myGen.getClassNameIndex(), - // Constants.CONSTANT_Class); + public String getInternalClassName() { + return getConstantPool().getConstantString_CONSTANTClass(myGen.getClassNameIndex()); + // getConstantPool().getConstantString( + // myGen.getClassNameIndex(), + // Constants.CONSTANT_Class); - } + } public String getInternalFileName() { String str = getInternalClassName(); int index = str.lastIndexOf('/'); if (index == -1) { - return getFileName(); + return getFileName(); } else { return str.substring(0, index + 1) + getFileName(); - } - } - - - public File getPackagePath(File root) { - String str = getInternalClassName(); - int index = str.lastIndexOf('/'); - if (index == -1) - return root; - return new File(root, str.substring(0, index)); - } - - /** Returns the packagename - if its the default package we return an empty string - */ - public String getPackageName() { - if (packageName!=null) return packageName; - String str = getInternalClassName(); - int index = str.indexOf("<"); - if (index!=-1) str = str.substring(0,index); // strip off the generics guff - index= str.lastIndexOf("/"); - if (index==-1) return ""; - return str.substring(0,index).replace('/','.'); - } - - public String getClassId() { - String str = getInternalClassName(); - int index = str.lastIndexOf('/'); - if (index == -1) - return str; - return str.substring(index + 1); - } + } + } + public File getPackagePath(File root) { + String str = getInternalClassName(); + int index = str.lastIndexOf('/'); + if (index == -1) + return root; + return new File(root, str.substring(0, index)); + } + + /** + * Returns the packagename - if its the default package we return an empty string + */ + public String getPackageName() { + if (packageName != null) + return packageName; + String str = getInternalClassName(); + int index = str.indexOf("<"); + if (index != -1) + str = str.substring(0, index); // strip off the generics guff + index = str.lastIndexOf("/"); + if (index == -1) + return ""; + return str.substring(0, index).replace('/', '.'); + } + + public String getClassId() { + String str = getInternalClassName(); + int index = str.lastIndexOf('/'); + if (index == -1) + return str; + return str.substring(index + 1); + } public void addMethodGen(LazyMethodGen gen) { - //assert gen.getClassName() == super.getClassName(); + // assert gen.getClassName() == super.getClassName(); methodGens.add(gen); - if (highestLineNumber < gen.highestLineNumber) highestLineNumber = gen.highestLineNumber; + if (highestLineNumber < gen.highestLineNumber) + highestLineNumber = gen.highestLineNumber; } - + public void addMethodGen(LazyMethodGen gen, ISourceLocation sourceLocation) { addMethodGen(gen); - if (!gen.getMethod().isPrivate()) { - warnOnAddedMethod(gen.getMethod(),sourceLocation); + if (!gen.getMethod().isPrivate()) { + warnOnAddedMethod(gen.getMethod(), sourceLocation); } } - - public void errorOnAddedField (FieldGen field, ISourceLocation sourceLocation) { + public void errorOnAddedField(FieldGen field, ISourceLocation sourceLocation) { if (isSerializable && !hasSerialVersionUIDField) { getWorld().getLint().serialVersionUIDBroken.signal( - new String[] { - myType.getResolvedTypeX().getName(), - field.getName() - }, - sourceLocation, - null); + new String[] { myType.getResolvedTypeX().getName(), field.getName() }, sourceLocation, null); } } - public void warnOnAddedInterface (String name, ISourceLocation sourceLocation) { - warnOnModifiedSerialVersionUID(sourceLocation,"added interface " + name); + public void warnOnAddedInterface(String name, ISourceLocation sourceLocation) { + warnOnModifiedSerialVersionUID(sourceLocation, "added interface " + name); } - public void warnOnAddedMethod (Method method, ISourceLocation sourceLocation) { - warnOnModifiedSerialVersionUID(sourceLocation,"added non-private method " + method.getName()); + public void warnOnAddedMethod(Method method, ISourceLocation sourceLocation) { + warnOnModifiedSerialVersionUID(sourceLocation, "added non-private method " + method.getName()); } - public void warnOnAddedStaticInitializer (Shadow shadow, ISourceLocation sourceLocation) { + public void warnOnAddedStaticInitializer(Shadow shadow, ISourceLocation sourceLocation) { if (!hasClinit) { - warnOnModifiedSerialVersionUID(sourceLocation,"added static initializer"); + warnOnModifiedSerialVersionUID(sourceLocation, "added static initializer"); } } - public void warnOnModifiedSerialVersionUID (ISourceLocation sourceLocation, String reason) { + public void warnOnModifiedSerialVersionUID(ISourceLocation sourceLocation, String reason) { if (isSerializable && !hasSerialVersionUIDField) - getWorld().getLint().needsSerialVersionUIDField.signal( - new String[] { - myType.getResolvedTypeX().getName().toString(), - reason - }, - sourceLocation, - null); + getWorld().getLint().needsSerialVersionUIDField.signal(new String[] { myType.getResolvedTypeX().getName().toString(), + reason }, sourceLocation, null); } - public World getWorld () { + public World getWorld() { return world; } - public List getMethodGens() { - return methodGens; //???Collections.unmodifiableList(methodGens); - } - - public List/*BcelField*/ getFieldGens() { - return fields; - // return myGen.getFields(); - } - -// public Field getField(String name) { -// Field[] allFields = myGen.getFields(); -// if (allFields==null) return null; -// for (int i = 0; i < allFields.length; i++) { -// Field field = allFields[i]; -// if (field.getName().equals(name)) return field; -// } -// return null; -// } - - // FIXME asc How do the ones on the underlying class surface if this just returns new ones added? - // FIXME asc ...although no one calls this right now ! - public List getAnnotations() { - return annotations; - } - - private void writeBack(BcelWorld world) { - if (getConstantPool().getSize() > Short.MAX_VALUE) { - reportClassTooBigProblem(); - return; - } - - if (annotations.size()>0) { - for (Iterator iter = annotations.iterator(); iter.hasNext();) { + public List getMethodGens() { + return methodGens; // ???Collections.unmodifiableList(methodGens); + } + + public List/* BcelField */getFieldGens() { + return fields; + // return myGen.getFields(); + } + + // public Field getField(String name) { + // Field[] allFields = myGen.getFields(); + // if (allFields==null) return null; + // for (int i = 0; i < allFields.length; i++) { + // Field field = allFields[i]; + // if (field.getName().equals(name)) return field; + // } + // return null; + // } + + private void writeBack(BcelWorld world) { + if (getConstantPool().getSize() > Short.MAX_VALUE) { + reportClassTooBigProblem(); + return; + } + + if (annotations.size() > 0) { + for (Iterator iter = annotations.iterator(); iter.hasNext();) { AnnotationGen element = (AnnotationGen) iter.next(); myGen.addAnnotation(element); } -// Attribute[] annAttributes = org.aspectj.apache.bcel.classfile.Utility.getAnnotationAttributes(getConstantPool(),annotations); -// for (int i = 0; i < annAttributes.length; i++) { -// Attribute attribute = annAttributes[i]; -// System.err.println("Adding attribute for "+attribute); -// myGen.addAttribute(attribute); -// } - } - - // Add a weaver version attribute to the file being produced (if necessary...) - if (!myGen.hasAttribute("org.aspectj.weaver.WeaverVersion")) { - myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPool())); - } - - if (myType != null && myType.getWeaverState() != null) { - myGen.addAttribute(Utility.bcelAttribute( - new AjAttribute.WeaverState(myType.getWeaverState()), - getConstantPool())); - } - - //FIXME ATAJ needed only for slow Aspects.aspectOf() - keep or remove - //make a lot of test fail since the test compare weaved class file - // based on some test data as text files... -// if (!myGen.isInterface()) { -// addAjClassField(); -// } - - addAjcInitializers(); - - // 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430). Will be revisited when contents + // Attribute[] annAttributes = + // org.aspectj.apache.bcel.classfile.Utility.getAnnotationAttributes(getConstantPool(),annotations); + // for (int i = 0; i < annAttributes.length; i++) { + // Attribute attribute = annAttributes[i]; + // System.err.println("Adding attribute for "+attribute); + // myGen.addAttribute(attribute); + // } + } + + // Add a weaver version attribute to the file being produced (if necessary...) + if (!myGen.hasAttribute("org.aspectj.weaver.WeaverVersion")) { + myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverVersionInfo(), getConstantPool())); + } + + if (myType != null && myType.getWeaverState() != null) { + myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverState(myType.getWeaverState()), getConstantPool())); + } + + // FIXME ATAJ needed only for slow Aspects.aspectOf() - keep or remove + // make a lot of test fail since the test compare weaved class file + // based on some test data as text files... + // if (!myGen.isInterface()) { + // addAjClassField(); + // } + + addAjcInitializers(); + + // 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430). Will be revisited when contents // of attribute are confirmed to be correct. - boolean sourceDebugExtensionSupportSwitchedOn = false; - - if (sourceDebugExtensionSupportSwitchedOn) { - calculateSourceDebugExtensionOffsets(); - } - - int len = methodGens.size(); - myGen.setMethods(Method.NoMethods); - for (int i = 0; i < len; i++) { - LazyMethodGen gen = (LazyMethodGen) methodGens.get(i); - // we skip empty clinits - if (isEmptyClinit(gen)) continue; - myGen.addMethod(gen.getMethod()); - } - - len = fields.size(); - myGen.setFields(Field.NoFields); - for (int i = 0; i < len; i++) { - BcelField gen = (BcelField) fields.get(i); - myGen.addField(gen.getField(this.cp)); - } - - if (sourceDebugExtensionSupportSwitchedOn) { + boolean sourceDebugExtensionSupportSwitchedOn = false; + + if (sourceDebugExtensionSupportSwitchedOn) { + calculateSourceDebugExtensionOffsets(); + } + + int len = methodGens.size(); + myGen.setMethods(Method.NoMethods); + for (int i = 0; i < len; i++) { + LazyMethodGen gen = (LazyMethodGen) methodGens.get(i); + // we skip empty clinits + if (isEmptyClinit(gen)) + continue; + myGen.addMethod(gen.getMethod()); + } + + len = fields.size(); + myGen.setFields(Field.NoFields); + for (int i = 0; i < len; i++) { + BcelField gen = (BcelField) fields.get(i); + myGen.addField(gen.getField(this.cp)); + } + + if (sourceDebugExtensionSupportSwitchedOn) { if (inlinedFiles.size() != 0) { if (hasSourceDebugExtensionAttribute(myGen)) { - world.showMessage( - IMessage.WARNING, - WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()), - null, - null); + world.showMessage(IMessage.WARNING, WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45, getFileName()), null, + null); } // myGen.addAttribute(getSourceDebugExtensionAttribute()); } - } - + } + fixupGenericSignatureAttribute(); - } - - /** - * When working with 1.5 generics, a signature attribute is attached to the type which indicates - * how it was declared. This routine ensures the signature attribute for what we are about - * to write out is correct. Basically its responsibilities are: - * 1. Checking whether the attribute needs changing (i.e. did weaving change the type hierarchy) - * 2. If it did, removing the old attribute - * 3. Check if we need an attribute at all, are we generic? are our supertypes parameterized/generic? - * 4. Build the new attribute which includes all typevariable, supertype and superinterface information - */ - private void fixupGenericSignatureAttribute () { - - if (getWorld() != null && !getWorld().isInJava5Mode()) return; - - // TODO asc generics Temporarily assume that types we generate dont need a signature attribute (closure/etc).. will need revisiting no doubt... - if (myType==null) return; - + } + + /** + * When working with 1.5 generics, a signature attribute is attached to the type which indicates how it was declared. This + * routine ensures the signature attribute for what we are about to write out is correct. Basically its responsibilities are: 1. + * Checking whether the attribute needs changing (i.e. did weaving change the type hierarchy) 2. If it did, removing the old + * attribute 3. Check if we need an attribute at all, are we generic? are our supertypes parameterized/generic? 4. Build the new + * attribute which includes all typevariable, supertype and superinterface information + */ + private void fixupGenericSignatureAttribute() { + + if (getWorld() != null && !getWorld().isInJava5Mode()) + return; + + // TODO asc generics Temporarily assume that types we generate dont need a signature attribute (closure/etc).. will need + // revisiting no doubt... + if (myType == null) + return; + // 1. Has anything changed that would require us to modify this attribute? - if (!regenerateGenericSignatureAttribute) return; - + if (!regenerateGenericSignatureAttribute) + return; + // 2. Find the old attribute Signature sigAttr = null; - if (myType!=null) { // if null, this is a type built from scratch, it won't already have a sig attribute + if (myType != null) { // if null, this is a type built from scratch, it won't already have a sig attribute sigAttr = (Signature) myGen.getAttribute("Signature"); } - + // 3. Do we need an attribute? boolean needAttribute = false; - if (sigAttr!=null) needAttribute = true; // If we had one before, we definetly still need one as types can't be 'removed' from the hierarchy - + if (sigAttr != null) + needAttribute = true; // If we had one before, we definetly still need one as types can't be 'removed' from the + // hierarchy + // check the interfaces if (!needAttribute) { ResolvedType[] interfaceRTXs = myType.getDeclaredInterfaces(); for (int i = 0; i < interfaceRTXs.length; i++) { ResolvedType typeX = interfaceRTXs[i]; - if (typeX.isGenericType() || typeX.isParameterizedType()) needAttribute = true; + if (typeX.isGenericType() || typeX.isParameterizedType()) + needAttribute = true; } - + // check the supertype ResolvedType superclassRTX = myType.getSuperclass(); - if (superclassRTX.isGenericType() || superclassRTX.isParameterizedType()) needAttribute = true; + if (superclassRTX.isGenericType() || superclassRTX.isParameterizedType()) + needAttribute = true; } - + if (needAttribute) { StringBuffer signature = new StringBuffer(); // first, the type variables... TypeVariable[] tVars = myType.getTypeVariables(); - if (tVars.length>0) { + if (tVars.length > 0) { signature.append("<"); for (int i = 0; i < tVars.length; i++) { TypeVariable variable = tVars[i]; @@ -612,19 +585,19 @@ public final class LazyClassGen { String s = interfaceRTXs[i].getSignatureForAttribute(); signature.append(s); } - if (sigAttr!=null) myGen.removeAttribute(sigAttr); + if (sigAttr != null) + myGen.removeAttribute(sigAttr); myGen.addAttribute(createSignatureAttribute(signature.toString())); } } - - /** - * Helper method to create a signature attribute based on a string signature: - * e.g. "Ljava/lang/Object;LI<Ljava/lang/Double;>;" + + /** + * Helper method to create a signature attribute based on a string signature: e.g. "Ljava/lang/Object;LI<Ljava/lang/Double;>;" */ private Signature createSignatureAttribute(String signature) { int nameIndex = cp.addUtf8("Signature"); - int sigIndex = cp.addUtf8(signature); - return new Signature(nameIndex,2,sigIndex,cp); + int sigIndex = cp.addUtf8(signature); + return new Signature(nameIndex, 2, sigIndex, cp); } /** @@ -636,82 +609,78 @@ public final class LazyClassGen { // again haven't you? come on, admit it, no-one writes classes this big by hand). // create an empty myGen so that we can give back a return value that doesn't upset the // rest of the process. - myGen = new ClassGen(myGen.getClassName(), myGen.getSuperclassName(), - myGen.getFileName(), myGen.getModifiers(), myGen.getInterfaceNames()); + myGen = new ClassGen(myGen.getClassName(), myGen.getSuperclassName(), myGen.getFileName(), myGen.getModifiers(), myGen + .getInterfaceNames()); // raise an error against this compilation unit. - getWorld().showMessage( - IMessage.ERROR, - WeaverMessages.format(WeaverMessages.CLASS_TOO_BIG, - this.getClassName()), - new SourceLocation(new File(myGen.getFileName()),0), null - ); + getWorld().showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.CLASS_TOO_BIG, this.getClassName()), + new SourceLocation(new File(myGen.getFileName()), 0), null); } private static boolean hasSourceDebugExtensionAttribute(ClassGen gen) { return gen.hasAttribute("SourceDebugExtension"); } - public JavaClass getJavaClass(BcelWorld world) { - writeBack(world); - return myGen.getJavaClass(); - } - - public byte [] getJavaClassBytesIncludingReweavable(BcelWorld world){ - writeBack(world); - byte [] wovenClassFileData = myGen.getJavaClass().getBytes(); - WeaverStateInfo wsi = myType.getWeaverState();//getOrCreateWeaverStateInfo(); - if(wsi != null && wsi.isReweavable()){ // && !reweavableDataInserted - //reweavableDataInserted = true; - return wsi.replaceKeyWithDiff(wovenClassFileData); - } else{ - return wovenClassFileData; - } - } - - public void addGeneratedInner(LazyClassGen newClass) { - classGens.add(newClass); - } - - public void addInterface(UnresolvedType typeX, ISourceLocation sourceLocation) { - regenerateGenericSignatureAttribute = true; - myGen.addInterface(typeX.getRawName()); - if (!typeX.equals(UnresolvedType.SERIALIZABLE)) - warnOnAddedInterface(typeX.getName(),sourceLocation); - } - + public JavaClass getJavaClass(BcelWorld world) { + writeBack(world); + return myGen.getJavaClass(); + } + + public byte[] getJavaClassBytesIncludingReweavable(BcelWorld world) { + writeBack(world); + byte[] wovenClassFileData = myGen.getJavaClass().getBytes(); + WeaverStateInfo wsi = myType.getWeaverState();// getOrCreateWeaverStateInfo(); + if (wsi != null && wsi.isReweavable()) { // && !reweavableDataInserted + // reweavableDataInserted = true; + return wsi.replaceKeyWithDiff(wovenClassFileData); + } else { + return wovenClassFileData; + } + } + + public void addGeneratedInner(LazyClassGen newClass) { + classGens.add(newClass); + } + + public void addInterface(UnresolvedType typeX, ISourceLocation sourceLocation) { + regenerateGenericSignatureAttribute = true; + myGen.addInterface(typeX.getRawName()); + if (!typeX.equals(UnresolvedType.SERIALIZABLE)) + warnOnAddedInterface(typeX.getName(), sourceLocation); + } + public void setSuperClass(ResolvedType typeX) { - regenerateGenericSignatureAttribute = true; - myType.addParent(typeX); // used for the attribute - if (typeX.getGenericType()!=null) typeX = typeX.getGenericType(); + regenerateGenericSignatureAttribute = true; + myType.addParent(typeX); // used for the attribute + if (typeX.getGenericType() != null) + typeX = typeX.getGenericType(); myGen.setSuperclassName(typeX.getName()); // used in the real class data - } - - public String getSuperClassname() { - return myGen.getSuperclassName(); - } + } - // FIXME asc not great that some of these ask the gen and some ask the type ! (see the related setters too) + public String getSuperClassname() { + return myGen.getSuperclassName(); + } + + // FIXME asc not great that some of these ask the gen and some ask the type ! (see the related setters too) public ResolvedType getSuperClass() { return myType.getSuperclass(); - } - - public String[] getInterfaceNames() { - return myGen.getInterfaceNames(); - } - + } - // non-recursive, may be a bug, ha ha. - private List getClassGens() { - List ret = new ArrayList(); - ret.add(this); - ret.addAll(classGens); + public String[] getInterfaceNames() { + return myGen.getInterfaceNames(); + } - return ret; - } + // non-recursive, may be a bug, ha ha. + private List getClassGens() { + List ret = new ArrayList(); + ret.add(this); + ret.addAll(classGens); + return ret; + } public List getChildClasses(BcelWorld world) { - if (classGens.isEmpty()) return Collections.EMPTY_LIST; + if (classGens.isEmpty()) + return Collections.EMPTY_LIST; List ret = new ArrayList(); for (Iterator i = classGens.iterator(); i.hasNext();) { LazyClassGen clazz = (LazyClassGen) i.next(); @@ -719,7 +688,7 @@ public final class LazyClassGen { String name = clazz.getName(); int index = name.lastIndexOf('$'); // XXX this could be bad, check use of dollar signs. - name = name.substring(index+1); + name = name.substring(index + 1); ret.add(new UnwovenClassFile.ChildClass(name, bytes)); } return ret; @@ -729,496 +698,459 @@ public final class LazyClassGen { return toShortString(); } - public String toShortString() { - String s = - org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getModifiers(), true); - if (s != "") - s += " "; - s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getModifiers()); - s += " "; - s += myGen.getClassName(); - return s; - } - - public String toLongString() { - ByteArrayOutputStream s = new ByteArrayOutputStream(); - print(new PrintStream(s)); - return new String(s.toByteArray()); - } - - public void print() { print(System.out); } - - public void print(PrintStream out) { - List classGens = getClassGens(); - for (Iterator iter = classGens.iterator(); iter.hasNext();) { - LazyClassGen element = (LazyClassGen) iter.next(); - element.printOne(out); - if (iter.hasNext()) out.println(); - } - } - - private void printOne(PrintStream out) { - out.print(toShortString()); - out.print(" extends "); - out.print( - org.aspectj.apache.bcel.classfile.Utility.compactClassName( - myGen.getSuperclassName(), - false)); - - int size = myGen.getInterfaces().length; - - if (size > 0) { - out.print(" implements "); - for (int i = 0; i < size; i++) { - out.print(myGen.getInterfaceNames()[i]); - if (i < size - 1) - out.print(", "); - } - } - out.print(":"); - out.println(); - // XXX make sure to pass types correctly around, so this doesn't happen. - if (myType != null) { - myType.printWackyStuff(out); - } - Field[] fields = myGen.getFields(); - for (int i = 0, len = fields.length; i < len; i++) { - out.print(" "); - out.println(fields[i]); - } - List methodGens = getMethodGens(); - for (Iterator iter = methodGens.iterator(); iter.hasNext();) { - LazyMethodGen gen = (LazyMethodGen) iter.next(); - // we skip empty clinits - if (isEmptyClinit(gen)) continue; - gen.print(out, (myType != null ? myType.getWeaverVersionAttribute() : WeaverVersionInfo.UNKNOWN)); - if (iter.hasNext()) out.println(); - } -// out.println(" ATTRIBS: " + Arrays.asList(myGen.getAttributes())); - - out.println("end " + toShortString()); - } - - private boolean isEmptyClinit(LazyMethodGen gen) { - - if (!gen.getName().equals("<clinit>")) return false; - //System.err.println("checking clinig: " + gen); - InstructionHandle start = gen.getBody().getStart(); - while (start != null) { - if (Range.isRangeHandle(start) || (start.getInstruction().opcode==Constants.RETURN)) { - start = start.getNext(); - } else { - return false; - } - } - - return true; - } - - public ConstantPool getConstantPool() { - return cp; - } - - public String getName() { - return myGen.getClassName(); - } + public String toShortString() { + String s = org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getModifiers(), true); + if (s != "") + s += " "; + s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getModifiers()); + s += " "; + s += myGen.getClassName(); + return s; + } + + public String toLongString() { + ByteArrayOutputStream s = new ByteArrayOutputStream(); + print(new PrintStream(s)); + return new String(s.toByteArray()); + } + + public void print() { + print(System.out); + } + + public void print(PrintStream out) { + List classGens = getClassGens(); + for (Iterator iter = classGens.iterator(); iter.hasNext();) { + LazyClassGen element = (LazyClassGen) iter.next(); + element.printOne(out); + if (iter.hasNext()) + out.println(); + } + } + + private void printOne(PrintStream out) { + out.print(toShortString()); + out.print(" extends "); + out.print(org.aspectj.apache.bcel.classfile.Utility.compactClassName(myGen.getSuperclassName(), false)); + + int size = myGen.getInterfaces().length; + + if (size > 0) { + out.print(" implements "); + for (int i = 0; i < size; i++) { + out.print(myGen.getInterfaceNames()[i]); + if (i < size - 1) + out.print(", "); + } + } + out.print(":"); + out.println(); + // XXX make sure to pass types correctly around, so this doesn't happen. + if (myType != null) { + myType.printWackyStuff(out); + } + Field[] fields = myGen.getFields(); + for (int i = 0, len = fields.length; i < len; i++) { + out.print(" "); + out.println(fields[i]); + } + List methodGens = getMethodGens(); + for (Iterator iter = methodGens.iterator(); iter.hasNext();) { + LazyMethodGen gen = (LazyMethodGen) iter.next(); + // we skip empty clinits + if (isEmptyClinit(gen)) + continue; + gen.print(out, (myType != null ? myType.getWeaverVersionAttribute() : WeaverVersionInfo.UNKNOWN)); + if (iter.hasNext()) + out.println(); + } + // out.println(" ATTRIBS: " + Arrays.asList(myGen.getAttributes())); + + out.println("end " + toShortString()); + } + + private boolean isEmptyClinit(LazyMethodGen gen) { + + if (!gen.getName().equals("<clinit>")) + return false; + // System.err.println("checking clinig: " + gen); + InstructionHandle start = gen.getBody().getStart(); + while (start != null) { + if (Range.isRangeHandle(start) || (start.getInstruction().opcode == Constants.RETURN)) { + start = start.getNext(); + } else { + return false; + } + } + + return true; + } + + public ConstantPool getConstantPool() { + return cp; + } + + public String getName() { + return myGen.getClassName(); + } public boolean isWoven() { return myType.getWeaverState() != null; } - + public boolean isReweavable() { - if (myType.getWeaverState()==null) return true; - return myType.getWeaverState().isReweavable(); + if (myType.getWeaverState() == null) + return true; + return myType.getWeaverState().isReweavable(); } - + public Set getAspectsAffectingType() { - if (myType.getWeaverState()==null) return null; + if (myType.getWeaverState() == null) + return null; return myType.getWeaverState().getAspectsAffectingType(); } - + public WeaverStateInfo getOrCreateWeaverStateInfo(boolean inReweavableMode) { WeaverStateInfo ret = myType.getWeaverState(); - if (ret != null) return ret; + if (ret != null) + return ret; ret = new WeaverStateInfo(inReweavableMode); myType.setWeaverState(ret); return ret; } - public InstructionFactory getFactory() { - return fact; - } - - public LazyMethodGen getStaticInitializer() { - for (Iterator i = methodGens.iterator(); i.hasNext();) { - LazyMethodGen gen = (LazyMethodGen) i.next(); - // OPTIMIZE persist kind of member into the gen object? for clinit - if (gen.getName().equals("<clinit>")) return gen; - } - LazyMethodGen clinit = new LazyMethodGen( - Modifier.STATIC, - Type.VOID, - "<clinit>", - new Type[0], - NO_STRINGS, - this); - clinit.getBody().insert(InstructionConstants.RETURN); - methodGens.add(clinit); - return clinit; - } - - public LazyMethodGen getAjcPreClinit() { - for (Iterator i = methodGens.iterator(); i.hasNext();) { - LazyMethodGen gen = (LazyMethodGen) i.next(); - if (gen.getName().equals(NameMangler.AJC_PRE_CLINIT_NAME)) return gen; - } - LazyMethodGen ajcClinit = new LazyMethodGen( - Modifier.STATIC, - Type.VOID, - NameMangler.AJC_PRE_CLINIT_NAME, - new Type[0], - NO_STRINGS, - this); - ajcClinit.getBody().insert(InstructionConstants.RETURN); - methodGens.add(ajcClinit); - - getStaticInitializer().getBody().insert(Utility.createInvoke(getFactory(), ajcClinit)); - return ajcClinit; - } - - - - // reflective thisJoinPoint support - Map/*BcelShadow, Field*/ tjpFields = new HashMap(); - public static final ObjectType proceedingTjpType = - new ObjectType("org.aspectj.lang.ProceedingJoinPoint"); - public static final ObjectType tjpType = - new ObjectType("org.aspectj.lang.JoinPoint"); - public static final ObjectType staticTjpType = - new ObjectType("org.aspectj.lang.JoinPoint$StaticPart"); - public static final ObjectType enclosingStaticTjpType = - new ObjectType("org.aspectj.lang.JoinPoint$EnclosingStaticPart"); - private static final ObjectType sigType = - new ObjectType("org.aspectj.lang.Signature"); -// private static final ObjectType slType = -// new ObjectType("org.aspectj.lang.reflect.SourceLocation"); - private static final ObjectType factoryType = - new ObjectType("org.aspectj.runtime.reflect.Factory"); - private static final ObjectType classType = - new ObjectType("java.lang.Class"); - - public Field getTjpField(BcelShadow shadow, final boolean isEnclosingJp) { - Field ret = (Field)tjpFields.get(shadow); - if (ret != null) return ret; - + public InstructionFactory getFactory() { + return fact; + } + + public LazyMethodGen getStaticInitializer() { + for (Iterator i = methodGens.iterator(); i.hasNext();) { + LazyMethodGen gen = (LazyMethodGen) i.next(); + // OPTIMIZE persist kind of member into the gen object? for clinit + if (gen.getName().equals("<clinit>")) + return gen; + } + LazyMethodGen clinit = new LazyMethodGen(Modifier.STATIC, Type.VOID, "<clinit>", new Type[0], NO_STRINGS, this); + clinit.getBody().insert(InstructionConstants.RETURN); + methodGens.add(clinit); + return clinit; + } + + public LazyMethodGen getAjcPreClinit() { + for (Iterator i = methodGens.iterator(); i.hasNext();) { + LazyMethodGen gen = (LazyMethodGen) i.next(); + if (gen.getName().equals(NameMangler.AJC_PRE_CLINIT_NAME)) + return gen; + } + LazyMethodGen ajcClinit = new LazyMethodGen(Modifier.STATIC, Type.VOID, NameMangler.AJC_PRE_CLINIT_NAME, new Type[0], + NO_STRINGS, this); + ajcClinit.getBody().insert(InstructionConstants.RETURN); + methodGens.add(ajcClinit); + + getStaticInitializer().getBody().insert(Utility.createInvoke(getFactory(), ajcClinit)); + return ajcClinit; + } + + // reflective thisJoinPoint support + Map/* BcelShadow, Field */tjpFields = new HashMap(); + public static final ObjectType proceedingTjpType = new ObjectType("org.aspectj.lang.ProceedingJoinPoint"); + public static final ObjectType tjpType = new ObjectType("org.aspectj.lang.JoinPoint"); + public static final ObjectType staticTjpType = new ObjectType("org.aspectj.lang.JoinPoint$StaticPart"); + public static final ObjectType enclosingStaticTjpType = new ObjectType("org.aspectj.lang.JoinPoint$EnclosingStaticPart"); + private static final ObjectType sigType = new ObjectType("org.aspectj.lang.Signature"); + // private static final ObjectType slType = + // new ObjectType("org.aspectj.lang.reflect.SourceLocation"); + private static final ObjectType factoryType = new ObjectType("org.aspectj.runtime.reflect.Factory"); + private static final ObjectType classType = new ObjectType("java.lang.Class"); + + public Field getTjpField(BcelShadow shadow, final boolean isEnclosingJp) { + Field ret = (Field) tjpFields.get(shadow); + if (ret != null) + return ret; + int modifiers = Modifier.STATIC | Modifier.FINAL; - + // XXX - Do we ever inline before or after advice? If we do, then we // better include them in the check below. (or just change it to // shadow.getEnclosingMethod().getCanInline()) - + // If the enclosing method is around advice, we could inline the join point - // that has led to this shadow. If we do that then the TJP we are creating - // here must be PUBLIC so it is visible to the type in which the + // that has led to this shadow. If we do that then the TJP we are creating + // here must be PUBLIC so it is visible to the type in which the // advice is inlined. (PR71377) LazyMethodGen encMethod = shadow.getEnclosingMethod(); boolean shadowIsInAroundAdvice = false; - if (encMethod!=null && encMethod.getName().startsWith(NameMangler.PREFIX+"around")) { + if (encMethod != null && encMethod.getName().startsWith(NameMangler.PREFIX + "around")) { shadowIsInAroundAdvice = true; } - + if (getType().isInterface() || shadowIsInAroundAdvice) { modifiers |= Modifier.PUBLIC; - } - else { + } else { modifiers |= Modifier.PRIVATE; } ObjectType jpType = null; if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have different staticjp types in 1.2 jpType = staticTjpType; } else { - jpType = isEnclosingJp?enclosingStaticTjpType:staticTjpType; + jpType = isEnclosingJp ? enclosingStaticTjpType : staticTjpType; + } + FieldGen fGen = new FieldGen(modifiers, jpType, "ajc$tjp_" + tjpFields.size(), getConstantPool()); + addField(fGen); + ret = fGen.getField(); + tjpFields.put(shadow, ret); + return ret; + } + + // FIXME ATAJ needed only for slow Aspects.aspectOf - keep or remove + // private void addAjClassField() { + // // Andy: Why build it again?? + // Field ajClassField = new FieldGen( + // Modifier.PRIVATE | Modifier.FINAL | Modifier.STATIC, + // classType, + // "aj$class", + // getConstantPool()).getField(); + // addField(ajClassField); + // + // InstructionList il = new InstructionList(); + // il.append(new PUSH(getConstantPool(), getClassName())); + // il.append(fact.createInvoke("java.lang.Class", "forName", classType, + // new Type[] {Type.STRING}, Constants.INVOKESTATIC)); + // il.append(fact.createFieldAccess(getClassName(), ajClassField.getName(), + // classType, Constants.PUTSTATIC)); + // + // getStaticInitializer().getBody().insert(il); + // } + + private void addAjcInitializers() { + if (tjpFields.size() == 0 && !serialVersionUIDRequiresInitialization) + return; + InstructionList il = null; + + if (tjpFields.size() > 0) { + il = initializeAllTjps(); + } + + if (serialVersionUIDRequiresInitialization) { + if (il == null) { + il = new InstructionList(); + } + il.append(InstructionFactory.PUSH(getConstantPool(), calculatedSerialVersionUID)); + il.append(getFactory().createFieldAccess(getClassName(), "serialVersionUID", BasicType.LONG, Constants.PUTSTATIC)); + } + + getStaticInitializer().getBody().insert(il); + } + + private InstructionList initializeAllTjps() { + InstructionList list = new InstructionList(); + InstructionFactory fact = getFactory(); + + // make a new factory + list.append(fact.createNew(factoryType)); + list.append(InstructionFactory.createDup(1)); + + list.append(InstructionFactory.PUSH(getConstantPool(), getFileName())); + + // load the current Class object + // XXX check that this works correctly for inners/anonymous + list.append(InstructionFactory.PUSH(getConstantPool(), getClassName())); + // XXX do we need to worry about the fact the theorectically this could throw + // a ClassNotFoundException + list.append(fact.createInvoke("java.lang.Class", "forName", classType, new Type[] { Type.STRING }, Constants.INVOKESTATIC)); + + list.append(fact.createInvoke(factoryType.getClassName(), "<init>", Type.VOID, new Type[] { Type.STRING, classType }, + Constants.INVOKESPECIAL)); + + list.append(InstructionFactory.createStore(factoryType, 0)); + + List entries = new ArrayList(tjpFields.entrySet()); + Collections.sort(entries, new Comparator() { + public int compare(Object a, Object b) { + Map.Entry ae = (Map.Entry) a; + Map.Entry be = (Map.Entry) b; + return ((Field) ae.getValue()).getName().compareTo(((Field) be.getValue()).getName()); + } + }); + + for (Iterator i = entries.iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + initializeTjp(fact, list, (Field) entry.getValue(), (BcelShadow) entry.getKey()); + } + + return list; + } + + private void initializeTjp(InstructionFactory fact, InstructionList list, Field field, BcelShadow shadow) { + Member sig = shadow.getSignature(); + // ResolvedMember mem = shadow.getSignature().resolve(shadow.getWorld()); + + // load the factory + list.append(InstructionFactory.createLoad(factoryType, 0)); + + // load the kind + list.append(InstructionFactory.PUSH(getConstantPool(), shadow.getKind().getName())); + + // create the signature + list.append(InstructionFactory.createLoad(factoryType, 0)); + + String signatureMakerName = SignatureUtils.getSignatureMakerName(sig); + ObjectType signatureType = new ObjectType(SignatureUtils.getSignatureType(sig)); + + if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have optimized factory methods in 1.2 + list.append(InstructionFactory.PUSH(getConstantPool(), SignatureUtils.getSignatureString(sig, shadow.getWorld()))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY1, + Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.METHOD)) { + BcelWorld w = shadow.getWorld(); + // For methods, push the parts of the signature on. + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getModifiers(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), sig.getName())); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getDeclaringType()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterTypes()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterNames(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getExceptions(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getReturnType()))); + // And generate a call to the variant of makeMethodSig() that takes 7 strings + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY7, + Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.MONITORENTER)) { + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getDeclaringType()))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY1, + Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.MONITOREXIT)) { + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getDeclaringType()))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY1, + Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.HANDLER)) { + BcelWorld w = shadow.getWorld(); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getDeclaringType()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterTypes()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterNames(w)))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY3, + Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.CONSTRUCTOR)) { + BcelWorld w = shadow.getWorld(); + if (w.isJoinpointArrayConstructionEnabled() && sig.getDeclaringType().isArray()) { + // its the magical new jp + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(Modifier.PUBLIC))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getDeclaringType()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterTypes()))); + list.append(InstructionFactory.PUSH(getConstantPool(), ""));// makeString("")));//sig.getParameterNames(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), ""));// makeString("")));//sig.getExceptions(w)))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY5, + Constants.INVOKEVIRTUAL)); + } else { + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getModifiers(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getDeclaringType()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterTypes()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterNames(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getExceptions(w)))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY5, + Constants.INVOKEVIRTUAL)); + } + } else if (sig.getKind().equals(Member.FIELD)) { + BcelWorld w = shadow.getWorld(); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getModifiers(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), sig.getName())); + // see pr227401 + UnresolvedType dType = sig.getDeclaringType(); + if (dType.getTypekind() == TypeKind.PARAMETERIZED || dType.getTypekind() == TypeKind.GENERIC) { + dType = sig.getDeclaringType().resolve(world).getGenericType(); + } + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(dType))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getReturnType()))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY4, + Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.ADVICE)) { + BcelWorld w = shadow.getWorld(); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getModifiers(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), sig.getName())); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getDeclaringType()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterTypes()))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getParameterNames(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getExceptions(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString((sig.getReturnType())))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, new Type[] { Type.STRING, + Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING }, Constants.INVOKEVIRTUAL)); + } else if (sig.getKind().equals(Member.STATIC_INITIALIZATION)) { + BcelWorld w = shadow.getWorld(); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getModifiers(w)))); + list.append(InstructionFactory.PUSH(getConstantPool(), makeString(sig.getDeclaringType()))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY2, + Constants.INVOKEVIRTUAL)); + } else { + list.append(InstructionFactory.PUSH(getConstantPool(), SignatureUtils.getSignatureString(sig, shadow.getWorld()))); + list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY1, + Constants.INVOKEVIRTUAL)); + } + + // XXX should load source location from shadow + list.append(Utility.createConstant(fact, shadow.getSourceLine())); + + final String factoryMethod; + + if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have makeESJP() in 1.2 + list.append(fact.createInvoke(factoryType.getClassName(), "makeSJP", staticTjpType, new Type[] { Type.STRING, sigType, + Type.INT }, Constants.INVOKEVIRTUAL)); + + // put it in the field + list.append(fact.createFieldAccess(getClassName(), field.getName(), staticTjpType, Constants.PUTSTATIC)); + + } else { + if (staticTjpType.equals(field.getType())) { + factoryMethod = "makeSJP"; + } else if (enclosingStaticTjpType.equals(field.getType())) { + factoryMethod = "makeESJP"; + } else { + throw new Error("should not happen"); + } + list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(), new Type[] { Type.STRING, + sigType, Type.INT }, Constants.INVOKEVIRTUAL)); + // put it in the field + list.append(fact.createFieldAccess(getClassName(), field.getName(), field.getType(), Constants.PUTSTATIC)); + } + } + + protected String makeString(int i) { + return Integer.toString(i, 16); // ??? expensive + } + + protected 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 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 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(':'); } - FieldGen fGen = new FieldGen(modifiers,jpType,"ajc$tjp_" + tjpFields.size(),getConstantPool()); - addField(fGen); - ret = fGen.getField(); - tjpFields.put(shadow, ret); - return ret; - } - - - //FIXME ATAJ needed only for slow Aspects.aspectOf - keep or remove -// private void addAjClassField() { -// // Andy: Why build it again?? -// Field ajClassField = new FieldGen( -// Modifier.PRIVATE | Modifier.FINAL | Modifier.STATIC, -// classType, -// "aj$class", -// getConstantPool()).getField(); -// addField(ajClassField); -// -// InstructionList il = new InstructionList(); -// il.append(new PUSH(getConstantPool(), getClassName())); -// il.append(fact.createInvoke("java.lang.Class", "forName", classType, -// new Type[] {Type.STRING}, Constants.INVOKESTATIC)); -// il.append(fact.createFieldAccess(getClassName(), ajClassField.getName(), -// classType, Constants.PUTSTATIC)); -// -// getStaticInitializer().getBody().insert(il); -// } - - private void addAjcInitializers() { - if (tjpFields.size() == 0 && !serialVersionUIDRequiresInitialization) return; - InstructionList il = null; - - if (tjpFields.size()>0) { - il = initializeAllTjps(); - } - - if (serialVersionUIDRequiresInitialization) { - if (il==null) { - il= new InstructionList(); - } - il.append(InstructionFactory.PUSH(getConstantPool(),calculatedSerialVersionUID)); - il.append(getFactory().createFieldAccess(getClassName(), "serialVersionUID", BasicType.LONG, Constants.PUTSTATIC)); - } - - getStaticInitializer().getBody().insert(il); - } - - - private InstructionList initializeAllTjps() { - InstructionList list = new InstructionList(); - InstructionFactory fact = getFactory(); - - // make a new factory - list.append(fact.createNew(factoryType)); - list.append(InstructionFactory.createDup(1)); - - list.append(InstructionFactory.PUSH(getConstantPool(), getFileName())); - - // load the current Class object - //XXX check that this works correctly for inners/anonymous - list.append(InstructionFactory.PUSH(getConstantPool(), getClassName())); - //XXX do we need to worry about the fact the theorectically this could throw - //a ClassNotFoundException - list.append(fact.createInvoke("java.lang.Class", "forName", classType, - new Type[] {Type.STRING}, Constants.INVOKESTATIC)); - - list.append(fact.createInvoke(factoryType.getClassName(), "<init>", - Type.VOID, new Type[] {Type.STRING, classType}, - Constants.INVOKESPECIAL)); - - list.append(InstructionFactory.createStore(factoryType, 0)); - - List entries = new ArrayList(tjpFields.entrySet()); - Collections.sort(entries, new Comparator() { - public int compare(Object a, Object b) { - Map.Entry ae = (Map.Entry) a; - Map.Entry be = (Map.Entry) b; - return ((Field) ae.getValue()) - .getName() - .compareTo(((Field)be.getValue()).getName()); - } - }); - - for (Iterator i = entries.iterator(); i.hasNext(); ) { - Map.Entry entry = (Map.Entry)i.next(); - initializeTjp(fact, list, (Field)entry.getValue(), (BcelShadow)entry.getKey()); - } - - return list; - } - - - private void initializeTjp(InstructionFactory fact, InstructionList list, - Field field, BcelShadow shadow) - { - Member sig = shadow.getSignature(); - //ResolvedMember mem = shadow.getSignature().resolve(shadow.getWorld()); - - // load the factory - list.append(InstructionFactory.createLoad(factoryType, 0)); - - // load the kind - list.append(InstructionFactory.PUSH(getConstantPool(), shadow.getKind().getName())); - - // create the signature - list.append(InstructionFactory.createLoad(factoryType, 0)); - - String signatureMakerName = SignatureUtils.getSignatureMakerName(sig); - ObjectType signatureType = new ObjectType(SignatureUtils.getSignatureType(sig)); - - - if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have optimized factory methods in 1.2 - list.append(InstructionFactory.PUSH(getConstantPool(), SignatureUtils.getSignatureString(sig,shadow.getWorld()))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY1, Constants.INVOKEVIRTUAL)); - } else if (sig.getKind().equals(Member.METHOD)) { - BcelWorld w = shadow.getWorld(); - // For methods, push the parts of the signature on. - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName())); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getReturnType()))); - // And generate a call to the variant of makeMethodSig() that takes 7 strings - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY7, - Constants.INVOKEVIRTUAL)); - } else if (sig.getKind().equals(Member.MONITORENTER)) { - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY1, - Constants.INVOKEVIRTUAL)); - } else if (sig.getKind().equals(Member.MONITOREXIT)) { - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY1, - Constants.INVOKEVIRTUAL)); - } else if (sig.getKind().equals(Member.HANDLER)) { - BcelWorld w = shadow.getWorld(); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w)))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY3, - Constants.INVOKEVIRTUAL)); - } else if(sig.getKind().equals(Member.CONSTRUCTOR)) { - BcelWorld w = shadow.getWorld(); - if (w.isJoinpointArrayConstructionEnabled() && sig.getDeclaringType().isArray()) { - // its the magical new jp - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(Modifier.PUBLIC))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); - list.append(InstructionFactory.PUSH(getConstantPool(),""));//makeString("")));//sig.getParameterNames(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),""));//makeString("")));//sig.getExceptions(w)))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY5, - Constants.INVOKEVIRTUAL)); - } else { - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w)))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY5, - Constants.INVOKEVIRTUAL)); - } - } else if(sig.getKind().equals(Member.FIELD)) { - BcelWorld w = shadow.getWorld(); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName())); - // see pr227401 - UnresolvedType dType = sig.getDeclaringType(); - if (dType.getTypekind()==TypeKind.PARAMETERIZED || - dType.getTypekind()==TypeKind.GENERIC) { - dType = sig.getDeclaringType().resolve(world).getGenericType(); - } - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(dType))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getReturnType()))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY4, - Constants.INVOKEVIRTUAL)); - } else if(sig.getKind().equals(Member.ADVICE)) { - BcelWorld w = shadow.getWorld(); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),sig.getName())); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterTypes()))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getParameterNames(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getExceptions(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString((sig.getReturnType())))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType, - new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING }, - Constants.INVOKEVIRTUAL)); - } else if(sig.getKind().equals(Member.STATIC_INITIALIZATION)) { - BcelWorld w = shadow.getWorld(); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getModifiers(w)))); - list.append(InstructionFactory.PUSH(getConstantPool(),makeString(sig.getDeclaringType()))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY2, - Constants.INVOKEVIRTUAL)); - } else { - list.append(InstructionFactory.PUSH(getConstantPool(), SignatureUtils.getSignatureString(sig,shadow.getWorld()))); - list.append(fact.createInvoke(factoryType.getClassName(), - signatureMakerName,signatureType,Type.STRINGARRAY1, - Constants.INVOKEVIRTUAL)); - } - - //XXX should load source location from shadow - list.append(Utility.createConstant(fact, shadow.getSourceLine())); - - final String factoryMethod; - - if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have makeESJP() in 1.2 - list.append(fact.createInvoke(factoryType.getClassName(), - "makeSJP", staticTjpType, - new Type[] { Type.STRING, sigType, Type.INT}, - Constants.INVOKEVIRTUAL)); - - // put it in the field - list.append(fact.createFieldAccess(getClassName(), field.getName(),staticTjpType, Constants.PUTSTATIC)); - - } else { - if (staticTjpType.equals(field.getType())) { - factoryMethod = "makeSJP"; - } else if (enclosingStaticTjpType.equals(field.getType())) { - factoryMethod = "makeESJP"; - } else { - throw new Error("should not happen"); - } - list.append(fact.createInvoke(factoryType.getClassName(), - factoryMethod, field.getType(), - new Type[] { Type.STRING, sigType, Type.INT}, - Constants.INVOKEVIRTUAL)); - // put it in the field - list.append(fact.createFieldAccess(getClassName(), field.getName(), field.getType(), Constants.PUTSTATIC)); - } - } - - - protected String makeString(int i) { - return Integer.toString(i, 16); //??? expensive - } - - - protected 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 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 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(); - } - + return buf.toString(); + } + public ResolvedType getType() { - if (myType == null) return null; + if (myType == null) + return null; return myType.getResolvedTypeX(); } @@ -1235,18 +1167,17 @@ public final class LazyClassGen { makeSyntheticAndTransientIfNeeded(field); BcelField bcelField = null; if (getBcelObjectType() != null) { - bcelField = new BcelField(getBcelObjectType(),field.getField()); + bcelField = new BcelField(getBcelObjectType(), field.getField()); } else { - bcelField = new BcelField(getName(),field.getField(),world); + bcelField = new BcelField(getName(), field.getField(), world); } fields.add(bcelField); -// myGen.addField(field.getField()); + // myGen.addField(field.getField()); } - + private void makeSyntheticAndTransientIfNeeded(FieldGen field) { - if (field.getName().startsWith(NameMangler.PREFIX) && - !field.getName().startsWith("ajc$interField$") && - !field.getName().startsWith("ajc$instance$")) { + if (field.getName().startsWith(NameMangler.PREFIX) && !field.getName().startsWith("ajc$interField$") + && !field.getName().startsWith("ajc$instance$")) { // it's an aj added field // first do transient if (!field.isStatic()) { @@ -1258,34 +1189,33 @@ public final class LazyClassGen { field.setModifiers(field.getModifiers() | ACC_SYNTHETIC); } if (!hasSyntheticAttribute(field.getAttributes())) { - // belt and braces, do the attribute even on Java 5 in addition to the modifier flag -// Attribute[] oldAttrs = field.getAttributes(); -// Attribute[] newAttrs = new Attribute[oldAttrs.length + 1]; -// System.arraycopy(oldAttrs, 0, newAttrs, 0, oldAttrs.length); - ConstantPool cpg = myGen.getConstantPool(); - int index = cpg.addUtf8("Synthetic"); - Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg); - field.addAttribute(synthetic); -// newAttrs[newAttrs.length - 1] = synthetic; -// field.setAttributes(newAttrs); + // belt and braces, do the attribute even on Java 5 in addition to the modifier flag + // Attribute[] oldAttrs = field.getAttributes(); + // Attribute[] newAttrs = new Attribute[oldAttrs.length + 1]; + // System.arraycopy(oldAttrs, 0, newAttrs, 0, oldAttrs.length); + ConstantPool cpg = myGen.getConstantPool(); + int index = cpg.addUtf8("Synthetic"); + Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg); + field.addAttribute(synthetic); + // newAttrs[newAttrs.length - 1] = synthetic; + // field.setAttributes(newAttrs); } } } - - private boolean hasSyntheticAttribute(List attributes) { + + private boolean hasSyntheticAttribute(List attributes) { for (int i = 0; i < attributes.size(); i++) { - if (((Attribute)attributes.get(i)).getName().equals("Synthetic")) { + if (((Attribute) attributes.get(i)).getName().equals("Synthetic")) { return true; } } return false; } - + public void addField(FieldGen field, ISourceLocation sourceLocation) { addField(field); - if (!(field.isPrivate() - && (field.isStatic() || field.isTransient()))) { - errorOnAddedField(field,sourceLocation); + if (!(field.isPrivate() && (field.isStatic() || field.isTransient()))) { + errorOnAddedField(field, sourceLocation); } } @@ -1296,73 +1226,75 @@ public final class LazyClassGen { public boolean isInterface() { return myGen.isInterface(); } - - public boolean isAbstract() { - return myGen.isAbstract(); - } + + public boolean isAbstract() { + return myGen.isAbstract(); + } public LazyMethodGen getLazyMethodGen(Member m) { - return getLazyMethodGen(m.getName(), m.getSignature(),false); + return getLazyMethodGen(m.getName(), m.getSignature(), false); } public LazyMethodGen getLazyMethodGen(String name, String signature) { - return getLazyMethodGen(name,signature,false); + return getLazyMethodGen(name, signature, false); } - - public LazyMethodGen getLazyMethodGen(String name, String signature,boolean allowMissing) { + + public LazyMethodGen getLazyMethodGen(String name, String signature, boolean allowMissing) { for (Iterator i = methodGens.iterator(); i.hasNext();) { LazyMethodGen gen = (LazyMethodGen) i.next(); if (gen.getName().equals(name) && gen.getSignature().equals(signature)) return gen; } - + if (!allowMissing) { - throw new BCException("Class " + this.getName() + " does not have a method " - + name + " with signature " + signature); - } - + throw new BCException("Class " + this.getName() + " does not have a method " + name + " with signature " + signature); + } + return null; } - - + public void forcePublic() { myGen.setModifiers(Utility.makePublic(myGen.getModifiers())); } - public boolean hasAnnotation(UnresolvedType t) { - + // annotations on the real thing AnnotationGen agens[] = myGen.getAnnotations(); - if (agens==null) return false; + if (agens == null) + return false; for (int i = 0; i < agens.length; i++) { AnnotationGen gen = agens[i]; - if (t.equals(UnresolvedType.forSignature(gen.getTypeSignature()))) return true; + if (t.equals(UnresolvedType.forSignature(gen.getTypeSignature()))) + return true; } - + // annotations added during this weave - + return false; } - + public void addAnnotation(AnnotationGen a) { if (!hasAnnotation(UnresolvedType.forSignature(a.getTypeSignature()))) { - annotations.add(new AnnotationGen(a,getConstantPool(),true)); + annotations.add(new AnnotationGen(a, getConstantPool(), true)); } } - + // this test is like asking: // if (UnresolvedType.SERIALIZABLE.resolve(getType().getWorld()).isAssignableFrom(getType())) { - // only we don't do that because this forces us to find all the supertypes of the type, + // only we don't do that because this forces us to find all the supertypes of the type, // and if one of them is missing we fail, and it's not worth failing just to put out // a warning message! private boolean implementsSerializable(ResolvedType aType) { - if (aType.getSignature().equals(UnresolvedType.SERIALIZABLE.getSignature())) return true; - + if (aType.getSignature().equals(UnresolvedType.SERIALIZABLE.getSignature())) + return true; + ResolvedType[] interfaces = aType.getDeclaredInterfaces(); for (int i = 0; i < interfaces.length; i++) { - if (interfaces[i].isMissing()) continue; - if (implementsSerializable(interfaces[i])) return true; + if (interfaces[i].isMissing()) + continue; + if (implementsSerializable(interfaces[i])) + return true; } ResolvedType superType = aType.getSuperclass(); if (superType != null && !superType.isMissing()) { @@ -1370,30 +1302,31 @@ public final class LazyClassGen { } return false; } - + public boolean isAtLeastJava5() { - return (myGen.getMajor()>=Constants.MAJOR_1_5); + return (myGen.getMajor() >= Constants.MAJOR_1_5); } /** - * Return the next available field name with the specified 'prefix', e.g. - * for prefix 'class$' where class$0, class$1 exist then return class$2 + * Return the next available field name with the specified 'prefix', e.g. for prefix 'class$' where class$0, class$1 exist then + * return class$2 */ public String allocateField(String prefix) { int highestAllocated = -1; - List/*BcelField*/ fs = getFieldGens(); + List/* BcelField */fs = getFieldGens(); for (int i = 0; i < fs.size(); i++) { - BcelField field = (BcelField)fs.get(i); + BcelField field = (BcelField) fs.get(i); if (field.getName().startsWith(prefix)) { try { int num = Integer.parseInt(field.getName().substring(prefix.length())); - if (num>highestAllocated) highestAllocated = num; + if (num > highestAllocated) + highestAllocated = num; } catch (NumberFormatException nfe) { // something wrong with the number on the end of that field... } } } - return prefix+Integer.toString(highestAllocated+1); + return prefix + Integer.toString(highestAllocated + 1); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/Bindings.java b/weaver/src/org/aspectj/weaver/patterns/Bindings.java index 2fc3dfc1c..4853dd049 100644 --- a/weaver/src/org/aspectj/weaver/patterns/Bindings.java +++ b/weaver/src/org/aspectj/weaver/patterns/Bindings.java @@ -10,7 +10,6 @@ * PARC initial implementation * ******************************************************************/ - package org.aspectj.weaver.patterns; import org.aspectj.bridge.IMessage; @@ -19,37 +18,34 @@ import org.aspectj.weaver.UnresolvedType; public class Bindings { public static final Bindings NONE = new Bindings(0); - + private BindingPattern[] bindings; - + public Bindings(BindingPattern[] bindings) { this.bindings = bindings; } - + public Bindings(int count) { this(new BindingPattern[count]); } - + public void register(BindingPattern binding, IScope scope) { int index = binding.getFormalIndex(); BindingPattern existingBinding = bindings[index]; if (existingBinding != null) { - scope.message(IMessage.ERROR, existingBinding, binding, - "multiple bindings" + index + ", " + binding); + scope.message(IMessage.ERROR, existingBinding, binding, "multiple bindings" + index + ", " + binding); } bindings[index] = binding; } - + public void mergeIn(Bindings other, IScope scope) { - for (int i=0, len=other.bindings.length; i < len; i++) { + for (int i = 0, len = other.bindings.length; i < len; i++) { if (other.bindings[i] != null) { register(other.bindings[i], scope); } } } - - - + /** * signals an error if one has a binding and other doesn't */ @@ -60,8 +56,8 @@ public class Bindings { if (len != b2.length) { throw new BCException("INSANE"); } - - for (int i=0; i < len; i++) { + + for (int i = 0; i < len; i++) { if (b1[i] == null && b2[i] != null) { scope.message(IMessage.ERROR, b2[i], "inconsistent binding"); b1[i] = b2[i]; // done just to produce fewer error messages @@ -74,74 +70,67 @@ public class Bindings { public String toString() { StringBuffer buf = new StringBuffer("Bindings("); - for (int i=0, len=bindings.length; i < len; i++) { - if (i > 0) buf.append(", "); + for (int i = 0, len = bindings.length; i < len; i++) { + if (i > 0) + buf.append(", "); buf.append(bindings[i]); } buf.append(")"); return buf.toString(); } - - + public int[] getUsedFormals() { - //System.out.println("used: " + this); + // System.out.println("used: " + this); int[] ret = new int[bindings.length]; int index = 0; - for (int i=0, len=bindings.length; i < len; i++) { + for (int i = 0, len = bindings.length; i < len; i++) { if (bindings[i] != null) { ret[index++] = i; } } int[] newRet = new int[index]; System.arraycopy(ret, 0, newRet, 0, index); - //System.out.println("ret: " + index); + // System.out.println("ret: " + index); return newRet; } - + public UnresolvedType[] getUsedFormalTypes() { UnresolvedType[] ret = new UnresolvedType[bindings.length]; int index = 0; - for (int i=0, len=bindings.length; i < len; i++) { + for (int i = 0, len = bindings.length; i < len; i++) { if (bindings[i] != null) { - ret[index++] = ((BindingTypePattern)bindings[i]).getExactType(); + ret[index++] = ((BindingTypePattern) bindings[i]).getExactType(); } } UnresolvedType[] newRet = new UnresolvedType[index]; System.arraycopy(ret, 0, newRet, 0, index); - //System.out.println("ret: " + index); + // System.out.println("ret: " + index); return newRet; } - public Bindings copy() { -// int len = bindings.length; -// boolean[] a = new boolean[len]; -// System.arraycopy(bindings, 0, a, 0, len); - return new Bindings((BindingPattern[])bindings.clone()); + // int len = bindings.length; + // boolean[] a = new boolean[len]; + // System.arraycopy(bindings, 0, a, 0, len); + return new Bindings((BindingPattern[]) bindings.clone()); } public void checkAllBound(IScope scope) { - for (int i=0, len=bindings.length; i < len; i++) { + for (int i = 0, len = bindings.length; i < len; i++) { if (bindings[i] == null) { - // ATAJ: avoid warnings for implicit bindings - if (scope.getFormal(i) instanceof FormalBinding.ImplicitFormalBinding) { - bindings[i] = new BindingTypePattern(scope.getFormal(i), false); - } else { - scope.message(IMessage.ERROR, scope.getFormal(i), "formal unbound in pointcut "); - } + // ATAJ: avoid warnings for implicit bindings + if (scope.getFormal(i) instanceof FormalBinding.ImplicitFormalBinding) { + bindings[i] = new BindingTypePattern(scope.getFormal(i), false); + } else { + scope.message(IMessage.ERROR, scope.getFormal(i), "formal unbound in pointcut "); + } } } } - public int size() { return bindings.length; } - - public void checkEmpty(IScope scope, String message) { - for (int i=0, len=bindings.length; i < len; i++) { - if (bindings[i] != null) { - scope.message(IMessage.ERROR, bindings[i], message); - } - } + public int size() { + return bindings.length; } } |