aboutsummaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authorjhugunin <jhugunin>2003-04-11 00:48:49 +0000
committerjhugunin <jhugunin>2003-04-11 00:48:49 +0000
commit039d04d39da57d5ef47193509a364d9ceed9b98e (patch)
tree98870c277b2da902ef8deda9f20b18aad0247b91 /weaver
parent11b3b0740b66f1d962b5179ece2f2d23e88f040b (diff)
downloadaspectj-039d04d39da57d5ef47193509a364d9ceed9b98e.tar.gz
aspectj-039d04d39da57d5ef47193509a364d9ceed9b98e.zip
fixing declare parents problems
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/NewParentTypeMunger.java39
-rw-r--r--weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java2
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java18
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java15
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java32
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java5
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/DeclareParents.java58
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;
+ }
}