diff options
author | jhugunin <jhugunin> | 2003-04-11 00:48:49 +0000 |
---|---|---|
committer | jhugunin <jhugunin> | 2003-04-11 00:48:49 +0000 |
commit | 039d04d39da57d5ef47193509a364d9ceed9b98e (patch) | |
tree | 98870c277b2da902ef8deda9f20b18aad0247b91 /weaver | |
parent | 11b3b0740b66f1d962b5179ece2f2d23e88f040b (diff) | |
download | aspectj-039d04d39da57d5ef47193509a364d9ceed9b98e.tar.gz aspectj-039d04d39da57d5ef47193509a364d9ceed9b98e.zip |
fixing declare parents problems
Diffstat (limited to 'weaver')
7 files changed, 167 insertions, 2 deletions
diff --git a/weaver/src/org/aspectj/weaver/NewParentTypeMunger.java b/weaver/src/org/aspectj/weaver/NewParentTypeMunger.java new file mode 100644 index 000000000..05f66ac63 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/NewParentTypeMunger.java @@ -0,0 +1,39 @@ +/* ******************************************************************* + * 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.Set; + +public class NewParentTypeMunger extends ResolvedTypeMunger { + ResolvedTypeX newParent; + + public NewParentTypeMunger(ResolvedTypeX newParent) { + super(Parent, null); + this.newParent = newParent; + } + + public void write(DataOutputStream s) throws IOException { + throw new RuntimeException("unimplemented"); + } + + + public ResolvedTypeX getNewParent() { + return newParent; + } + + +} diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java index 8944e788f..086ade7b2 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java @@ -154,6 +154,8 @@ public abstract class ResolvedTypeMunger { // not serialized, only created during concretization of aspects public static final Kind PerObjectInterface = new Kind("PerObjectInterface", 3); public static final Kind PrivilegedAccess = new Kind("PrivilegedAccess", 4); + + public static final Kind Parent = new Kind("Parent", 6); public static final String SUPER_DISPATCH_NAME = "superDispatch"; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java index 5cd46b71d..864f127d6 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java @@ -246,6 +246,8 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName { 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; } @@ -264,6 +266,22 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName { public ISourceLocation getSourceLocation() { return getResolvedTypeX().getSourceContext().makeSourceLocation(0); //FIXME, we can do better than this } + + public void addParent(ResolvedTypeX newParent) { + if (newParent.isClass()) { + superClass = newParent; + } else { + ResolvedTypeX[] oldInterfaceNames = getDeclaredInterfaces(); + int len = oldInterfaceNames.length; + ResolvedTypeX[] newInterfaceNames = new ResolvedTypeX[len+1]; + System.arraycopy(oldInterfaceNames, 0, newInterfaceNames, 0, len); + newInterfaceNames[len] = newParent; + + interfaces = newInterfaceNames; + } + //System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + javaClass.getSuperclassName()); + //if (lazyClassGen != null) lazyClassGen.print(); + } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 0e08a1b14..9c1b28a0c 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -29,6 +29,7 @@ import org.aspectj.weaver.NameMangler; import org.aspectj.weaver.NewConstructorTypeMunger; import org.aspectj.weaver.NewFieldTypeMunger; import org.aspectj.weaver.NewMethodTypeMunger; +import org.aspectj.weaver.NewParentTypeMunger; import org.aspectj.weaver.PerObjectInterfaceTypeMunger; import org.aspectj.weaver.PrivilegedAccessMunger; import org.aspectj.weaver.ResolvedMember; @@ -60,13 +61,25 @@ public class BcelTypeMunger extends ConcreteTypeMunger { return mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger); } else if (munger.getKind() == ResolvedTypeMunger.Constructor) { return mungeNewConstructor(weaver, (NewConstructorTypeMunger)munger); + } else if (munger.getKind() == ResolvedTypeMunger.Parent) { + return mungeNewParent(weaver, (NewParentTypeMunger)munger); } else { throw new RuntimeException("unimplemented"); } } - + private boolean mungeNewParent(BcelClassWeaver weaver, NewParentTypeMunger munger) { + LazyClassGen gen = weaver.getLazyClassGen(); + ResolvedTypeX newParent = munger.getNewParent(); + if (newParent.isClass()) { + //gen.setSuperClass(newParent); + } else { + gen.addInterface(newParent); + } + return true; + } + private boolean mungePrivilegedAccess( BcelClassWeaver weaver, PrivilegedAccessMunger munger) diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index bb6515a40..c3598ed49 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -22,6 +22,7 @@ import org.apache.bcel.classfile.JavaClass; import org.aspectj.bridge.IMessage; import org.aspectj.util.FileUtil; import org.aspectj.weaver.*; +import org.aspectj.weaver.patterns.DeclareParents; import org.aspectj.weaver.patterns.Pointcut; public class BcelWeaver implements IWeaver { @@ -45,7 +46,8 @@ public class BcelWeaver implements IWeaver { private boolean needToReweaveWorld = false; private List shadowMungerList = null; // setup by prepareForWeave - private List typeMungerList = null; // setup by prepareForWeave + private List typeMungerList = null; // setup by prepareForWeave + private List declareParentsList = null; // setup by prepareForWeave private ZipOutputStream zipOutputStream; @@ -172,6 +174,7 @@ public class BcelWeaver implements IWeaver { shadowMungerList = xcutSet.getShadowMungers(); typeMungerList = xcutSet.getTypeMungers(); + declareParentsList = xcutSet.getDeclareParents(); //XXX this gets us a stable (but completely meaningless) order Collections.sort( @@ -284,6 +287,32 @@ public class BcelWeaver implements IWeaver { public void weave(ResolvedTypeX onType) { onType.clearInterTypeMungers(); + + // need to do any declare parents before the matching below + for (Iterator i = declareParentsList.iterator(); i.hasNext(); ) { + DeclareParents p = (DeclareParents)i.next(); + List newParents = p.findMatchingNewParents(onType); + if (!newParents.isEmpty()) { + //??? + BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(onType.getClassName())); + //System.err.println("need to do declare parents for: " + onType); + for (Iterator j = newParents.iterator(); j.hasNext(); ) { + ResolvedTypeX newParent = (ResolvedTypeX)j.next(); + if (newParent.isClass()) { + world.showMessage(IMessage.ERROR, + "can't use declare parents to change superclass of binary form \'" + + onType.getClassName() + "\' (implementation limitation)", + p.getSourceLocation(), null); + continue; + } + + classType.addParent(newParent); + ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(newParent); + onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, null)); + } + } + } + for (Iterator i = typeMungerList.iterator(); i.hasNext(); ) { ConcreteTypeMunger m = (ConcreteTypeMunger)i.next(); if (m.matches(onType)) { @@ -292,6 +321,7 @@ public class BcelWeaver implements IWeaver { } } + // exposed for ClassLoader dynamic weaving public LazyClassGen weaveWithoutDump(UnwovenClassFile classFile, BcelObjectType classType) throws IOException { return weave(classFile, classType, false); diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java index 39f3427e9..aa5c157ec 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java @@ -177,6 +177,11 @@ public final class LazyClassGen { public void addInterface(TypeX typeX) { myGen.addInterface(typeX.getName()); } + + public void setSuperClass(TypeX typeX) { + myGen.setSuperclassName(typeX.getName()); + } + // non-recursive, may be a bug, ha ha. private List getClassGens() { diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java b/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java index d71633e7f..efc8bf69b 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java @@ -16,10 +16,15 @@ package org.aspectj.weaver.patterns; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import org.aspectj.bridge.IMessage; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ResolvedTypeX; +import org.aspectj.weaver.TypeX; +import org.aspectj.weaver.World; public class DeclareParents extends Declare { private TypePattern child; @@ -103,5 +108,58 @@ public class DeclareParents extends Declare { public boolean isAdviceLike() { return false; } + + private ResolvedTypeX maybeGetNewParent(ResolvedTypeX targetType, TypePattern typePattern, World world) { + if (typePattern == TypePattern.NO) return null; // already had an error here + TypeX iType = typePattern.getExactType(); + ResolvedTypeX parentType = iType.resolve(world); + + if (parentType.isAssignableFrom(targetType)) return null; // already a parent + + if (targetType.isAssignableFrom(parentType)) { + world.showMessage(IMessage.ERROR, + "type can not extend itself", this.getSourceLocation(), null + ); + return null; + } + + if (parentType.isClass()) { + if (targetType.isInterface()) { + world.showMessage(IMessage.ERROR, + "interface can not extend a class", + this.getSourceLocation(), null + ); + return null; + // how to handle xcutting errors??? + } + + if (!targetType.getSuperclass().isAssignableFrom(parentType)) { + world.showMessage(IMessage.ERROR, + "can only insert a class into hierarchy, but " + + iType.getName() + " is not a subtype of " + + targetType.getSuperclass().getName(), + this.getSourceLocation(), null + ); + return null; + } else { + return parentType; + } + } else { + return parentType; + } + } + + + public List/*<ResolvedTypeX>*/ findMatchingNewParents(ResolvedTypeX onType) { + if (!match(onType)) return Collections.EMPTY_LIST; + + List ret = new ArrayList(); + for (int i=0; i < parents.size(); i++) { + ResolvedTypeX t = maybeGetNewParent(onType, parents.get(i), onType.getWorld()); + if (t != null) ret.add(t); + } + + return ret; + } } |