binary aspect-declared methods conflict, lost their exception clauses larger fix to address more issues with aspect-declared methods in bytecode form also addressed declared exception issue more generally this fix should be more stable than a smaller hack that just fixed this specific bug report would have been. added a few tests to match increased scope.tags/V1_1_1
@@ -212,8 +212,8 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration { | |||
ResolvedMember signature = | |||
new ResolvedMember(Member.CONSTRUCTOR, declaringTypeX, declaredModifiers, | |||
ResolvedTypeX.VOID, "<init>", bindingAsMember.getParameterTypes()); | |||
signature.setCheckedExceptions(world.fromEclipse(binding.thrownExceptions)); | |||
ResolvedTypeX.VOID, "<init>", bindingAsMember.getParameterTypes(), | |||
world.fromEclipse(binding.thrownExceptions)); | |||
ResolvedMember syntheticInterMember = | |||
AjcMemberMaker.interConstructor(declaringTypeX, signature, aspectType); | |||
@@ -86,8 +86,8 @@ public class InterTypeMethodDeclaration extends InterTypeDeclaration { | |||
binding = classScope.referenceContext.binding.resolveTypesFor(binding); | |||
ResolvedMember sig = new ResolvedMember(Member.METHOD, EclipseFactory.fromBinding(onTypeBinding), | |||
declaredModifiers, EclipseFactory.fromBinding(binding.returnType), new String(declaredSelector), | |||
EclipseFactory.fromBindings(binding.parameters)); | |||
sig.setCheckedExceptions(world.fromEclipse(binding.thrownExceptions)); | |||
EclipseFactory.fromBindings(binding.parameters), | |||
world.fromEclipse(binding.thrownExceptions)); | |||
NewMethodTypeMunger myMunger = new NewMethodTypeMunger(sig, null); | |||
setMunger(myMunger); |
@@ -43,6 +43,7 @@ public class AjLookupEnvironment extends LookupEnvironment { | |||
// private boolean builtInterTypesAndPerClauses = false; | |||
private List pendingTypesToWeave = new ArrayList(); | |||
private Map dangerousInterfaces = new HashMap(); | |||
public AjLookupEnvironment( | |||
ITypeRequestor typeRequestor, | |||
@@ -151,16 +152,49 @@ public class AjLookupEnvironment extends LookupEnvironment { | |||
} | |||
} | |||
private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents, boolean skipInners) { | |||
// if (new String(sourceType.sourceName()).equals("Target")) { | |||
// Thread.currentThread().dumpStack(); | |||
// } | |||
// | |||
// System.out.println("weaving types: " + new String(sourceType.sourceName())); | |||
// System.out.println(" mungers: " + typeMungers); | |||
ResolvedTypeX onType = factory.fromEclipse(sourceType); | |||
WeaverStateInfo info = onType.getWeaverState(); | |||
if (info != null && !info.isOldStyle()) { | |||
Collection mungers = | |||
onType.getWeaverState().getTypeMungers(onType); | |||
//System.out.println("mungers: " + mungers); | |||
for (Iterator i = mungers.iterator(); i.hasNext(); ) { | |||
ConcreteTypeMunger m = (ConcreteTypeMunger)i.next(); | |||
EclipseTypeMunger munger = factory.makeEclipseTypeMunger(m); | |||
if (munger.munge(sourceType)) { | |||
if (onType.isInterface() && | |||
munger.getMunger().needsAccessToTopmostImplementor()) | |||
{ | |||
if (!onType.getWorld().getCrosscuttingMembersSet().containsAspect(munger.getAspectType())) { | |||
dangerousInterfaces.put(onType, | |||
"implementors of " + onType + " must be woven by " + | |||
munger.getAspectType()); | |||
} | |||
} | |||
} | |||
} | |||
return; | |||
} | |||
//System.out.println("dangerousInterfaces: " + dangerousInterfaces); | |||
for (Iterator i = dangerousInterfaces.entrySet().iterator(); i.hasNext();) { | |||
Map.Entry entry = (Map.Entry) i.next(); | |||
ResolvedTypeX interfaceType = (ResolvedTypeX)entry.getKey(); | |||
if (onType.isTopmostImplementor(interfaceType)) { | |||
factory.showMessage(IMessage.ERROR, | |||
onType + ": " + entry.getValue(), | |||
onType.getSourceLocation(), null); | |||
} | |||
} | |||
boolean needOldStyleWarning = (info != null && info.isOldStyle()); | |||
onType.clearInterTypeMungers(); | |||
for (Iterator i = declareParents.iterator(); i.hasNext();) { | |||
@@ -170,6 +204,12 @@ public class AjLookupEnvironment extends LookupEnvironment { | |||
for (Iterator i = typeMungers.iterator(); i.hasNext();) { | |||
EclipseTypeMunger munger = (EclipseTypeMunger) i.next(); | |||
if (munger.matches(onType)) { | |||
if (needOldStyleWarning) { | |||
factory.showMessage(IMessage.WARNING, | |||
"The class for " + onType + " should be recompiled with ajc-1.1.1 for best results", | |||
onType.getSourceLocation(), null); | |||
needOldStyleWarning = false; | |||
} | |||
onType.addInterTypeMunger(munger); | |||
} | |||
} |
@@ -192,8 +192,8 @@ public class EclipseFactory { | |||
binding.modifiers, | |||
fromBinding(binding.returnType), | |||
new String(binding.selector), | |||
fromBindings(binding.parameters)); | |||
ret.setCheckedExceptions(fromBindings(binding.thrownExceptions)); | |||
fromBindings(binding.parameters), | |||
fromBindings(binding.thrownExceptions)); | |||
return ret; | |||
} | |||
@@ -66,8 +66,8 @@ public class EclipseSourceType extends ResolvedTypeX.ConcreteName { | |||
return declaration instanceof AspectDeclaration; | |||
} | |||
public boolean isWovenBy(ResolvedTypeX aspectType) { | |||
return false; | |||
public WeaverStateInfo getWeaverState() { | |||
return null; | |||
} | |||
public ResolvedTypeX getSuperclass() { |
@@ -101,7 +101,7 @@ public class BinaryFormsTestCase extends CommandTestCase { | |||
args.add("testdata/src1/binary/client/Client1.java"); | |||
CommandTestCase.runCompiler(args, new int[] {9, 11, 15, 17}); | |||
CommandTestCase.runCompiler(args, new int[] {15, 17, 22}); | |||
args = new ArrayList(); | |||
args.add("-classpath"); |
@@ -6549,6 +6549,7 @@ | |||
<compile | |||
files="Client.java" | |||
classpath="aspectedInterfaceOnly.jar"> | |||
<message kind="error" line="0" text="LibraryAspect"/> | |||
<message kind="error" line="9" text="LibraryInterface"/> | |||
</compile> | |||
</ajc-test> | |||
@@ -6629,4 +6630,41 @@ | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs" | |||
pr="41175" | |||
title="reflective check of declared exceptions from aspect-declared methods"> | |||
<compile files="DeclaredExceptions.java"/> | |||
<run class="DeclaredExceptions"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs/interfaceLibrary" | |||
pr="41175" | |||
title="exception clause for aspect-declared interface methods - positive binary"> | |||
<compile files="Client.java" aspectpath="lib.jar"/> | |||
<run class="Client"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs/interfaceLibrary" | |||
pr="41175" | |||
title="exception clause for aspect-declared interface methods - negative binary"> | |||
<compile files="ClientCE.java" aspectpath="lib.jar"> | |||
<message kind="error" file="ClientCE.java" line="5"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs/interfaceLibrary" | |||
pr="41175" | |||
title="exception clause for aspect-declared class methods - positive binary"> | |||
<compile files="ClassClient.java" aspectpath="libClass.jar"/> | |||
<run class="ClassClient"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs/interfaceLibrary" | |||
pr="41175" | |||
title="exception clause for aspect-declared class methods - negative binary"> | |||
<compile files="ClassClientCE.java" aspectpath="libClass.jar"> | |||
<message kind="error" file="ClassClientCE.java" line="5"/> | |||
</compile> | |||
</ajc-test> | |||
</suite> |
@@ -12,36 +12,6 @@ | |||
<run class="Client"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs/interfaceLibrary" | |||
pr="41175" | |||
title="exception clause for aspect-declared interface methods - positive binary"> | |||
<compile files="Client.java" aspectpath="lib.jar"/> | |||
<run class="Client"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs/interfaceLibrary" | |||
pr="41175" | |||
title="exception clause for aspect-declared interface methods - negative binary"> | |||
<compile files="ClientCE.java" aspectpath="lib.jar"> | |||
<message kind="error" file="ClientCE.java" line="5"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs/interfaceLibrary" | |||
pr="41175" | |||
title="exception clause for aspect-declared class methods - positive binary"> | |||
<compile files="ClassClient.java" aspectpath="libClass.jar"/> | |||
<run class="Client"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs/interfaceLibrary" | |||
pr="41175" | |||
title="exception clause for aspect-declared class methods - negative binary"> | |||
<compile files="ClassClientCE.java" aspectpath="libClass.jar"> | |||
<message kind="error" file="ClassClientCE.java" line="5"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="new/pointcutLibrary" title="libraries-pointcuts compiles" | |||
comment="interim test just to show library compiles..."> | |||
<compile files="langlib/Pointcuts.java"/> |
@@ -0,0 +1,28 @@ | |||
import java.lang.reflect.Method; | |||
import java.io.*; | |||
import org.aspectj.testing.Tester; | |||
public class DeclaredExceptions { | |||
public static void main(String[] args) throws Exception { | |||
Class c = C.class; | |||
Method m = c.getDeclaredMethod("m", new Class[0]); | |||
Tester.checkEqual(m.getExceptionTypes().length, 1); | |||
Tester.checkEqual(m.getExceptionTypes()[0], IOException.class); | |||
c = I.class; | |||
m = c.getDeclaredMethod("m", new Class[0]); | |||
Tester.checkEqual(m.getExceptionTypes().length, 1); | |||
Tester.checkEqual(m.getExceptionTypes()[0], IOException.class); | |||
} | |||
} | |||
interface I {} | |||
class C {} | |||
aspect A { | |||
public void C.m() throws IOException { | |||
} | |||
public void I.m() throws IOException { } | |||
} |
@@ -88,7 +88,7 @@ public abstract class AjAttribute { | |||
if (name.equals(Aspect.AttributeName)) { | |||
return new Aspect(PerClause.readPerClause(s, context)); | |||
} else if (name.equals(WeaverState.AttributeName)) { | |||
return new WeaverState(WeaverStateKind.read(s)); | |||
return new WeaverState(WeaverStateInfo.read(s, context)); | |||
} else if (name.equals(AdviceAttribute.AttributeName)) { | |||
return AdviceAttribute.read(s, context); | |||
} else if (name.equals(PointcutDeclarationAttribute.AttributeName)) { | |||
@@ -162,15 +162,15 @@ public abstract class AjAttribute { | |||
public String getNameString() { | |||
return AttributeName; | |||
} | |||
private WeaverStateKind kind; | |||
public WeaverState(WeaverStateKind kind) { | |||
private WeaverStateInfo kind; | |||
public WeaverState(WeaverStateInfo kind) { | |||
this.kind = kind; | |||
} | |||
public void write(DataOutputStream s) throws IOException { | |||
kind.write(s); | |||
} | |||
public WeaverStateKind reify() { | |||
public WeaverStateInfo reify() { | |||
return kind; | |||
} | |||
} |
@@ -232,8 +232,8 @@ public class AjcMemberMaker { | |||
Modifier.PUBLIC, | |||
method.getReturnType(), | |||
NameMangler.superDispatchMethod(baseType, method.getName()), | |||
method.getParameterTypes()); | |||
//XXX needs thrown exceptions to be correct | |||
method.getParameterTypes(), | |||
method.getExceptions()); | |||
} | |||
public static ResolvedMember inlineAccessMethodForMethod(TypeX aspectType, ResolvedMember method) { | |||
@@ -249,8 +249,7 @@ public class AjcMemberMaker { | |||
NameMangler.inlineAccessMethodForMethod(method.getName(), | |||
method.getDeclaringType(), aspectType), | |||
paramTypes); | |||
//XXX needs thrown exceptions to be correct | |||
paramTypes, method.getExceptions()); | |||
} | |||
public static ResolvedMember inlineAccessMethodForFieldGet(TypeX aspectType, Member field) { | |||
@@ -382,7 +381,8 @@ public class AjcMemberMaker { | |||
Modifier.PUBLIC, | |||
ResolvedTypeX.VOID, | |||
"<init>", | |||
constructor.getParameterTypes()); | |||
constructor.getParameterTypes(), | |||
constructor.getExceptions()); | |||
//System.out.println("ret: " + ret + " mods: " + Modifier.toString(modifiers)); | |||
if (Modifier.isPublic(constructor.getModifiers())) | |||
return ret; | |||
@@ -429,7 +429,8 @@ public class AjcMemberMaker { | |||
return new ResolvedMember(Member.METHOD, aspectType, PUBLIC_STATIC, | |||
field.getReturnType(), | |||
NameMangler.interFieldGetDispatcher(aspectType, field.getDeclaringType(), field.getName()), | |||
field.isStatic() ? TypeX.NONE : new TypeX[] {field.getDeclaringType()} | |||
field.isStatic() ? TypeX.NONE : new TypeX[] {field.getDeclaringType()}, | |||
TypeX.NONE | |||
); | |||
} | |||
@@ -451,7 +452,7 @@ public class AjcMemberMaker { | |||
makePublicNonFinal(field.getModifiers()), | |||
field.getReturnType(), | |||
NameMangler.interFieldClassField(field.getModifiers(), aspectType, field.getDeclaringType(), field.getName()), | |||
TypeX.NONE | |||
TypeX.NONE, TypeX.NONE | |||
); | |||
} | |||
@@ -464,7 +465,7 @@ public class AjcMemberMaker { | |||
return new ResolvedMember(Member.FIELD, onClass, makePublicNonFinal(field.getModifiers()), | |||
field.getReturnType(), | |||
NameMangler.interFieldInterfaceField(aspectType, field.getDeclaringType(), field.getName()), | |||
TypeX.NONE | |||
TypeX.NONE, TypeX.NONE | |||
); | |||
} | |||
@@ -478,7 +479,7 @@ public class AjcMemberMaker { | |||
return new ResolvedMember(Member.METHOD, onType, modifiers, | |||
ResolvedTypeX.VOID, | |||
NameMangler.interFieldInterfaceSetter(aspectType, field.getDeclaringType(), field.getName()), | |||
new TypeX[] {field.getReturnType()} | |||
new TypeX[] {field.getReturnType()}, TypeX.NONE | |||
); | |||
} | |||
@@ -492,7 +493,7 @@ public class AjcMemberMaker { | |||
return new ResolvedMember(Member.METHOD, onType, modifiers, | |||
field.getReturnType(), | |||
NameMangler.interFieldInterfaceGetter(aspectType, field.getDeclaringType(), field.getName()), | |||
TypeX.NONE | |||
TypeX.NONE, TypeX.NONE | |||
); | |||
} | |||
@@ -514,7 +515,7 @@ public class AjcMemberMaker { | |||
modifiers, | |||
meth.getReturnType(), | |||
NameMangler.interMethod(meth.getModifiers(), aspectType, meth.getDeclaringType(), meth.getName()), | |||
meth.getParameterTypes()); | |||
meth.getParameterTypes(), meth.getExceptions()); | |||
} | |||
/** | |||
@@ -530,7 +531,7 @@ public class AjcMemberMaker { | |||
return new ResolvedMember(Member.METHOD, aspectType, PUBLIC_STATIC, | |||
meth.getReturnType(), | |||
NameMangler.interMethodDispatcher(aspectType, meth.getDeclaringType(), meth.getName()), | |||
paramTypes); | |||
paramTypes, meth.getExceptions()); | |||
} | |||
/** | |||
@@ -552,7 +553,7 @@ public class AjcMemberMaker { | |||
return new ResolvedMember(Member.METHOD, aspectType, modifiers, | |||
meth.getReturnType(), | |||
NameMangler.interMethodBody(aspectType, meth.getDeclaringType(), meth.getName()), | |||
paramTypes); | |||
paramTypes, meth.getExceptions()); | |||
} | |||
@@ -568,7 +569,7 @@ public class AjcMemberMaker { | |||
ret.getModifiers(), | |||
ret.getReturnType(), | |||
ret.getName(), | |||
freshParams); | |||
freshParams, ret.getExceptions()); | |||
} | |||
public static ResolvedMember toObjectConversionMethod(TypeX fromType) { | |||
@@ -580,7 +581,7 @@ public class AjcMemberMaker { | |||
PUBLIC_STATIC, | |||
TypeX.OBJECT, | |||
name, | |||
new TypeX[] { fromType }); | |||
new TypeX[] { fromType }, TypeX.NONE); | |||
} else { | |||
return null; | |||
} |
@@ -66,6 +66,10 @@ public class CrosscuttingMembersSet { | |||
return isAspect; | |||
} | |||
public boolean containsAspect(TypeX aspectType) { | |||
return members.containsKey(aspectType); | |||
} | |||
//XXX only for testing | |||
public void addFixedCrosscuttingMembers(ResolvedTypeX aspectType) { | |||
members.put(aspectType, aspectType.crosscuttingMembers); |
@@ -34,7 +34,19 @@ public class ResolvedMember extends Member implements IHasPosition { | |||
protected int start, end; | |||
protected ISourceContext sourceContext = null; | |||
// ---- | |||
//XXX deprecate this in favor of the constructor below | |||
public ResolvedMember( | |||
Kind kind, | |||
TypeX declaringType, | |||
int modifiers, | |||
TypeX returnType, | |||
String name, | |||
TypeX[] parameterTypes) | |||
{ | |||
super(kind, declaringType, modifiers, returnType, name, parameterTypes); | |||
} | |||
public ResolvedMember( | |||
Kind kind, | |||
@@ -42,9 +54,11 @@ public class ResolvedMember extends Member implements IHasPosition { | |||
int modifiers, | |||
TypeX returnType, | |||
String name, | |||
TypeX[] parameterTypes) | |||
TypeX[] parameterTypes, | |||
TypeX[] checkedExceptions) | |||
{ | |||
super(kind, declaringType, modifiers, returnType, name, parameterTypes); | |||
this.checkedExceptions = checkedExceptions; | |||
} | |||
public ResolvedMember( |
@@ -54,7 +54,7 @@ public abstract class ResolvedTypeMunger { | |||
//System.err.println("matching: " + this + " to " + matchType + " onType = " + onType); | |||
if (matchType.equals(onType)) { | |||
if (!onType.isExposedToWeaver()) { | |||
if (!onType.isWovenBy(aspectType)) { | |||
if (onType.getWeaverState() != null) { | |||
if (matchType.getWorld().getLint().typeNotExposedToWeaver.isEnabled()) { | |||
matchType.getWorld().getLint().typeNotExposedToWeaver.signal( | |||
matchType.getName(), signature.getSourceLocation()); | |||
@@ -183,4 +183,18 @@ public abstract class ResolvedTypeMunger { | |||
return null; | |||
} | |||
public boolean changesPublicSignature() { | |||
return kind == Field || kind == Method || kind == Constructor; | |||
} | |||
public boolean needsAccessToTopmostImplementor() { | |||
if (kind == Field) { | |||
return true; | |||
} else if (kind == Method) { | |||
return !signature.isAbstract(); | |||
} else { | |||
return false; | |||
} | |||
} | |||
} |
@@ -575,8 +575,8 @@ public abstract class ResolvedTypeX extends TypeX { | |||
return delegate.isExposedToWeaver(); //??? where does this belong | |||
} | |||
public boolean isWovenBy(ResolvedTypeX aspectType) { | |||
return delegate.isWovenBy(aspectType); | |||
public WeaverStateInfo getWeaverState() { | |||
return delegate.getWeaverState(); | |||
} | |||
public ResolvedMember[] getDeclaredFields() { | |||
@@ -684,7 +684,7 @@ public abstract class ResolvedTypeX extends TypeX { | |||
// public abstract ISourceLocation getSourceLocation(); | |||
public abstract boolean isWovenBy(ResolvedTypeX aspectType); | |||
public abstract WeaverStateInfo getWeaverState(); | |||
// public ISourceContext getSourceContext() { | |||
// return sourceContext; | |||
@@ -1270,8 +1270,7 @@ public abstract class ResolvedTypeX extends TypeX { | |||
public ISourceLocation getSourceLocation() { return null; } | |||
public boolean isExposedToWeaver() { return false; } | |||
public boolean isWovenBy(ResolvedTypeX aspectType) { | |||
return false; | |||
public WeaverStateInfo getWeaverState() { | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,121 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Common Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/cpl-v10.html | |||
* | |||
* Contributors: | |||
* PARC initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.weaver; | |||
import java.io.DataInputStream; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.util.TypeSafeEnum; | |||
import org.aspectj.weaver.bcel.BcelTypeMunger; | |||
public class WeaverStateInfo { | |||
private List/*Entry*/ typeMungers; | |||
private boolean oldStyle; | |||
public WeaverStateInfo() { | |||
this(new ArrayList(), false); | |||
} | |||
private WeaverStateInfo(List typeMungers, boolean oldStyle) { | |||
this.typeMungers = typeMungers; | |||
this.oldStyle = oldStyle; | |||
} | |||
private static final int UNTOUCHED=0, WOVEN=2, EXTENDED=3; | |||
public static final WeaverStateInfo read(DataInputStream s, ISourceContext context) throws IOException { | |||
byte b = s.readByte(); | |||
switch(b) { | |||
case UNTOUCHED: | |||
throw new RuntimeException("unexpected UNWOVEN"); | |||
case WOVEN: | |||
return new WeaverStateInfo(Collections.EMPTY_LIST, true); | |||
case EXTENDED: | |||
int n = s.readShort(); | |||
List l = new ArrayList(); | |||
for (int i=0; i < n; i++) { | |||
TypeX aspectType = TypeX.read(s); | |||
ResolvedTypeMunger typeMunger = | |||
ResolvedTypeMunger.read(s, context); | |||
l.add(new Entry(aspectType, typeMunger)); | |||
} | |||
return new WeaverStateInfo(l, false); | |||
} | |||
throw new RuntimeException("bad WeaverState.Kind: " + b); | |||
} | |||
private static class Entry { | |||
public TypeX aspectType; | |||
public ResolvedTypeMunger typeMunger; | |||
public Entry(TypeX aspectType, ResolvedTypeMunger typeMunger) { | |||
this.aspectType = aspectType; | |||
this.typeMunger = typeMunger; | |||
} | |||
public String toString() { | |||
return "<" + aspectType + ", " + typeMunger + ">"; | |||
} | |||
} | |||
public void write(DataOutputStream s) throws IOException { | |||
if (oldStyle) throw new RuntimeException("shouldn't be writing this"); | |||
s.writeByte(EXTENDED); | |||
int n = typeMungers.size(); | |||
s.writeShort(n); | |||
for (int i=0; i < n; i++) { | |||
Entry e = (Entry)typeMungers.get(i); | |||
e.aspectType.write(s); | |||
e.typeMunger.write(s); | |||
} | |||
} | |||
public void addConcreteMunger(ConcreteTypeMunger munger) { | |||
typeMungers.add(new Entry(munger.getAspectType(), munger.getMunger())); | |||
} | |||
public String toString() { | |||
return "WeaverStateInfo(" + typeMungers + ", " + oldStyle + ")"; | |||
} | |||
public List getTypeMungers(ResolvedTypeX onType) { | |||
World world = onType.getWorld(); | |||
List ret = new ArrayList(); | |||
for (Iterator i = typeMungers.iterator(); i.hasNext();) { | |||
Entry entry = (Entry) i.next(); | |||
ResolvedTypeX aspectType = world.resolve(entry.aspectType, true); | |||
if (aspectType == ResolvedTypeX.MISSING) { | |||
world.showMessage(IMessage.ERROR, "aspect " + entry.aspectType + | |||
" is needed when using type " + onType, | |||
onType.getSourceLocation(), null); | |||
continue; | |||
} | |||
ret.add(new BcelTypeMunger(entry.typeMunger, aspectType)); | |||
} | |||
return ret; | |||
} | |||
public boolean isOldStyle() { | |||
return oldStyle; | |||
} | |||
} |
@@ -1,48 +0,0 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Common Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/cpl-v10.html | |||
* | |||
* Contributors: | |||
* PARC initial implementation | |||
* ******************************************************************/ | |||
package org.aspectj.weaver; | |||
import java.io.DataInputStream; | |||
import java.io.IOException; | |||
import org.aspectj.util.TypeSafeEnum; | |||
public class WeaverStateKind extends TypeSafeEnum { | |||
private WeaverStateKind(String name, int key) { | |||
super(name, key); | |||
} | |||
public static final WeaverStateKind read(DataInputStream s) throws IOException { | |||
byte b = s.readByte(); | |||
switch(b) { | |||
case 0: return Untouched; | |||
case 2: return Woven; | |||
} | |||
throw new RuntimeException("bad WeaverState.Kind: " + b); | |||
} | |||
public static final WeaverStateKind Untouched = new WeaverStateKind("Untouched", 0); | |||
public static final WeaverStateKind Woven = new WeaverStateKind("Woven", 2); | |||
public byte[] getBytes() { | |||
return new byte[] { getKey(), }; | |||
} | |||
public boolean isWoven() { | |||
return this == Woven; | |||
} | |||
} |
@@ -374,5 +374,4 @@ public abstract class World { | |||
return ret; | |||
} | |||
} |
@@ -107,8 +107,7 @@ public class BcelAdvice extends Advice { | |||
if (concreteAspect.getWorld().isXnoInline()) return false; | |||
//System.err.println("isWoven? " + ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState()); | |||
return BcelWorld.getBcelObjectType(concreteAspect).getLazyClassGen().getWeaverState() | |||
== WeaverStateKind.Woven; | |||
return BcelWorld.getBcelObjectType(concreteAspect).getLazyClassGen().isWoven(); | |||
} | |||
public void implementOn(Shadow s) { |
@@ -61,7 +61,7 @@ import org.aspectj.weaver.ResolvedMember; | |||
import org.aspectj.weaver.ResolvedTypeX; | |||
import org.aspectj.weaver.Shadow; | |||
import org.aspectj.weaver.ShadowMunger; | |||
import org.aspectj.weaver.WeaverStateKind; | |||
import org.aspectj.weaver.WeaverStateInfo; | |||
class BcelClassWeaver implements IClassWeaver { | |||
@@ -75,7 +75,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
List typeMungers) | |||
{ | |||
boolean b = new BcelClassWeaver(world, clazz, shadowMungers, typeMungers).weave(); | |||
//System.err.println(clazz.getClassName() + ", " + clazz.getWeaverState()); | |||
//System.out.println(clazz.getClassName() + ", " + clazz.getType().getWeaverState()); | |||
//clazz.print(); | |||
return b; | |||
} | |||
@@ -241,7 +241,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
// ---- | |||
public boolean weave() { | |||
if (clazz.getWeaverState().isWoven()) { | |||
if (clazz.isWoven()) { | |||
world.showMessage(IMessage.ERROR, | |||
"class \'" + clazz.getType().getName() + "\' is already woven", | |||
ty.getSourceLocation(), null); | |||
@@ -309,7 +309,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
// finally, if we changed, we add in the introduced methods. | |||
if (isChanged) { | |||
clazz.setWeaverState(WeaverStateKind.Woven); | |||
clazz.getOrCreateWeaverStateInfo(); | |||
weaveInAddedMethods(); | |||
} | |||
@@ -32,7 +32,7 @@ import org.aspectj.weaver.ResolvedMember; | |||
import org.aspectj.weaver.ResolvedPointcutDefinition; | |||
import org.aspectj.weaver.ResolvedTypeX; | |||
import org.aspectj.weaver.TypeX; | |||
import org.aspectj.weaver.WeaverStateKind; | |||
import org.aspectj.weaver.WeaverStateInfo; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.patterns.PerClause; | |||
@@ -51,7 +51,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName { | |||
// strangely non-lazy | |||
private ResolvedPointcutDefinition[] pointcuts = null; | |||
private PerClause perClause = null; | |||
private WeaverStateKind weaverState = null; | |||
private WeaverStateInfo weaverState = null; | |||
private List typeMungers = Collections.EMPTY_LIST; | |||
private List declares = Collections.EMPTY_LIST; | |||
private ResolvedMember[] privilegedAccess = null; | |||
@@ -212,18 +212,11 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName { | |||
unpackAspectAttributes(); | |||
} | |||
//XXX we've lost information so that we don't know who wove into this | |||
// class, only that someone did. For better error messages we should | |||
// probably expand the information in weaverState | |||
public boolean isWovenBy(ResolvedTypeX aspectType) { | |||
return weaverState == WeaverStateKind.Woven; | |||
} | |||
public WeaverStateKind getWeaverState() { | |||
public WeaverStateInfo getWeaverState() { | |||
return weaverState; | |||
} | |||
public void setWeaverState(WeaverStateKind weaverState) { | |||
void setWeaverState(WeaverStateInfo weaverState) { | |||
this.weaverState = weaverState; | |||
} | |||
@@ -36,6 +36,7 @@ import org.aspectj.weaver.ResolvedMember; | |||
import org.aspectj.weaver.ResolvedTypeMunger; | |||
import org.aspectj.weaver.ResolvedTypeX; | |||
import org.aspectj.weaver.TypeX; | |||
import org.aspectj.weaver.WeaverStateInfo; | |||
import org.aspectj.weaver.patterns.Pointcut; | |||
@@ -51,21 +52,31 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
} | |||
public boolean munge(BcelClassWeaver weaver) { | |||
boolean changed = false; | |||
if (munger.getKind() == ResolvedTypeMunger.Field) { | |||
return mungeNewField(weaver, (NewFieldTypeMunger)munger); | |||
changed = mungeNewField(weaver, (NewFieldTypeMunger)munger); | |||
} else if (munger.getKind() == ResolvedTypeMunger.Method) { | |||
return mungeNewMethod(weaver, (NewMethodTypeMunger)munger); | |||
changed = mungeNewMethod(weaver, (NewMethodTypeMunger)munger); | |||
} else if (munger.getKind() == ResolvedTypeMunger.PerObjectInterface) { | |||
return mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger)munger); | |||
changed = mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger)munger); | |||
} else if (munger.getKind() == ResolvedTypeMunger.PrivilegedAccess) { | |||
return mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger); | |||
changed = mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger); | |||
} else if (munger.getKind() == ResolvedTypeMunger.Constructor) { | |||
return mungeNewConstructor(weaver, (NewConstructorTypeMunger)munger); | |||
changed = mungeNewConstructor(weaver, (NewConstructorTypeMunger)munger); | |||
} else if (munger.getKind() == ResolvedTypeMunger.Parent) { | |||
return mungeNewParent(weaver, (NewParentTypeMunger)munger); | |||
changed = mungeNewParent(weaver, (NewParentTypeMunger)munger); | |||
} else { | |||
throw new RuntimeException("unimplemented"); | |||
} | |||
if (changed && munger.changesPublicSignature()) { | |||
WeaverStateInfo info = | |||
weaver.getLazyClassGen().getOrCreateWeaverStateInfo(); | |||
info.addConcreteMunger(this); | |||
} | |||
return changed; | |||
} | |||
@@ -19,6 +19,7 @@ import java.io.IOException; | |||
import java.io.PrintStream; | |||
import java.lang.reflect.Modifier; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.Comparator; | |||
import java.util.HashMap; | |||
@@ -49,7 +50,7 @@ import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.NameMangler; | |||
import org.aspectj.weaver.TypeX; | |||
import org.aspectj.weaver.WeaverStateKind; | |||
import org.aspectj.weaver.WeaverStateInfo; | |||
public final class LazyClassGen { | |||
@@ -152,8 +153,13 @@ public final class LazyClassGen { | |||
} | |||
private void writeBack() { | |||
addAjcInitializers(); | |||
if (myType != null && myType.getWeaverState() != null) { | |||
myGen.addAttribute(BcelAttributes.bcelAttribute( | |||
new AjAttribute.WeaverState(myType.getWeaverState()), | |||
getConstantPoolGen())); | |||
} | |||
addAjcInitializers(); | |||
int len = methodGens.size(); | |||
myGen.setMethods(new Method[0]); | |||
@@ -305,29 +311,17 @@ public final class LazyClassGen { | |||
return myGen.getClassName(); | |||
} | |||
public WeaverStateKind getWeaverState() { | |||
WeaverStateKind kind = myType.getWeaverState(); | |||
if (kind == null) return WeaverStateKind.Untouched; | |||
return kind; | |||
public boolean isWoven() { | |||
return myType.getWeaverState() != null; | |||
} | |||
public void setWeaverState(WeaverStateKind s) { | |||
Attribute[] attributes = myGen.getAttributes(); | |||
if (attributes != null) { | |||
for (int i = attributes.length - 1; i >=0; i--) { | |||
Attribute a = attributes[i]; | |||
if (a instanceof Unknown) { | |||
Unknown u = (Unknown) a; | |||
if (u.getName().equals(AjAttribute.WeaverState.AttributeName)) { | |||
myGen.removeAttribute(u); | |||
} | |||
} | |||
} | |||
} | |||
myGen.addAttribute(BcelAttributes.bcelAttribute( | |||
new AjAttribute.WeaverState(s), | |||
getConstantPoolGen())); | |||
myType.setWeaverState(s); | |||
public WeaverStateInfo getOrCreateWeaverStateInfo() { | |||
WeaverStateInfo ret = myType.getWeaverState(); | |||
if (ret != null) return ret; | |||
ret = new WeaverStateInfo(); | |||
myType.setWeaverState(ret); | |||
return ret; | |||
} | |||
public InstructionFactory getFactory() { | |||
@@ -531,4 +525,5 @@ public final class LazyClassGen { | |||
public void forcePublic() { | |||
myGen.setAccessFlags(Utility.makePublic(myGen.getAccessFlags())); | |||
} | |||
} |