aboutsummaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2008-08-31 22:08:32 +0000
committeraclement <aclement>2008-08-31 22:08:32 +0000
commitcb46b4aa17ef055539ec9b6a7335564d2bc388d7 (patch)
treebb35f31e199e7eb27a004af50f8ade03b9e3bda9 /weaver
parentee77d7cdc0e0bb67abe21023e06fe18ea763a3b9 (diff)
downloadaspectj-cb46b4aa17ef055539ec9b6a7335564d2bc388d7.tar.gz
aspectj-cb46b4aa17ef055539ec9b6a7335564d2bc388d7.zip
remove unused code
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/ast/CastExpr.java48
-rw-r--r--weaver/src/org/aspectj/weaver/ast/Expr.java15
-rw-r--r--weaver/src/org/aspectj/weaver/ast/FieldGetOn.java41
-rw-r--r--weaver/src/org/aspectj/weaver/ast/IExprVisitor.java23
-rw-r--r--weaver/src/org/aspectj/weaver/ast/StringConstExpr.java45
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelRenderer.java369
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java2224
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelWorld.java12
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java18
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java2646
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/Range.java362
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java153
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/Utility.java1223
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/FormalBinding.java91
-rw-r--r--weaver/testsrc/org/aspectj/weaver/TestUtils.java624
15 files changed, 3706 insertions, 4188 deletions
diff --git a/weaver/src/org/aspectj/weaver/ast/CastExpr.java b/weaver/src/org/aspectj/weaver/ast/CastExpr.java
deleted file mode 100644
index 3bb07f4aa..000000000
--- a/weaver/src/org/aspectj/weaver/ast/CastExpr.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 Contributors.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * initial implementation Alexandre Vasseur
- *******************************************************************************/
-package org.aspectj.weaver.ast;
-
-import org.aspectj.weaver.ResolvedType;
-
-/**
- * Represents a cast expression.
- * <p/>
- * Used when aspectOf is not existing in the aspect class (no pre-processing of aspects) ie when
- * Object Aspects.aspectOf(..) API is used.
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
-public class CastExpr extends Expr {
-
- private String m_castToTypeName;
-
- private CallExpr m_expr;
-
- public CastExpr(CallExpr expr, String castToSignature) {
- super();
- m_expr = expr;
- m_castToTypeName = castToSignature;
- }
-
- public void accept(IExprVisitor v) {
- v.visit(m_expr);
- v.visit(this);
- }
-
- public String getTypeName() {
- return m_castToTypeName;
- }
-
- public ResolvedType getType() {
- throw new RuntimeException("not supported");
- }
-}
diff --git a/weaver/src/org/aspectj/weaver/ast/Expr.java b/weaver/src/org/aspectj/weaver/ast/Expr.java
index 238510a1e..1b22c8f42 100644
--- a/weaver/src/org/aspectj/weaver/ast/Expr.java
+++ b/weaver/src/org/aspectj/weaver/ast/Expr.java
@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.ast;
import org.aspectj.weaver.Member;
@@ -21,23 +20,15 @@ public abstract class Expr extends ASTNode {
public Expr() {
super();
}
-
- public static final Expr[] NONE = new Expr[0];
- public abstract void accept(IExprVisitor v);
+ public static final Expr[] NONE = new Expr[0];
- public abstract ResolvedType getType();
+ public abstract void accept(IExprVisitor v);
- public static FieldGet makeFieldGet(Member myField, ResolvedType inAspect) {
- return new FieldGet(myField, inAspect);
- }
+ public abstract ResolvedType getType();
public static CallExpr makeCallExpr(Member member, Expr[] exprs, ResolvedType returnType) {
return new CallExpr(member, exprs, returnType);
}
- public static Expr makeStringConstantExpr(final String stringConst) {
- return new StringConstExpr(stringConst);
- }
-
}
diff --git a/weaver/src/org/aspectj/weaver/ast/FieldGetOn.java b/weaver/src/org/aspectj/weaver/ast/FieldGetOn.java
deleted file mode 100644
index 6bf0d38d8..000000000
--- a/weaver/src/org/aspectj/weaver/ast/FieldGetOn.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 Contributors.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * initial implementation Alexandre Vasseur
- *******************************************************************************/
-package org.aspectj.weaver.ast;
-
-import org.aspectj.weaver.Member;
-import org.aspectj.weaver.UnresolvedType;
-
-/**
- * Represents a field access on a given type.
- * <p/>
- * Used when aspectOf is not existing in the aspect class (no pre-processing of aspects)
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
-public class FieldGetOn extends FieldGet {
-
- private UnresolvedType m_declaringType;
-
- public FieldGetOn(Member field, UnresolvedType declaringType) {
- super(field, null);
- m_declaringType = declaringType;
- }
-
- public UnresolvedType getDeclaringType() {
- return m_declaringType;
- }
-
- public void accept(IExprVisitor v) {
- v.visit(this);
- }
-
-}
diff --git a/weaver/src/org/aspectj/weaver/ast/IExprVisitor.java b/weaver/src/org/aspectj/weaver/ast/IExprVisitor.java
index 47392e802..89e0b3d74 100644
--- a/weaver/src/org/aspectj/weaver/ast/IExprVisitor.java
+++ b/weaver/src/org/aspectj/weaver/ast/IExprVisitor.java
@@ -10,33 +10,14 @@
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.ast;
-
public interface IExprVisitor {
void visit(Var i);
- void visit(FieldGet fieldGet);
- void visit(CallExpr callExpr);
-
- /**
- * Visit a string constant
- * @param stringConstExpr
- */
- void visit(StringConstExpr stringConstExpr);
- /**
- * Visit a CHECKCAST instruction
- * @param castExpr
- */
- void visit(CastExpr castExpr);
-
- /**
- * Visit a field GET
- * @param fieldGetOn
- */
- void visit(FieldGetOn fieldGetOn);
+ void visit(FieldGet fieldGet);
+ void visit(CallExpr callExpr);
}
diff --git a/weaver/src/org/aspectj/weaver/ast/StringConstExpr.java b/weaver/src/org/aspectj/weaver/ast/StringConstExpr.java
deleted file mode 100644
index c48e72e37..000000000
--- a/weaver/src/org/aspectj/weaver/ast/StringConstExpr.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 Contributors.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * initial implementation Alexandre Vasseur
- *******************************************************************************/
-package org.aspectj.weaver.ast;
-
-import org.aspectj.weaver.ast.Expr;
-import org.aspectj.weaver.ast.IExprVisitor;
-import org.aspectj.weaver.ResolvedType;
-
-/**
- * Represents a String constant instruction.
- * <p/>
- * Used when aspectOf is not existing in the aspect class (no pre-processing of aspects)
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
-public class StringConstExpr extends Expr {
-
- private String m_stringConst;
-
- public StringConstExpr(String stringConst) {
- super();
- m_stringConst = stringConst;
- }
-
- public void accept(IExprVisitor v) {
- v.visit(this);
- }
-
- public ResolvedType getType() {
- throw new RuntimeException("not supported");
- }
-
- public String getStringConst() {
- return m_stringConst;
- }
-}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelRenderer.java b/weaver/src/org/aspectj/weaver/bcel/BcelRenderer.java
index a26d46f0a..5b8efc31b 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelRenderer.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelRenderer.java
@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.bcel;
import org.aspectj.apache.bcel.Constants;
@@ -28,11 +27,9 @@ import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.ast.And;
import org.aspectj.weaver.ast.Call;
import org.aspectj.weaver.ast.CallExpr;
-import org.aspectj.weaver.ast.CastExpr;
import org.aspectj.weaver.ast.Expr;
import org.aspectj.weaver.ast.FieldGet;
import org.aspectj.weaver.ast.FieldGetCall;
-import org.aspectj.weaver.ast.FieldGetOn;
import org.aspectj.weaver.ast.HasAnnotation;
import org.aspectj.weaver.ast.IExprVisitor;
import org.aspectj.weaver.ast.ITestVisitor;
@@ -40,7 +37,6 @@ import org.aspectj.weaver.ast.Instanceof;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Not;
import org.aspectj.weaver.ast.Or;
-import org.aspectj.weaver.ast.StringConstExpr;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.ast.Var;
import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
@@ -48,209 +44,172 @@ import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
// we generate right to left, btw.
public final class BcelRenderer implements ITestVisitor, IExprVisitor {
- private InstructionList instructions;
- private InstructionFactory fact;
- private BcelWorld world;
+ private InstructionList instructions;
+ private InstructionFactory fact;
+ private BcelWorld world;
- InstructionHandle sk, fk, next = null;
+ InstructionHandle sk, fk, next = null;
- private BcelRenderer(InstructionFactory fact, BcelWorld world) {
- super();
- this.fact = fact;
- this.world = world;
- this.instructions = new InstructionList();
- }
+ private BcelRenderer(InstructionFactory fact, BcelWorld world) {
+ super();
+ this.fact = fact;
+ this.world = world;
+ this.instructions = new InstructionList();
+ }
- // ---- renderers
-
- public static InstructionList renderExpr(
- InstructionFactory fact,
- BcelWorld world,
- Expr e)
- {
- BcelRenderer renderer = new BcelRenderer(fact, world);
- e.accept(renderer);
- return renderer.instructions;
- }
- public static InstructionList renderExpr(
- InstructionFactory fact,
- BcelWorld world,
- Expr e,
- Type desiredType)
- {
- BcelRenderer renderer = new BcelRenderer(fact, world);
- e.accept(renderer);
- InstructionList il = renderer.instructions;
- il.append(Utility.createConversion(fact, BcelWorld.makeBcelType(e.getType()), desiredType));
- return il;
- }
+ // ---- renderers
- public static InstructionList renderExprs(
- InstructionFactory fact,
- BcelWorld world,
- Expr[] es)
- {
- BcelRenderer renderer = new BcelRenderer(fact, world);
- for (int i = es.length - 1; i >= 0; i--) {
- es[i].accept(renderer);
- }
- return renderer.instructions;
- }
+ public static InstructionList renderExpr(InstructionFactory fact, BcelWorld world, Expr e) {
+ BcelRenderer renderer = new BcelRenderer(fact, world);
+ e.accept(renderer);
+ return renderer.instructions;
+ }
- /*
- * Get the instructions representing this test.
- *
- * @param e test to render
- * @param sk instructionHandle to jump to if our rendered check succeeds (typically start of advice)
- * @param fk instructionHandle to jump to if our rendered check fails (typically after end of advice)
- * @param next instructionHandle that will follow this generated code. Passing in null will generate
- * one unnecessary GOTO instruction.
- *
- * @returns the instruction list representing this expression
- */
- public static InstructionList renderTest(
- InstructionFactory fact,
- BcelWorld world,
- Test e,
- InstructionHandle sk,
- InstructionHandle fk,
- InstructionHandle next)
- {
- BcelRenderer renderer = new BcelRenderer(fact, world);
- renderer.recur(e, sk, fk, next);
- return renderer.instructions;
- }
+ public static InstructionList renderExpr(InstructionFactory fact, BcelWorld world, Expr e, Type desiredType) {
+ BcelRenderer renderer = new BcelRenderer(fact, world);
+ e.accept(renderer);
+ InstructionList il = renderer.instructions;
+ il.append(Utility.createConversion(fact, BcelWorld.makeBcelType(e.getType()), desiredType));
+ return il;
+ }
- /*
- * Get the instructions representing this test.
- *
- * @param e test to render
- * @param sk instructionHandle to jump to if our rendered check succeeds (typically start of advice)
- * @param fk instructionHandle to jump to if our rendered check fails (typically after end of advice)
- *
- * @returns the instruction list representing this expression
- */
- public static InstructionList renderTest(
- InstructionFactory fact,
- BcelWorld world,
- Test e,
- InstructionHandle sk,
- InstructionHandle fk)
- {
- return renderTest(fact, world, e, sk, fk, null);
- }
+ public static InstructionList renderExprs(InstructionFactory fact, BcelWorld world, Expr[] es) {
+ BcelRenderer renderer = new BcelRenderer(fact, world);
+ for (int i = es.length - 1; i >= 0; i--) {
+ es[i].accept(renderer);
+ }
+ return renderer.instructions;
+ }
- // ---- recurrers
+ /*
+ * Get the instructions representing this test.
+ *
+ * @param e test to render
+ *
+ * @param sk instructionHandle to jump to if our rendered check succeeds (typically start of advice)
+ *
+ * @param fk instructionHandle to jump to if our rendered check fails (typically after end of advice)
+ *
+ * @param next instructionHandle that will follow this generated code. Passing in null will generate one unnecessary GOTO
+ * instruction.
+ *
+ * @returns the instruction list representing this expression
+ */
+ public static InstructionList renderTest(InstructionFactory fact, BcelWorld world, Test e, InstructionHandle sk,
+ InstructionHandle fk, InstructionHandle next) {
+ BcelRenderer renderer = new BcelRenderer(fact, world);
+ renderer.recur(e, sk, fk, next);
+ return renderer.instructions;
+ }
- private void recur(
- Test e,
- InstructionHandle sk,
- InstructionHandle fk,
- InstructionHandle next)
- {
- this.sk = sk;
- this.fk = fk;
- this.next = next;
- e.accept(this);
- }
+ // ---- recurrers
- // ---- test visitors
+ private void recur(Test e, InstructionHandle sk, InstructionHandle fk, InstructionHandle next) {
+ this.sk = sk;
+ this.fk = fk;
+ this.next = next;
+ e.accept(this);
+ }
- public void visit(And e) {
- InstructionHandle savedFk = fk;
- recur(e.getRight(), sk, fk, next);
- InstructionHandle ning = instructions.getStart();
- recur(e.getLeft(), ning, savedFk, ning);
- }
+ // ---- test visitors
- public void visit(Or e) {
- InstructionHandle savedSk = sk;
- recur(e.getRight(), sk, fk, next);
- recur(e.getLeft(), savedSk, instructions.getStart(), instructions.getStart());
- }
+ public void visit(And e) {
+ InstructionHandle savedFk = fk;
+ recur(e.getRight(), sk, fk, next);
+ InstructionHandle ning = instructions.getStart();
+ recur(e.getLeft(), ning, savedFk, ning);
+ }
- public void visit(Not e) {
- recur(e.getBody(), fk, sk, next);
- }
+ public void visit(Or e) {
+ InstructionHandle savedSk = sk;
+ recur(e.getRight(), sk, fk, next);
+ recur(e.getLeft(), savedSk, instructions.getStart(), instructions.getStart());
+ }
- public void visit(Instanceof i) {
- instructions.insert(createJumpBasedOnBooleanOnStack());
- instructions.insert(
- Utility.createInstanceof(fact, (ReferenceType) BcelWorld.makeBcelType(i.getType())));
- i.getVar().accept(this);
- }
+ public void visit(Not e) {
+ recur(e.getBody(), fk, sk, next);
+ }
- public void visit(HasAnnotation hasAnnotation) {
- // in Java:
- // foo.class.isAnnotationPresent(annotationClass);
- // in bytecode:
- // load var onto the stack (done for us later)
- // invokevirtual java/lang/Object.getClass:()Ljava/lang/Class
- // ldc_w annotationClass
- // invokevirtual java/lang/Class.isAnnotationPresent:(Ljava/lang/Class;)Z
- InstructionList il = new InstructionList();
- Member getClass = MemberImpl.method(UnresolvedType.OBJECT, 0, UnresolvedType.JAVA_LANG_CLASS,"getClass", UnresolvedType.NONE);
- il.append(Utility.createInvoke(fact, world, getClass));
- // aload annotationClass
- il.append(fact.createConstant(new ObjectType(hasAnnotation.getAnnotationType().getName())));
-// int annClassIndex = fact.getConstantPool().addClass(hasAnnotation.getAnnotationType().getSignature());
-// il.append(new LDC_W(annClassIndex));
- Member isAnnotationPresent = MemberImpl.method(UnresolvedType.JAVA_LANG_CLASS,0,ResolvedType.BOOLEAN,"isAnnotationPresent",new UnresolvedType[]{UnresolvedType.JAVA_LANG_CLASS});
- il.append(Utility.createInvoke(fact,world,isAnnotationPresent));
- il.append(createJumpBasedOnBooleanOnStack());
- instructions.insert(il);
- hasAnnotation.getVar().accept(this);
- }
-
- /* (non-Javadoc)
- * @see org.aspectj.weaver.ast.ITestVisitor#visit(org.aspectj.weaver.internal.tools.MatchingContextBasedTest)
- */
- public void visit(MatchingContextBasedTest matchingContextTest) {
- throw new UnsupportedOperationException("matching context extension not supported in bytecode weaving");
- }
-
- private InstructionList createJumpBasedOnBooleanOnStack() {
+ public void visit(Instanceof i) {
+ instructions.insert(createJumpBasedOnBooleanOnStack());
+ instructions.insert(Utility.createInstanceof(fact, (ReferenceType) BcelWorld.makeBcelType(i.getType())));
+ i.getVar().accept(this);
+ }
+
+ public void visit(HasAnnotation hasAnnotation) {
+ // in Java:
+ // foo.class.isAnnotationPresent(annotationClass);
+ // in bytecode:
+ // load var onto the stack (done for us later)
+ // invokevirtual java/lang/Object.getClass:()Ljava/lang/Class
+ // ldc_w annotationClass
+ // invokevirtual java/lang/Class.isAnnotationPresent:(Ljava/lang/Class;)Z
InstructionList il = new InstructionList();
- if (sk == fk) {
- // don't bother generating if it doesn't matter
- if (sk != next) {
- il.insert(InstructionFactory.createBranchInstruction(Constants.GOTO, sk));
- }
- return il;
- }
+ Member getClass = MemberImpl.method(UnresolvedType.OBJECT, 0, UnresolvedType.JAVA_LANG_CLASS, "getClass",
+ UnresolvedType.NONE);
+ il.append(Utility.createInvoke(fact, world, getClass));
+ // aload annotationClass
+ il.append(fact.createConstant(new ObjectType(hasAnnotation.getAnnotationType().getName())));
+ // int annClassIndex = fact.getConstantPool().addClass(hasAnnotation.getAnnotationType().getSignature());
+ // il.append(new LDC_W(annClassIndex));
+ Member isAnnotationPresent = MemberImpl.method(UnresolvedType.JAVA_LANG_CLASS, 0, ResolvedType.BOOLEAN,
+ "isAnnotationPresent", new UnresolvedType[] { UnresolvedType.JAVA_LANG_CLASS });
+ il.append(Utility.createInvoke(fact, world, isAnnotationPresent));
+ il.append(createJumpBasedOnBooleanOnStack());
+ instructions.insert(il);
+ hasAnnotation.getVar().accept(this);
+ }
- if (fk == next) {
- il.insert(InstructionFactory.createBranchInstruction(Constants.IFNE, sk));
- } else if (sk == next) {
- il.insert(InstructionFactory.createBranchInstruction(Constants.IFEQ, fk));
- } else {
- il.insert(InstructionFactory.createBranchInstruction(Constants.GOTO, sk));
- il.insert(InstructionFactory.createBranchInstruction(Constants.IFEQ, fk));
- }
- return il;
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.ast.ITestVisitor#visit(org.aspectj.weaver.internal.tools.MatchingContextBasedTest)
+ */
+ public void visit(MatchingContextBasedTest matchingContextTest) {
+ throw new UnsupportedOperationException("matching context extension not supported in bytecode weaving");
}
+ private InstructionList createJumpBasedOnBooleanOnStack() {
+ InstructionList il = new InstructionList();
+ if (sk == fk) {
+ // don't bother generating if it doesn't matter
+ if (sk != next) {
+ il.insert(InstructionFactory.createBranchInstruction(Constants.GOTO, sk));
+ }
+ return il;
+ }
+
+ if (fk == next) {
+ il.insert(InstructionFactory.createBranchInstruction(Constants.IFNE, sk));
+ } else if (sk == next) {
+ il.insert(InstructionFactory.createBranchInstruction(Constants.IFEQ, fk));
+ } else {
+ il.insert(InstructionFactory.createBranchInstruction(Constants.GOTO, sk));
+ il.insert(InstructionFactory.createBranchInstruction(Constants.IFEQ, fk));
+ }
+ return il;
+ }
- public void visit(Literal literal) {
- if (literal == Literal.FALSE)
- throw new BCException("bad");
- }
+ public void visit(Literal literal) {
+ if (literal == Literal.FALSE)
+ throw new BCException("bad");
+ }
public void visit(Call call) {
Member method = call.getMethod();
// assert method.isStatic()
Expr[] args = call.getArgs();
- //System.out.println("args: " + Arrays.asList(args));
+ // System.out.println("args: " + Arrays.asList(args));
InstructionList callIl = new InstructionList();
- for (int i=0, len=args.length; i < len; i++) {
- //XXX only correct for static method calls
+ for (int i = 0, len = args.length; i < len; i++) {
+ // XXX only correct for static method calls
Type desiredType = BcelWorld.makeBcelType(method.getParameterTypes()[i]);
callIl.append(renderExpr(fact, world, args[i], desiredType));
}
- //System.out.println("rendered args: " + callIl);
+ // System.out.println("rendered args: " + callIl);
callIl.append(Utility.createInvoke(fact, world, method));
callIl.append(createJumpBasedOnBooleanOnStack());
- instructions.insert(callIl);
+ instructions.insert(callIl);
}
public void visit(FieldGetCall fieldGetCall) {
@@ -260,58 +219,34 @@ public final class BcelRenderer implements ITestVisitor, IExprVisitor {
il.append(Utility.createGet(fact, field));
// assert !method.isStatic()
Expr[] args = fieldGetCall.getArgs();
- //System.out.println("args: " + Arrays.asList(args));
- il.append(renderExprs(fact, world, args));
- //System.out.println("rendered args: " + callIl);
+ // System.out.println("args: " + Arrays.asList(args));
+ il.append(renderExprs(fact, world, args));
+ // System.out.println("rendered args: " + callIl);
il.append(Utility.createInvoke(fact, world, method));
il.append(createJumpBasedOnBooleanOnStack());
- instructions.insert(il);
+ instructions.insert(il);
}
- // ---- expr visitors
+ // ---- expr visitors
- public void visit(Var var) {
- BcelVar bvar = (BcelVar) var;
- bvar.insertLoad(instructions, fact);
- }
-
- public void visit(FieldGet fieldGet) {
+ public void visit(Var var) {
+ BcelVar bvar = (BcelVar) var;
+ bvar.insertLoad(instructions, fact);
+ }
+
+ public void visit(FieldGet fieldGet) {
Member field = fieldGet.getField();
// assert field.isStatic()
- instructions.insert(Utility.createGet(fact, field));
- }
-
+ instructions.insert(Utility.createGet(fact, field));
+ }
+
public void visit(CallExpr call) {
Member method = call.getMethod();
// assert method.isStatic()
Expr[] args = call.getArgs();
- InstructionList callIl = renderExprs(fact, world, args);
+ InstructionList callIl = renderExprs(fact, world, args);
callIl.append(Utility.createInvoke(fact, world, method));
- instructions.insert(callIl);
+ instructions.insert(callIl);
}
- /**
- * Visit a string constant
- * @param stringConst
- */
- public void visit(StringConstExpr stringConst) {
- instructions.insert(fact.createConstant(stringConst.getStringConst()));
- }
-
- /**
- * Visit a CHECKCAST
- * @param castExpr
- */
- public void visit(CastExpr castExpr) {
- instructions.append(fact.createCheckCast(new ObjectType(castExpr.getTypeName())));
- }
-
- /**
- * Visit a field GET (static or not, depends on the field)
- * @param fieldGet
- */
- public void visit(FieldGetOn fieldGet) {
- Member field = fieldGet.getField();
- instructions.insert(Utility.createGetOn(fact, field, fieldGet.getDeclaringType()));
- }
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
index f253a3900..1430f0929 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
@@ -11,10 +11,8 @@
* Alexandre Vasseur support for @AJ aspects
* ******************************************************************/
-
package org.aspectj.weaver.bcel;
-
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileFilter;
@@ -47,7 +45,6 @@ import org.aspectj.apache.bcel.classfile.ClassParser;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.asm.AsmManager;
import org.aspectj.bridge.IMessage;
-import org.aspectj.bridge.IProgressListener;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;
import org.aspectj.bridge.MessageUtil;
@@ -96,144 +93,138 @@ import org.aspectj.weaver.patterns.WithinPointcut;
import org.aspectj.weaver.tools.Trace;
import org.aspectj.weaver.tools.TraceFactory;
-
public class BcelWeaver {
public static final String CLOSURE_CLASS_PREFIX = "$Ajc";
-
+
public static final String SYNTHETIC_CLASS_POSTFIX = "$ajc";
-
- private BcelWorld world;
- private CrosscuttingMembersSet xcutSet;
- private IProgressListener progressListener = null;
- private double progressMade;
- private double progressPerClassFile;
-
- private boolean inReweavableMode = false;
-
- private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWeaver.class);
-
- public BcelWeaver(BcelWorld world) {
- super();
- if (trace.isTraceEnabled()) trace.enter("<init>",this,world);
- this.world = world;
- this.xcutSet = world.getCrosscuttingMembersSet();
- if (trace.isTraceEnabled()) trace.exit("<init>");
- }
-
- public BcelWeaver() {
- this(new BcelWorld());
- }
-
- // ---- fields
-// private Map sourceJavaClasses = new HashMap(); /* String -> UnwovenClassFile */
- private List addedClasses = new ArrayList(); /* List<UnovenClassFile> */
- private List deletedTypenames = new ArrayList(); /* List<String> */
-// private Map resources = new HashMap(); /* String -> UnwovenClassFile */
+
+ private BcelWorld world;
+ private CrosscuttingMembersSet xcutSet;
+
+ private boolean inReweavableMode = false;
+
+ private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWeaver.class);
+
+ public BcelWeaver(BcelWorld world) {
+ super();
+ if (trace.isTraceEnabled())
+ trace.enter("<init>", this, world);
+ this.world = world;
+ this.xcutSet = world.getCrosscuttingMembersSet();
+ if (trace.isTraceEnabled())
+ trace.exit("<init>");
+ }
+
+ // ---- fields
+ // private Map sourceJavaClasses = new HashMap(); /* String -> UnwovenClassFile */
+ private List addedClasses = new ArrayList(); /* List<UnwovenClassFile> */
+ private List deletedTypenames = new ArrayList(); /* List<String> */
+ // private Map resources = new HashMap(); /* String -> UnwovenClassFile */
private Manifest manifest = null;
- private boolean needToReweaveWorld = false;
+ private boolean needToReweaveWorld = false;
- private boolean isBatchWeave = true;
- private List shadowMungerList = null; // setup by prepareForWeave
+ private boolean isBatchWeave = true;
+ private List shadowMungerList = null; // setup by prepareForWeave
private List typeMungerList = null; // setup by prepareForWeave
- private List lateTypeMungerList = null; // setup by prepareForWeave
+ private List lateTypeMungerList = null; // setup by prepareForWeave
private List declareParentsList = null; // setup by prepareForWeave
- private ZipOutputStream zipOutputStream;
+ private ZipOutputStream zipOutputStream;
private CustomMungerFactory customMungerFactory;
// ----
-
+
// only called for testing
- public void setShadowMungers(List l) {
- shadowMungerList = l;
- }
-
-
- /**
- * Add the given aspect to the weaver.
- * The type is resolved to support DOT for static inner classes as well as DOLLAR
- *
- * @param aspectName
- * @return aspect
- */
- public ResolvedType addLibraryAspect(String aspectName) {
- if (trace.isTraceEnabled()) trace.enter("addLibraryAspect",this,aspectName);
-
- // 1 - resolve as is
- UnresolvedType unresolvedT = UnresolvedType.forName(aspectName);
- unresolvedT.setNeedsModifiableDelegate(true);
- ResolvedType type = world.resolve(unresolvedT, true);
- if (type.isMissing()) {
- // fallback on inner class lookup mechanism
- String fixedName = aspectName;
- int hasDot = fixedName.lastIndexOf('.');
- while (hasDot > 0) {
- //System.out.println("BcelWeaver.addLibraryAspect " + fixedName);
- char[] fixedNameChars = fixedName.toCharArray();
- fixedNameChars[hasDot] = '$';
- fixedName = new String(fixedNameChars);
- hasDot = fixedName.lastIndexOf('.');
- UnresolvedType ut = UnresolvedType.forName(fixedName);
- ut.setNeedsModifiableDelegate(true);
- type = world.resolve(ut, true);
- if (!type.isMissing()) {
- break;
- }
- }
- }
-
- //System.out.println("type: " + type + " for " + aspectName);
+ public void setShadowMungers(List l) {
+ shadowMungerList = l;
+ }
+
+ /**
+ * Add the given aspect to the weaver. The type is resolved to support DOT for static inner classes as well as DOLLAR
+ *
+ * @param aspectName
+ * @return aspect
+ */
+ public ResolvedType addLibraryAspect(String aspectName) {
+ if (trace.isTraceEnabled())
+ trace.enter("addLibraryAspect", this, aspectName);
+
+ // 1 - resolve as is
+ UnresolvedType unresolvedT = UnresolvedType.forName(aspectName);
+ unresolvedT.setNeedsModifiableDelegate(true);
+ ResolvedType type = world.resolve(unresolvedT, true);
+ if (type.isMissing()) {
+ // fallback on inner class lookup mechanism
+ String fixedName = aspectName;
+ int hasDot = fixedName.lastIndexOf('.');
+ while (hasDot > 0) {
+ // System.out.println("BcelWeaver.addLibraryAspect " + fixedName);
+ char[] fixedNameChars = fixedName.toCharArray();
+ fixedNameChars[hasDot] = '$';
+ fixedName = new String(fixedNameChars);
+ hasDot = fixedName.lastIndexOf('.');
+ UnresolvedType ut = UnresolvedType.forName(fixedName);
+ ut.setNeedsModifiableDelegate(true);
+ type = world.resolve(ut, true);
+ if (!type.isMissing()) {
+ break;
+ }
+ }
+ }
+
+ // System.out.println("type: " + type + " for " + aspectName);
if (type.isAspect()) {
-
+
// Bug 119657 ensure we use the unwoven aspect
- WeaverStateInfo wsi = type.getWeaverState();
+ WeaverStateInfo wsi = type.getWeaverState();
if (wsi != null && wsi.isReweavable()) {
- BcelObjectType classType = getClassType(type.getName());
+ BcelObjectType classType = getClassType(type.getName());
JavaClass wovenJavaClass = classType.getJavaClass();
- JavaClass unwovenJavaClass = Utility.makeJavaClass(wovenJavaClass.getFileName(),
- wsi.getUnwovenClassFileData(wovenJavaClass.getBytes()));
+ JavaClass unwovenJavaClass = Utility.makeJavaClass(wovenJavaClass.getFileName(), wsi
+ .getUnwovenClassFileData(wovenJavaClass.getBytes()));
world.storeClass(unwovenJavaClass);
classType.setJavaClass(unwovenJavaClass);
-// classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes())));
+ // classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(),
+ // wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes())));
}
-
- //TODO AV - happens to reach that a lot of time: for each type flagged reweavable X for each aspect in the weaverstate
- //=> mainly for nothing for LTW - pbly for something in incremental build...
+
+ // TODO AV - happens to reach that a lot of time: for each type flagged reweavable X for each aspect in the weaverstate
+ // => mainly for nothing for LTW - pbly for something in incremental build...
xcutSet.addOrReplaceAspect(type);
- if (trace.isTraceEnabled()) trace.exit("addLibraryAspect",type);
- if (type.getSuperclass().isAspect()) {
- // If the supertype includes ITDs and the user has not included that aspect in the aop.xml, they will
- // not get picked up, which can give unusual behaviour! See bug 223094
- // This change causes us to pick up the super aspect regardless of what was said in the aop.xml - giving
- // predictable behaviour. If the user also supplied it, there will be no problem other than the second
- // addition overriding the first
- addLibraryAspect(type.getSuperclass().getName());
- }
- return type;
- } else {
- // FIXME AV - better warning upon no such aspect from aop.xml
+ if (trace.isTraceEnabled())
+ trace.exit("addLibraryAspect", type);
+ if (type.getSuperclass().isAspect()) {
+ // If the supertype includes ITDs and the user has not included that aspect in the aop.xml, they will
+ // not get picked up, which can give unusual behaviour! See bug 223094
+ // This change causes us to pick up the super aspect regardless of what was said in the aop.xml - giving
+ // predictable behaviour. If the user also supplied it, there will be no problem other than the second
+ // addition overriding the first
+ addLibraryAspect(type.getSuperclass().getName());
+ }
+ return type;
+ } else {
+ // FIXME AV - better warning upon no such aspect from aop.xml
RuntimeException ex = new RuntimeException("Cannot register non aspect: " + type.getName() + " , " + aspectName);
- if (trace.isTraceEnabled()) trace.exit("addLibraryAspect",ex);
+ if (trace.isTraceEnabled())
+ trace.exit("addLibraryAspect", ex);
throw ex;
}
- }
-
-
+ }
- /**
- *
- * @param inFile File path to class directory or zip/jar class archive
- * @throws IOException
- */
- public void addLibraryJarFile(File inFile) throws IOException {
+ /**
+ *
+ * @param inFile File path to class directory or zip/jar class archive
+ * @throws IOException
+ */
+ public void addLibraryJarFile(File inFile) throws IOException {
List addedAspects = null;
if (inFile.isDirectory()) {
addedAspects = addAspectsFromDirectory(inFile);
} else {
addedAspects = addAspectsFromJarFile(inFile);
}
-
+
for (Iterator i = addedAspects.iterator(); i.hasNext();) {
ResolvedType aspectX = (ResolvedType) i.next();
xcutSet.addOrReplaceAspect(aspectX);
@@ -241,456 +232,449 @@ public class BcelWeaver {
}
private List addAspectsFromJarFile(File inFile) throws FileNotFoundException, IOException {
- ZipInputStream inStream = new ZipInputStream(new FileInputStream(inFile)); //??? buffered
+ ZipInputStream inStream = new ZipInputStream(new FileInputStream(inFile)); // ??? buffered
List addedAspects = new ArrayList();
while (true) {
ZipEntry entry = inStream.getNextEntry();
- if (entry == null) break;
-
+ if (entry == null)
+ break;
+
if (entry.isDirectory() || !entry.getName().endsWith(".class")) {
continue;
}
-
+
// FIXME ASC performance? of this alternative soln.
ClassParser parser = new ClassParser(new ByteArrayInputStream(FileUtil.readAsByteArray(inStream)), entry.getName());
- JavaClass jc = parser.parse();
+ JavaClass jc = parser.parse();
inStream.closeEntry();
-
+
ResolvedType type = world.addSourceObjectType(jc).getResolvedTypeX();
type.setBinaryPath(inFile.getAbsolutePath());
- if (type.isAspect()) {
- addedAspects.add(type);
- }
-
+ if (type.isAspect()) {
+ addedAspects.add(type);
+ }
+
}
-
+
inStream.close();
return addedAspects;
}
- private List addAspectsFromDirectory(File dir) throws FileNotFoundException, IOException{
+ private List addAspectsFromDirectory(File dir) throws FileNotFoundException, IOException {
List addedAspects = new ArrayList();
- File[] classFiles = FileUtil.listFiles(dir,new FileFilter(){
-
+ File[] classFiles = FileUtil.listFiles(dir, new FileFilter() {
+
public boolean accept(File pathname) {
return pathname.getName().endsWith(".class");
}
-
+
});
for (int i = 0; i < classFiles.length; i++) {
FileInputStream fis = new FileInputStream(classFiles[i]);
byte[] bytes = FileUtil.readAsByteArray(fis);
- addIfAspect(bytes,classFiles[i].getAbsolutePath(),addedAspects,dir);
+ addIfAspect(bytes, classFiles[i].getAbsolutePath(), addedAspects, dir);
fis.close();
}
return addedAspects;
}
-
+
private void addIfAspect(byte[] bytes, String name, List toList, File dir) throws IOException {
- ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes),name);
+ ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), name);
JavaClass jc = parser.parse();
ResolvedType type = world.addSourceObjectType(jc).getResolvedTypeX();
String typeName = type.getName().replace('.', File.separatorChar);
- int end = name.lastIndexOf(typeName+".class");
+ int end = name.lastIndexOf(typeName + ".class");
String binaryPath = null;
// if end is -1 then something wierd happened, the class file is not in the correct place, something like
// bin/A.class when the declaration for A specifies it is in a package.
- if (end==-1) {
+ if (end == -1) {
binaryPath = dir.getAbsolutePath();
} else {
- binaryPath = name.substring(0,end-1);
+ binaryPath = name.substring(0, end - 1);
}
- type.setBinaryPath(binaryPath);
+ type.setBinaryPath(binaryPath);
if (type.isAspect()) {
toList.add(type);
}
}
-
-// // The ANT copy task should be used to copy resources across.
-// private final static boolean CopyResourcesFromInpathDirectoriesToOutput=false;
+ // // The ANT copy task should be used to copy resources across.
+ // private final static boolean CopyResourcesFromInpathDirectoriesToOutput=false;
/**
- * Add any .class files in the directory to the outdir. Anything other than .class files in
- * the directory (or its subdirectories) are considered resources and are also copied.
- *
+ * Add any .class files in the directory to the outdir. Anything other than .class files in the directory (or its
+ * subdirectories) are considered resources and are also copied.
+ *
*/
- public List addDirectoryContents(File inFile,File outDir) throws IOException {
+ public List addDirectoryContents(File inFile, File outDir) throws IOException {
List addedClassFiles = new ArrayList();
-
+
// Get a list of all files (i.e. everything that isnt a directory)
- File[] files = FileUtil.listFiles(inFile,new FileFilter() {
+ File[] files = FileUtil.listFiles(inFile, new FileFilter() {
public boolean accept(File f) {
boolean accept = !f.isDirectory();
return accept;
}
});
-
+
// For each file, add it either as a real .class file or as a resource
for (int i = 0; i < files.length; i++) {
- addedClassFiles.add(addClassFile(files[i],inFile,outDir));
+ addedClassFiles.add(addClassFile(files[i], inFile, outDir));
}
-
+
return addedClassFiles;
}
-
- /** Adds all class files in the jar
+ /**
+ * Adds all class files in the jar
*/
- public List addJarFile(File inFile, File outDir, boolean canBeDirectory){
-// System.err.println("? addJarFile(" + inFile + ", " + outDir + ")");
+ public List addJarFile(File inFile, File outDir, boolean canBeDirectory) {
+ // System.err.println("? addJarFile(" + inFile + ", " + outDir + ")");
List addedClassFiles = new ArrayList();
needToReweaveWorld = true;
JarFile inJar = null;
-
+
try {
// Is this a directory we are looking at?
if (inFile.isDirectory() && canBeDirectory) {
- addedClassFiles.addAll(addDirectoryContents(inFile,outDir));
+ addedClassFiles.addAll(addDirectoryContents(inFile, outDir));
} else {
-
+
inJar = new JarFile(inFile);
addManifest(inJar.getManifest());
Enumeration entries = inJar.entries();
-
+
while (entries.hasMoreElements()) {
- JarEntry entry = (JarEntry)entries.nextElement();
+ JarEntry entry = (JarEntry) entries.nextElement();
InputStream inStream = inJar.getInputStream(entry);
-
+
byte[] bytes = FileUtil.readAsByteArray(inStream);
String filename = entry.getName();
-// System.out.println("? addJarFile() filename='" + filename + "'");
+ // System.out.println("? addJarFile() filename='" + filename + "'");
UnwovenClassFile classFile = new UnwovenClassFile(new File(outDir, filename).getAbsolutePath(), bytes);
if (filename.endsWith(".class")) {
this.addClassFile(classFile);
addedClassFiles.add(classFile);
}
-// else if (!entry.isDirectory()) {
-//
-// /* bug-44190 Copy meta-data */
-// addResource(filename,classFile);
-// }
+ // else if (!entry.isDirectory()) {
+ //
+ // /* bug-44190 Copy meta-data */
+ // addResource(filename,classFile);
+ // }
inStream.close();
}
inJar.close();
}
} catch (FileNotFoundException ex) {
- IMessage message = new Message(
- "Could not find input jar file " + inFile.getPath() + ", ignoring",
- new SourceLocation(inFile,0),
- false);
+ IMessage message = new Message("Could not find input jar file " + inFile.getPath() + ", ignoring", new SourceLocation(
+ inFile, 0), false);
world.getMessageHandler().handleMessage(message);
} catch (IOException ex) {
- IMessage message = new Message(
- "Could not read input jar file " + inFile.getPath() + "(" + ex.getMessage() + ")",
- new SourceLocation(inFile,0),
- true);
+ IMessage message = new Message("Could not read input jar file " + inFile.getPath() + "(" + ex.getMessage() + ")",
+ new SourceLocation(inFile, 0), true);
world.getMessageHandler().handleMessage(message);
} finally {
if (inJar != null) {
- try {inJar.close();}
- catch (IOException ex) {
- IMessage message = new Message(
- "Could not close input jar file " + inFile.getPath() + "(" + ex.getMessage() + ")",
- new SourceLocation(inFile,0),
- true);
- world.getMessageHandler().handleMessage(message);
+ try {
+ inJar.close();
+ } catch (IOException ex) {
+ IMessage message = new Message("Could not close input jar file " + inFile.getPath() + "(" + ex.getMessage()
+ + ")", new SourceLocation(inFile, 0), true);
+ world.getMessageHandler().handleMessage(message);
}
}
}
-
+
return addedClassFiles;
}
-// public void addResource(String name, File inPath, File outDir) throws IOException {
-//
-// /* Eliminate CVS files. Relative paths use "/" */
-// if (!name.startsWith("CVS/") && (-1 == name.indexOf("/CVS/")) && !name.endsWith("/CVS")) {
-//// System.err.println("? addResource('" + name + "')");
-//// BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(inPath));
-//// byte[] bytes = new byte[(int)inPath.length()];
-//// inStream.read(bytes);
-//// inStream.close();
-// byte[] bytes = FileUtil.readAsByteArray(inPath);
-// UnwovenClassFile resourceFile = new UnwovenClassFile(new File(outDir, name).getAbsolutePath(), bytes);
-// addResource(name,resourceFile);
-// }
-// }
+ // public void addResource(String name, File inPath, File outDir) throws IOException {
+ //
+ // /* Eliminate CVS files. Relative paths use "/" */
+ // if (!name.startsWith("CVS/") && (-1 == name.indexOf("/CVS/")) && !name.endsWith("/CVS")) {
+ // // System.err.println("? addResource('" + name + "')");
+ // // BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(inPath));
+ // // byte[] bytes = new byte[(int)inPath.length()];
+ // // inStream.read(bytes);
+ // // inStream.close();
+ // byte[] bytes = FileUtil.readAsByteArray(inPath);
+ // UnwovenClassFile resourceFile = new UnwovenClassFile(new File(outDir, name).getAbsolutePath(), bytes);
+ // addResource(name,resourceFile);
+ // }
+ // }
public boolean needToReweaveWorld() {
return needToReweaveWorld;
}
-
- /** Should be addOrReplace
- */
- public void addClassFile(UnwovenClassFile classFile) {
- addedClasses.add(classFile);
-// if (null != sourceJavaClasses.put(classFile.getClassName(), classFile)) {
-//// throw new RuntimeException(classFile.getClassName());
-// }
- world.addSourceObjectType(classFile.getJavaClass());
- }
-
- public UnwovenClassFile addClassFile(File classFile, File inPathDir, File outDir) throws IOException {
+
+ /**
+ * Should be addOrReplace
+ */
+ public void addClassFile(UnwovenClassFile classFile) {
+ addedClasses.add(classFile);
+ // if (null != sourceJavaClasses.put(classFile.getClassName(), classFile)) {
+ // // throw new RuntimeException(classFile.getClassName());
+ // }
+ world.addSourceObjectType(classFile.getJavaClass());
+ }
+
+ public UnwovenClassFile addClassFile(File classFile, File inPathDir, File outDir) throws IOException {
FileInputStream fis = new FileInputStream(classFile);
byte[] bytes = FileUtil.readAsByteArray(fis);
// String relativePath = files[i].getPath();
-
+
// ASSERT: files[i].getAbsolutePath().startsWith(inFile.getAbsolutePath()
// or we are in trouble...
- String filename = classFile.getAbsolutePath().substring(
- inPathDir.getAbsolutePath().length()+1);
- UnwovenClassFile ucf = new UnwovenClassFile(new File(outDir,filename).getAbsolutePath(),bytes);
+ String filename = classFile.getAbsolutePath().substring(inPathDir.getAbsolutePath().length() + 1);
+ UnwovenClassFile ucf = new UnwovenClassFile(new File(outDir, filename).getAbsolutePath(), bytes);
if (filename.endsWith(".class")) {
// System.err.println("BCELWeaver: processing class from input directory "+classFile);
this.addClassFile(ucf);
}
fis.close();
return ucf;
- }
-
-
- public void deleteClassFile(String typename) {
- deletedTypenames.add(typename);
-// sourceJavaClasses.remove(typename);
- world.deleteSourceObjectType(UnresolvedType.forName(typename));
- }
-
-// public void addResource (String name, UnwovenClassFile resourceFile) {
-// /* bug-44190 Change error to warning and copy first resource */
-// if (!resources.containsKey(name)) {
-// resources.put(name, resourceFile);
-// }
-// else {
-// world.showMessage(IMessage.WARNING, "duplicate resource: '" + name + "'",
-// null, null);
-// }
-// }
+ }
+
+ public void deleteClassFile(String typename) {
+ deletedTypenames.add(typename);
+ // sourceJavaClasses.remove(typename);
+ world.deleteSourceObjectType(UnresolvedType.forName(typename));
+ }
+
+ // public void addResource (String name, UnwovenClassFile resourceFile) {
+ // /* bug-44190 Change error to warning and copy first resource */
+ // if (!resources.containsKey(name)) {
+ // resources.put(name, resourceFile);
+ // }
+ // else {
+ // world.showMessage(IMessage.WARNING, "duplicate resource: '" + name + "'",
+ // null, null);
+ // }
+ // }
// ---- weave preparation
- public void setIsBatchWeave(boolean b) {
- isBatchWeave=b;
- }
-
- public void prepareForWeave() {
- if (trace.isTraceEnabled()) trace.enter("prepareForWeave",this);
- needToReweaveWorld = xcutSet.hasChangedSinceLastReset();
-
-
- // update mungers
- for (Iterator i = addedClasses.iterator(); i.hasNext(); ) {
- UnwovenClassFile jc = (UnwovenClassFile)i.next();
- String name = jc.getClassName();
- ResolvedType type = world.resolve(name);
- //System.err.println("added: " + type + " aspect? " + type.isAspect());
- if (type.isAspect()) {
- needToReweaveWorld |= xcutSet.addOrReplaceAspect(type);
- }
- }
-
- for (Iterator i = deletedTypenames.iterator(); i.hasNext(); ) {
- String name = (String)i.next();
- if (xcutSet.deleteAspect(UnresolvedType.forName(name))) needToReweaveWorld = true;
- }
+ public void setIsBatchWeave(boolean b) {
+ isBatchWeave = b;
+ }
+
+ public void prepareForWeave() {
+ if (trace.isTraceEnabled())
+ trace.enter("prepareForWeave", this);
+ needToReweaveWorld = xcutSet.hasChangedSinceLastReset();
+
+ // update mungers
+ for (Iterator i = addedClasses.iterator(); i.hasNext();) {
+ UnwovenClassFile jc = (UnwovenClassFile) i.next();
+ String name = jc.getClassName();
+ ResolvedType type = world.resolve(name);
+ // System.err.println("added: " + type + " aspect? " + type.isAspect());
+ if (type.isAspect()) {
+ needToReweaveWorld |= xcutSet.addOrReplaceAspect(type);
+ }
+ }
+
+ for (Iterator i = deletedTypenames.iterator(); i.hasNext();) {
+ String name = (String) i.next();
+ if (xcutSet.deleteAspect(UnresolvedType.forName(name)))
+ needToReweaveWorld = true;
+ }
shadowMungerList = xcutSet.getShadowMungers();
-// world.debug("shadow mungers=" + shadowMungerList);
+ // world.debug("shadow mungers=" + shadowMungerList);
rewritePointcuts(shadowMungerList);
// Sometimes an error occurs during rewriting pointcuts (for example, if ambiguous bindings
// are detected) - we ought to fail the prepare when this happens because continuing with
// inconsistent pointcuts could lead to problems
typeMungerList = xcutSet.getTypeMungers();
- lateTypeMungerList = xcutSet.getLateTypeMungers();
+ lateTypeMungerList = xcutSet.getLateTypeMungers();
declareParentsList = xcutSet.getDeclareParents();
-
+
addCustomMungers();
-
- // The ordering here used to be based on a string compare on toString() for the two mungers -
- // that breaks for the @AJ style where advice names aren't programmatically generated. So we
+
+ // The ordering here used to be based on a string compare on toString() for the two mungers -
+ // that breaks for the @AJ style where advice names aren't programmatically generated. So we
// have changed the sorting to be based on source location in the file - this is reliable, in
// the case of source locations missing, we assume they are 'sorted' - i.e. the order in
// which they were added to the collection is correct, this enables the @AJ stuff to work properly.
-
+
// When @AJ processing starts filling in source locations for mungers, this code may need
// a bit of alteration...
-
- Collections.sort(
- shadowMungerList,
- new Comparator() {
- public int compare(Object o1, Object o2) {
- ShadowMunger sm1 = (ShadowMunger)o1;
- ShadowMunger sm2 = (ShadowMunger)o2;
- if (sm1.getSourceLocation()==null) return (sm2.getSourceLocation()==null?0:1);
- if (sm2.getSourceLocation()==null) return -1;
-
- return (sm2.getSourceLocation().getOffset()-sm1.getSourceLocation().getOffset());
- }
- });
-
+
+ Collections.sort(shadowMungerList, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ ShadowMunger sm1 = (ShadowMunger) o1;
+ ShadowMunger sm2 = (ShadowMunger) o2;
+ if (sm1.getSourceLocation() == null)
+ return (sm2.getSourceLocation() == null ? 0 : 1);
+ if (sm2.getSourceLocation() == null)
+ return -1;
+
+ return (sm2.getSourceLocation().getOffset() - sm1.getSourceLocation().getOffset());
+ }
+ });
+
if (inReweavableMode)
- world.showMessage(IMessage.INFO,
- WeaverMessages.format(WeaverMessages.REWEAVABLE_MODE),
- null, null);
-
- if (trace.isTraceEnabled()) trace.exit("prepareForWeave");
- }
-
- private void addCustomMungers() {
+ world.showMessage(IMessage.INFO, WeaverMessages.format(WeaverMessages.REWEAVABLE_MODE), null, null);
+
+ if (trace.isTraceEnabled())
+ trace.exit("prepareForWeave");
+ }
+
+ private void addCustomMungers() {
if (customMungerFactory != null) {
for (Iterator i = addedClasses.iterator(); i.hasNext();) {
UnwovenClassFile jc = (UnwovenClassFile) i.next();
String name = jc.getClassName();
ResolvedType type = world.resolve(name);
if (type.isAspect()) {
- Collection/*ShadowMunger*/ shadowMungers = customMungerFactory.createCustomShadowMungers(type);
+ Collection/* ShadowMunger */shadowMungers = customMungerFactory.createCustomShadowMungers(type);
if (shadowMungers != null) {
shadowMungerList.addAll(shadowMungers);
}
- Collection/*ConcreteTypeMunger*/ typeMungers = customMungerFactory
- .createCustomTypeMungers(type);
+ Collection/* ConcreteTypeMunger */typeMungers = customMungerFactory.createCustomTypeMungers(type);
if (typeMungers != null)
typeMungerList.addAll(typeMungers);
}
}
}
}
-
- public void setCustomMungerFactory(CustomMungerFactory factory) {
- customMungerFactory = factory;
- }
-
- /*
- * Rewrite all of the pointcuts in the world into their most efficient
- * form for subsequent matching. Also ensure that if pc1.equals(pc2)
- * then pc1 == pc2 (for non-binding pcds) by making references all
- * point to the same instance.
- * Since pointcuts remember their match decision on the last shadow,
- * this makes matching faster when many pointcuts share common elements,
- * or even when one single pointcut has one common element (which can
- * be a side-effect of DNF rewriting).
- */
- private void rewritePointcuts(List/*ShadowMunger*/ shadowMungers) {
- PointcutRewriter rewriter = new PointcutRewriter();
- for (Iterator iter = shadowMungers.iterator(); iter.hasNext();) {
+
+ public void setCustomMungerFactory(CustomMungerFactory factory) {
+ customMungerFactory = factory;
+ }
+
+ /*
+ * Rewrite all of the pointcuts in the world into their most efficient form for subsequent matching. Also ensure that if
+ * pc1.equals(pc2) then pc1 == pc2 (for non-binding pcds) by making references all point to the same instance. Since pointcuts
+ * remember their match decision on the last shadow, this makes matching faster when many pointcuts share common elements, or
+ * even when one single pointcut has one common element (which can be a side-effect of DNF rewriting).
+ */
+ private void rewritePointcuts(List/* ShadowMunger */shadowMungers) {
+ PointcutRewriter rewriter = new PointcutRewriter();
+ for (Iterator iter = shadowMungers.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
Pointcut p = munger.getPointcut();
Pointcut newP = rewriter.rewrite(p);
// validateBindings now whilst we still have around the pointcut
// that resembles what the user actually wrote in their program
- // text.
+ // text.
if (munger instanceof Advice) {
Advice advice = (Advice) munger;
if (advice.getSignature() != null) {
final int numFormals;
- final String names[];
- // If the advice is being concretized in a @AJ aspect *and* the advice was declared in
- // an @AJ aspect (it could have been inherited from a code style aspect) then
- // evaluate the alternative set of formals. pr125699
- if (advice.getConcreteAspect().isAnnotationStyleAspect()
- && advice.getDeclaringAspect()!=null
- && advice.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
- numFormals = advice.getBaseParameterCount();
- int numArgs = advice.getSignature().getParameterTypes().length;
- if (numFormals > 0) {
- names = advice.getSignature().getParameterNames(world);
- validateBindings(newP,p,numArgs,names);
- }
- } else {
- numFormals = advice.getBaseParameterCount();
- if (numFormals > 0) {
- names = advice.getBaseParameterNames(world);
- validateBindings(newP,p,numFormals,names);
- }
- }
+ final String names[];
+ // If the advice is being concretized in a @AJ aspect *and* the advice was declared in
+ // an @AJ aspect (it could have been inherited from a code style aspect) then
+ // evaluate the alternative set of formals. pr125699
+ if (advice.getConcreteAspect().isAnnotationStyleAspect() && advice.getDeclaringAspect() != null
+ && advice.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
+ numFormals = advice.getBaseParameterCount();
+ int numArgs = advice.getSignature().getParameterTypes().length;
+ if (numFormals > 0) {
+ names = advice.getSignature().getParameterNames(world);
+ validateBindings(newP, p, numArgs, names);
+ }
+ } else {
+ numFormals = advice.getBaseParameterCount();
+ if (numFormals > 0) {
+ names = advice.getBaseParameterNames(world);
+ validateBindings(newP, p, numFormals, names);
+ }
+ }
}
}
munger.setPointcut(newP);
}
- // now that we have optimized individual pointcuts, optimize
- // across the set of pointcuts....
- // Use a map from key based on pc equality, to value based on
- // pc identity.
- Map/*<Pointcut,Pointcut>*/ pcMap = new HashMap();
- for (Iterator iter = shadowMungers.iterator(); iter.hasNext();) {
+ // now that we have optimized individual pointcuts, optimize
+ // across the set of pointcuts....
+ // Use a map from key based on pc equality, to value based on
+ // pc identity.
+ Map/* <Pointcut,Pointcut> */pcMap = new HashMap();
+ for (Iterator iter = shadowMungers.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
Pointcut p = munger.getPointcut();
- munger.setPointcut(shareEntriesFromMap(p,pcMap));
- }
- }
-
- private Pointcut shareEntriesFromMap(Pointcut p,Map pcMap) {
- // some things cant be shared...
- if (p instanceof NameBindingPointcut) return p;
- if (p instanceof IfPointcut) return p;
- if (p instanceof ConcreteCflowPointcut) return p;
- if (p instanceof AndPointcut) {
- AndPointcut apc = (AndPointcut) p;
- Pointcut left = shareEntriesFromMap(apc.getLeft(),pcMap);
- Pointcut right = shareEntriesFromMap(apc.getRight(),pcMap);
- return new AndPointcut(left,right);
- } else if (p instanceof OrPointcut) {
- OrPointcut opc = (OrPointcut) p;
- Pointcut left = shareEntriesFromMap(opc.getLeft(),pcMap);
- Pointcut right = shareEntriesFromMap(opc.getRight(),pcMap);
- return new OrPointcut(left,right);
- } else if (p instanceof NotPointcut) {
- NotPointcut npc = (NotPointcut) p;
- Pointcut not = shareEntriesFromMap(npc.getNegatedPointcut(),pcMap);
- return new NotPointcut(not);
- } else {
- // primitive pcd
- if (pcMap.containsKey(p)) { // based on equality
- return (Pointcut) pcMap.get(p); // same instance (identity)
- } else {
- pcMap.put(p,p);
- return p;
- }
- }
- }
-
- // userPointcut is the pointcut that the user wrote in the program text.
- // dnfPointcut is the same pointcut rewritten in DNF
- // numFormals is the number of formal parameters in the pointcut
- // if numFormals > 0 then every branch of a disjunction must bind each formal once and only once.
- // in addition, the left and right branches of a disjunction must hold on join point kinds in
- // common.
- private void validateBindings(Pointcut dnfPointcut, Pointcut userPointcut, int numFormals, String[] names) {
- if (numFormals == 0) return; // nothing to check
- if (dnfPointcut.couldMatchKinds()==Shadow.NO_SHADOW_KINDS_BITS) return; // cant have problems if you dont match!
- if (dnfPointcut instanceof OrPointcut) {
- OrPointcut orBasedDNFPointcut = (OrPointcut) dnfPointcut;
- Pointcut[] leftBindings = new Pointcut[numFormals];
- Pointcut[] rightBindings = new Pointcut[numFormals];
- validateOrBranch(orBasedDNFPointcut,userPointcut,numFormals,names,leftBindings,rightBindings);
- } else {
- Pointcut[] bindings = new Pointcut[numFormals];
- validateSingleBranch(dnfPointcut, userPointcut, numFormals, names,bindings);
- }
- }
-
- private void validateOrBranch(OrPointcut pc, Pointcut userPointcut, int numFormals,
- String[] names, Pointcut[] leftBindings, Pointcut[] rightBindings) {
- Pointcut left = pc.getLeft();
- Pointcut right = pc.getRight();
- if (left instanceof OrPointcut) {
- Pointcut[] newRightBindings = new Pointcut[numFormals];
- validateOrBranch((OrPointcut)left,userPointcut,numFormals,names,leftBindings,newRightBindings);
- } else {
- if (left.couldMatchKinds()!=Shadow.NO_SHADOW_KINDS_BITS)
- validateSingleBranch(left, userPointcut, numFormals, names, leftBindings);
- }
- if (right instanceof OrPointcut) {
- Pointcut[] newLeftBindings = new Pointcut[numFormals];
- validateOrBranch((OrPointcut)right,userPointcut,numFormals,names,newLeftBindings,rightBindings);
- } else {
- if (right.couldMatchKinds()!=Shadow.NO_SHADOW_KINDS_BITS)
- validateSingleBranch(right, userPointcut, numFormals, names, rightBindings);
- }
+ munger.setPointcut(shareEntriesFromMap(p, pcMap));
+ }
+ }
+
+ private Pointcut shareEntriesFromMap(Pointcut p, Map pcMap) {
+ // some things cant be shared...
+ if (p instanceof NameBindingPointcut)
+ return p;
+ if (p instanceof IfPointcut)
+ return p;
+ if (p instanceof ConcreteCflowPointcut)
+ return p;
+ if (p instanceof AndPointcut) {
+ AndPointcut apc = (AndPointcut) p;
+ Pointcut left = shareEntriesFromMap(apc.getLeft(), pcMap);
+ Pointcut right = shareEntriesFromMap(apc.getRight(), pcMap);
+ return new AndPointcut(left, right);
+ } else if (p instanceof OrPointcut) {
+ OrPointcut opc = (OrPointcut) p;
+ Pointcut left = shareEntriesFromMap(opc.getLeft(), pcMap);
+ Pointcut right = shareEntriesFromMap(opc.getRight(), pcMap);
+ return new OrPointcut(left, right);
+ } else if (p instanceof NotPointcut) {
+ NotPointcut npc = (NotPointcut) p;
+ Pointcut not = shareEntriesFromMap(npc.getNegatedPointcut(), pcMap);
+ return new NotPointcut(not);
+ } else {
+ // primitive pcd
+ if (pcMap.containsKey(p)) { // based on equality
+ return (Pointcut) pcMap.get(p); // same instance (identity)
+ } else {
+ pcMap.put(p, p);
+ return p;
+ }
+ }
+ }
+
+ // userPointcut is the pointcut that the user wrote in the program text.
+ // dnfPointcut is the same pointcut rewritten in DNF
+ // numFormals is the number of formal parameters in the pointcut
+ // if numFormals > 0 then every branch of a disjunction must bind each formal once and only once.
+ // in addition, the left and right branches of a disjunction must hold on join point kinds in
+ // common.
+ private void validateBindings(Pointcut dnfPointcut, Pointcut userPointcut, int numFormals, String[] names) {
+ if (numFormals == 0)
+ return; // nothing to check
+ if (dnfPointcut.couldMatchKinds() == Shadow.NO_SHADOW_KINDS_BITS)
+ return; // cant have problems if you dont match!
+ if (dnfPointcut instanceof OrPointcut) {
+ OrPointcut orBasedDNFPointcut = (OrPointcut) dnfPointcut;
+ Pointcut[] leftBindings = new Pointcut[numFormals];
+ Pointcut[] rightBindings = new Pointcut[numFormals];
+ validateOrBranch(orBasedDNFPointcut, userPointcut, numFormals, names, leftBindings, rightBindings);
+ } else {
+ Pointcut[] bindings = new Pointcut[numFormals];
+ validateSingleBranch(dnfPointcut, userPointcut, numFormals, names, bindings);
+ }
+ }
+
+ private void validateOrBranch(OrPointcut pc, Pointcut userPointcut, int numFormals, String[] names, Pointcut[] leftBindings,
+ Pointcut[] rightBindings) {
+ Pointcut left = pc.getLeft();
+ Pointcut right = pc.getRight();
+ if (left instanceof OrPointcut) {
+ Pointcut[] newRightBindings = new Pointcut[numFormals];
+ validateOrBranch((OrPointcut) left, userPointcut, numFormals, names, leftBindings, newRightBindings);
+ } else {
+ if (left.couldMatchKinds() != Shadow.NO_SHADOW_KINDS_BITS)
+ validateSingleBranch(left, userPointcut, numFormals, names, leftBindings);
+ }
+ if (right instanceof OrPointcut) {
+ Pointcut[] newLeftBindings = new Pointcut[numFormals];
+ validateOrBranch((OrPointcut) right, userPointcut, numFormals, names, newLeftBindings, rightBindings);
+ } else {
+ if (right.couldMatchKinds() != Shadow.NO_SHADOW_KINDS_BITS)
+ validateSingleBranch(right, userPointcut, numFormals, names, rightBindings);
+ }
int kindsInCommon = left.couldMatchKinds() & right.couldMatchKinds();
- if (kindsInCommon!=Shadow.NO_SHADOW_KINDS_BITS && couldEverMatchSameJoinPoints(left,right)) {
+ if (kindsInCommon != Shadow.NO_SHADOW_KINDS_BITS && couldEverMatchSameJoinPoints(left, right)) {
// we know that every branch binds every formal, so there is no ambiguity
// if each branch binds it in exactly the same way...
List ambiguousNames = new ArrayList();
@@ -704,143 +688,151 @@ public class BcelWeaver {
}
}
if (!ambiguousNames.isEmpty())
- raiseAmbiguityInDisjunctionError(userPointcut,ambiguousNames);
- }
- }
-
+ raiseAmbiguityInDisjunctionError(userPointcut, ambiguousNames);
+ }
+ }
+
// pc is a pointcut that does not contain any disjunctions
- // check that every formal is bound (negation doesn't count).
- // we know that numFormals > 0 or else we would not be called
- private void validateSingleBranch(Pointcut pc, Pointcut userPointcut, int numFormals, String[] names, Pointcut[] bindings) {
- boolean[] foundFormals = new boolean[numFormals];
- for (int i = 0; i < foundFormals.length; i++) {
+ // check that every formal is bound (negation doesn't count).
+ // we know that numFormals > 0 or else we would not be called
+ private void validateSingleBranch(Pointcut pc, Pointcut userPointcut, int numFormals, String[] names, Pointcut[] bindings) {
+ boolean[] foundFormals = new boolean[numFormals];
+ for (int i = 0; i < foundFormals.length; i++) {
foundFormals[i] = false;
}
- validateSingleBranchRecursion(pc, userPointcut, foundFormals, names, bindings);
- for (int i = 0; i < foundFormals.length; i++) {
+ validateSingleBranchRecursion(pc, userPointcut, foundFormals, names, bindings);
+ for (int i = 0; i < foundFormals.length; i++) {
if (!foundFormals[i]) {
- boolean ignore = false;
- // ATAJ soften the unbound error for implicit bindings like JoinPoint in @AJ style
- for (int j = 0; j < userPointcut.m_ignoreUnboundBindingForNames.length; j++) {
- if (names[i] != null && names[i].equals(userPointcut.m_ignoreUnboundBindingForNames[j])) {
- ignore = true;
- break;
- }
- }
- if (!ignore) {
- raiseUnboundFormalError(names[i],userPointcut);
- }
+ boolean ignore = false;
+ // ATAJ soften the unbound error for implicit bindings like JoinPoint in @AJ style
+ for (int j = 0; j < userPointcut.m_ignoreUnboundBindingForNames.length; j++) {
+ if (names[i] != null && names[i].equals(userPointcut.m_ignoreUnboundBindingForNames[j])) {
+ ignore = true;
+ break;
+ }
+ }
+ if (!ignore) {
+ raiseUnboundFormalError(names[i], userPointcut);
+ }
}
}
- }
-
+ }
+
// each formal must appear exactly once
- private void validateSingleBranchRecursion(Pointcut pc, Pointcut userPointcut, boolean[] foundFormals, String[] names, Pointcut[] bindings) {
- if (pc instanceof NotPointcut) {
- // nots can only appear at leaves in DNF
- NotPointcut not = (NotPointcut) pc;
- if (not.getNegatedPointcut() instanceof NameBindingPointcut) {
- NameBindingPointcut nnbp = (NameBindingPointcut) not.getNegatedPointcut();
- if (!nnbp.getBindingAnnotationTypePatterns().isEmpty() && !nnbp.getBindingTypePatterns().isEmpty())
- raiseNegationBindingError(userPointcut);
- }
- } else if (pc instanceof AndPointcut) {
- AndPointcut and = (AndPointcut) pc;
- validateSingleBranchRecursion(and.getLeft(), userPointcut,foundFormals,names,bindings);
- validateSingleBranchRecursion(and.getRight(),userPointcut,foundFormals,names,bindings);
- } else if (pc instanceof NameBindingPointcut) {
- List/*BindingTypePattern*/ btps = ((NameBindingPointcut)pc).getBindingTypePatterns();
- for (Iterator iter = btps.iterator(); iter.hasNext();) {
+ private void validateSingleBranchRecursion(Pointcut pc, Pointcut userPointcut, boolean[] foundFormals, String[] names,
+ Pointcut[] bindings) {
+ if (pc instanceof NotPointcut) {
+ // nots can only appear at leaves in DNF
+ NotPointcut not = (NotPointcut) pc;
+ if (not.getNegatedPointcut() instanceof NameBindingPointcut) {
+ NameBindingPointcut nnbp = (NameBindingPointcut) not.getNegatedPointcut();
+ if (!nnbp.getBindingAnnotationTypePatterns().isEmpty() && !nnbp.getBindingTypePatterns().isEmpty())
+ raiseNegationBindingError(userPointcut);
+ }
+ } else if (pc instanceof AndPointcut) {
+ AndPointcut and = (AndPointcut) pc;
+ validateSingleBranchRecursion(and.getLeft(), userPointcut, foundFormals, names, bindings);
+ validateSingleBranchRecursion(and.getRight(), userPointcut, foundFormals, names, bindings);
+ } else if (pc instanceof NameBindingPointcut) {
+ List/* BindingTypePattern */btps = ((NameBindingPointcut) pc).getBindingTypePatterns();
+ for (Iterator iter = btps.iterator(); iter.hasNext();) {
BindingTypePattern btp = (BindingTypePattern) iter.next();
int index = btp.getFormalIndex();
- bindings[index] = pc;
+ bindings[index] = pc;
if (foundFormals[index]) {
- raiseAmbiguousBindingError(names[index],userPointcut);
+ raiseAmbiguousBindingError(names[index], userPointcut);
} else {
foundFormals[index] = true;
}
}
- List/* BindingPattern */baps = ((NameBindingPointcut) pc).getBindingAnnotationTypePatterns();
- for (Iterator iter = baps.iterator(); iter.hasNext();) {
- BindingPattern bap = (BindingPattern) iter.next();
+ List/* BindingPattern */baps = ((NameBindingPointcut) pc).getBindingAnnotationTypePatterns();
+ for (Iterator iter = baps.iterator(); iter.hasNext();) {
+ BindingPattern bap = (BindingPattern) iter.next();
int index = bap.getFormalIndex();
bindings[index] = pc;
if (foundFormals[index]) {
- raiseAmbiguousBindingError(names[index],userPointcut);
+ raiseAmbiguousBindingError(names[index], userPointcut);
} else {
foundFormals[index] = true;
}
}
- } else if (pc instanceof ConcreteCflowPointcut) {
- ConcreteCflowPointcut cfp = (ConcreteCflowPointcut) pc;
- int[] slots = cfp.getUsedFormalSlots();
- for (int i = 0; i < slots.length; i++) {
- bindings[slots[i]] = cfp;
+ } else if (pc instanceof ConcreteCflowPointcut) {
+ ConcreteCflowPointcut cfp = (ConcreteCflowPointcut) pc;
+ int[] slots = cfp.getUsedFormalSlots();
+ for (int i = 0; i < slots.length; i++) {
+ bindings[slots[i]] = cfp;
if (foundFormals[slots[i]]) {
- raiseAmbiguousBindingError(names[slots[i]],userPointcut);
+ raiseAmbiguousBindingError(names[slots[i]], userPointcut);
} else {
foundFormals[slots[i]] = true;
- }
+ }
}
- }
- }
-
-
- // By returning false from this method, we are allowing binding of the same
- // variable on either side of an or.
- // Be conservative :- have to consider overriding, varargs, autoboxing,
- // the effects of itds (on within for example), interfaces, the fact that
- // join points can have multiple signatures and so on.
- private boolean couldEverMatchSameJoinPoints(Pointcut left, Pointcut right) {
-
- if (left instanceof OrPointcut) {
- OrPointcut leftOrPointcut = (OrPointcut)left;
- if (couldEverMatchSameJoinPoints(leftOrPointcut.getLeft(),right)) return true;
- if (couldEverMatchSameJoinPoints(leftOrPointcut.getRight(),right)) return true;
- return false;
- }
-
- if (right instanceof OrPointcut) {
- OrPointcut rightOrPointcut = (OrPointcut)right;
- if (couldEverMatchSameJoinPoints(left,rightOrPointcut.getLeft())) return true;
- if (couldEverMatchSameJoinPoints(left,rightOrPointcut.getRight())) return true;
- return false;
- }
-
- // look for withins
- WithinPointcut leftWithin = (WithinPointcut) findFirstPointcutIn(left,WithinPointcut.class);
- WithinPointcut rightWithin = (WithinPointcut) findFirstPointcutIn(right,WithinPointcut.class);
- if ((leftWithin != null) && (rightWithin != null)) {
- if (!leftWithin.couldEverMatchSameJoinPointsAs(rightWithin)) return false;
- }
- // look for kinded
- KindedPointcut leftKind = (KindedPointcut) findFirstPointcutIn(left,KindedPointcut.class);
- KindedPointcut rightKind = (KindedPointcut) findFirstPointcutIn(right,KindedPointcut.class);
- if ((leftKind != null) && (rightKind != null)) {
- if (!leftKind.couldEverMatchSameJoinPointsAs(rightKind)) return false;
- }
- return true;
- }
-
- private Pointcut findFirstPointcutIn(Pointcut toSearch, Class toLookFor) {
- if (toSearch instanceof NotPointcut) return null;
- if (toLookFor.isInstance(toSearch)) return toSearch;
- if (toSearch instanceof AndPointcut) {
- AndPointcut apc = (AndPointcut) toSearch;
- Pointcut left = findFirstPointcutIn(apc.getLeft(),toLookFor);
- if (left != null) return left;
- return findFirstPointcutIn(apc.getRight(),toLookFor);
- }
- return null;
- }
-
- /**
+ }
+ }
+
+ // By returning false from this method, we are allowing binding of the same
+ // variable on either side of an or.
+ // Be conservative :- have to consider overriding, varargs, autoboxing,
+ // the effects of itds (on within for example), interfaces, the fact that
+ // join points can have multiple signatures and so on.
+ private boolean couldEverMatchSameJoinPoints(Pointcut left, Pointcut right) {
+
+ if (left instanceof OrPointcut) {
+ OrPointcut leftOrPointcut = (OrPointcut) left;
+ if (couldEverMatchSameJoinPoints(leftOrPointcut.getLeft(), right))
+ return true;
+ if (couldEverMatchSameJoinPoints(leftOrPointcut.getRight(), right))
+ return true;
+ return false;
+ }
+
+ if (right instanceof OrPointcut) {
+ OrPointcut rightOrPointcut = (OrPointcut) right;
+ if (couldEverMatchSameJoinPoints(left, rightOrPointcut.getLeft()))
+ return true;
+ if (couldEverMatchSameJoinPoints(left, rightOrPointcut.getRight()))
+ return true;
+ return false;
+ }
+
+ // look for withins
+ WithinPointcut leftWithin = (WithinPointcut) findFirstPointcutIn(left, WithinPointcut.class);
+ WithinPointcut rightWithin = (WithinPointcut) findFirstPointcutIn(right, WithinPointcut.class);
+ if ((leftWithin != null) && (rightWithin != null)) {
+ if (!leftWithin.couldEverMatchSameJoinPointsAs(rightWithin))
+ return false;
+ }
+ // look for kinded
+ KindedPointcut leftKind = (KindedPointcut) findFirstPointcutIn(left, KindedPointcut.class);
+ KindedPointcut rightKind = (KindedPointcut) findFirstPointcutIn(right, KindedPointcut.class);
+ if ((leftKind != null) && (rightKind != null)) {
+ if (!leftKind.couldEverMatchSameJoinPointsAs(rightKind))
+ return false;
+ }
+ return true;
+ }
+
+ private Pointcut findFirstPointcutIn(Pointcut toSearch, Class toLookFor) {
+ if (toSearch instanceof NotPointcut)
+ return null;
+ if (toLookFor.isInstance(toSearch))
+ return toSearch;
+ if (toSearch instanceof AndPointcut) {
+ AndPointcut apc = (AndPointcut) toSearch;
+ Pointcut left = findFirstPointcutIn(apc.getLeft(), toLookFor);
+ if (left != null)
+ return left;
+ return findFirstPointcutIn(apc.getRight(), toLookFor);
+ }
+ return null;
+ }
+
+ /**
* @param userPointcut
*/
private void raiseNegationBindingError(Pointcut userPointcut) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.NEGATION_DOESNT_ALLOW_BINDING),
- userPointcut.getSourceContext().makeSourceLocation(userPointcut),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.NEGATION_DOESNT_ALLOW_BINDING), userPointcut
+ .getSourceContext().makeSourceLocation(userPointcut), null);
}
/**
@@ -848,10 +840,8 @@ public class BcelWeaver {
* @param userPointcut
*/
private void raiseAmbiguousBindingError(String name, Pointcut userPointcut) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.AMBIGUOUS_BINDING,
- name),
- userPointcut.getSourceContext().makeSourceLocation(userPointcut),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.AMBIGUOUS_BINDING, name), userPointcut
+ .getSourceContext().makeSourceLocation(userPointcut), null);
}
/**
@@ -863,108 +853,103 @@ public class BcelWeaver {
formalNames.append(", ");
formalNames.append(names.get(i));
}
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.AMBIGUOUS_BINDING_IN_OR,formalNames),
- userPointcut.getSourceContext().makeSourceLocation(userPointcut),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.AMBIGUOUS_BINDING_IN_OR, formalNames), userPointcut
+ .getSourceContext().makeSourceLocation(userPointcut), null);
}
- /**
+ /**
* @param name
* @param userPointcut
*/
private void raiseUnboundFormalError(String name, Pointcut userPointcut) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.UNBOUND_FORMAL,name),userPointcut.getSourceLocation(),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.UNBOUND_FORMAL, name), userPointcut
+ .getSourceLocation(), null);
}
-
-// public void dumpUnwoven(File file) throws IOException {
-// BufferedOutputStream os = FileUtil.makeOutputStream(file);
-// this.zipOutputStream = new ZipOutputStream(os);
-// dumpUnwoven();
-// /* BUG 40943*/
-// dumpResourcesToOutJar();
-// zipOutputStream.close(); //this flushes and closes the acutal file
-// }
-//
-//
-// public void dumpUnwoven() throws IOException {
-// Collection filesToDump = new HashSet(sourceJavaClasses.values());
-// for (Iterator i = filesToDump.iterator(); i.hasNext(); ) {
-// UnwovenClassFile classFile = (UnwovenClassFile)i.next();
-// dumpUnchanged(classFile);
-// }
-// }
-
-// public void dumpResourcesToOutPath() throws IOException {
-//// System.err.println("? dumpResourcesToOutPath() resources=" + resources.keySet());
-// Iterator i = resources.keySet().iterator();
-// while (i.hasNext()) {
-// UnwovenClassFile res = (UnwovenClassFile)resources.get(i.next());
-// dumpUnchanged(res);
-// }
-// //resources = new HashMap();
-// }
-//
+ // public void dumpUnwoven(File file) throws IOException {
+ // BufferedOutputStream os = FileUtil.makeOutputStream(file);
+ // this.zipOutputStream = new ZipOutputStream(os);
+ // dumpUnwoven();
+ // /* BUG 40943*/
+ // dumpResourcesToOutJar();
+ // zipOutputStream.close(); //this flushes and closes the acutal file
+ // }
+ //
+ //
+ // public void dumpUnwoven() throws IOException {
+ // Collection filesToDump = new HashSet(sourceJavaClasses.values());
+ // for (Iterator i = filesToDump.iterator(); i.hasNext(); ) {
+ // UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ // dumpUnchanged(classFile);
+ // }
+ // }
+
+ // public void dumpResourcesToOutPath() throws IOException {
+ // // System.err.println("? dumpResourcesToOutPath() resources=" + resources.keySet());
+ // Iterator i = resources.keySet().iterator();
+ // while (i.hasNext()) {
+ // UnwovenClassFile res = (UnwovenClassFile)resources.get(i.next());
+ // dumpUnchanged(res);
+ // }
+ // //resources = new HashMap();
+ // }
+ //
/* BUG #40943 */
-// public void dumpResourcesToOutJar() throws IOException {
-//// System.err.println("? dumpResourcesToOutJar() resources=" + resources.keySet());
-// Iterator i = resources.keySet().iterator();
-// while (i.hasNext()) {
-// String name = (String)i.next();
-// UnwovenClassFile res = (UnwovenClassFile)resources.get(name);
-// writeZipEntry(name,res.getBytes());
-// }
-// resources = new HashMap();
-// }
-//
-// // halfway house for when the jar is managed outside of the weaver, but the resources
-// // to be copied are known in the weaver.
-// public void dumpResourcesToOutJar(ZipOutputStream zos) throws IOException {
-// this.zipOutputStream = zos;
-// dumpResourcesToOutJar();
-// }
-
- public void addManifest (Manifest newManifest) {
-// System.out.println("? addManifest() newManifest=" + newManifest);
+ // public void dumpResourcesToOutJar() throws IOException {
+ // // System.err.println("? dumpResourcesToOutJar() resources=" + resources.keySet());
+ // Iterator i = resources.keySet().iterator();
+ // while (i.hasNext()) {
+ // String name = (String)i.next();
+ // UnwovenClassFile res = (UnwovenClassFile)resources.get(name);
+ // writeZipEntry(name,res.getBytes());
+ // }
+ // resources = new HashMap();
+ // }
+ //
+ // // halfway house for when the jar is managed outside of the weaver, but the resources
+ // // to be copied are known in the weaver.
+ // public void dumpResourcesToOutJar(ZipOutputStream zos) throws IOException {
+ // this.zipOutputStream = zos;
+ // dumpResourcesToOutJar();
+ // }
+ public void addManifest(Manifest newManifest) {
+ // System.out.println("? addManifest() newManifest=" + newManifest);
if (manifest == null) {
manifest = newManifest;
}
}
-
- public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
-
+
private static final String WEAVER_MANIFEST_VERSION = "1.0";
private static final Attributes.Name CREATED_BY = new Name("Created-By");
private static final String WEAVER_CREATED_BY = "AspectJ Compiler";
-
- public Manifest getManifest (boolean shouldCreate) {
-
+
+ public Manifest getManifest(boolean shouldCreate) {
+
if (manifest == null && shouldCreate) {
manifest = new Manifest();
Attributes attributes = manifest.getMainAttributes();
- attributes.put(Name.MANIFEST_VERSION,WEAVER_MANIFEST_VERSION);
- attributes.put(CREATED_BY,WEAVER_CREATED_BY);
+ attributes.put(Name.MANIFEST_VERSION, WEAVER_MANIFEST_VERSION);
+ attributes.put(CREATED_BY, WEAVER_CREATED_BY);
}
-
+
return manifest;
- }
-
- // ---- weaving
-
- // Used by some test cases only...
- public Collection weave(File file) throws IOException {
- OutputStream os = FileUtil.makeOutputStream(file);
- this.zipOutputStream = new ZipOutputStream(os);
- prepareForWeave();
- Collection c = weave( new IClassFileProvider() {
-
- public boolean isApplyAtAspectJMungersOnly() {
- return false;
- }
-
- public Iterator getClassFileIterator() {
+ }
+
+ // ---- weaving
+
+ // Used by some test cases only...
+ public Collection weave(File file) throws IOException {
+ OutputStream os = FileUtil.makeOutputStream(file);
+ this.zipOutputStream = new ZipOutputStream(os);
+ prepareForWeave();
+ Collection c = weave(new IClassFileProvider() {
+
+ public boolean isApplyAtAspectJMungersOnly() {
+ return false;
+ }
+
+ public Iterator getClassFileIterator() {
return addedClasses.iterator();
}
@@ -973,427 +958,441 @@ public class BcelWeaver {
public void acceptResult(UnwovenClassFile result) {
try {
writeZipEntry(result.filename, result.bytes);
- } catch(IOException ex) {}
+ } catch (IOException ex) {
+ }
+ }
+
+ public void processingReweavableState() {
+ }
+
+ public void addingTypeMungers() {
+ }
+
+ public void weavingAspects() {
+ }
+
+ public void weavingClasses() {
+ }
+
+ public void weaveCompleted() {
}
- public void processingReweavableState() {}
- public void addingTypeMungers() {}
- public void weavingAspects() {}
- public void weavingClasses() {}
- public void weaveCompleted() {}
};
}
});
-// /* BUG 40943*/
-// dumpResourcesToOutJar();
- zipOutputStream.close(); //this flushes and closes the acutal file
- return c;
- }
-
-// public Collection weave() throws IOException {
-// prepareForWeave();
-// Collection filesToWeave;
-//
-// if (needToReweaveWorld) {
-// filesToWeave = sourceJavaClasses.values();
-// } else {
-// filesToWeave = addedClasses;
-// }
-//
-// Collection wovenClassNames = new ArrayList();
-// world.showMessage(IMessage.INFO, "might need to weave " + filesToWeave +
-// "(world=" + needToReweaveWorld + ")", null, null);
-//
-//
-// //System.err.println("typeMungers: " + typeMungerList);
-//
-// prepareToProcessReweavableState();
-// // clear all state from files we'll be reweaving
-// for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) {
-// UnwovenClassFile classFile = (UnwovenClassFile)i.next();
-// String className = classFile.getClassName();
-// BcelObjectType classType = getClassType(className);
-// processReweavableStateIfPresent(className, classType);
-// }
-//
-//
-//
-// //XXX this isn't quite the right place for this...
-// for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) {
-// UnwovenClassFile classFile = (UnwovenClassFile)i.next();
-// String className = classFile.getClassName();
-// addTypeMungers(className);
-// }
-//
-// // first weave into aspects
-// for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) {
-// UnwovenClassFile classFile = (UnwovenClassFile)i.next();
-// String className = classFile.getClassName();
-// BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(className));
-// if (classType.isAspect()) {
-// weave(classFile, classType);
-// wovenClassNames.add(className);
-// }
-// }
-//
-// // then weave into non-aspects
-// for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) {
-// UnwovenClassFile classFile = (UnwovenClassFile)i.next();
-// String className = classFile.getClassName();
-// BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(className));
-// if (! classType.isAspect()) {
-// weave(classFile, classType);
-// wovenClassNames.add(className);
-// }
-// }
-//
-// if (zipOutputStream != null && !needToReweaveWorld) {
-// Collection filesToDump = new HashSet(sourceJavaClasses.values());
-// filesToDump.removeAll(filesToWeave);
-// for (Iterator i = filesToDump.iterator(); i.hasNext(); ) {
-// UnwovenClassFile classFile = (UnwovenClassFile)i.next();
-// dumpUnchanged(classFile);
-// }
-// }
-//
-// addedClasses = new ArrayList();
-// deletedTypenames = new ArrayList();
-//
-// return wovenClassNames;
-// }
-
- // variation of "weave" that sources class files from an external source.
- public Collection weave(IClassFileProvider input) throws IOException {
- if (trace.isTraceEnabled()) trace.enter("weave",this,input);
- ContextToken weaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING, "");
- Collection wovenClassNames = new ArrayList();
- IWeaveRequestor requestor = input.getRequestor();
-
- for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
- UnwovenClassFile classFile = (UnwovenClassFile)i.next();
- if (AsmManager.isCreatingModel() && !isBatchWeave) {
- // remove all relationships where this file being woven is the target of the relationship
- AsmManager.getDefault().removeRelationshipsTargettingThisType(classFile.getClassName());
- }
- }
-
- // Go through the types and ensure any 'damaged' during compile time are repaired prior to weaving
- for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
- UnwovenClassFile classFile = (UnwovenClassFile)i.next();
- String className = classFile.getClassName();
- ResolvedType theType = world.resolve(className);
- if (theType!=null) {
- BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
- if (classType!=null) classType.ensureDelegateConsistent();
- }
- }
-
- // special case for AtAspectJMungerOnly - see #113587
- if (input.isApplyAtAspectJMungersOnly()) {
- ContextToken atAspectJMungersOnly = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY, "");
- requestor.weavingAspects();
-// ContextToken aspectToken =
- CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, "");
- for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
- UnwovenClassFile classFile = (UnwovenClassFile)i.next();
- String className = classFile.getClassName();
- ResolvedType theType = world.resolve(className);
- if (theType.isAnnotationStyleAspect()) {
- BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
- if (classType==null) {
- throw new BCException("Can't find bcel delegate for "+className+" type="+theType.getClass());
- }
- LazyClassGen clazz = classType.getLazyClassGen();
- BcelPerClauseAspectAdder selfMunger = new BcelPerClauseAspectAdder(theType, theType.getPerClause().getKind());
- selfMunger.forceMunge(clazz, true);
- classType.finishedWith();
- UnwovenClassFile[] newClasses = getClassFilesFor(clazz);
- for (int news = 0; news < newClasses.length; news++) {
- requestor.acceptResult(newClasses[news]);
- }
- wovenClassNames.add(classFile.getClassName());
- }
- }
- requestor.weaveCompleted();
- CompilationAndWeavingContext.leavingPhase(atAspectJMungersOnly);
- return wovenClassNames;
- }
-
- requestor.processingReweavableState();
- ContextToken reweaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE,"");
+ // /* BUG 40943*/
+ // dumpResourcesToOutJar();
+ zipOutputStream.close(); // this flushes and closes the acutal file
+ return c;
+ }
+
+ // public Collection weave() throws IOException {
+ // prepareForWeave();
+ // Collection filesToWeave;
+ //
+ // if (needToReweaveWorld) {
+ // filesToWeave = sourceJavaClasses.values();
+ // } else {
+ // filesToWeave = addedClasses;
+ // }
+ //
+ // Collection wovenClassNames = new ArrayList();
+ // world.showMessage(IMessage.INFO, "might need to weave " + filesToWeave +
+ // "(world=" + needToReweaveWorld + ")", null, null);
+ //
+ //
+ // //System.err.println("typeMungers: " + typeMungerList);
+ //
+ // prepareToProcessReweavableState();
+ // // clear all state from files we'll be reweaving
+ // for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) {
+ // UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ // String className = classFile.getClassName();
+ // BcelObjectType classType = getClassType(className);
+ // processReweavableStateIfPresent(className, classType);
+ // }
+ //
+ //
+ //
+ // //XXX this isn't quite the right place for this...
+ // for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) {
+ // UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ // String className = classFile.getClassName();
+ // addTypeMungers(className);
+ // }
+ //
+ // // first weave into aspects
+ // for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) {
+ // UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ // String className = classFile.getClassName();
+ // BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(className));
+ // if (classType.isAspect()) {
+ // weave(classFile, classType);
+ // wovenClassNames.add(className);
+ // }
+ // }
+ //
+ // // then weave into non-aspects
+ // for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) {
+ // UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ // String className = classFile.getClassName();
+ // BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(className));
+ // if (! classType.isAspect()) {
+ // weave(classFile, classType);
+ // wovenClassNames.add(className);
+ // }
+ // }
+ //
+ // if (zipOutputStream != null && !needToReweaveWorld) {
+ // Collection filesToDump = new HashSet(sourceJavaClasses.values());
+ // filesToDump.removeAll(filesToWeave);
+ // for (Iterator i = filesToDump.iterator(); i.hasNext(); ) {
+ // UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ // dumpUnchanged(classFile);
+ // }
+ // }
+ //
+ // addedClasses = new ArrayList();
+ // deletedTypenames = new ArrayList();
+ //
+ // return wovenClassNames;
+ // }
+
+ // variation of "weave" that sources class files from an external source.
+ public Collection weave(IClassFileProvider input) throws IOException {
+ if (trace.isTraceEnabled())
+ trace.enter("weave", this, input);
+ ContextToken weaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING, "");
+ Collection wovenClassNames = new ArrayList();
+ IWeaveRequestor requestor = input.getRequestor();
+
+ for (Iterator i = input.getClassFileIterator(); i.hasNext();) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
+ if (AsmManager.isCreatingModel() && !isBatchWeave) {
+ // remove all relationships where this file being woven is the target of the relationship
+ AsmManager.getDefault().removeRelationshipsTargettingThisType(classFile.getClassName());
+ }
+ }
+
+ // Go through the types and ensure any 'damaged' during compile time are repaired prior to weaving
+ for (Iterator i = input.getClassFileIterator(); i.hasNext();) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
+ String className = classFile.getClassName();
+ ResolvedType theType = world.resolve(className);
+ if (theType != null) {
+ BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
+ if (classType != null)
+ classType.ensureDelegateConsistent();
+ }
+ }
+
+ // special case for AtAspectJMungerOnly - see #113587
+ if (input.isApplyAtAspectJMungersOnly()) {
+ ContextToken atAspectJMungersOnly = CompilationAndWeavingContext.enteringPhase(
+ CompilationAndWeavingContext.PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY, "");
+ requestor.weavingAspects();
+ // ContextToken aspectToken =
+ CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, "");
+ for (Iterator i = input.getClassFileIterator(); i.hasNext();) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
+ String className = classFile.getClassName();
+ ResolvedType theType = world.resolve(className);
+ if (theType.isAnnotationStyleAspect()) {
+ BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
+ if (classType == null) {
+ throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass());
+ }
+ LazyClassGen clazz = classType.getLazyClassGen();
+ BcelPerClauseAspectAdder selfMunger = new BcelPerClauseAspectAdder(theType, theType.getPerClause().getKind());
+ selfMunger.forceMunge(clazz, true);
+ classType.finishedWith();
+ UnwovenClassFile[] newClasses = getClassFilesFor(clazz);
+ for (int news = 0; news < newClasses.length; news++) {
+ requestor.acceptResult(newClasses[news]);
+ }
+ wovenClassNames.add(classFile.getClassName());
+ }
+ }
+ requestor.weaveCompleted();
+ CompilationAndWeavingContext.leavingPhase(atAspectJMungersOnly);
+ return wovenClassNames;
+ }
+
+ requestor.processingReweavableState();
+ ContextToken reweaveToken = CompilationAndWeavingContext.enteringPhase(
+ CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, "");
prepareToProcessReweavableState();
// clear all state from files we'll be reweaving
- for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
- UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ for (Iterator i = input.getClassFileIterator(); i.hasNext();) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
String className = classFile.getClassName();
- BcelObjectType classType = getClassType(className);
-
- // null return from getClassType() means the delegate is an eclipse source type - so
- // there *cant* be any reweavable state... (he bravely claimed...)
- if (classType !=null) {
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, className);
- processReweavableStateIfPresent(className, classType);
- CompilationAndWeavingContext.leavingPhase(tok);
- }
+ BcelObjectType classType = getClassType(className);
+
+ // null return from getClassType() means the delegate is an eclipse source type - so
+ // there *cant* be any reweavable state... (he bravely claimed...)
+ if (classType != null) {
+ ContextToken tok = CompilationAndWeavingContext.enteringPhase(
+ CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, className);
+ processReweavableStateIfPresent(className, classType);
+ CompilationAndWeavingContext.leavingPhase(tok);
+ }
}
CompilationAndWeavingContext.leavingPhase(reweaveToken);
-
- ContextToken typeMungingToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS,"");
+
+ ContextToken typeMungingToken = CompilationAndWeavingContext.enteringPhase(
+ CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS, "");
requestor.addingTypeMungers();
-
- // We process type mungers in two groups, first mungers that change the type
- // hierarchy, then 'normal' ITD type mungers.
-
-
- // Process the types in a predictable order (rather than the order encountered).
- // For class A, the order is superclasses of A then superinterfaces of A
- // (and this mechanism is applied recursively)
- List typesToProcess = new ArrayList();
- for (Iterator iter = input.getClassFileIterator(); iter.hasNext();) {
+
+ // We process type mungers in two groups, first mungers that change the type
+ // hierarchy, then 'normal' ITD type mungers.
+
+ // Process the types in a predictable order (rather than the order encountered).
+ // For class A, the order is superclasses of A then superinterfaces of A
+ // (and this mechanism is applied recursively)
+ List typesToProcess = new ArrayList();
+ for (Iterator iter = input.getClassFileIterator(); iter.hasNext();) {
UnwovenClassFile clf = (UnwovenClassFile) iter.next();
- typesToProcess.add(clf.getClassName());
- }
- while (typesToProcess.size()>0) {
- weaveParentsFor(typesToProcess,(String)typesToProcess.get(0));
- }
-
- for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
- UnwovenClassFile classFile = (UnwovenClassFile)i.next();
- String className = classFile.getClassName();
- addNormalTypeMungers(className);
- }
-
- CompilationAndWeavingContext.leavingPhase(typeMungingToken);
-
+ typesToProcess.add(clf.getClassName());
+ }
+ while (typesToProcess.size() > 0) {
+ weaveParentsFor(typesToProcess, (String) typesToProcess.get(0));
+ }
+
+ for (Iterator i = input.getClassFileIterator(); i.hasNext();) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
+ String className = classFile.getClassName();
+ addNormalTypeMungers(className);
+ }
+
+ CompilationAndWeavingContext.leavingPhase(typeMungingToken);
+
requestor.weavingAspects();
ContextToken aspectToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, "");
// first weave into aspects
- for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
- UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ for (Iterator i = input.getClassFileIterator(); i.hasNext();) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
String className = classFile.getClassName();
ResolvedType theType = world.resolve(className);
if (theType.isAspect()) {
- BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
- if (classType==null) {
-
+ BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
+ if (classType == null) {
+
// Sometimes.. if the Bcel Delegate couldn't be found then a problem occurred at compile time - on
- // a previous compiler run. In this case I assert the delegate will still be an EclipseSourceType
+ // a previous compiler run. In this case I assert the delegate will still be an EclipseSourceType
// and we can ignore the problem here (the original compile error will be reported again from
// the eclipse source type) - pr113531
- ReferenceTypeDelegate theDelegate = ((ReferenceType)theType).getDelegate();
- if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) continue;
+ ReferenceTypeDelegate theDelegate = ((ReferenceType) theType).getDelegate();
+ if (theDelegate.getClass().getName().endsWith("EclipseSourceType"))
+ continue;
- throw new BCException("Can't find bcel delegate for "+className+" type="+theType.getClass());
+ throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass());
}
- weaveAndNotify(classFile, classType,requestor);
- wovenClassNames.add(className);
- }
+ weaveAndNotify(classFile, classType, requestor);
+ wovenClassNames.add(className);
+ }
}
-
+
CompilationAndWeavingContext.leavingPhase(aspectToken);
requestor.weavingClasses();
ContextToken classToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_CLASSES, "");
// then weave into non-aspects
- for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
- UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+ for (Iterator i = input.getClassFileIterator(); i.hasNext();) {
+ UnwovenClassFile classFile = (UnwovenClassFile) i.next();
String className = classFile.getClassName();
ResolvedType theType = world.resolve(className);
if (!theType.isAspect()) {
BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
- if (classType==null) {
-
+ if (classType == null) {
+
// bug 119882 - see above comment for bug 113531
- ReferenceTypeDelegate theDelegate = ((ReferenceType)theType).getDelegate();
-
+ ReferenceTypeDelegate theDelegate = ((ReferenceType) theType).getDelegate();
+
// TODO urgh - put a method on the interface to check this, string compare is hideous
- if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) continue;
+ if (theDelegate.getClass().getName().endsWith("EclipseSourceType"))
+ continue;
- throw new BCException("Can't find bcel delegate for "+className+" type="+theType.getClass());
+ throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass());
}
- weaveAndNotify(classFile, classType, requestor);
- wovenClassNames.add(className);
- }
+ weaveAndNotify(classFile, classType, requestor);
+ wovenClassNames.add(className);
+ }
}
CompilationAndWeavingContext.leavingPhase(classToken);
-
+
addedClasses = new ArrayList();
deletedTypenames = new ArrayList();
-
-
- requestor.weaveCompleted();
- CompilationAndWeavingContext.leavingPhase(weaveToken);
- if (trace.isTraceEnabled()) trace.exit("weave",wovenClassNames);
- return wovenClassNames;
- }
-
- public void allWeavingComplete() {
- warnOnUnmatchedAdvice();
- }
-
- /**
- * In 1.5 mode and with XLint:adviceDidNotMatch enabled, put out messages for any
- * mungers that did not match anything.
- */
+
+ requestor.weaveCompleted();
+ CompilationAndWeavingContext.leavingPhase(weaveToken);
+ if (trace.isTraceEnabled())
+ trace.exit("weave", wovenClassNames);
+ return wovenClassNames;
+ }
+
+ public void allWeavingComplete() {
+ warnOnUnmatchedAdvice();
+ }
+
+ /**
+ * In 1.5 mode and with XLint:adviceDidNotMatch enabled, put out messages for any mungers that did not match anything.
+ */
private void warnOnUnmatchedAdvice() {
-
+
class AdviceLocation {
- private int lineNo;
+ private int lineNo;
private UnresolvedType inAspect;
public AdviceLocation(BcelAdvice advice) {
this.lineNo = advice.getSourceLocation().getLine();
this.inAspect = advice.getDeclaringAspect();
}
-
+
public boolean equals(Object obj) {
- if (!(obj instanceof AdviceLocation)) return false;
+ if (!(obj instanceof AdviceLocation))
+ return false;
AdviceLocation other = (AdviceLocation) obj;
- if (this.lineNo != other.lineNo) return false;
- if (!this.inAspect.equals(other.inAspect)) return false;
+ if (this.lineNo != other.lineNo)
+ return false;
+ if (!this.inAspect.equals(other.inAspect))
+ return false;
return true;
}
-
+
public int hashCode() {
- return 37 + 17*lineNo + 17*inAspect.hashCode();
+ return 37 + 17 * lineNo + 17 * inAspect.hashCode();
}
}
-
+
// FIXME asc Should be factored out into Xlint code and done automatically for all xlint messages, ideally.
- // if a piece of advice hasn't matched anywhere and we are in -1.5 mode, put out a warning
- if (world.isInJava5Mode() &&
- world.getLint().adviceDidNotMatch.isEnabled()) {
- List l = world.getCrosscuttingMembersSet().getShadowMungers();
- Set alreadyWarnedLocations = new HashSet();
-
- for (Iterator iter = l.iterator(); iter.hasNext();) {
- ShadowMunger element = (ShadowMunger) iter.next();
- if (element instanceof BcelAdvice) { // This will stop us incorrectly reporting deow Checkers
- BcelAdvice ba = (BcelAdvice)element;
- if (!ba.hasMatchedSomething()) {
- // Because we implement some features of AJ itself by creating our own kind of mungers, you sometimes
- // find that ba.getSignature() is not a BcelMethod - for example it might be a cflow entry munger.
- if (ba.getSignature()!=null) {
-
- // check we haven't already warned on this advice and line
- // (cflow creates multiple mungers for the same advice)
- AdviceLocation loc = new AdviceLocation(ba);
- if (alreadyWarnedLocations.contains(loc)) {
- continue;
- } else {
- alreadyWarnedLocations.add(loc);
- }
-
- if (!(ba.getSignature() instanceof BcelMethod)
- || !Utility.isSuppressing(ba.getSignature(),"adviceDidNotMatch")) {
- world.getLint().adviceDidNotMatch.signal(ba.getDeclaringAspect().toString(),
- new SourceLocation(element.getSourceLocation().getSourceFile(),element.getSourceLocation().getLine()));//element.getSourceLocation());
- }
- }
- }
- }
- }
- }
+ // if a piece of advice hasn't matched anywhere and we are in -1.5 mode, put out a warning
+ if (world.isInJava5Mode() && world.getLint().adviceDidNotMatch.isEnabled()) {
+ List l = world.getCrosscuttingMembersSet().getShadowMungers();
+ Set alreadyWarnedLocations = new HashSet();
+
+ for (Iterator iter = l.iterator(); iter.hasNext();) {
+ ShadowMunger element = (ShadowMunger) iter.next();
+ if (element instanceof BcelAdvice) { // This will stop us incorrectly reporting deow Checkers
+ BcelAdvice ba = (BcelAdvice) element;
+ if (!ba.hasMatchedSomething()) {
+ // Because we implement some features of AJ itself by creating our own kind of mungers, you sometimes
+ // find that ba.getSignature() is not a BcelMethod - for example it might be a cflow entry munger.
+ if (ba.getSignature() != null) {
+
+ // check we haven't already warned on this advice and line
+ // (cflow creates multiple mungers for the same advice)
+ AdviceLocation loc = new AdviceLocation(ba);
+ if (alreadyWarnedLocations.contains(loc)) {
+ continue;
+ } else {
+ alreadyWarnedLocations.add(loc);
+ }
+
+ if (!(ba.getSignature() instanceof BcelMethod)
+ || !Utility.isSuppressing(ba.getSignature(), "adviceDidNotMatch")) {
+ world.getLint().adviceDidNotMatch.signal(ba.getDeclaringAspect().toString(), new SourceLocation(
+ element.getSourceLocation().getSourceFile(), element.getSourceLocation().getLine()));// element
+ // .
+ // getSourceLocation
+ // (
+ // )
+ // )
+ // ;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 'typeToWeave' is one from the 'typesForWeaving' list. This routine ensures we process supertypes (classes/interfaces) of
+ * 'typeToWeave' that are in the 'typesForWeaving' list before 'typeToWeave' itself. 'typesToWeave' is then removed from the
+ * 'typesForWeaving' list.
+ *
+ * Note: Future gotcha in here ... when supplying partial hierarchies, this algorithm may break down. If you have a hierarchy
+ * A>B>C and only give A and C to the weaver, it may choose to weave them in either order - but you'll probably have other
+ * problems if you are supplying partial hierarchies like that !
+ */
+ private void weaveParentsFor(List typesForWeaving, String typeToWeave) {
+ // Look at the supertype first
+ ResolvedType rtx = world.resolve(typeToWeave);
+ ResolvedType superType = rtx.getSuperclass();
+
+ if (superType != null && typesForWeaving.contains(superType.getName())) {
+ weaveParentsFor(typesForWeaving, superType.getName());
+ }
+
+ // Then look at the superinterface list
+ ResolvedType[] interfaceTypes = rtx.getDeclaredInterfaces();
+ for (int i = 0; i < interfaceTypes.length; i++) {
+ ResolvedType rtxI = interfaceTypes[i];
+ if (typesForWeaving.contains(rtxI.getName())) {
+ weaveParentsFor(typesForWeaving, rtxI.getName());
+ }
+ }
+ ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS, rtx
+ .getName());
+ weaveParentTypeMungers(rtx); // Now do this type
+ CompilationAndWeavingContext.leavingPhase(tok);
+ typesForWeaving.remove(typeToWeave); // and remove it from the list of those to process
}
-
- /**
- * 'typeToWeave' is one from the 'typesForWeaving' list. This routine ensures we process
- * supertypes (classes/interfaces) of 'typeToWeave' that are in the
- * 'typesForWeaving' list before 'typeToWeave' itself. 'typesToWeave' is then removed from
- * the 'typesForWeaving' list.
- *
- * Note: Future gotcha in here ... when supplying partial hierarchies, this algorithm may
- * break down. If you have a hierarchy A>B>C and only give A and C to the weaver, it
- * may choose to weave them in either order - but you'll probably have other problems if
- * you are supplying partial hierarchies like that !
- */
- private void weaveParentsFor(List typesForWeaving,String typeToWeave) {
- // Look at the supertype first
- ResolvedType rtx = world.resolve(typeToWeave);
- ResolvedType superType = rtx.getSuperclass();
-
- if (superType!=null && typesForWeaving.contains(superType.getName())) {
- weaveParentsFor(typesForWeaving,superType.getName());
- }
-
- // Then look at the superinterface list
- ResolvedType[] interfaceTypes = rtx.getDeclaredInterfaces();
- for (int i = 0; i < interfaceTypes.length; i++) {
- ResolvedType rtxI = interfaceTypes[i];
- if (typesForWeaving.contains(rtxI.getName())) {
- weaveParentsFor(typesForWeaving,rtxI.getName());
- }
- }
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS,rtx.getName());
- weaveParentTypeMungers(rtx); // Now do this type
- CompilationAndWeavingContext.leavingPhase(tok);
- typesForWeaving.remove(typeToWeave); // and remove it from the list of those to process
- }
-
- public void prepareToProcessReweavableState() {
- }
-
- public void processReweavableStateIfPresent(String className, BcelObjectType classType) {
+
+ public void prepareToProcessReweavableState() {
+ }
+
+ public void processReweavableStateIfPresent(String className, BcelObjectType classType) {
// If the class is marked reweavable, check any aspects around when it was built are in this world
- WeaverStateInfo wsi = classType.getWeaverState();
- if (wsi!=null && wsi.isReweavable()) { // Check all necessary types are around!
- world.showMessage(IMessage.INFO,
- WeaverMessages.format(WeaverMessages.PROCESSING_REWEAVABLE,className,classType.getSourceLocation().getSourceFile()),
- null,null);
+ WeaverStateInfo wsi = classType.getWeaverState();
+ if (wsi != null && wsi.isReweavable()) { // Check all necessary types are around!
+ world.showMessage(IMessage.INFO, WeaverMessages.format(WeaverMessages.PROCESSING_REWEAVABLE, className, classType
+ .getSourceLocation().getSourceFile()), null, null);
Set aspectsPreviouslyInWorld = wsi.getAspectsAffectingType();
- if (aspectsPreviouslyInWorld!=null) {
- // keep track of them just to ensure unique missing aspect error reporting
- Set alreadyConfirmedReweavableState = new HashSet();
+ if (aspectsPreviouslyInWorld != null) {
+ // keep track of them just to ensure unique missing aspect error reporting
+ Set alreadyConfirmedReweavableState = new HashSet();
for (Iterator iter = aspectsPreviouslyInWorld.iterator(); iter.hasNext();) {
String requiredTypeName = (String) iter.next();
if (!alreadyConfirmedReweavableState.contains(requiredTypeName)) {
- ResolvedType rtx = world.resolve(UnresolvedType.forName(requiredTypeName),true);
+ ResolvedType rtx = world.resolve(UnresolvedType.forName(requiredTypeName), true);
boolean exists = !rtx.isMissing();
if (!exists) {
- world.showMessage(IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.MISSING_REWEAVABLE_TYPE,requiredTypeName,className),
- classType.getSourceLocation(), null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.MISSING_REWEAVABLE_TYPE,
+ requiredTypeName, className), classType.getSourceLocation(), null);
} else {
- // weaved in aspect that are not declared in aop.xml trigger an error for now
- // may cause headhache for LTW and packaged lib without aop.xml in
- // see #104218
- if(!xcutSet.containsAspect(rtx)){
- world.showMessage(
- IMessage.ERROR,
- WeaverMessages.format(
- WeaverMessages.REWEAVABLE_ASPECT_NOT_REGISTERED,
- requiredTypeName,
- className
- ),
- null,
- null
- );
- } else if (!world.getMessageHandler().isIgnoring(IMessage.INFO))
- world.showMessage(IMessage.INFO,
- WeaverMessages.format(WeaverMessages.VERIFIED_REWEAVABLE_TYPE,requiredTypeName,rtx.getSourceLocation().getSourceFile()),
- null,null);
- alreadyConfirmedReweavableState.add(requiredTypeName);
+ // weaved in aspect that are not declared in aop.xml trigger an error for now
+ // may cause headhache for LTW and packaged lib without aop.xml in
+ // see #104218
+ if (!xcutSet.containsAspect(rtx)) {
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(
+ WeaverMessages.REWEAVABLE_ASPECT_NOT_REGISTERED, requiredTypeName, className), null, null);
+ } else if (!world.getMessageHandler().isIgnoring(IMessage.INFO))
+ world.showMessage(IMessage.INFO, WeaverMessages.format(WeaverMessages.VERIFIED_REWEAVABLE_TYPE,
+ requiredTypeName, rtx.getSourceLocation().getSourceFile()), null, null);
+ alreadyConfirmedReweavableState.add(requiredTypeName);
}
- }
+ }
}
}
// old:
- //classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData()));
+ // classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData()));
// new: reweavable default with clever diff
- classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes())));
-// } else {
-// classType.resetState();
+ classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi
+ .getUnwovenClassFileData(classType.getJavaClass().getBytes())));
+ // } else {
+ // classType.resetState();
}
}
- private void weaveAndNotify(UnwovenClassFile classFile, BcelObjectType classType,
- IWeaveRequestor requestor) throws IOException {
- trace.enter("weaveAndNotify",this,new Object[] {classFile,classType,requestor});
-
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_TYPE, classType.getResolvedTypeX().getName());
- LazyClassGen clazz = weaveWithoutDump(classFile,classType);
- classType.finishedWith();
- //clazz is null if the classfile was unchanged by weaving...
+ private void weaveAndNotify(UnwovenClassFile classFile, BcelObjectType classType, IWeaveRequestor requestor) throws IOException {
+ trace.enter("weaveAndNotify", this, new Object[] { classFile, classType, requestor });
+
+ ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_TYPE, classType
+ .getResolvedTypeX().getName());
+ LazyClassGen clazz = weaveWithoutDump(classFile, classType);
+ classType.finishedWith();
+ // clazz is null if the classfile was unchanged by weaving...
if (clazz != null) {
UnwovenClassFile[] newClasses = getClassFilesFor(clazz);
// OPTIMIZE can we avoid using the string name at all in UnwovenClassFile instances?
@@ -1409,60 +1408,57 @@ public class BcelWeaver {
}
classType.weavingCompleted();
CompilationAndWeavingContext.leavingPhase(tok);
-
+
trace.exit("weaveAndNotify");
- }
-
+ }
+
/** helper method - will return NULL if the underlying delegate is an EclipseSourceType and not a BcelObjectType */
- public BcelObjectType getClassType(String forClass) {
- return BcelWorld.getBcelObjectType(world.resolve(forClass));
- }
-
-
- public void addParentTypeMungers(String typeName) {
- weaveParentTypeMungers(world.resolve(typeName));
- }
-
- public void addNormalTypeMungers(String typeName) {
- weaveNormalTypeMungers(world.resolve(typeName));
- }
-
- public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) {
- List childClasses = clazz.getChildClasses(world);
- UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()];
- ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getClassName(),clazz.getJavaClassBytesIncludingReweavable(world));
- int index = 1;
- for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
+ public BcelObjectType getClassType(String forClass) {
+ return BcelWorld.getBcelObjectType(world.resolve(forClass));
+ }
+
+ public void addParentTypeMungers(String typeName) {
+ weaveParentTypeMungers(world.resolve(typeName));
+ }
+
+ public void addNormalTypeMungers(String typeName) {
+ weaveNormalTypeMungers(world.resolve(typeName));
+ }
+
+ public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) {
+ List childClasses = clazz.getChildClasses(world);
+ UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()];
+ ret[0] = new UnwovenClassFile(clazz.getFileName(), clazz.getClassName(), clazz.getJavaClassBytesIncludingReweavable(world));
+ int index = 1;
+ for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter.next();
UnwovenClassFile childClass = new UnwovenClassFile(clazz.getFileName() + "$" + element.name, element.bytes);
ret[index++] = childClass;
}
- return ret;
- }
-
- /**
- * Weaves new parents and annotations onto a type ("declare parents" and "declare @type")
- *
- * Algorithm:
- * 1. First pass, do parents then do annotations. During this pass record:
- * - any parent mungers that don't match but have a non-wild annotation type pattern
- * - any annotation mungers that don't match
- * 2. Multiple subsequent passes which go over the munger lists constructed in the first
- * pass, repeatedly applying them until nothing changes.
- * FIXME asc confirm that algorithm is optimal ??
- */
+ return ret;
+ }
+
+ /**
+ * Weaves new parents and annotations onto a type ("declare parents" and "declare @type")
+ *
+ * Algorithm: 1. First pass, do parents then do annotations. During this pass record: - any parent mungers that don't match but
+ * have a non-wild annotation type pattern - any annotation mungers that don't match 2. Multiple subsequent passes which go over
+ * the munger lists constructed in the first pass, repeatedly applying them until nothing changes. FIXME asc confirm that
+ * algorithm is optimal ??
+ */
public void weaveParentTypeMungers(ResolvedType onType) {
- 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 {
@@ -1471,80 +1467,75 @@ public class BcelWeaver {
}
// Still first pass - apply all dec @type mungers
- for (Iterator i = xcutSet.getDeclareAnnotationOnTypes().iterator();i.hasNext();) {
- DeclareAnnotation decA = (DeclareAnnotation)i.next();
- boolean typeChanged = applyDeclareAtType(decA,onType,true);
+ for (Iterator i = xcutSet.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 = xcutSet.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;
}
- }
+ }
-
/**
* 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())) {
- // Could put out a lint here for an already annotated type ...
-// if (reportProblems) {
-// world.getLint().elementAlreadyAnnotated.signal(
-// new String[]{onType.toString(),decA.getAnnotationTypeX().toString()},
-// onType.getSourceLocation(),new ISourceLocation[]{decA.getSourceLocation()});
-// }
- return false;
- }
-
+
+ if (onType.hasAnnotation(decA.getAnnotationX().getSignature())) {
+ // Could put out a lint here for an already annotated type ...
+ // if (reportProblems) {
+ // world.getLint().elementAlreadyAnnotated.signal(
+ // new String[]{onType.toString(),decA.getAnnotationTypeX().toString()},
+ // onType.getSourceLocation(),new ISourceLocation[]{decA.getSourceLocation()});
+ // }
+ return false;
+ }
+
AnnotationX annoX = decA.getAnnotationX();
-
+
// check the annotation is suitable for the target
- boolean problemReported = verifyTargetIsOK(decA, onType, annoX,reportProblems);
+ boolean problemReported = verifyTargetIsOK(decA, onType, annoX, reportProblems);
if (!problemReported) {
- AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decA.getSourceLocation(),onType.getSourceLocation());
- // TAG: WeavingMessage
- if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)){
- getWorld().getMessageHandler().handleMessage(
- WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES,
- new String[]{
- onType.toString(),
- Utility.beautifyLocation(onType.getSourceLocation()),
- decA.getAnnotationString(),
- "type",
- decA.getAspect().toString(),
- Utility.beautifyLocation(decA.getSourceLocation())
- }));
+ AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decA.getSourceLocation(),
+ onType.getSourceLocation());
+ // TAG: WeavingMessage
+ if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
+ getWorld().getMessageHandler().handleMessage(
+ WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES, new String[] {
+ onType.toString(), Utility.beautifyLocation(onType.getSourceLocation()),
+ decA.getAnnotationString(), "type", decA.getAspect().toString(),
+ Utility.beautifyLocation(decA.getSourceLocation()) }));
}
didSomething = true;
ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger(annoX);
newAnnotationTM.setSourceLocation(decA.getSourceLocation());
- onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM,decA.getAspect().resolve(world)));
+ onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, decA.getAspect().resolve(world)));
decA.copyAnnotationTo(onType);
}
}
@@ -1552,62 +1543,64 @@ public class BcelWeaver {
}
/**
- * 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 verifyTargetIsOK(DeclareAnnotation decA, ResolvedType onType, AnnotationX annoX,boolean outputProblems) {
+ private boolean verifyTargetIsOK(DeclareAnnotation decA, ResolvedType onType, AnnotationX annoX, boolean outputProblems) {
boolean problemReported = false;
if (annoX.specifiesTarget()) {
- if ( (onType.isAnnotation() && !annoX.allowedOnAnnotationType()) ||
- (!annoX.allowedOnRegularType())) {
- if (outputProblems) {
- if (decA.isExactPattern()) {
- world.getMessageHandler().handleMessage(MessageUtil.error(
- WeaverMessages.format(WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION,
- onType.getName(),annoX.stringify(),annoX.getValidTargets()),decA.getSourceLocation()));
- } else {
- if (world.getLint().invalidTargetForAnnotation.isEnabled()) {
- world.getLint().invalidTargetForAnnotation.signal(
- new String[]{onType.getName(),annoX.stringify(),annoX.getValidTargets()},decA.getSourceLocation(),new ISourceLocation[]{onType.getSourceLocation()});
+ if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) || (!annoX.allowedOnRegularType())) {
+ if (outputProblems) {
+ if (decA.isExactPattern()) {
+ world.getMessageHandler().handleMessage(
+ MessageUtil.error(WeaverMessages.format(WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION,
+ onType.getName(), annoX.stringify(), annoX.getValidTargets()), decA.getSourceLocation()));
+ } else {
+ if (world.getLint().invalidTargetForAnnotation.isEnabled()) {
+ world.getLint().invalidTargetForAnnotation.signal(new String[] { onType.getName(), annoX.stringify(),
+ annoX.getValidTargets() }, decA.getSourceLocation(), new ISourceLocation[] { onType
+ .getSourceLocation() });
+ }
+ }
}
+ problemReported = true;
}
- }
- problemReported = true;
- }
}
return problemReported;
}
-
+
/**
* 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());
+ newParentMunger.setSourceLocation(p.getSourceLocation());
onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, xcutSet.findAspectDeclaringParents(p)));
}
}
return didSomething;
}
-
- public void weaveNormalTypeMungers(ResolvedType onType) {
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS, onType.getName());
- if (onType.isRawType() || onType.isParameterizedType()) onType = onType.getGenericType();
- for (Iterator i = typeMungerList.iterator(); i.hasNext(); ) {
- ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
+
+ public void weaveNormalTypeMungers(ResolvedType onType) {
+ ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS, onType
+ .getName());
+ if (onType.isRawType() || onType.isParameterizedType())
+ onType = onType.getGenericType();
+ for (Iterator i = typeMungerList.iterator(); i.hasNext();) {
+ ConcreteTypeMunger m = (ConcreteTypeMunger) i.next();
if (!m.isLateMunger() && m.matches(onType)) {
onType.addInterTypeMunger(m);
}
@@ -1615,7 +1608,6 @@ public class BcelWeaver {
CompilationAndWeavingContext.leavingPhase(tok);
}
-
// exposed for ClassLoader dynamic weaving
public LazyClassGen weaveWithoutDump(UnwovenClassFile classFile, BcelObjectType classType) throws IOException {
return weave(classFile, classType, false);
@@ -1624,56 +1616,45 @@ public class BcelWeaver {
// non-private for testing
LazyClassGen weave(UnwovenClassFile classFile, BcelObjectType classType) throws IOException {
LazyClassGen ret = weave(classFile, classType, true);
-
- if (progressListener != null) {
- progressMade += progressPerClassFile;
- progressListener.setProgress(progressMade);
- progressListener.setText("woven: " + classFile.getFilename());
- }
-
return ret;
}
- private LazyClassGen weave(UnwovenClassFile classFile, BcelObjectType classType, boolean dump) throws IOException {
+ private LazyClassGen weave(UnwovenClassFile classFile, BcelObjectType classType, boolean dump) throws IOException {
if (classType.isSynthetic()) { // Don't touch synthetic classes
- if (dump) dumpUnchanged(classFile);
+ if (dump)
+ dumpUnchanged(classFile);
return null;
}
-
+
List shadowMungers = fastMatch(shadowMungerList, classType.getResolvedTypeX());
- List typeMungers = classType.getResolvedTypeX().getInterTypeMungers();
-
- classType.getResolvedTypeX().checkInterTypeMungers();
+ List typeMungers = classType.getResolvedTypeX().getInterTypeMungers();
+
+ classType.getResolvedTypeX().checkInterTypeMungers();
// Decide if we need to do actual weaving for this class
- boolean mightNeedToWeave =
- shadowMungers.size() > 0 ||
- typeMungers.size() > 0 ||
- classType.isAspect() ||
- world.getDeclareAnnotationOnMethods().size()>0 ||
- world.getDeclareAnnotationOnFields().size()>0;
+ boolean mightNeedToWeave = shadowMungers.size() > 0 || typeMungers.size() > 0 || classType.isAspect()
+ || world.getDeclareAnnotationOnMethods().size() > 0 || world.getDeclareAnnotationOnFields().size() > 0;
// May need bridge methods if on 1.5 and something in our hierarchy is affected by ITDs
- boolean mightNeedBridgeMethods =
- world.isInJava5Mode() &&
- !classType.isInterface() &&
- classType.getResolvedTypeX().getInterTypeMungersIncludingSupers().size()>0;
+ boolean mightNeedBridgeMethods = world.isInJava5Mode() && !classType.isInterface()
+ && classType.getResolvedTypeX().getInterTypeMungersIncludingSupers().size() > 0;
LazyClassGen clazz = null;
if (mightNeedToWeave || mightNeedBridgeMethods) {
clazz = classType.getLazyClassGen();
- //System.err.println("got lazy gen: " + clazz + ", " + clazz.getWeaverState());
+ // System.err.println("got lazy gen: " + clazz + ", " + clazz.getWeaverState());
try {
boolean isChanged = false;
-
- if (mightNeedToWeave)
+
+ if (mightNeedToWeave)
isChanged = BcelClassWeaver.weave(world, clazz, shadowMungers, typeMungers, lateTypeMungerList);
- if (mightNeedBridgeMethods)
- isChanged = BcelClassWeaver.calculateAnyRequiredBridgeMethods(world,clazz) || isChanged;
-
+ if (mightNeedBridgeMethods)
+ isChanged = BcelClassWeaver.calculateAnyRequiredBridgeMethods(world, clazz) || isChanged;
+
if (isChanged) {
- if (dump) dump(classFile, clazz);
+ if (dump)
+ dump(classFile, clazz);
return clazz;
}
} catch (RuntimeException re) {
@@ -1685,9 +1666,7 @@ public class BcelWeaver {
classDebugInfo = clazz.getClassName();
}
String messageText = "trouble in: \n" + classDebugInfo;
- getWorld().getMessageHandler().handleMessage(
- new Message(messageText,IMessage.ABORT,re,null)
- );
+ getWorld().getMessageHandler().handleMessage(new Message(messageText, IMessage.ABORT, re, null));
} catch (Error re) {
String classDebugInfo = null;
try {
@@ -1697,29 +1676,25 @@ public class BcelWeaver {
classDebugInfo = clazz.getClassName();
}
String messageText = "trouble in: \n" + classDebugInfo;
- getWorld().getMessageHandler().handleMessage(
- new Message(messageText,IMessage.ABORT,re,null)
- );
+ getWorld().getMessageHandler().handleMessage(new Message(messageText, IMessage.ABORT, re, null));
}
}
-
+
// this is very odd return behavior trying to keep everyone happy
if (dump) {
dumpUnchanged(classFile);
return clazz;
} else {
- // ATAJ: the class was not weaved, but since it gets there early it may have new generated inner classes
- // attached to it to support LTW perX aspectOf support (see BcelPerClauseAspectAdder)
- // that aggressively defines the inner <aspect>$mayHaveAspect interface.
- if (clazz != null && !clazz.getChildClasses(world).isEmpty()) {
- return clazz;
- }
+ // ATAJ: the class was not weaved, but since it gets there early it may have new generated inner classes
+ // attached to it to support LTW perX aspectOf support (see BcelPerClauseAspectAdder)
+ // that aggressively defines the inner <aspect>$mayHaveAspect interface.
+ if (clazz != null && !clazz.getChildClasses(world).isEmpty()) {
+ return clazz;
+ }
return null;
}
}
-
-
// ---- writing
private void dumpUnchanged(UnwovenClassFile classFile) throws IOException {
@@ -1731,15 +1706,14 @@ public class BcelWeaver {
}
private String getEntryName(String className) {
- //XXX what does bcel's getClassName do for inner names
+ // XXX what does bcel's getClassName do for inner names
return className.replace('.', '/') + ".class";
}
private void dump(UnwovenClassFile classFile, LazyClassGen clazz) throws IOException {
if (zipOutputStream != null) {
String mainClassName = classFile.getJavaClass().getClassName();
- writeZipEntry(getEntryName(mainClassName),
- clazz.getJavaClass(world).getBytes());
+ writeZipEntry(getEntryName(mainClassName), clazz.getJavaClass(world).getBytes());
if (!clazz.getChildClasses(world).isEmpty()) {
for (Iterator i = clazz.getChildClasses(world).iterator(); i.hasNext();) {
UnwovenClassFile.ChildClass c = (UnwovenClassFile.ChildClass) i.next();
@@ -1747,23 +1721,21 @@ public class BcelWeaver {
}
}
} else {
- classFile.writeWovenBytes(
- clazz.getJavaClass(world).getBytes(),
- clazz.getChildClasses(world)
- );
+ classFile.writeWovenBytes(clazz.getJavaClass(world).getBytes(), clazz.getChildClasses(world));
}
}
-
+
private void writeZipEntry(String name, byte[] bytes) throws IOException {
- ZipEntry newEntry = new ZipEntry(name); //??? get compression scheme right
-
+ ZipEntry newEntry = new ZipEntry(name); // ??? get compression scheme right
+
zipOutputStream.putNextEntry(newEntry);
zipOutputStream.write(bytes);
zipOutputStream.closeEntry();
}
private List fastMatch(List list, ResolvedType type) {
- if (list == null) return Collections.EMPTY_LIST;
+ if (list == null)
+ return Collections.EMPTY_LIST;
// here we do the coarsest grained fast match with no kind constraints
// this will remove all obvious non-matches and see if we need to do any weaving
@@ -1772,7 +1744,7 @@ public class BcelWeaver {
List result = new ArrayList();
Iterator iter = list.iterator();
while (iter.hasNext()) {
- ShadowMunger munger = (ShadowMunger)iter.next();
+ ShadowMunger munger = (ShadowMunger) iter.next();
FuzzyBoolean fb = munger.getPointcut().fastMatch(info);
if (fb.maybeTrue()) {
result.add(munger);
@@ -1781,34 +1753,32 @@ public class BcelWeaver {
return result;
}
- public void setProgressListener(IProgressListener listener, double previousProgress, double progressPerClassFile) {
- progressListener = listener;
- this.progressMade = previousProgress;
- this.progressPerClassFile = progressPerClassFile;
- }
-
public void setReweavableMode(boolean xNotReweavable) {
- if (trace.isTraceEnabled()) trace.enter("setReweavableMode",this,xNotReweavable);
+ if (trace.isTraceEnabled())
+ trace.enter("setReweavableMode", this, xNotReweavable);
inReweavableMode = !xNotReweavable;
- WeaverStateInfo.setReweavableModeDefaults(!xNotReweavable,false,true);
+ WeaverStateInfo.setReweavableModeDefaults(!xNotReweavable, false, true);
BcelClassWeaver.setReweavableMode(!xNotReweavable);
- if (trace.isTraceEnabled()) trace.exit("setReweavableMode");
+ if (trace.isTraceEnabled())
+ trace.exit("setReweavableMode");
}
public boolean isReweavable() {
return inReweavableMode;
}
- public World getWorld() {
- return world;
- }
+ public World getWorld() {
+ return world;
+ }
public void tidyUp() {
- if (trace.isTraceEnabled()) trace.enter("tidyUp",this);
- shadowMungerList = null; // setup by prepareForWeave
+ if (trace.isTraceEnabled())
+ trace.enter("tidyUp", this);
+ shadowMungerList = null; // setup by prepareForWeave
typeMungerList = null; // setup by prepareForWeave
- lateTypeMungerList = null; // setup by prepareForWeave
+ lateTypeMungerList = null; // setup by prepareForWeave
declareParentsList = null; // setup by prepareForWeave
- if (trace.isTraceEnabled()) trace.exit("tidyUp");
+ if (trace.isTraceEnabled())
+ trace.exit("tidyUp");
}
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
index 346f2c1f4..48970547c 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
@@ -25,7 +25,6 @@ import org.aspectj.apache.bcel.Constants;
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.generic.FieldInstruction;
import org.aspectj.apache.bcel.generic.INVOKEINTERFACE;
import org.aspectj.apache.bcel.generic.Instruction;
@@ -397,17 +396,6 @@ public class BcelWorld extends World implements Repository {
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(");
diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
index dcf553ce3..1f03069ae 100644
--- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
+++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
@@ -345,14 +345,6 @@ public final class LazyClassGen {
}
}
- 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
*/
@@ -369,14 +361,6 @@ public final class LazyClassGen {
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();
methodGens.add(gen);
@@ -548,7 +532,7 @@ public final class LazyClassGen {
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
+ // hierarchy
// check the interfaces
if (!needAttribute) {
diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
index 433a213f8..c3623b896 100644
--- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
+++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.bcel;
import java.io.ByteArrayOutputStream;
@@ -65,311 +64,295 @@ import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.tools.Traceable;
-
-
-/**
- * A LazyMethodGen should be treated as a MethodGen. It's our way of abstracting over the
- * low-level Method objects. It converts through {@link MethodGen} to create
- * and to serialize, but that's it.
+/**
+ * A LazyMethodGen should be treated as a MethodGen. It's our way of abstracting over the low-level Method objects. It converts
+ * through {@link MethodGen} to create and to serialize, but that's it.
*
- * <p> At any rate, there are two ways to create LazyMethodGens.
- * One is from a method, which
- * does work through MethodGen to do the correct thing.
- * The other is the creation of a completely empty
- * LazyMethodGen, and it is used when we're constructing code from scratch.
+ * <p>
+ * At any rate, there are two ways to create LazyMethodGens. One is from a method, which does work through MethodGen to do the
+ * correct thing. The other is the creation of a completely empty LazyMethodGen, and it is used when we're constructing code from
+ * scratch.
*
- * <p> We stay away from targeters for rangey things like Shadows and Exceptions.
+ * <p>
+ * We stay away from targeters for rangey things like Shadows and Exceptions.
*/
public final class LazyMethodGen implements Traceable {
- private static final int ACC_SYNTHETIC = 0x1000;
-
- private int accessFlags;
- private Type returnType;
- private final String name;
- private Type[] argumentTypes;
- //private final String[] argumentNames;
- private String[] declaredExceptions;
- private InstructionList body; // leaving null for abstracts
- private List attributes;
- private List newAnnotations;
- private final LazyClassGen enclosingClass;
- private BcelMethod memberView;
- private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
- int highestLineNumber = 0;
- boolean wasPackedOptimally = false;
-
- /*
- * We use LineNumberTags and not Gens.
- *
- * This option specifies whether we let the BCEL classes create LineNumberGens and LocalVariableGens
- * or if we make it create LineNumberTags and LocalVariableTags. Up until 1.5.1 we always created
- * Gens - then on return from the MethodGen ctor we took them apart, reprocessed them all and
- * created Tags. (see unpackLocals/unpackLineNumbers). As we have our own copy of Bcel, why not create
- * the right thing straightaway? So setting this to true will call the MethodGen ctor() in such
- * a way that it creates Tags - removing the need for unpackLocals/unpackLineNumbers - HOWEVER see
- * the ensureAllLineNumberSetup() method for some other relevant info.
- *
- * Whats the difference between a Tag and a Gen? A Tag is more lightweight, it doesn't know which
- * instructions it targets, it relies on the instructions targetting *it* - this reduces the amount
- * of targeter manipulation we have to do.
- *
- */
-
- /** This is nonnull if this method is the result of an "inlining". We currently
- * copy methods into other classes for around advice. We add this field so
- * we can get JSR45 information correct. If/when we do _actual_ inlining,
- * we'll need to subtype LineNumberTag to have external line numbers.
+ private static final int ACC_SYNTHETIC = 0x1000;
+
+ private int accessFlags;
+ private Type returnType;
+ private final String name;
+ private Type[] argumentTypes;
+ // private final String[] argumentNames;
+ private String[] declaredExceptions;
+ private InstructionList body; // leaving null for abstracts
+ private List attributes;
+ private List newAnnotations;
+ private final LazyClassGen enclosingClass;
+ private BcelMethod memberView;
+ private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
+ int highestLineNumber = 0;
+ boolean wasPackedOptimally = false;
+
+ /*
+ * We use LineNumberTags and not Gens.
+ *
+ * This option specifies whether we let the BCEL classes create LineNumberGens and LocalVariableGens or if we make it create
+ * LineNumberTags and LocalVariableTags. Up until 1.5.1 we always created Gens - then on return from the MethodGen ctor we took
+ * them apart, reprocessed them all and created Tags. (see unpackLocals/unpackLineNumbers). As we have our own copy of Bcel, why
+ * not create the right thing straightaway? So setting this to true will call the MethodGen ctor() in such a way that it creates
+ * Tags - removing the need for unpackLocals/unpackLineNumbers - HOWEVER see the ensureAllLineNumberSetup() method for some
+ * other relevant info.
+ *
+ * Whats the difference between a Tag and a Gen? A Tag is more lightweight, it doesn't know which instructions it targets, it
+ * relies on the instructions targettingit - this reduces the amount of targeter manipulation we have to do.
+ */
+
+ /**
+ * This is nonnull if this method is the result of an "inlining". We currently copy methods into other classes for around
+ * advice. We add this field so we can get JSR45 information correct. If/when we do _actual_ inlining, we'll need to subtype
+ * LineNumberTag to have external line numbers.
*/
String fromFilename = null;
- private int maxLocals;
-
- private boolean canInline = true;
-// private boolean hasExceptionHandlers;
-
- private boolean isSynthetic = false;
-
- /**
- * only used by {@link BcelClassWeaver}
- */
- List /*ShadowMungers*/ matchedShadows;
- List /*Test*/ matchedShadowTests;
-
- // Used for interface introduction
- // this is the type of the interface the method is technically on
- public ResolvedType definingType = null;
-
- public LazyMethodGen(
- int accessFlags,
- Type returnType,
- String name,
- Type[] paramTypes,
- String[] declaredExceptions,
- LazyClassGen enclosingClass)
- {
- //System.err.println("raw create of: " + name + ", " + enclosingClass.getName() + ", " + returnType);
+ private int maxLocals;
+
+ private boolean canInline = true;
+ // private boolean hasExceptionHandlers;
+
+ private boolean isSynthetic = false;
+
+ /**
+ * only used by {@link BcelClassWeaver}
+ */
+ List /* ShadowMungers */matchedShadows;
+
+ // Used for interface introduction
+ // this is the type of the interface the method is technically on
+ public ResolvedType definingType = null;
+
+ public LazyMethodGen(int accessFlags, Type returnType, String name, Type[] paramTypes, String[] declaredExceptions,
+ LazyClassGen enclosingClass) {
+ // System.err.println("raw create of: " + name + ", " + enclosingClass.getName() + ", " + returnType);
this.memberView = null; // ??? should be okay, since constructed ones aren't woven into
- this.accessFlags = accessFlags;
- this.returnType = returnType;
- this.name = name;
- this.argumentTypes = paramTypes;
- //this.argumentNames = Utility.makeArgNames(paramTypes.length);
- this.declaredExceptions = declaredExceptions;
- if (!Modifier.isAbstract(accessFlags)) {
- body = new InstructionList();
- setMaxLocals(calculateMaxLocals());
- } else {
- body = null;
- }
- this.attributes = new ArrayList();
- this.enclosingClass = enclosingClass;
- assertGoodBody();
-
- // @AJ advice are not inlined by default since requires further analysis
- // and weaving ordering control
- // TODO AV - improve - note: no room for improvement as long as aspects are reweavable
- // since the inlined version with wrappers and an to be done annotation to keep
- // inline state will be garbaged due to reweavable impl
- if (memberView != null && isAdviceMethod()) {
- if (enclosingClass.getType().isAnnotationStyleAspect()) {
- //TODO we could check for @Around advice as well
- this.canInline = false;
- }
- }
- }
-
- private int calculateMaxLocals() {
- int ret = 0;
- if (!Modifier.isStatic(accessFlags)) ret++;
- for (int i = 0, len = argumentTypes.length; i < len; i++) {
- ret += argumentTypes[i].getSize();
- }
- return ret;
- }
-
- private Method savedMethod = null;
- // build from an existing method, lazy build saves most work for initialization
- public LazyMethodGen(Method m, LazyClassGen enclosingClass) {
- savedMethod = m;
-
- this.enclosingClass = enclosingClass;
- if (!(m.isAbstract() || m.isNative()) && m.getCode() == null) {
- throw new RuntimeException("bad non-abstract method with no code: " + m + " on " + enclosingClass);
- }
- if ((m.isAbstract() || m.isNative()) && m.getCode() != null) {
- throw new RuntimeException("bad abstract method with code: " + m + " on " + enclosingClass);
- }
+ this.accessFlags = accessFlags;
+ this.returnType = returnType;
+ this.name = name;
+ this.argumentTypes = paramTypes;
+ // this.argumentNames = Utility.makeArgNames(paramTypes.length);
+ this.declaredExceptions = declaredExceptions;
+ if (!Modifier.isAbstract(accessFlags)) {
+ body = new InstructionList();
+ setMaxLocals(calculateMaxLocals());
+ } else {
+ body = null;
+ }
+ this.attributes = new ArrayList();
+ this.enclosingClass = enclosingClass;
+ assertGoodBody();
+
+ // @AJ advice are not inlined by default since requires further analysis
+ // and weaving ordering control
+ // TODO AV - improve - note: no room for improvement as long as aspects are reweavable
+ // since the inlined version with wrappers and an to be done annotation to keep
+ // inline state will be garbaged due to reweavable impl
+ if (memberView != null && isAdviceMethod()) {
+ if (enclosingClass.getType().isAnnotationStyleAspect()) {
+ // TODO we could check for @Around advice as well
+ this.canInline = false;
+ }
+ }
+ }
+
+ private int calculateMaxLocals() {
+ int ret = 0;
+ if (!Modifier.isStatic(accessFlags))
+ ret++;
+ for (int i = 0, len = argumentTypes.length; i < len; i++) {
+ ret += argumentTypes[i].getSize();
+ }
+ return ret;
+ }
+
+ private Method savedMethod = null;
+
+ // build from an existing method, lazy build saves most work for initialization
+ public LazyMethodGen(Method m, LazyClassGen enclosingClass) {
+ savedMethod = m;
+
+ this.enclosingClass = enclosingClass;
+ if (!(m.isAbstract() || m.isNative()) && m.getCode() == null) {
+ throw new RuntimeException("bad non-abstract method with no code: " + m + " on " + enclosingClass);
+ }
+ if ((m.isAbstract() || m.isNative()) && m.getCode() != null) {
+ throw new RuntimeException("bad abstract method with code: " + m + " on " + enclosingClass);
+ }
this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
-
+
this.accessFlags = m.getModifiers();
this.name = m.getName();
- // @AJ advice are not inlined by default since requires further analysis
- // and weaving ordering control
- // TODO AV - improve - note: no room for improvement as long as aspects are reweavable
- // since the inlined version with wrappers and an to be done annotation to keep
- // inline state will be garbaged due to reweavable impl
- if (memberView != null && isAdviceMethod()) {
- if (enclosingClass.getType().isAnnotationStyleAspect()) {
- //TODO we could check for @Around advice as well
- this.canInline = false;
- }
- }
- }
- public LazyMethodGen(BcelMethod m,LazyClassGen enclosingClass) {
- savedMethod = m.getMethod();
- this.enclosingClass = enclosingClass;
- if (!(m.isAbstract() || m.isNative()) && savedMethod.getCode() == null) {
- throw new RuntimeException("bad non-abstract method with no code: " + m + " on " + enclosingClass);
- }
- if ((m.isAbstract() || m.isNative()) && savedMethod.getCode() != null) {
- throw new RuntimeException("bad abstract method with code: " + m + " on " + enclosingClass);
- }
- //this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
- this.memberView = m;
+ // @AJ advice are not inlined by default since requires further analysis
+ // and weaving ordering control
+ // TODO AV - improve - note: no room for improvement as long as aspects are reweavable
+ // since the inlined version with wrappers and an to be done annotation to keep
+ // inline state will be garbaged due to reweavable impl
+ if (memberView != null && isAdviceMethod()) {
+ if (enclosingClass.getType().isAnnotationStyleAspect()) {
+ // TODO we could check for @Around advice as well
+ this.canInline = false;
+ }
+ }
+ }
+
+ public LazyMethodGen(BcelMethod m, LazyClassGen enclosingClass) {
+ savedMethod = m.getMethod();
+ this.enclosingClass = enclosingClass;
+ if (!(m.isAbstract() || m.isNative()) && savedMethod.getCode() == null) {
+ throw new RuntimeException("bad non-abstract method with no code: " + m + " on " + enclosingClass);
+ }
+ if ((m.isAbstract() || m.isNative()) && savedMethod.getCode() != null) {
+ throw new RuntimeException("bad abstract method with code: " + m + " on " + enclosingClass);
+ }
+ // this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
+ this.memberView = m;
this.accessFlags = savedMethod.getModifiers();
this.name = m.getName();
- // @AJ advice are not inlined by default since requires further analysis
- // and weaving ordering control
- // TODO AV - improve - note: no room for improvement as long as aspects are reweavable
- // since the inlined version with wrappers and an to be done annotation to keep
- // inline state will be garbaged due to reweavable impl
- if (memberView != null && isAdviceMethod()) {
- if (enclosingClass.getType().isAnnotationStyleAspect()) {
- //TODO we could check for @Around advice as well
- this.canInline = false;
- }
- }
-
- }
-
- public boolean hasDeclaredLineNumberInfo() {
- return (memberView != null && memberView.hasDeclarationLineNumberInfo());
- }
-
- public int getDeclarationLineNumber() {
- if (hasDeclaredLineNumberInfo()) {
- return memberView.getDeclarationLineNumber();
- } else {
- return -1;
- }
- }
-
+ // @AJ advice are not inlined by default since requires further analysis
+ // and weaving ordering control
+ // TODO AV - improve - note: no room for improvement as long as aspects are reweavable
+ // since the inlined version with wrappers and an to be done annotation to keep
+ // inline state will be garbaged due to reweavable impl
+ if (memberView != null && isAdviceMethod()) {
+ if (enclosingClass.getType().isAnnotationStyleAspect()) {
+ // TODO we could check for @Around advice as well
+ this.canInline = false;
+ }
+ }
+
+ }
+
+ public boolean hasDeclaredLineNumberInfo() {
+ return (memberView != null && memberView.hasDeclarationLineNumberInfo());
+ }
+
+ public int getDeclarationLineNumber() {
+ if (hasDeclaredLineNumberInfo()) {
+ return memberView.getDeclarationLineNumber();
+ } else {
+ return -1;
+ }
+ }
+
public int getDeclarationOffset() {
- if (hasDeclaredLineNumberInfo()) {
- return memberView.getDeclarationOffset();
- } else {
- return 0;
- }
- }
-
- public void addAnnotation(AnnotationX ax) {
- initialize();
- if (memberView==null) {
+ if (hasDeclaredLineNumberInfo()) {
+ return memberView.getDeclarationOffset();
+ } else {
+ return 0;
+ }
+ }
+
+ public void addAnnotation(AnnotationX ax) {
+ initialize();
+ if (memberView == null) {
// If member view is null, we manage them in newAnnotations
- if (newAnnotations==null) newAnnotations = new ArrayList();
+ if (newAnnotations == null)
+ newAnnotations = new ArrayList();
newAnnotations.add(ax);
} else {
memberView.addAnnotation(ax);
}
- }
-
+ }
public boolean hasAnnotation(UnresolvedType annotationTypeX) {
initialize();
- if (memberView==null) {
+ if (memberView == null) {
// Check local annotations first
- if (newAnnotations!=null) {
+ if (newAnnotations != null) {
for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) {
AnnotationX element = (AnnotationX) iter.next();
- if (element.getBcelAnnotation().getTypeName().equals(annotationTypeX.getName())) return true;
+ if (element.getBcelAnnotation().getTypeName().equals(annotationTypeX.getName()))
+ return true;
}
}
- memberView = new BcelMethod(getEnclosingClass().getBcelObjectType(), getMethod());
- return memberView.hasAnnotation(annotationTypeX);
+ memberView = new BcelMethod(getEnclosingClass().getBcelObjectType(), getMethod());
+ return memberView.hasAnnotation(annotationTypeX);
}
return memberView.hasAnnotation(annotationTypeX);
}
-
- private void initialize() {
- if (returnType != null) return;
-
- //System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " + savedMethod);
-
- MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(),true);
-
+
+ private void initialize() {
+ if (returnType != null)
+ return;
+
+ // System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " +
+ // savedMethod);
+
+ MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(), true);
+
this.returnType = gen.getReturnType();
this.argumentTypes = gen.getArgumentTypes();
this.declaredExceptions = gen.getExceptions();
this.attributes = gen.getAttributes();
- //this.annotations = gen.getAnnotations();
+ // this.annotations = gen.getAnnotations();
this.maxLocals = gen.getMaxLocals();
-
-// this.returnType = BcelWorld.makeBcelType(memberView.getReturnType());
-// this.argumentTypes = BcelWorld.makeBcelTypes(memberView.getParameterTypes());
-//
-// this.declaredExceptions = UnresolvedType.getNames(memberView.getExceptions()); //gen.getExceptions();
-// this.attributes = new Attribute[0]; //gen.getAttributes();
-// this.maxLocals = savedMethod.getCode().getMaxLocals();
-
-
- if (gen.isAbstract() || gen.isNative()) {
- body = null;
- } else {
- //body = new InstructionList(savedMethod.getCode().getCode());
- body = gen.getInstructionList();
-
- unpackHandlers(gen);
-
+
+ // this.returnType = BcelWorld.makeBcelType(memberView.getReturnType());
+ // this.argumentTypes = BcelWorld.makeBcelTypes(memberView.getParameterTypes());
+ //
+ // this.declaredExceptions = UnresolvedType.getNames(memberView.getExceptions()); //gen.getExceptions();
+ // this.attributes = new Attribute[0]; //gen.getAttributes();
+ // this.maxLocals = savedMethod.getCode().getMaxLocals();
+
+ if (gen.isAbstract() || gen.isNative()) {
+ body = null;
+ } else {
+ // body = new InstructionList(savedMethod.getCode().getCode());
+ body = gen.getInstructionList();
+
+ unpackHandlers(gen);
+
ensureAllLineNumberSetup();
- highestLineNumber = gen.getHighestlinenumber();
-
- }
- assertGoodBody();
-
- //System.err.println("initialized: " + this.getClassName() + "." + this.getName());
- }
-
- // XXX we're relying on the javac promise I've just made up that we won't have an early exception
- // in the list mask a later exception: That is, for two exceptions E and F,
- // if E preceeds F, then either E \cup F = {}, or E \nonstrictsubset F. So when we add F,
- // we add it on the _OUTSIDE_ of any handlers that share starts or ends with it.
-
- // with that in mind, we merrily go adding ranges for exceptions.
-
- private void unpackHandlers(MethodGen gen) {
- CodeExceptionGen[] exns = gen.getExceptionHandlers();
- if (exns != null) {
- int len = exns.length;
- // if (len > 0) hasExceptionHandlers = true;
- int priority = len - 1;
- for (int i = 0; i < len; i++, priority--) {
- CodeExceptionGen exn = exns[i];
-
- InstructionHandle start =
- Range.genStart(
- body,
- getOutermostExceptionStart(exn.getStartPC()));
- InstructionHandle end = Range.genEnd(body, getOutermostExceptionEnd(exn.getEndPC()));
- // this doesn't necessarily handle overlapping correctly!!!
- ExceptionRange er =
- new ExceptionRange(
- body,
- exn.getCatchType() == null
- ? null
- : BcelWorld.fromBcel(exn.getCatchType()),
- priority);
- er.associateWithTargets(start, end, exn.getHandlerPC());
- exn.setStartPC(null); // also removes from target
- exn.setEndPC(null); // also removes from target
- exn.setHandlerPC(null); // also removes from target
- }
- gen.removeExceptionHandlers();
- }
- }
+ highestLineNumber = gen.getHighestlinenumber();
+
+ }
+ assertGoodBody();
+
+ // System.err.println("initialized: " + this.getClassName() + "." + this.getName());
+ }
+
+ // XXX we're relying on the javac promise I've just made up that we won't have an early exception
+ // in the list mask a later exception: That is, for two exceptions E and F,
+ // if E preceeds F, then either E \cup F = {}, or E \nonstrictsubset F. So when we add F,
+ // we add it on the _OUTSIDE_ of any handlers that share starts or ends with it.
+
+ // with that in mind, we merrily go adding ranges for exceptions.
+
+ private void unpackHandlers(MethodGen gen) {
+ CodeExceptionGen[] exns = gen.getExceptionHandlers();
+ if (exns != null) {
+ int len = exns.length;
+ // if (len > 0) hasExceptionHandlers = true;
+ int priority = len - 1;
+ for (int i = 0; i < len; i++, priority--) {
+ CodeExceptionGen exn = exns[i];
+
+ InstructionHandle start = Range.genStart(body, getOutermostExceptionStart(exn.getStartPC()));
+ InstructionHandle end = Range.genEnd(body, getOutermostExceptionEnd(exn.getEndPC()));
+ // this doesn't necessarily handle overlapping correctly!!!
+ ExceptionRange er = new ExceptionRange(body, exn.getCatchType() == null ? null : BcelWorld.fromBcel(exn
+ .getCatchType()), priority);
+ er.associateWithTargets(start, end, exn.getHandlerPC());
+ exn.setStartPC(null); // also removes from target
+ exn.setEndPC(null); // also removes from target
+ exn.setHandlerPC(null); // also removes from target
+ }
+ gen.removeExceptionHandlers();
+ }
+ }
private InstructionHandle getOutermostExceptionStart(InstructionHandle ih) {
while (true) {
@@ -379,7 +362,8 @@ public final class LazyMethodGen implements Traceable {
return ih;
}
}
- }
+ }
+
private InstructionHandle getOutermostExceptionEnd(InstructionHandle ih) {
while (true) {
if (ExceptionRange.isExceptionEnd(ih.getNext())) {
@@ -390,1058 +374,1010 @@ public final class LazyMethodGen implements Traceable {
}
}
- /**
- * On entry to this method we have a method whose instruction stream contains a few instructions
- * that have line numbers assigned to them (LineNumberTags). The aim is to ensure every instruction
- * has the right line number. This is necessary because some of them may be extracted out into other
- * methods - and it'd be useful for them to maintain the source line number for debugging.
- */
- public void ensureAllLineNumberSetup() {
- LineNumberTag lr = null;
- boolean skip = false;
- for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
- Iterator tIter = ih.getTargeters().iterator();
- skip = false;
- while (tIter.hasNext()) {
- InstructionTargeter targeter = (InstructionTargeter)tIter.next();
- if (targeter instanceof LineNumberTag) {
- lr = (LineNumberTag) targeter;
- skip=true;
- }
- }
- if (lr != null && !skip) {
- ih.addTargeter(lr);
- }
- }
- }
-
- // ===============
-
- public int allocateLocal(Type type) {
- return allocateLocal(type.getSize());
- }
-
- public int allocateLocal(int slots) {
- int max = getMaxLocals();
- setMaxLocals(max + slots);
- return max;
- }
-
- public Method getMethod() {
- if (savedMethod != null) return savedMethod; //??? this relies on gentle treatment of constant pool
-
- try {
+ /**
+ * On entry to this method we have a method whose instruction stream contains a few instructions that have line numbers assigned
+ * to them (LineNumberTags). The aim is to ensure every instruction has the right line number. This is necessary because some of
+ * them may be extracted out into other methods - and it'd be useful for them to maintain the source line number for debugging.
+ */
+ public void ensureAllLineNumberSetup() {
+ LineNumberTag lr = null;
+ boolean skip = false;
+ for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
+ Iterator tIter = ih.getTargeters().iterator();
+ skip = false;
+ while (tIter.hasNext()) {
+ InstructionTargeter targeter = (InstructionTargeter) tIter.next();
+ if (targeter instanceof LineNumberTag) {
+ lr = (LineNumberTag) targeter;
+ skip = true;
+ }
+ }
+ if (lr != null && !skip) {
+ ih.addTargeter(lr);
+ }
+ }
+ }
+
+ // ===============
+
+ public int allocateLocal(Type type) {
+ return allocateLocal(type.getSize());
+ }
+
+ public int allocateLocal(int slots) {
+ int max = getMaxLocals();
+ setMaxLocals(max + slots);
+ return max;
+ }
+
+ public Method getMethod() {
+ if (savedMethod != null)
+ return savedMethod; // ??? this relies on gentle treatment of constant pool
+
+ try {
MethodGen gen = pack();
savedMethod = gen.getMethod();
return savedMethod;
- } catch (ClassGenException e) {
- enclosingClass.getBcelObjectType().getResolvedTypeX().getWorld().showMessage(
- IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.PROBLEM_GENERATING_METHOD,
- this.getClassName(),
- this.getName(),
- e.getMessage()),
- this.getMemberView() == null ? null : this.getMemberView().getSourceLocation(), null);
-// throw e; PR 70201.... let the normal problem reporting infrastructure deal with this rather than crashing.
- body = null;
- MethodGen gen = pack();
- return gen.getMethod();
- }
- }
-
- public void markAsChanged() {
- if (wasPackedOptimally) {
- throw new RuntimeException("Already packed method is being re-modified: "+getClassName()+" "+toShortString());
- }
- initialize();
- savedMethod = null;
- }
-
- // =============================
+ } catch (ClassGenException e) {
+ enclosingClass.getBcelObjectType().getResolvedTypeX().getWorld().showMessage(
+ IMessage.ERROR,
+ WeaverMessages.format(WeaverMessages.PROBLEM_GENERATING_METHOD, this.getClassName(), this.getName(), e
+ .getMessage()), this.getMemberView() == null ? null : this.getMemberView().getSourceLocation(), null);
+ // throw e; PR 70201.... let the normal problem reporting infrastructure deal with this rather than crashing.
+ body = null;
+ MethodGen gen = pack();
+ return gen.getMethod();
+ }
+ }
+
+ public void markAsChanged() {
+ if (wasPackedOptimally) {
+ throw new RuntimeException("Already packed method is being re-modified: " + getClassName() + " " + toShortString());
+ }
+ initialize();
+ savedMethod = null;
+ }
+
+ // =============================
public String toString() {
BcelObjectType bot = enclosingClass.getBcelObjectType();
- WeaverVersionInfo weaverVersion = (bot==null?WeaverVersionInfo.CURRENT:bot.getWeaverVersionAttribute());
+ WeaverVersionInfo weaverVersion = (bot == null ? WeaverVersionInfo.CURRENT : bot.getWeaverVersionAttribute());
return toLongString(weaverVersion);
}
- public String toShortString() {
- String access = org.aspectj.apache.bcel.classfile.Utility.accessToString(getAccessFlags());
-
- StringBuffer buf = new StringBuffer();
-
- if (!access.equals("")) {
- buf.append(access);
- buf.append(" ");
- }
- buf.append(
- org.aspectj.apache.bcel.classfile.Utility.signatureToString(
- getReturnType().getSignature(),
- true));
- buf.append(" ");
- buf.append(getName());
- buf.append("(");
+ public String toShortString() {
+ String access = org.aspectj.apache.bcel.classfile.Utility.accessToString(getAccessFlags());
+
+ StringBuffer buf = new StringBuffer();
+
+ if (!access.equals("")) {
+ buf.append(access);
+ buf.append(" ");
+ }
+ buf.append(org.aspectj.apache.bcel.classfile.Utility.signatureToString(getReturnType().getSignature(), true));
+ buf.append(" ");
+ buf.append(getName());
+ buf.append("(");
{
int len = argumentTypes.length;
if (len > 0) {
- buf.append(
- org.aspectj.apache.bcel.classfile.Utility.signatureToString(
- argumentTypes[0].getSignature(),
- true));
+ buf.append(org.aspectj.apache.bcel.classfile.Utility.signatureToString(argumentTypes[0].getSignature(), true));
for (int i = 1; i < argumentTypes.length; i++) {
buf.append(", ");
- buf.append(
- org.aspectj.apache.bcel.classfile.Utility.signatureToString(
- argumentTypes[i].getSignature(),
- true));
+ buf.append(org.aspectj.apache.bcel.classfile.Utility.signatureToString(argumentTypes[i].getSignature(), true));
+ }
+ }
+ }
+ buf.append(")");
+
+ {
+ int len = declaredExceptions != null ? declaredExceptions.length : 0;
+ if (len > 0) {
+ buf.append(" throws ");
+ buf.append(declaredExceptions[0]);
+ for (int i = 1; i < declaredExceptions.length; i++) {
+ buf.append(", ");
+ buf.append(declaredExceptions[i]);
}
}
}
- buf.append(")");
-
- {
- int len = declaredExceptions != null ? declaredExceptions.length : 0;
- if (len > 0) {
- buf.append(" throws ");
- buf.append(declaredExceptions[0]);
- for (int i = 1; i < declaredExceptions.length; i++) {
- buf.append(", ");
- buf.append(declaredExceptions[i]);
- }
- }
- }
- return buf.toString();
- }
-
- public String toLongString(WeaverVersionInfo weaverVersion) {
- ByteArrayOutputStream s = new ByteArrayOutputStream();
- print(new PrintStream(s),weaverVersion);
- return new String(s.toByteArray());
- }
-
- public void print(WeaverVersionInfo weaverVersion) {
- print(System.out,weaverVersion);
- }
-
- public void print(PrintStream out, WeaverVersionInfo weaverVersion) {
- out.print(" " + toShortString());
- printAspectAttributes(out,weaverVersion);
-
- InstructionList body = getBody();
- if (body == null) {
- out.println(";");
- return;
- }
- out.println(":");
- new BodyPrinter(out).run();
- out.println(" end " + toShortString());
- }
+ return buf.toString();
+ }
+ public String toLongString(WeaverVersionInfo weaverVersion) {
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+ print(new PrintStream(s), weaverVersion);
+ return new String(s.toByteArray());
+ }
+
+ public void print(WeaverVersionInfo weaverVersion) {
+ print(System.out, weaverVersion);
+ }
+
+ public void print(PrintStream out, WeaverVersionInfo weaverVersion) {
+ out.print(" " + toShortString());
+ printAspectAttributes(out, weaverVersion);
+
+ InstructionList body = getBody();
+ if (body == null) {
+ out.println(";");
+ return;
+ }
+ out.println(":");
+ new BodyPrinter(out).run();
+ out.println(" end " + toShortString());
+ }
private void printAspectAttributes(PrintStream out, WeaverVersionInfo weaverVersion) {
ISourceContext context = null;
if (enclosingClass != null && enclosingClass.getType() != null) {
context = enclosingClass.getType().getSourceContext();
}
- List as = BcelAttributes.readAjAttributes(getClassName(), (Attribute[])attributes.toArray(new Attribute[]{}), context,null,weaverVersion);
- if (! as.isEmpty()) {
+ List as = BcelAttributes.readAjAttributes(getClassName(), (Attribute[]) attributes.toArray(new Attribute[] {}), context,
+ null, weaverVersion);
+ if (!as.isEmpty()) {
out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger...
}
}
+ private class BodyPrinter {
+ Map labelMap = new HashMap();
+
+ InstructionList body;
+ PrintStream out;
+ ConstantPool pool;
+
+ BodyPrinter(PrintStream out) {
+ this.pool = enclosingClass.getConstantPool();
+ this.body = getBodyForPrint();
+ this.out = out;
+ }
+
+ BodyPrinter(PrintStream out, InstructionList il) {
+ this.pool = enclosingClass.getConstantPool();
+ this.body = il;
+ this.out = out;
+ }
+
+ void run() {
+ // killNops();
+ assignLabels();
+ print();
+ }
+
+ // label assignment
+ void assignLabels() {
+ LinkedList exnTable = new LinkedList();
+ String pendingLabel = null;
+ // boolean hasPendingTargeters = false;
+ int lcounter = 0;
+ for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
+ Iterator tIter = ih.getTargeters().iterator();
+ while (tIter.hasNext()) {
+ InstructionTargeter t = (InstructionTargeter) tIter.next();// targeters[i];
+ if (t instanceof ExceptionRange) {
+ // assert isRangeHandle(h);
+ ExceptionRange r = (ExceptionRange) t;
+ if (r.getStart() == ih) {
+ insertHandler(r, exnTable);
+ }
+ } else if (t instanceof InstructionBranch) {
+ if (pendingLabel == null) {
+ pendingLabel = "L" + lcounter++;
+ }
+ } else {
+ // assert isRangeHandle(h)
+ }
+ }
+ if (pendingLabel != null) {
+ labelMap.put(ih, pendingLabel);
+ if (!Range.isRangeHandle(ih)) {
+ pendingLabel = null;
+ }
+ }
+ }
+ int ecounter = 0;
+ for (Iterator i = exnTable.iterator(); i.hasNext();) {
+ ExceptionRange er = (ExceptionRange) i.next();
+ String exceptionLabel = "E" + ecounter++;
+ labelMap.put(Range.getRealStart(er.getHandler()), exceptionLabel);
+ labelMap.put(er.getHandler(), exceptionLabel);
+ }
+ }
- private class BodyPrinter {
- Map labelMap = new HashMap();
-
- InstructionList body;
- PrintStream out;
- ConstantPool pool;
-
- BodyPrinter(PrintStream out) {
- this.pool = enclosingClass.getConstantPool();
- this.body = getBodyForPrint();
- this.out = out;
- }
-
- BodyPrinter(PrintStream out,InstructionList il) {
- this.pool = enclosingClass.getConstantPool();
- this.body = il;
- this.out = out;
- }
-
- void run() {
- //killNops();
- assignLabels();
- print();
- }
-
- // label assignment
- void assignLabels() {
- LinkedList exnTable = new LinkedList();
- String pendingLabel = null;
-// boolean hasPendingTargeters = false;
- int lcounter = 0;
- for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
- Iterator tIter = ih.getTargeters().iterator();
- while (tIter.hasNext()) {
- InstructionTargeter t = (InstructionTargeter)tIter.next();//targeters[i];
- if (t instanceof ExceptionRange) {
- // assert isRangeHandle(h);
- ExceptionRange r = (ExceptionRange) t;
- if (r.getStart() == ih) {
- insertHandler(r, exnTable);
- }
- } else if (t instanceof InstructionBranch) {
- if (pendingLabel == null) {
- pendingLabel = "L" + lcounter++;
- }
- } else {
- // assert isRangeHandle(h)
- }
- }
- if (pendingLabel != null) {
- labelMap.put(ih, pendingLabel);
- if (! Range.isRangeHandle(ih)) {
- pendingLabel = null;
- }
- }
- }
- int ecounter = 0;
- for (Iterator i = exnTable.iterator(); i.hasNext();) {
- ExceptionRange er = (ExceptionRange) i.next();
- String exceptionLabel = "E" + ecounter++;
- labelMap.put(Range.getRealStart(er.getHandler()), exceptionLabel);
- labelMap.put(er.getHandler(), exceptionLabel);
- }
- }
-
- // printing
-
- void print() {
- int depth = 0;
- int currLine = -1;
- bodyPrint:
- for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
- if (Range.isRangeHandle(ih)) {
- Range r = Range.getRange(ih);
- // don't print empty ranges, that is, ranges who contain no actual instructions
- for (InstructionHandle xx = r.getStart(); Range.isRangeHandle(xx); xx = xx.getNext()) {
- if (xx == r.getEnd()) continue bodyPrint;
- }
-
- // doesn't handle nested: if (r.getStart().getNext() == r.getEnd()) continue;
- if (r.getStart() == ih) {
- printRangeString(r, depth++);
- } else {
- if (r.getEnd() != ih) throw new RuntimeException("bad");
- printRangeString(r, --depth);
- }
- } else {
- printInstruction(ih, depth);
- int line = getLineNumber(ih, currLine);
- if (line != currLine) {
- currLine = line;
- out.println(" (line " + line + ")");
- } else {
- out.println();
- }
- }
- }
- }
-
- void printRangeString(Range r, int depth) {
- printDepth(depth);
- out.println(getRangeString(r, labelMap));
- }
-
-
- String getRangeString(Range r, Map labelMap) {
- if (r instanceof ExceptionRange) {
- ExceptionRange er = (ExceptionRange) r;
- return er.toString() + " -> " + labelMap.get(er.getHandler());
-//
-// + " PRI " + er.getPriority();
- } else {
- return r.toString();
- }
- }
-
- void printDepth(int depth) {
- pad(BODY_INDENT);
- while (depth > 0) {
- out.print("| ");
- depth--;
- }
- }
-
-
- void printLabel(String s, int depth) {
- int space = Math.max(CODE_INDENT - depth * 2, 0);
- if (s == null) {
- pad(space);
- } else {
- space = Math.max(space - (s.length() + 2), 0);
- pad(space);
- out.print(s);
- out.print(": ");
- }
- }
-
- void printInstruction(InstructionHandle h, int depth) {
- printDepth(depth);
- printLabel((String) labelMap.get(h), depth);
-
- Instruction inst = h.getInstruction();
- if (inst.isConstantPoolInstruction()) {
- out.print(Constants.OPCODE_NAMES[inst.opcode].toUpperCase());
- out.print(" ");
- out.print(pool.constantToString(pool.getConstant(inst.getIndex())));
- } else if (inst instanceof InstructionSelect) {
- InstructionSelect sinst = (InstructionSelect) inst;
- out.println(Constants.OPCODE_NAMES[sinst.opcode].toUpperCase());
- int[] matches = sinst.getMatchs();
- InstructionHandle[] targets = sinst.getTargets();
- InstructionHandle defaultTarget = sinst.getTarget();
- for (int i = 0, len = matches.length; i < len; i++) {
- printDepth(depth);
- printLabel(null, depth);
- out.print(" ");
- out.print(matches[i]);
- out.print(": \t");
- out.println(labelMap.get(targets[i]));
- }
- printDepth(depth);
- printLabel(null, depth);
- out.print(" ");
- out.print("default: \t");
- out.print(labelMap.get(defaultTarget));
- } else if (inst instanceof InstructionBranch) {
- InstructionBranch brinst = (InstructionBranch) inst;
- out.print(Constants.OPCODE_NAMES[brinst.getOpcode()].toUpperCase());
- out.print(" ");
- out.print(labelMap.get(brinst.getTarget()));
- } else if (inst.isLocalVariableInstruction()) {
- //LocalVariableInstruction lvinst = (LocalVariableInstruction) inst;
- out.print(inst.toString(false).toUpperCase());
- int index = inst.getIndex();
- LocalVariableTag tag = getLocalVariableTag(h, index);
- if (tag != null) {
- out.print(" // ");
- out.print(tag.getType());
- out.print(" ");
- out.print(tag.getName());
- }
- } else {
- out.print(inst.toString(false).toUpperCase());
- }
- }
-
-
-
-
- static final int BODY_INDENT = 4;
- static final int CODE_INDENT = 16;
-
- void pad(int size) {
- for (int i = 0; i < size; i++) {
- out.print(" ");
- }
- }
- }
-
-
- static LocalVariableTag getLocalVariableTag(
- InstructionHandle ih,
- int index)
- {
- Iterator tIter = ih.getTargeters().iterator();
- while (tIter.hasNext()) {
- InstructionTargeter t = (InstructionTargeter)tIter.next();
- if (t instanceof LocalVariableTag) {
- LocalVariableTag lvt = (LocalVariableTag) t;
- if (lvt.getSlot() == index) return lvt;
- }
- }
- return null;
- }
-
- static int getLineNumber(
- InstructionHandle ih,
- int prevLine)
- {
- Iterator tIter = ih.getTargeters().iterator();
- while (tIter.hasNext()) {
- InstructionTargeter t = (InstructionTargeter)tIter.next();
- if (t instanceof LineNumberTag) {
- return ((LineNumberTag)t).getLineNumber();
- }
- }
- return prevLine;
- }
+ // printing
+
+ void print() {
+ int depth = 0;
+ int currLine = -1;
+ bodyPrint: for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
+ if (Range.isRangeHandle(ih)) {
+ Range r = Range.getRange(ih);
+ // don't print empty ranges, that is, ranges who contain no actual instructions
+ for (InstructionHandle xx = r.getStart(); Range.isRangeHandle(xx); xx = xx.getNext()) {
+ if (xx == r.getEnd())
+ continue bodyPrint;
+ }
+
+ // doesn't handle nested: if (r.getStart().getNext() == r.getEnd()) continue;
+ if (r.getStart() == ih) {
+ printRangeString(r, depth++);
+ } else {
+ if (r.getEnd() != ih)
+ throw new RuntimeException("bad");
+ printRangeString(r, --depth);
+ }
+ } else {
+ printInstruction(ih, depth);
+ int line = getLineNumber(ih, currLine);
+ if (line != currLine) {
+ currLine = line;
+ out.println(" (line " + line + ")");
+ } else {
+ out.println();
+ }
+ }
+ }
+ }
+
+ void printRangeString(Range r, int depth) {
+ printDepth(depth);
+ out.println(getRangeString(r, labelMap));
+ }
+
+ String getRangeString(Range r, Map labelMap) {
+ if (r instanceof ExceptionRange) {
+ ExceptionRange er = (ExceptionRange) r;
+ return er.toString() + " -> " + labelMap.get(er.getHandler());
+ //
+ // + " PRI " + er.getPriority();
+ } else {
+ return r.toString();
+ }
+ }
+
+ void printDepth(int depth) {
+ pad(BODY_INDENT);
+ while (depth > 0) {
+ out.print("| ");
+ depth--;
+ }
+ }
+
+ void printLabel(String s, int depth) {
+ int space = Math.max(CODE_INDENT - depth * 2, 0);
+ if (s == null) {
+ pad(space);
+ } else {
+ space = Math.max(space - (s.length() + 2), 0);
+ pad(space);
+ out.print(s);
+ out.print(": ");
+ }
+ }
+
+ void printInstruction(InstructionHandle h, int depth) {
+ printDepth(depth);
+ printLabel((String) labelMap.get(h), depth);
+
+ Instruction inst = h.getInstruction();
+ if (inst.isConstantPoolInstruction()) {
+ out.print(Constants.OPCODE_NAMES[inst.opcode].toUpperCase());
+ out.print(" ");
+ out.print(pool.constantToString(pool.getConstant(inst.getIndex())));
+ } else if (inst instanceof InstructionSelect) {
+ InstructionSelect sinst = (InstructionSelect) inst;
+ out.println(Constants.OPCODE_NAMES[sinst.opcode].toUpperCase());
+ int[] matches = sinst.getMatchs();
+ InstructionHandle[] targets = sinst.getTargets();
+ InstructionHandle defaultTarget = sinst.getTarget();
+ for (int i = 0, len = matches.length; i < len; i++) {
+ printDepth(depth);
+ printLabel(null, depth);
+ out.print(" ");
+ out.print(matches[i]);
+ out.print(": \t");
+ out.println(labelMap.get(targets[i]));
+ }
+ printDepth(depth);
+ printLabel(null, depth);
+ out.print(" ");
+ out.print("default: \t");
+ out.print(labelMap.get(defaultTarget));
+ } else if (inst instanceof InstructionBranch) {
+ InstructionBranch brinst = (InstructionBranch) inst;
+ out.print(Constants.OPCODE_NAMES[brinst.getOpcode()].toUpperCase());
+ out.print(" ");
+ out.print(labelMap.get(brinst.getTarget()));
+ } else if (inst.isLocalVariableInstruction()) {
+ // LocalVariableInstruction lvinst = (LocalVariableInstruction) inst;
+ out.print(inst.toString(false).toUpperCase());
+ int index = inst.getIndex();
+ LocalVariableTag tag = getLocalVariableTag(h, index);
+ if (tag != null) {
+ out.print(" // ");
+ out.print(tag.getType());
+ out.print(" ");
+ out.print(tag.getName());
+ }
+ } else {
+ out.print(inst.toString(false).toUpperCase());
+ }
+ }
+
+ static final int BODY_INDENT = 4;
+ static final int CODE_INDENT = 16;
+
+ void pad(int size) {
+ for (int i = 0; i < size; i++) {
+ out.print(" ");
+ }
+ }
+ }
+
+ static LocalVariableTag getLocalVariableTag(InstructionHandle ih, int index) {
+ Iterator tIter = ih.getTargeters().iterator();
+ while (tIter.hasNext()) {
+ InstructionTargeter t = (InstructionTargeter) tIter.next();
+ if (t instanceof LocalVariableTag) {
+ LocalVariableTag lvt = (LocalVariableTag) t;
+ if (lvt.getSlot() == index)
+ return lvt;
+ }
+ }
+ return null;
+ }
+
+ static int getLineNumber(InstructionHandle ih, int prevLine) {
+ Iterator tIter = ih.getTargeters().iterator();
+ while (tIter.hasNext()) {
+ InstructionTargeter t = (InstructionTargeter) tIter.next();
+ if (t instanceof LineNumberTag) {
+ return ((LineNumberTag) t).getLineNumber();
+ }
+ }
+ return prevLine;
+ }
public boolean isStatic() {
return Modifier.isStatic(getAccessFlags());
}
-
+
public boolean isAbstract() {
return Modifier.isAbstract(getAccessFlags());
}
-
+
public boolean isBridgeMethod() {
return (getAccessFlags() & Constants.ACC_BRIDGE) != 0;
}
-
- public void addExceptionHandler(
- InstructionHandle start,
- InstructionHandle end,
- InstructionHandle handlerStart,
- ObjectType catchType,
- boolean highPriority) {
-
- InstructionHandle start1 = Range.genStart(body, start);
- InstructionHandle end1 = Range.genEnd(body, end);
-
- ExceptionRange er =
- new ExceptionRange(body, (catchType==null?null:BcelWorld.fromBcel(catchType)), highPriority);
- er.associateWithTargets(start1, end1, handlerStart);
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
-
- public int getAccessFlagsWithoutSynchronized() {
- if (isSynchronized()) return accessFlags - Modifier.SYNCHRONIZED;
- return accessFlags;
- }
-
- public boolean isSynchronized() {
- return (accessFlags & Modifier.SYNCHRONIZED)!=0;
- }
-
- public void setAccessFlags(int newFlags) {
- this.accessFlags = newFlags;
- }
-
- public Type[] getArgumentTypes() {
- initialize();
- return argumentTypes;
- }
-
- public LazyClassGen getEnclosingClass() {
- return enclosingClass;
- }
-
- public int getMaxLocals() {
- return maxLocals;
- }
-
- public String getName() {
- return name;
- }
-
- public String getGenericReturnTypeSignature() {
- if (memberView == null) {
- return getReturnType().getSignature();
- } else {
- return memberView.getGenericReturnType().getSignature();
- }
- }
-
- public Type getReturnType() {
- initialize();
- return returnType;
- }
-
- public void setMaxLocals(int maxLocals) {
- this.maxLocals = maxLocals;
- }
-
- public InstructionList getBody() {
- markAsChanged();
- return body;
- }
- public InstructionList getBodyForPrint() {
- return body;
- }
-
- public boolean hasBody() {
- if (savedMethod != null) return savedMethod.getCode() != null;
- return body != null;
- }
-
- public List/*Attribute*/ getAttributes() {
- return attributes;
- }
-
- public String[] getDeclaredExceptions() {
- return declaredExceptions;
- }
-
- public String getClassName() {
- return enclosingClass.getName();
- }
-
-
- // ---- packing!
-
- public MethodGen pack() {
- forceSyntheticForAjcMagicMembers();
-
- //killNops();
- int flags = getAccessFlags();
- if (enclosingClass.getWorld().isJoinpointSynchronizationEnabled() &&
- enclosingClass.getWorld().areSynchronizationPointcutsInUse()) {
- flags = getAccessFlagsWithoutSynchronized();
- }
- MethodGen gen =
- new MethodGen(
- flags,
- getReturnType(),
- getArgumentTypes(),
- null, //getArgumentNames(),
- getName(),
- getEnclosingClass().getName(),
- new InstructionList(),
- getEnclosingClass().getConstantPool());
- for (int i = 0, len = declaredExceptions.length; i < len; i++) {
- gen.addException(declaredExceptions[i]);
- }
-
- for (int i = 0, len = attributes.size(); i < len; i++) {
- gen.addAttribute((Attribute)attributes.get(i));
- }
-
- if (newAnnotations!=null) {
+
+ public void addExceptionHandler(InstructionHandle start, InstructionHandle end, InstructionHandle handlerStart,
+ ObjectType catchType, boolean highPriority) {
+
+ InstructionHandle start1 = Range.genStart(body, start);
+ InstructionHandle end1 = Range.genEnd(body, end);
+
+ ExceptionRange er = new ExceptionRange(body, (catchType == null ? null : BcelWorld.fromBcel(catchType)), highPriority);
+ er.associateWithTargets(start1, end1, handlerStart);
+ }
+
+ public int getAccessFlags() {
+ return accessFlags;
+ }
+
+ public int getAccessFlagsWithoutSynchronized() {
+ if (isSynchronized())
+ return accessFlags - Modifier.SYNCHRONIZED;
+ return accessFlags;
+ }
+
+ public boolean isSynchronized() {
+ return (accessFlags & Modifier.SYNCHRONIZED) != 0;
+ }
+
+ public void setAccessFlags(int newFlags) {
+ this.accessFlags = newFlags;
+ }
+
+ public Type[] getArgumentTypes() {
+ initialize();
+ return argumentTypes;
+ }
+
+ public LazyClassGen getEnclosingClass() {
+ return enclosingClass;
+ }
+
+ public int getMaxLocals() {
+ return maxLocals;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getGenericReturnTypeSignature() {
+ if (memberView == null) {
+ return getReturnType().getSignature();
+ } else {
+ return memberView.getGenericReturnType().getSignature();
+ }
+ }
+
+ public Type getReturnType() {
+ initialize();
+ return returnType;
+ }
+
+ public void setMaxLocals(int maxLocals) {
+ this.maxLocals = maxLocals;
+ }
+
+ public InstructionList getBody() {
+ markAsChanged();
+ return body;
+ }
+
+ public InstructionList getBodyForPrint() {
+ return body;
+ }
+
+ public boolean hasBody() {
+ if (savedMethod != null)
+ return savedMethod.getCode() != null;
+ return body != null;
+ }
+
+ public List/* Attribute */getAttributes() {
+ return attributes;
+ }
+
+ public String[] getDeclaredExceptions() {
+ return declaredExceptions;
+ }
+
+ public String getClassName() {
+ return enclosingClass.getName();
+ }
+
+ // ---- packing!
+
+ public MethodGen pack() {
+ forceSyntheticForAjcMagicMembers();
+
+ // killNops();
+ int flags = getAccessFlags();
+ if (enclosingClass.getWorld().isJoinpointSynchronizationEnabled()
+ && enclosingClass.getWorld().areSynchronizationPointcutsInUse()) {
+ flags = getAccessFlagsWithoutSynchronized();
+ }
+ MethodGen gen = new MethodGen(flags, getReturnType(), getArgumentTypes(), null, // getArgumentNames(),
+ getName(), getEnclosingClass().getName(), new InstructionList(), getEnclosingClass().getConstantPool());
+ for (int i = 0, len = declaredExceptions.length; i < len; i++) {
+ gen.addException(declaredExceptions[i]);
+ }
+
+ for (int i = 0, len = attributes.size(); i < len; i++) {
+ gen.addAttribute((Attribute) attributes.get(i));
+ }
+
+ if (newAnnotations != null) {
for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) {
AnnotationX element = (AnnotationX) iter.next();
- gen.addAnnotation(new AnnotationGen(element.getBcelAnnotation(),gen.getConstantPool(),true));
+ gen.addAnnotation(new AnnotationGen(element.getBcelAnnotation(), gen.getConstantPool(), true));
+ }
+ }
+
+ if (memberView != null && memberView.getAnnotations() != null && memberView.getAnnotations().length != 0) {
+ AnnotationX[] ans = memberView.getAnnotations();
+ for (int i = 0, len = ans.length; i < len; i++) {
+ AnnotationGen a = ans[i].getBcelAnnotation();
+ gen.addAnnotation(new AnnotationGen(a, gen.getConstantPool(), true));
}
- }
-
- if (memberView!=null && memberView.getAnnotations()!=null && memberView.getAnnotations().length!=0) {
- AnnotationX[] ans = memberView.getAnnotations();
- for (int i = 0, len = ans.length; i < len; i++) {
- AnnotationGen a= ans[i].getBcelAnnotation();
- gen.addAnnotation(new AnnotationGen(a,gen.getConstantPool(),true));
- }
- }
-
- if (isSynthetic) {
- if (enclosingClass.getWorld().isInJava5Mode()) {
- gen.setModifiers(gen.getModifiers() | ACC_SYNTHETIC);
- }
- // belt and braces, do the attribute even on Java 5 in addition to the modifier flag
- ConstantPool cpg = gen.getConstantPool();
- int index = cpg.addUtf8("Synthetic");
- gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg));
- }
-
- if (hasBody()) {
- if (this.enclosingClass.getWorld().shouldFastPackMethods()) {
- if (isAdviceMethod() || getName().equals("<clinit>")) {
- packBody(gen);
- } else {
- optimizedPackBody(gen);
- }
- } else {
- packBody(gen);
- }
- gen.setMaxLocals();
- gen.setMaxStack();
- } else {
- gen.setInstructionList(null);
- }
- return gen;
- }
-
- private void forceSyntheticForAjcMagicMembers() {
+ }
+
+ if (isSynthetic) {
+ if (enclosingClass.getWorld().isInJava5Mode()) {
+ gen.setModifiers(gen.getModifiers() | ACC_SYNTHETIC);
+ }
+ // belt and braces, do the attribute even on Java 5 in addition to the modifier flag
+ ConstantPool cpg = gen.getConstantPool();
+ int index = cpg.addUtf8("Synthetic");
+ gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg));
+ }
+
+ if (hasBody()) {
+ if (this.enclosingClass.getWorld().shouldFastPackMethods()) {
+ if (isAdviceMethod() || getName().equals("<clinit>")) {
+ packBody(gen);
+ } else {
+ optimizedPackBody(gen);
+ }
+ } else {
+ packBody(gen);
+ }
+ gen.setMaxLocals();
+ gen.setMaxStack();
+ } else {
+ gen.setInstructionList(null);
+ }
+ return gen;
+ }
+
+ private void forceSyntheticForAjcMagicMembers() {
if (NameMangler.isSyntheticMethod(getName(), inAspect())) {
makeSynthetic();
}
}
-
- private boolean inAspect() {
- BcelObjectType objectType = enclosingClass.getBcelObjectType();
- return (objectType == null ? false : objectType.isAspect());
- }
+
+ private boolean inAspect() {
+ BcelObjectType objectType = enclosingClass.getBcelObjectType();
+ return (objectType == null ? false : objectType.isAspect());
+ }
public void makeSynthetic() {
- isSynthetic = true;
- }
-
- private static class LVPosition {
- InstructionHandle start = null;
- InstructionHandle end = null;
- }
-
- /** fill the newly created method gen with our body,
- * inspired by InstructionList.copy()
- */
- public void packBody(MethodGen gen) {
- InstructionList fresh = gen.getInstructionList();
- Map map = copyAllInstructionsExceptRangeInstructionsInto(fresh);
-
- // at this point, no rangeHandles are in fresh. Let's use that...
-
- /* Update branch targets and insert various attributes.
- * Insert our exceptionHandlers
- * into a sorted list, so they can be added in order later.
- */
- InstructionHandle oldInstructionHandle = getBody().getStart();
- InstructionHandle newInstructionHandle = fresh.getStart();
- LinkedList exceptionList = new LinkedList();
+ isSynthetic = true;
+ }
+
+ private static class LVPosition {
+ InstructionHandle start = null;
+ InstructionHandle end = null;
+ }
+
+ /**
+ * fill the newly created method gen with our body, inspired by InstructionList.copy()
+ */
+ public void packBody(MethodGen gen) {
+ InstructionList fresh = gen.getInstructionList();
+ Map map = copyAllInstructionsExceptRangeInstructionsInto(fresh);
+
+ // at this point, no rangeHandles are in fresh. Let's use that...
+
+ /*
+ * Update branch targets and insert various attributes. Insert our exceptionHandlers into a sorted list, so they can be
+ * added in order later.
+ */
+ InstructionHandle oldInstructionHandle = getBody().getStart();
+ InstructionHandle newInstructionHandle = fresh.getStart();
+ LinkedList exceptionList = new LinkedList();
// map from localvariabletag to instruction handle
- Map localVariables = new HashMap();
-
- int currLine = -1;
- int lineNumberOffset = (fromFilename == null) ? 0: getEnclosingClass().getSourceDebugExtensionOffset(fromFilename);
-
- while (oldInstructionHandle != null) {
- if (map.get(oldInstructionHandle) == null) {
- // must be a range instruction since they're the only things we didn't copy across
- handleRangeInstruction(oldInstructionHandle, exceptionList);
- // just increment ih.
- oldInstructionHandle = oldInstructionHandle.getNext();
- } else {
- // assert map.get(ih) == jh
- Instruction oldInstruction = oldInstructionHandle.getInstruction();
- Instruction newInstruction = newInstructionHandle.getInstruction();
-
- if (oldInstruction instanceof InstructionBranch) {
- handleBranchInstruction(map, oldInstruction, newInstruction);
- }
-
- // now deal with line numbers
- // and store up info for local variables
- Iterator tIter = oldInstructionHandle.getTargeters().iterator();
- while (tIter.hasNext()) {
- InstructionTargeter targeter = (InstructionTargeter)tIter.next();//targeters[k];
- if (targeter instanceof LineNumberTag) {
- int line = ((LineNumberTag)targeter).getLineNumber();
- if (line != currLine) {
- gen.addLineNumber(newInstructionHandle, line + lineNumberOffset);
- currLine = line;
- }
- } else if (targeter instanceof LocalVariableTag) {
- LocalVariableTag lvt = (LocalVariableTag) targeter;
- LVPosition p = (LVPosition)localVariables.get(lvt);
- // If we don't know about it, create a new position and store
- // If we do know about it - update its end position
- if (p==null) {
- LVPosition newp = new LVPosition();
- newp.start=newp.end=newInstructionHandle;
- localVariables.put(lvt,newp);
- } else {
- p.end = newInstructionHandle;
- }
- }
- }
-
- // now continue
- oldInstructionHandle = oldInstructionHandle.getNext();
- newInstructionHandle = newInstructionHandle.getNext();
- }
- }
-
- addExceptionHandlers(gen, map, exceptionList);
- addLocalVariables(gen,localVariables);
-
- // JAVAC adds line number tables (with just one entry) to generated accessor methods - this
- // keeps some tools that rely on finding at least some form of linenumbertable happy.
- // Let's check if we have one - if we don't then let's add one.
- // TODO Could be made conditional on whether line debug info is being produced
- if (gen.getLineNumbers().length==0) {
- gen.addLineNumber(gen.getInstructionList().getStart(),1);
- }
- }
-
-
- /*
- * Optimized packing that does a 'local packing' of the code rather than building a brand new method
- * and packing into it. Only usable when the packing is going to be done just once.
- */
- public void optimizedPackBody(MethodGen gen) {
- InstructionList theBody = getBody();
- InstructionHandle iHandle = theBody.getStart();
-
- int currLine = -1;
- int lineNumberOffset = (fromFilename == null) ? 0: getEnclosingClass().getSourceDebugExtensionOffset(fromFilename);
- Map localVariables = new HashMap();
- LinkedList exceptionList = new LinkedList();
- Set forDeletion = new HashSet();
- Set branchInstructions = new HashSet();
- // OPTIMIZE sort out in here: getRange()/insertHandler() and type of exceptionList
- while (iHandle != null) {
- Instruction inst = iHandle.getInstruction();
-// InstructionHandle nextInst = iHandle.getNext();
- // OPTIMIZE remove this instructionhandle as it now points to nowhere?
- if (inst == Range.RANGEINSTRUCTION) {
- Range r = Range.getRange(iHandle);
- if (r instanceof ExceptionRange) {
- ExceptionRange er = (ExceptionRange) r;
- if (er.getStart() == iHandle) {
- if (!er.isEmpty()){
- // order is important, insert handlers in order of start
- insertHandler(er, exceptionList);
- }
- }
- }
- forDeletion.add(iHandle);
- } else {
- if (inst instanceof InstructionBranch) {
- branchInstructions.add(iHandle);
- }
-
- InstructionTargeter[] targeters = iHandle.getTargetersArray();
- if (targeters != null) {
- for (int k = targeters.length - 1; k >= 0; k--) {
- InstructionTargeter targeter = targeters[k];
- if (targeter instanceof LineNumberTag) {
- int line = ((LineNumberTag)targeter).getLineNumber();
- if (line != currLine) {
- gen.addLineNumber(iHandle, line + lineNumberOffset);
- currLine = line;
- }
- } else if (targeter instanceof LocalVariableTag) {
- LocalVariableTag lvt = (LocalVariableTag) targeter;
- LVPosition p = (LVPosition)localVariables.get(lvt);
- // If we don't know about it, create a new position and store
- // If we do know about it - update its end position
- if (p==null) {
- LVPosition newp = new LVPosition();
- newp.start=newp.end=iHandle;
- localVariables.put(lvt,newp);
- } else {
- p.end = iHandle;
- }
- }
- }
- }
- }
- iHandle = iHandle.getNext();
- }
- for (Iterator iterator = branchInstructions.iterator(); iterator.hasNext();) {
+ Map localVariables = new HashMap();
+
+ int currLine = -1;
+ int lineNumberOffset = (fromFilename == null) ? 0 : getEnclosingClass().getSourceDebugExtensionOffset(fromFilename);
+
+ while (oldInstructionHandle != null) {
+ if (map.get(oldInstructionHandle) == null) {
+ // must be a range instruction since they're the only things we didn't copy across
+ handleRangeInstruction(oldInstructionHandle, exceptionList);
+ // just increment ih.
+ oldInstructionHandle = oldInstructionHandle.getNext();
+ } else {
+ // assert map.get(ih) == jh
+ Instruction oldInstruction = oldInstructionHandle.getInstruction();
+ Instruction newInstruction = newInstructionHandle.getInstruction();
+
+ if (oldInstruction instanceof InstructionBranch) {
+ handleBranchInstruction(map, oldInstruction, newInstruction);
+ }
+
+ // now deal with line numbers
+ // and store up info for local variables
+ Iterator tIter = oldInstructionHandle.getTargeters().iterator();
+ while (tIter.hasNext()) {
+ InstructionTargeter targeter = (InstructionTargeter) tIter.next();// targeters[k];
+ if (targeter instanceof LineNumberTag) {
+ int line = ((LineNumberTag) targeter).getLineNumber();
+ if (line != currLine) {
+ gen.addLineNumber(newInstructionHandle, line + lineNumberOffset);
+ currLine = line;
+ }
+ } else if (targeter instanceof LocalVariableTag) {
+ LocalVariableTag lvt = (LocalVariableTag) targeter;
+ LVPosition p = (LVPosition) localVariables.get(lvt);
+ // If we don't know about it, create a new position and store
+ // If we do know about it - update its end position
+ if (p == null) {
+ LVPosition newp = new LVPosition();
+ newp.start = newp.end = newInstructionHandle;
+ localVariables.put(lvt, newp);
+ } else {
+ p.end = newInstructionHandle;
+ }
+ }
+ }
+
+ // now continue
+ oldInstructionHandle = oldInstructionHandle.getNext();
+ newInstructionHandle = newInstructionHandle.getNext();
+ }
+ }
+
+ addExceptionHandlers(gen, map, exceptionList);
+ addLocalVariables(gen, localVariables);
+
+ // JAVAC adds line number tables (with just one entry) to generated accessor methods - this
+ // keeps some tools that rely on finding at least some form of linenumbertable happy.
+ // Let's check if we have one - if we don't then let's add one.
+ // TODO Could be made conditional on whether line debug info is being produced
+ if (gen.getLineNumbers().length == 0) {
+ gen.addLineNumber(gen.getInstructionList().getStart(), 1);
+ }
+ }
+
+ /*
+ * Optimized packing that does a 'local packing' of the code rather than building a brand new method and packing into it. Only
+ * usable when the packing is going to be done just once.
+ */
+ public void optimizedPackBody(MethodGen gen) {
+ InstructionList theBody = getBody();
+ InstructionHandle iHandle = theBody.getStart();
+
+ int currLine = -1;
+ int lineNumberOffset = (fromFilename == null) ? 0 : getEnclosingClass().getSourceDebugExtensionOffset(fromFilename);
+ Map localVariables = new HashMap();
+ LinkedList exceptionList = new LinkedList();
+ Set forDeletion = new HashSet();
+ Set branchInstructions = new HashSet();
+ // OPTIMIZE sort out in here: getRange()/insertHandler() and type of exceptionList
+ while (iHandle != null) {
+ Instruction inst = iHandle.getInstruction();
+ // InstructionHandle nextInst = iHandle.getNext();
+ // OPTIMIZE remove this instructionhandle as it now points to nowhere?
+ if (inst == Range.RANGEINSTRUCTION) {
+ Range r = Range.getRange(iHandle);
+ if (r instanceof ExceptionRange) {
+ ExceptionRange er = (ExceptionRange) r;
+ if (er.getStart() == iHandle) {
+ if (!er.isEmpty()) {
+ // order is important, insert handlers in order of start
+ insertHandler(er, exceptionList);
+ }
+ }
+ }
+ forDeletion.add(iHandle);
+ } else {
+ if (inst instanceof InstructionBranch) {
+ branchInstructions.add(iHandle);
+ }
+
+ InstructionTargeter[] targeters = iHandle.getTargetersArray();
+ if (targeters != null) {
+ for (int k = targeters.length - 1; k >= 0; k--) {
+ InstructionTargeter targeter = targeters[k];
+ if (targeter instanceof LineNumberTag) {
+ int line = ((LineNumberTag) targeter).getLineNumber();
+ if (line != currLine) {
+ gen.addLineNumber(iHandle, line + lineNumberOffset);
+ currLine = line;
+ }
+ } else if (targeter instanceof LocalVariableTag) {
+ LocalVariableTag lvt = (LocalVariableTag) targeter;
+ LVPosition p = (LVPosition) localVariables.get(lvt);
+ // If we don't know about it, create a new position and store
+ // If we do know about it - update its end position
+ if (p == null) {
+ LVPosition newp = new LVPosition();
+ newp.start = newp.end = iHandle;
+ localVariables.put(lvt, newp);
+ } else {
+ p.end = iHandle;
+ }
+ }
+ }
+ }
+ }
+ iHandle = iHandle.getNext();
+ }
+ for (Iterator iterator = branchInstructions.iterator(); iterator.hasNext();) {
BranchHandle iBranch = (BranchHandle) iterator.next();
- handleBranchInstruction(iBranch,forDeletion);
- }
- // now add exception handlers
- for (Iterator iter = exceptionList.iterator(); iter.hasNext();) {
- ExceptionRange r = (ExceptionRange) iter.next();
- if (r.isEmpty()) continue;
- gen.addExceptionHandler(
- jumpForward(r.getRealStart(),forDeletion),
- jumpForward(r.getRealEnd(),forDeletion),
- jumpForward(r.getHandler(),forDeletion),
- (r.getCatchType() == null)
- ? null
- : (ObjectType) BcelWorld.makeBcelType(r.getCatchType()));
- }
-
- for (Iterator iterator = forDeletion.iterator(); iterator.hasNext();) {
- try {
- theBody.delete((InstructionHandle)iterator.next());
+ handleBranchInstruction(iBranch, forDeletion);
+ }
+ // now add exception handlers
+ for (Iterator iter = exceptionList.iterator(); iter.hasNext();) {
+ ExceptionRange r = (ExceptionRange) iter.next();
+ if (r.isEmpty())
+ continue;
+ gen.addExceptionHandler(jumpForward(r.getRealStart(), forDeletion), jumpForward(r.getRealEnd(), forDeletion),
+ jumpForward(r.getHandler(), forDeletion), (r.getCatchType() == null) ? null : (ObjectType) BcelWorld
+ .makeBcelType(r.getCatchType()));
+ }
+
+ for (Iterator iterator = forDeletion.iterator(); iterator.hasNext();) {
+ try {
+ theBody.delete((InstructionHandle) iterator.next());
} catch (TargetLostException e) {
e.printStackTrace();
}
- }
- gen.setInstructionList(theBody);
- addLocalVariables(gen,localVariables);
-
- // JAVAC adds line number tables (with just one entry) to generated accessor methods - this
- // keeps some tools that rely on finding at least some form of linenumbertable happy.
- // Let's check if we have one - if we don't then let's add one.
- // TODO Could be made conditional on whether line debug info is being produced
- if (gen.getLineNumbers().length==0) {
- gen.addLineNumber(gen.getInstructionList().getStart(),1);
- }
- wasPackedOptimally = true;
- }
-
- private void addLocalVariables(MethodGen gen, Map localVariables) {
+ }
+ gen.setInstructionList(theBody);
+ addLocalVariables(gen, localVariables);
+
+ // JAVAC adds line number tables (with just one entry) to generated accessor methods - this
+ // keeps some tools that rely on finding at least some form of linenumbertable happy.
+ // Let's check if we have one - if we don't then let's add one.
+ // TODO Could be made conditional on whether line debug info is being produced
+ if (gen.getLineNumbers().length == 0) {
+ gen.addLineNumber(gen.getInstructionList().getStart(), 1);
+ }
+ wasPackedOptimally = true;
+ }
+
+ private void addLocalVariables(MethodGen gen, Map localVariables) {
// now add local variables
- gen.removeLocalVariables();
+ gen.removeLocalVariables();
// this next iteration _might_ be overkill, but we had problems with
- // bcel before with duplicate local variables. Now that we're patching
+ // bcel before with duplicate local variables. Now that we're patching
// bcel we should be able to do without it if we're paranoid enough
// through the rest of the compiler.
-
- Map duplicatedLocalMap = new HashMap();
- for (Iterator iter = localVariables.keySet().iterator(); iter.hasNext(); ) {
- LocalVariableTag tag = (LocalVariableTag) iter.next();
- // have we already added one with the same slot number and start location?
- // if so, just continue.
- LVPosition lvpos = (LVPosition)localVariables.get(tag);
- InstructionHandle start = lvpos.start;
- Set slots = (Set) duplicatedLocalMap.get(start);
- if (slots == null) {
- slots = new HashSet();
- duplicatedLocalMap.put(start, slots);
- } else if (slots.contains(new Integer(tag.getSlot()))) {
- // we already have a var starting at this tag with this slot
- continue;
- }
- slots.add(new Integer(tag.getSlot()));
- Type t = tag.getRealType();
- if (t==null) {
- t = BcelWorld.makeBcelType(UnresolvedType.forSignature(tag.getType()));
- }
- gen.addLocalVariable(
- tag.getName(),
- t,
- tag.getSlot(), start, lvpos.end);
- }
- }
+ Map duplicatedLocalMap = new HashMap();
+ for (Iterator iter = localVariables.keySet().iterator(); iter.hasNext();) {
+ LocalVariableTag tag = (LocalVariableTag) iter.next();
+ // have we already added one with the same slot number and start location?
+ // if so, just continue.
+ LVPosition lvpos = (LVPosition) localVariables.get(tag);
+ InstructionHandle start = lvpos.start;
+ Set slots = (Set) duplicatedLocalMap.get(start);
+ if (slots == null) {
+ slots = new HashSet();
+ duplicatedLocalMap.put(start, slots);
+ } else if (slots.contains(new Integer(tag.getSlot()))) {
+ // we already have a var starting at this tag with this slot
+ continue;
+ }
+ slots.add(new Integer(tag.getSlot()));
+ Type t = tag.getRealType();
+ if (t == null) {
+ t = BcelWorld.makeBcelType(UnresolvedType.forSignature(tag.getType()));
+ }
+ gen.addLocalVariable(tag.getName(), t, tag.getSlot(), start, lvpos.end);
+ }
+ }
private void addExceptionHandlers(MethodGen gen, Map map, LinkedList exnList) {
// now add exception handlers
- for (Iterator iter = exnList.iterator(); iter.hasNext();) {
- ExceptionRange r = (ExceptionRange) iter.next();
- if (r.isEmpty()) continue;
- InstructionHandle rMappedStart = remap(r.getRealStart(), map);
- InstructionHandle rMappedEnd = remap(r.getRealEnd(), map);
- InstructionHandle rMappedHandler = remap(r.getHandler(), map);
- gen.addExceptionHandler(rMappedStart,rMappedEnd,rMappedHandler,
- (r.getCatchType() == null)
- ? null
- : (ObjectType) BcelWorld.makeBcelType(r.getCatchType()));
- }
+ for (Iterator iter = exnList.iterator(); iter.hasNext();) {
+ ExceptionRange r = (ExceptionRange) iter.next();
+ if (r.isEmpty())
+ continue;
+ InstructionHandle rMappedStart = remap(r.getRealStart(), map);
+ InstructionHandle rMappedEnd = remap(r.getRealEnd(), map);
+ InstructionHandle rMappedHandler = remap(r.getHandler(), map);
+ gen.addExceptionHandler(rMappedStart, rMappedEnd, rMappedHandler, (r.getCatchType() == null) ? null
+ : (ObjectType) BcelWorld.makeBcelType(r.getCatchType()));
+ }
}
private void handleBranchInstruction(Map map, Instruction oldInstruction, Instruction newInstruction) {
InstructionBranch oldBranchInstruction = (InstructionBranch) oldInstruction;
InstructionBranch newBranchInstruction = (InstructionBranch) newInstruction;
- InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old target
-
- // New target is in hash map
- newBranchInstruction.setTarget(remap(oldTarget, map));
-
- if (oldBranchInstruction instanceof InstructionSelect) {
- // Either LOOKUPSWITCH or TABLESWITCH
- InstructionHandle[] oldTargets = ((InstructionSelect) oldBranchInstruction).getTargets();
- InstructionHandle[] newTargets = ((InstructionSelect) newBranchInstruction).getTargets();
-
- for (int k = oldTargets.length - 1; k >= 0; k--) {
- // Update all targets
- newTargets[k] = remap(oldTargets[k], map);
- newTargets[k].addTargeter(newBranchInstruction);
- }
- }
- }
-
- private InstructionHandle jumpForward(InstructionHandle t,Set handlesForDeletion) {
-
+ InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old target
+
+ // New target is in hash map
+ newBranchInstruction.setTarget(remap(oldTarget, map));
+
+ if (oldBranchInstruction instanceof InstructionSelect) {
+ // Either LOOKUPSWITCH or TABLESWITCH
+ InstructionHandle[] oldTargets = ((InstructionSelect) oldBranchInstruction).getTargets();
+ InstructionHandle[] newTargets = ((InstructionSelect) newBranchInstruction).getTargets();
+
+ for (int k = oldTargets.length - 1; k >= 0; k--) {
+ // Update all targets
+ newTargets[k] = remap(oldTargets[k], map);
+ newTargets[k].addTargeter(newBranchInstruction);
+ }
+ }
+ }
+
+ private InstructionHandle jumpForward(InstructionHandle t, Set handlesForDeletion) {
+
InstructionHandle target = t;
- if (handlesForDeletion.contains(target)) {
- do {
- target = target.getNext();
- } while (handlesForDeletion.contains(target));
- }
- return target;
- }
-
+ if (handlesForDeletion.contains(target)) {
+ do {
+ target = target.getNext();
+ } while (handlesForDeletion.contains(target));
+ }
+ return target;
+ }
+
private void handleBranchInstruction(BranchHandle branchHandle, Set handlesForDeletion) {
InstructionBranch branchInstruction = (InstructionBranch) branchHandle.getInstruction();
- InstructionHandle target = branchInstruction.getTarget(); // old target
-
- if (handlesForDeletion.contains(target)) {
- do {
- target = target.getNext();
- } while (handlesForDeletion.contains(target));
- branchInstruction.setTarget(target);
- }
-
- if (branchInstruction instanceof InstructionSelect) {
- // Either LOOKUPSWITCH or TABLESWITCH
- InstructionSelect iSelect = ((InstructionSelect)branchInstruction);
- InstructionHandle[] targets = iSelect.getTargets();
- for (int k = targets.length - 1; k >= 0; k--) {
- InstructionHandle oneTarget = targets[k];
- if (handlesForDeletion.contains(oneTarget)) {
- do {
- oneTarget = oneTarget.getNext();
- } while (handlesForDeletion.contains(oneTarget));
- iSelect.setTarget(k,oneTarget);
- oneTarget.addTargeter(branchInstruction);
- }
- }
- }
+ InstructionHandle target = branchInstruction.getTarget(); // old target
+
+ if (handlesForDeletion.contains(target)) {
+ do {
+ target = target.getNext();
+ } while (handlesForDeletion.contains(target));
+ branchInstruction.setTarget(target);
+ }
+
+ if (branchInstruction instanceof InstructionSelect) {
+ // Either LOOKUPSWITCH or TABLESWITCH
+ InstructionSelect iSelect = ((InstructionSelect) branchInstruction);
+ InstructionHandle[] targets = iSelect.getTargets();
+ for (int k = targets.length - 1; k >= 0; k--) {
+ InstructionHandle oneTarget = targets[k];
+ if (handlesForDeletion.contains(oneTarget)) {
+ do {
+ oneTarget = oneTarget.getNext();
+ } while (handlesForDeletion.contains(oneTarget));
+ iSelect.setTarget(k, oneTarget);
+ oneTarget.addTargeter(branchInstruction);
+ }
+ }
+ }
}
private void handleRangeInstruction(InstructionHandle ih, LinkedList exnList) {
// we're a range instruction
Range r = Range.getRange(ih);
if (r instanceof ExceptionRange) {
- ExceptionRange er = (ExceptionRange) r;
- if (er.getStart() == ih) {
- //System.err.println("er " + er);
- if (!er.isEmpty()){
- // order is important, insert handlers in order of start
- insertHandler(er, exnList);
- }
- }
+ ExceptionRange er = (ExceptionRange) r;
+ if (er.getStart() == ih) {
+ // System.err.println("er " + er);
+ if (!er.isEmpty()) {
+ // order is important, insert handlers in order of start
+ insertHandler(er, exnList);
+ }
+ }
} else {
- // we must be a shadow range or something equally useless,
- // so forget about doing anything
- }
- }
-
- /* Make copies of all instructions, append them to the new list
- * and associate old instruction references with the new ones, i.e.,
- * a 1:1 mapping.
- */
- private Map copyAllInstructionsExceptRangeInstructionsInto(InstructionList intoList) {
- HashMap map = new HashMap();
- for (InstructionHandle ih = getBody().getStart(); ih != null; ih = ih.getNext()) {
- if (Range.isRangeHandle(ih)) {
- continue;
- }
- Instruction i = ih.getInstruction();
- Instruction c = Utility.copyInstruction(i);
-
- if (c instanceof InstructionBranch)
- map.put(ih, intoList.append((InstructionBranch) c));
- else
- map.put(ih, intoList.append(c));
- }
- return map;
- }
-
- /** This procedure should not currently be used.
+ // we must be a shadow range or something equally useless,
+ // so forget about doing anything
+ }
+ }
+
+ /*
+ * Make copies of all instructions, append them to the new list and associate old instruction references with the new ones,
+ * i.e., a 1:1 mapping.
+ */
+ private Map copyAllInstructionsExceptRangeInstructionsInto(InstructionList intoList) {
+ HashMap map = new HashMap();
+ for (InstructionHandle ih = getBody().getStart(); ih != null; ih = ih.getNext()) {
+ if (Range.isRangeHandle(ih)) {
+ continue;
+ }
+ Instruction i = ih.getInstruction();
+ Instruction c = Utility.copyInstruction(i);
+
+ if (c instanceof InstructionBranch)
+ map.put(ih, intoList.append((InstructionBranch) c));
+ else
+ map.put(ih, intoList.append(c));
+ }
+ return map;
+ }
+
+ /**
+ * This procedure should not currently be used.
*/
-// public void killNops() {
-// InstructionHandle curr = body.getStart();
-// while (true) {
-// if (curr == null) break;
-// InstructionHandle next = curr.getNext();
-// if (curr.getInstruction() instanceof NOP) {
-// InstructionTargeter[] targeters = curr.getTargeters();
-// if (targeters != null) {
-// for (int i = 0, len = targeters.length; i < len; i++) {
-// InstructionTargeter targeter = targeters[i];
-// targeter.updateTarget(curr, next);
-// }
-// }
-// try {
-// body.delete(curr);
-// } catch (TargetLostException e) {
-// }
-// }
-// curr = next;
-// }
-// }
-
-// private static InstructionHandle fNext(InstructionHandle ih) {
-// while (true) {
-// if (ih.getInstruction()==Range.RANGEINSTRUCTION) ih = ih.getNext();
-// else return ih;
-// }
-// }
-
- private static InstructionHandle remap(InstructionHandle ih, Map map) {
- while (true) {
- Object ret = map.get(ih);
- if (ret == null) {
- ih = ih.getNext();
- } else {
- return (InstructionHandle) ret;
- }
- }
- }
-
- // Update to all these comments, ASC 11-01-2005
- // The right thing to do may be to do more with priorities as
- // we create new exception handlers, but that is a relatively
- // complex task. In the meantime, just taking account of the
- // priority here enables a couple of bugs to be fixed to do
- // with using return or break in code that contains a finally
- // block (pr78021,pr79554).
-
- // exception ordering.
- // What we should be doing is dealing with priority inversions way earlier than we are
- // and counting on the tree structure. In which case, the below code is in fact right.
-
-
- // XXX THIS COMMENT BELOW IS CURRENTLY WRONG.
- // An exception A preceeds an exception B in the exception table iff:
-
- // * A and B were in the original method, and A preceeded B in the original exception table
- // * If A has a higher priority than B, than it preceeds B.
- // * If A and B have the same priority, then the one whose START happens EARLIEST has LEAST priority.
- // in short, the outermost exception has least priority.
- // we implement this with a LinkedList. We could possibly implement this with a java.util.SortedSet,
- // but I don't trust the only implementation, TreeSet, to do the right thing.
-
- /* private */ static void insertHandler(ExceptionRange fresh, LinkedList l) {
- // Old implementation, simply: l.add(0,fresh);
- for (ListIterator iter = l.listIterator(); iter.hasNext();) {
- ExceptionRange r = (ExceptionRange) iter.next();
-// int freal = fresh.getRealStart().getPosition();
-// int rreal = r.getRealStart().getPosition();
- if (fresh.getPriority() >= r.getPriority()) {
- iter.previous();
- iter.add(fresh);
- return;
- }
- }
-
- // we have reached the end
- l.add(fresh);
- }
-
-
- public boolean isPrivate() {
- return Modifier.isPrivate(getAccessFlags());
- }
- public boolean isProtected() {
- return Modifier.isProtected(getAccessFlags());
- }
- public boolean isDefault() {
- return !(isProtected() || isPrivate() || isPublic());
- }
- public boolean isPublic() {
- return Modifier.isPublic(getAccessFlags());
- }
+ // public void killNops() {
+ // InstructionHandle curr = body.getStart();
+ // while (true) {
+ // if (curr == null) break;
+ // InstructionHandle next = curr.getNext();
+ // if (curr.getInstruction() instanceof NOP) {
+ // InstructionTargeter[] targeters = curr.getTargeters();
+ // if (targeters != null) {
+ // for (int i = 0, len = targeters.length; i < len; i++) {
+ // InstructionTargeter targeter = targeters[i];
+ // targeter.updateTarget(curr, next);
+ // }
+ // }
+ // try {
+ // body.delete(curr);
+ // } catch (TargetLostException e) {
+ // }
+ // }
+ // curr = next;
+ // }
+ // }
+ // private static InstructionHandle fNext(InstructionHandle ih) {
+ // while (true) {
+ // if (ih.getInstruction()==Range.RANGEINSTRUCTION) ih = ih.getNext();
+ // else return ih;
+ // }
+ // }
+ private static InstructionHandle remap(InstructionHandle ih, Map map) {
+ while (true) {
+ Object ret = map.get(ih);
+ if (ret == null) {
+ ih = ih.getNext();
+ } else {
+ return (InstructionHandle) ret;
+ }
+ }
+ }
+ // Update to all these comments, ASC 11-01-2005
+ // The right thing to do may be to do more with priorities as
+ // we create new exception handlers, but that is a relatively
+ // complex task. In the meantime, just taking account of the
+ // priority here enables a couple of bugs to be fixed to do
+ // with using return or break in code that contains a finally
+ // block (pr78021,pr79554).
+
+ // exception ordering.
+ // What we should be doing is dealing with priority inversions way earlier than we are
+ // and counting on the tree structure. In which case, the below code is in fact right.
+
+ // XXX THIS COMMENT BELOW IS CURRENTLY WRONG.
+ // An exception A preceeds an exception B in the exception table iff:
+
+ // * A and B were in the original method, and A preceeded B in the original exception table
+ // * If A has a higher priority than B, than it preceeds B.
+ // * If A and B have the same priority, then the one whose START happens EARLIEST has LEAST priority.
+ // in short, the outermost exception has least priority.
+ // we implement this with a LinkedList. We could possibly implement this with a java.util.SortedSet,
+ // but I don't trust the only implementation, TreeSet, to do the right thing.
+
+ /* private */static void insertHandler(ExceptionRange fresh, LinkedList l) {
+ // Old implementation, simply: l.add(0,fresh);
+ for (ListIterator iter = l.listIterator(); iter.hasNext();) {
+ ExceptionRange r = (ExceptionRange) iter.next();
+ // int freal = fresh.getRealStart().getPosition();
+ // int rreal = r.getRealStart().getPosition();
+ if (fresh.getPriority() >= r.getPriority()) {
+ iter.previous();
+ iter.add(fresh);
+ return;
+ }
+ }
+
+ // we have reached the end
+ l.add(fresh);
+ }
+
+ public boolean isPrivate() {
+ return Modifier.isPrivate(getAccessFlags());
+ }
+
+ public boolean isProtected() {
+ return Modifier.isProtected(getAccessFlags());
+ }
+
+ public boolean isDefault() {
+ return !(isProtected() || isPrivate() || isPublic());
+ }
+
+ public boolean isPublic() {
+ return Modifier.isPublic(getAccessFlags());
+ }
// ----
-
- /** A good body is a body with the following properties:
- *
+
+ /**
+ * A good body is a body with the following properties:
+ *
* <ul>
- * <li> For each branch instruction S in body, target T of S is in body.
- * <li> For each branch instruction S in body, target T of S has S as a targeter.
- * <li> For each instruction T in body, for each branch instruction S that is a
- * targeter of T, S is in body.
- * <li> For each non-range-handle instruction T in body, for each instruction S
- * that is a targeter of T, S is
- * either a branch instruction, an exception range or a tag
- * <li> For each range-handle instruction T in body, there is exactly one targeter S
- * that is a range.
- * <li> For each range-handle instruction T in body, the range R targeting T is in body.
- * <li> For each instruction T in body, for each exception range R targeting T, R is
- * in body.
- * <li> For each exception range R in body, let T := R.handler. T is in body, and R is one
- * of T's targeters
- * <li> All ranges are properly nested: For all ranges Q and R, if Q.start preceeds
- * R.start, then R.end preceeds Q.end.
+ * <li> For each branch instruction S in body, target T of S is in body. <li> For each branch instruction S in body, target T of
+ * S has S as a targeter. <li> For each instruction T in body, for each branch instruction S that is a targeter of T, S is in
+ * body. <li> For each non-range-handle instruction T in body, for each instruction S that is a targeter of T, S is either a
+ * branch instruction, an exception range or a tag <li> For each range-handle instruction T in body, there is exactly one
+ * targeter S that is a range. <li> For each range-handle instruction T in body, the range R targeting T is in body. <li> For
+ * each instruction T in body, for each exception range R targeting T, R is in body. <li> For each exception range R in body,
+ * let T := R.handler. T is in body, and R is one of T's targeters <li> All ranges are properly nested: For all ranges Q and R,
+ * if Q.start preceeds R.start, then R.end preceeds Q.end.
* </ul>
- *
- * Where the shorthand "R is in body" means "R.start is in body, R.end is in body, and
- * any InstructionHandle stored in a field of R (such as an exception handle) is in body".
+ *
+ * Where the shorthand "R is in body" means "R.start is in body, R.end is in body, and any InstructionHandle stored in a field
+ * of R (such as an exception handle) is in body".
*/
-
+
public void assertGoodBody() {
- if (true) return; // only enable for debugging, consider using cheaper toString()
- assertGoodBody(getBody(), toString()); //definingType.getNameAsIdentifier() + "." + getName()); //toString());
+ if (true)
+ return; // only enable for debugging, consider using cheaper toString()
+ assertGoodBody(getBody(), toString()); // definingType.getNameAsIdentifier() + "." + getName()); //toString());
}
-
+
public static void assertGoodBody(InstructionList il, String from) {
- if (true) return; // only to be enabled for debugging
- if (il == null) return;
+ if (true)
+ return; // only to be enabled for debugging
+ if (il == null)
+ return;
Set body = new HashSet();
Stack ranges = new Stack();
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
@@ -1450,12 +1386,12 @@ public final class LazyMethodGen implements Traceable {
body.add(ih.getInstruction());
}
}
-
+
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
assertGoodHandle(ih, body, ranges, from);
Iterator tIter = ih.getTargeters().iterator();
while (tIter.hasNext()) {
- assertGoodTargeter((InstructionTargeter)tIter.next(),ih,body,from);
+ assertGoodTargeter((InstructionTargeter) tIter.next(), ih, body, from);
}
}
}
@@ -1472,13 +1408,7 @@ public final class LazyMethodGen implements Traceable {
}
}
- private static void assertGoodBranchInstruction(
- BranchHandle ih,
- InstructionBranch inst,
- Set body,
- Stack ranges,
- String from)
- {
+ private static void assertGoodBranchInstruction(BranchHandle ih, InstructionBranch inst, Set body, Stack ranges, String from) {
if (ih.getTarget() != inst.getTarget()) {
throw new BCException("bad branch instruction/handle pair in " + from);
}
@@ -1487,31 +1417,33 @@ public final class LazyMethodGen implements Traceable {
assertTargetedBy(target, inst, from);
if (inst instanceof InstructionSelect) {
InstructionSelect sel = (InstructionSelect) inst;
- InstructionHandle[] itargets = sel.getTargets();
- for (int k = itargets.length - 1; k >= 0; k--) {
+ InstructionHandle[] itargets = sel.getTargets();
+ for (int k = itargets.length - 1; k >= 0; k--) {
assertInBody(itargets[k], body, from);
assertTargetedBy(itargets[k], inst, from);
- }
- }
+ }
+ }
}
/** ih is an InstructionHandle or a BranchInstruction */
private static void assertInBody(Object ih, Set body, String from) {
- if (! body.contains(ih)) throw new BCException("thing not in body in " + from);
+ if (!body.contains(ih))
+ throw new BCException("thing not in body in " + from);
}
- private static void assertGoodRangeHandle(InstructionHandle ih, Set body, Stack ranges, String from) {
+ private static void assertGoodRangeHandle(InstructionHandle ih, Set body, Stack ranges, String from) {
Range r = getRangeAndAssertExactlyOne(ih, from);
assertGoodRange(r, body, from);
if (r.getStart() == ih) {
ranges.push(r);
} else if (r.getEnd() == ih) {
- if (ranges.peek() != r) throw new BCException("bad range inclusion in " + from);
+ if (ranges.peek() != r)
+ throw new BCException("bad range inclusion in " + from);
ranges.pop();
}
- }
-
- private static void assertGoodRange(Range r, Set body, String from) {
+ }
+
+ private static void assertGoodRange(Range r, Set body, String from) {
assertInBody(r.getStart(), body, from);
assertRangeHandle(r.getStart(), from);
assertTargetedBy(r.getStart(), r, from);
@@ -1519,130 +1451,131 @@ public final class LazyMethodGen implements Traceable {
assertInBody(r.getEnd(), body, from);
assertRangeHandle(r.getEnd(), from);
assertTargetedBy(r.getEnd(), r, from);
-
+
if (r instanceof ExceptionRange) {
ExceptionRange er = (ExceptionRange) r;
assertInBody(er.getHandler(), body, from);
assertTargetedBy(er.getHandler(), r, from);
- }
- }
+ }
+ }
private static void assertRangeHandle(InstructionHandle ih, String from) {
- if (! Range.isRangeHandle(ih)) throw new BCException("bad range handle " + ih + " in " + from);
+ if (!Range.isRangeHandle(ih))
+ throw new BCException("bad range handle " + ih + " in " + from);
}
-
- private static void assertTargetedBy(
- InstructionHandle target,
- InstructionTargeter targeter,
- String from)
- {
- Iterator tIter = target.getTargeters().iterator();
- while (tIter.hasNext()) {
- if (((InstructionTargeter)tIter.next()) == targeter) return;
- }
+ private static void assertTargetedBy(InstructionHandle target, InstructionTargeter targeter, String from) {
+ Iterator tIter = target.getTargeters().iterator();
+ while (tIter.hasNext()) {
+ if (((InstructionTargeter) tIter.next()) == targeter)
+ return;
+ }
throw new RuntimeException("bad targeting relationship in " + from);
- }
-
+ }
+
private static void assertTargets(InstructionTargeter targeter, InstructionHandle target, String from) {
if (targeter instanceof Range) {
Range r = (Range) targeter;
- if (r.getStart() == target || r.getEnd() == target) return;
+ if (r.getStart() == target || r.getEnd() == target)
+ return;
if (r instanceof ExceptionRange) {
- if (((ExceptionRange)r).getHandler() == target) return;
+ if (((ExceptionRange) r).getHandler() == target)
+ return;
}
} else if (targeter instanceof InstructionBranch) {
InstructionBranch bi = (InstructionBranch) targeter;
- if (bi.getTarget() == target) return;
+ if (bi.getTarget() == target)
+ return;
if (targeter instanceof InstructionSelect) {
InstructionSelect sel = (InstructionSelect) targeter;
- InstructionHandle[] itargets = sel.getTargets();
- for (int k = itargets.length - 1; k >= 0; k--) {
- if (itargets[k] == target) return;
- }
- }
+ InstructionHandle[] itargets = sel.getTargets();
+ for (int k = itargets.length - 1; k >= 0; k--) {
+ if (itargets[k] == target)
+ return;
+ }
+ }
} else if (targeter instanceof Tag) {
return;
}
- throw new BCException(targeter + " doesn't target " + target + " in " + from );
- }
-
- private static Range getRangeAndAssertExactlyOne(InstructionHandle ih, String from) {
- Range ret = null;
- Iterator tIter = ih.getTargeters().iterator();
- if (!tIter.hasNext()) {
- throw new BCException("range handle with no range in " + from);
- }
- while (tIter.hasNext()) {
- InstructionTargeter ts = (InstructionTargeter)tIter.next();
- if (ts instanceof Range) {
- if (ret != null) throw new BCException("range handle with multiple ranges in " + from);
- ret = (Range) ts;
- }
- }
- if (ret == null) throw new BCException("range handle with no range in " + from);
+ throw new BCException(targeter + " doesn't target " + target + " in " + from);
+ }
+
+ private static Range getRangeAndAssertExactlyOne(InstructionHandle ih, String from) {
+ Range ret = null;
+ Iterator tIter = ih.getTargeters().iterator();
+ if (!tIter.hasNext()) {
+ throw new BCException("range handle with no range in " + from);
+ }
+ while (tIter.hasNext()) {
+ InstructionTargeter ts = (InstructionTargeter) tIter.next();
+ if (ts instanceof Range) {
+ if (ret != null)
+ throw new BCException("range handle with multiple ranges in " + from);
+ ret = (Range) ts;
+ }
+ }
+ if (ret == null)
+ throw new BCException("range handle with no range in " + from);
return ret;
- }
-
- private static void assertGoodTargeter(
- InstructionTargeter t,
- InstructionHandle ih,
- Set body,
- String from)
- {
- assertTargets(t, ih, from);
+ }
+
+ private static void assertGoodTargeter(InstructionTargeter t, InstructionHandle ih, Set body, String from) {
+ assertTargets(t, ih, from);
if (t instanceof Range) {
assertGoodRange((Range) t, body, from);
} else if (t instanceof InstructionBranch) {
assertInBody(t, body, from);
}
- }
-
-
- // ----
-
- boolean isAdviceMethod() {
- if (memberView==null) return false;
- return memberView.getAssociatedShadowMunger() != null;
- }
-
- boolean isAjSynthetic() {
- if (memberView == null) return true;
- return memberView.isAjSynthetic();
- }
-
-
- boolean isSynthetic() {
- if (memberView == null) return false;
- return memberView.isSynthetic();
- }
-
- public ISourceLocation getSourceLocation() {
- if (memberView!=null) return memberView.getSourceLocation();
- return null;
- }
-
- public AjAttribute.EffectiveSignatureAttribute getEffectiveSignature() {
- //if (memberView == null) return null;
- if (effectiveSignature != null) return effectiveSignature;
- return memberView.getEffectiveSignature();
- }
-
- public void setEffectiveSignature(ResolvedMember member, Shadow.Kind kind, boolean shouldWeave) {
- this.effectiveSignature =
- new AjAttribute.EffectiveSignatureAttribute(member,kind,shouldWeave);
- }
-
+ }
+
+ // ----
+
+ boolean isAdviceMethod() {
+ if (memberView == null)
+ return false;
+ return memberView.getAssociatedShadowMunger() != null;
+ }
+
+ boolean isAjSynthetic() {
+ if (memberView == null)
+ return true;
+ return memberView.isAjSynthetic();
+ }
+
+ boolean isSynthetic() {
+ if (memberView == null)
+ return false;
+ return memberView.isSynthetic();
+ }
+
+ public ISourceLocation getSourceLocation() {
+ if (memberView != null)
+ return memberView.getSourceLocation();
+ return null;
+ }
+
+ public AjAttribute.EffectiveSignatureAttribute getEffectiveSignature() {
+ // if (memberView == null) return null;
+ if (effectiveSignature != null)
+ return effectiveSignature;
+ return memberView.getEffectiveSignature();
+ }
+
+ public void setEffectiveSignature(ResolvedMember member, Shadow.Kind kind, boolean shouldWeave) {
+ this.effectiveSignature = new AjAttribute.EffectiveSignatureAttribute(member, kind, shouldWeave);
+ }
+
public String getSignature() {
- if (memberView!=null) return memberView.getSignature();
- return MemberImpl.typesToSignature(BcelWorld.fromBcel(getReturnType()),
- BcelWorld.fromBcel(getArgumentTypes()),false);
+ if (memberView != null)
+ return memberView.getSignature();
+ return MemberImpl.typesToSignature(BcelWorld.fromBcel(getReturnType()), BcelWorld.fromBcel(getArgumentTypes()), false);
+ }
+
+ public String getParameterSignature() {
+ if (memberView != null)
+ return memberView.getParameterSignature();
+ return MemberImpl.typesToSignature(BcelWorld.fromBcel(getArgumentTypes()));
}
-
- public String getParameterSignature() {
- if (memberView!=null) return memberView.getParameterSignature();
- return MemberImpl.typesToSignature(BcelWorld.fromBcel(getArgumentTypes()));
- }
public BcelMethod getMemberView() {
return memberView;
@@ -1661,17 +1594,18 @@ public final class LazyMethodGen implements Traceable {
this.canInline = canInline;
}
- /**
- * Adds an attribute to the method
- * @param attr
- */
- public void addAttribute(Attribute attr) {
- attributes.add(attr);
-// Attribute[] newAttributes = new Attribute[attributes.length + 1];
-// System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
-// newAttributes[attributes.length] = attr;
-// attributes = newAttributes;
- }
+ /**
+ * Adds an attribute to the method
+ *
+ * @param attr
+ */
+ public void addAttribute(Attribute attr) {
+ attributes.add(attr);
+ // Attribute[] newAttributes = new Attribute[attributes.length + 1];
+ // System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
+ // newAttributes[attributes.length] = attr;
+ // attributes = newAttributes;
+ }
public String toTraceString() {
return toShortString();
diff --git a/weaver/src/org/aspectj/weaver/bcel/Range.java b/weaver/src/org/aspectj/weaver/bcel/Range.java
index c0d46d8f0..b0516a3de 100644
--- a/weaver/src/org/aspectj/weaver/bcel/Range.java
+++ b/weaver/src/org/aspectj/weaver/bcel/Range.java
@@ -10,11 +10,9 @@
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.bcel;
import java.util.Iterator;
-import java.util.Map;
import org.aspectj.apache.bcel.generic.Instruction;
import org.aspectj.apache.bcel.generic.InstructionConstants;
@@ -25,9 +23,9 @@ import org.aspectj.weaver.BCException;
abstract class Range implements InstructionTargeter {
- protected InstructionList body;
- protected InstructionHandle start;
- protected InstructionHandle end;
+ protected InstructionList body;
+ protected InstructionHandle start;
+ protected InstructionHandle end;
// ---- initialization
@@ -35,202 +33,204 @@ abstract class Range implements InstructionTargeter {
this.body = il;
}
-
- // ----
+ // ----
final InstructionList getBody() {
return body;
}
- final InstructionHandle getStart() {
- return start;
- }
- final InstructionHandle getEnd() {
- return end;
- }
-
- // ----
-
- boolean isEmpty() {
- InstructionHandle ih = start;
- //System.err.println(" looking for " + end);
- while (ih != end) {
- //System.err.println(" ih " + ih);
- if (! Range.isRangeHandle(ih)) return false;
- ih = ih.getNext();
- }
- return true;
- }
-
- static InstructionHandle getRealStart(InstructionHandle ih) {
- while (Range.isRangeHandle(ih)) {
- ih = ih.getNext();
- }
- return ih;
- }
-
- InstructionHandle getRealStart() {
- return getRealStart(start);
- }
-
- static InstructionHandle getRealEnd(InstructionHandle ih) {
- while (Range.isRangeHandle(ih)) {
- ih = ih.getPrev();
- }
- return ih;
- }
- InstructionHandle getRealEnd() {
- return getRealEnd(end);
- }
-
- InstructionHandle getRealNext() {
- return getRealStart(end);
- }
-
- static InstructionHandle getRealPrev(InstructionHandle ih) {
- InstructionHandle ret = ih.getPrev();
- while (isRangeHandle(ret)) {
- ret = ret.getPrev();
+
+ final InstructionHandle getStart() {
+ return start;
+ }
+
+ final InstructionHandle getEnd() {
+ return end;
+ }
+
+ // ----
+
+ boolean isEmpty() {
+ InstructionHandle ih = start;
+ // System.err.println(" looking for " + end);
+ while (ih != end) {
+ // System.err.println(" ih " + ih);
+ if (!Range.isRangeHandle(ih))
+ return false;
+ ih = ih.getNext();
+ }
+ return true;
+ }
+
+ static InstructionHandle getRealStart(InstructionHandle ih) {
+ while (Range.isRangeHandle(ih)) {
+ ih = ih.getNext();
+ }
+ return ih;
+ }
+
+ InstructionHandle getRealStart() {
+ return getRealStart(start);
+ }
+
+ static InstructionHandle getRealEnd(InstructionHandle ih) {
+ while (Range.isRangeHandle(ih)) {
+ ih = ih.getPrev();
}
+ return ih;
+ }
+
+ InstructionHandle getRealEnd() {
+ return getRealEnd(end);
+ }
+
+ InstructionHandle getRealNext() {
+ return getRealStart(end);
+ }
+
+ // ----
+
+ InstructionHandle insert(Instruction i, Where where) {
+ InstructionList il = new InstructionList();
+ InstructionHandle ret = il.insert(i);
+ insert(il, where);
return ret;
}
- // ----
-
- InstructionHandle insert(Instruction i, Where where) {
- InstructionList il = new InstructionList();
- InstructionHandle ret = il.insert(i);
- insert(il, where);
- return ret;
- }
- void insert(InstructionList freshIl, Where where) {
- InstructionHandle h;
- if (where == InsideBefore || where == OutsideBefore) {
- h = getStart();
- } else {
- h = getEnd();
- }
- if (where == InsideBefore || where == OutsideAfter) {
- body.append(h, freshIl);
- } else {
- InstructionHandle newStart = body.insert(h, freshIl);
- if (where == OutsideBefore) {
- // XXX this is slow. There's a better design than this. We should
- // never have to retarget branches apart from the creation of ranges.
- // basically, we should never weave OutsideBefore.
+ void insert(InstructionList freshIl, Where where) {
+ InstructionHandle h;
+ if (where == InsideBefore || where == OutsideBefore) {
+ h = getStart();
+ } else {
+ h = getEnd();
+ }
+ if (where == InsideBefore || where == OutsideAfter) {
+ body.append(h, freshIl);
+ } else {
+ InstructionHandle newStart = body.insert(h, freshIl);
+ if (where == OutsideBefore) {
+ // XXX this is slow. There's a better design than this. We should
+ // never have to retarget branches apart from the creation of ranges.
+ // basically, we should never weave OutsideBefore.
BcelShadow.retargetAllBranches(h, newStart);
- }
- }
-
- }
- InstructionHandle append(Instruction i) {
- return insert(i, InsideAfter);
- }
- void append(InstructionList i) {
- insert(i, InsideAfter);
- }
-
- static InstructionHandle remap(InstructionHandle h, Map m) {
- return (InstructionHandle) m.get(h);
- }
-
- private static void setLineNumberFromNext(InstructionHandle ih) {
- int lineNumber = Utility.getSourceLine(ih.getNext());
- if (lineNumber != -1) {
- Utility.setSourceLine(ih, lineNumber);
- }
- }
-
- static InstructionHandle genStart(InstructionList body) {
- InstructionHandle ih = body.insert(Range.RANGEINSTRUCTION);
- setLineNumberFromNext(ih);
- return ih;
- }
-
- static InstructionHandle genEnd(InstructionList body) {
- return body.append(Range.RANGEINSTRUCTION);
- }
- static InstructionHandle genStart(InstructionList body, InstructionHandle ih) {
- if (ih == null) return genStart(body);
- InstructionHandle freshIh = body.insert(ih, Range.RANGEINSTRUCTION);
- setLineNumberFromNext(freshIh);
- return freshIh;
- }
-
- static InstructionHandle genEnd(InstructionList body, InstructionHandle ih) {
- if (ih == null) return genEnd(body);
- return body.append(ih, Range.RANGEINSTRUCTION);
- }
-
- // -----
-
- public boolean containsTarget(InstructionHandle ih) {
- return false;
- }
-
- public final void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
- throw new RuntimeException("Ranges must be updated with an enclosing instructionList");
- }
-
- protected void updateTarget(
- InstructionHandle old_ih,
- InstructionHandle new_ih,
- InstructionList new_il)
- {
- old_ih.removeTargeter(this);
- if (new_ih != null)
- new_ih.addTargeter(this);
- body = new_il;
-
- if (old_ih == start) {
- start = new_ih;
- }
- if (old_ih == end) {
- end = new_ih;
- }
- }
-
- public static final boolean isRangeHandle(InstructionHandle ih) {
- if (ih == null) return false;
- return ih.getInstruction() == Range.RANGEINSTRUCTION;
- }
-
- protected static final Range getRange(InstructionHandle ih) {
- // assert isRangeHandle(ih)
+ }
+ }
+
+ }
+
+ InstructionHandle append(Instruction i) {
+ return insert(i, InsideAfter);
+ }
+
+ void append(InstructionList i) {
+ insert(i, InsideAfter);
+ }
+
+ private static void setLineNumberFromNext(InstructionHandle ih) {
+ int lineNumber = Utility.getSourceLine(ih.getNext());
+ if (lineNumber != -1) {
+ Utility.setSourceLine(ih, lineNumber);
+ }
+ }
+
+ static InstructionHandle genStart(InstructionList body) {
+ InstructionHandle ih = body.insert(Range.RANGEINSTRUCTION);
+ setLineNumberFromNext(ih);
+ return ih;
+ }
+
+ static InstructionHandle genEnd(InstructionList body) {
+ return body.append(Range.RANGEINSTRUCTION);
+ }
+
+ static InstructionHandle genStart(InstructionList body, InstructionHandle ih) {
+ if (ih == null)
+ return genStart(body);
+ InstructionHandle freshIh = body.insert(ih, Range.RANGEINSTRUCTION);
+ setLineNumberFromNext(freshIh);
+ return freshIh;
+ }
+
+ static InstructionHandle genEnd(InstructionList body, InstructionHandle ih) {
+ if (ih == null)
+ return genEnd(body);
+ return body.append(ih, Range.RANGEINSTRUCTION);
+ }
+
+ // -----
+
+ public boolean containsTarget(InstructionHandle ih) {
+ return false;
+ }
+
+ public final void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
+ throw new RuntimeException("Ranges must be updated with an enclosing instructionList");
+ }
+
+ protected void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih, InstructionList new_il) {
+ old_ih.removeTargeter(this);
+ if (new_ih != null)
+ new_ih.addTargeter(this);
+ body = new_il;
+
+ if (old_ih == start) {
+ start = new_ih;
+ }
+ if (old_ih == end) {
+ end = new_ih;
+ }
+ }
+
+ public static final boolean isRangeHandle(InstructionHandle ih) {
+ if (ih == null)
+ return false;
+ return ih.getInstruction() == Range.RANGEINSTRUCTION;
+ }
+
+ protected static final Range getRange(InstructionHandle ih) {
+ // assert isRangeHandle(ih)
Range ret = null;
Iterator tIter = ih.getTargeters().iterator();
while (tIter.hasNext()) {
- InstructionTargeter targeter = (InstructionTargeter)tIter.next();
- if (targeter instanceof Range) {
- Range r = (Range) targeter;
- if (r.getStart() != ih && r.getEnd() != ih) continue;
- if (ret != null) throw new BCException("multiple ranges on same range handle: " + ret + ", " + targeter);
- ret = r;
- }
- }
+ InstructionTargeter targeter = (InstructionTargeter) tIter.next();
+ if (targeter instanceof Range) {
+ Range r = (Range) targeter;
+ if (r.getStart() != ih && r.getEnd() != ih)
+ continue;
+ if (ret != null)
+ throw new BCException("multiple ranges on same range handle: " + ret + ", " + targeter);
+ ret = r;
+ }
+ }
if (ret == null) {
throw new BCException("shouldn't happen");
}
return ret;
- }
+ }
+
+ // ----
- // ----
+ static final Where InsideBefore = new Where("insideBefore");
+ static final Where InsideAfter = new Where("insideAfter");
+ static final Where OutsideBefore = new Where("outsideBefore");
+ static final Where OutsideAfter = new Where("outsideAfter");
- static final Where InsideBefore = new Where("insideBefore");
- static final Where InsideAfter = new Where("insideAfter");
- static final Where OutsideBefore = new Where("outsideBefore");
- static final Where OutsideAfter = new Where("outsideAfter");
+ // ---- constants
- // ---- constants
+ // note that this is STUPIDLY copied by Instruction.copy(), so don't do that.
- // note that this is STUPIDLY copied by Instruction.copy(), so don't do that.
+ public static final Instruction RANGEINSTRUCTION = InstructionConstants.IMPDEP1;
- public static final Instruction RANGEINSTRUCTION = InstructionConstants.IMPDEP1;
-
- // ----
+ // ----
- static class Where {
- private String name;
- public Where(String name) { this.name = name; }
- public String toString() { return name; }
- }
+ static class Where {
+ private String name;
+
+ public Where(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java b/weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java
index 7e43d465d..e45eac109 100644
--- a/weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java
+++ b/weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java
@@ -10,12 +10,10 @@
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.bcel;
import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
@@ -28,104 +26,97 @@ public class UnwovenClassFile {
protected String filename;
protected char[] charfilename;
protected byte[] bytes;
-// protected JavaClass javaClass = null;
- //protected byte[] writtenBytes = null;
- protected List /* ChildClass */ writtenChildClasses = Collections.EMPTY_LIST;
+ // protected JavaClass javaClass = null;
+ // protected byte[] writtenBytes = null;
+ protected List /* ChildClass */writtenChildClasses = Collections.EMPTY_LIST;
protected String className = null;
-
+
public UnwovenClassFile(String filename, byte[] bytes) {
this.filename = filename;
this.bytes = bytes;
}
- /** Use if the classname is known, saves a bytecode parse */
- public UnwovenClassFile(String filename, String classname,byte[] bytes) {
+ /** Use if the classname is known, saves a bytecode parse */
+ public UnwovenClassFile(String filename, String classname, byte[] bytes) {
this.filename = filename;
this.className = classname;
this.bytes = bytes;
}
-
+
public String getFilename() {
return filename;
}
-
+
public String makeInnerFileName(String innerName) {
- String prefix = filename.substring(0, filename.length()-6); // strip the .class
+ String prefix = filename.substring(0, filename.length() - 6); // strip the .class
return prefix + "$" + innerName + ".class";
}
-
+
public byte[] getBytes() {
-// if (bytes == null) bytes = javaClass.getBytes();
+ // if (bytes == null) bytes = javaClass.getBytes();
return bytes;
}
-
+
public JavaClass getJavaClass() {
- //XXX need to know when to make a new class and when not to
- //XXX this is an important optimization
+ // XXX need to know when to make a new class and when not to
+ // XXX this is an important optimization
if (getBytes() == null) {
System.out.println("no bytes for: " + getFilename());
- //Thread.currentThread().dumpStack();
- Thread.dumpStack();
+ // Thread.currentThread().dumpStack();
+ Thread.dumpStack();
}
return Utility.makeJavaClass(filename, getBytes());
-// if (javaClass == null) javaClass = Utility.makeJavaClass(filename, getBytes());
-// return javaClass;
- }
-
- public boolean exists() {
- return getBytes() != null;
+ // if (javaClass == null) javaClass = Utility.makeJavaClass(filename, getBytes());
+ // return javaClass;
}
-
public void writeUnchangedBytes() throws IOException {
writeWovenBytes(getBytes(), Collections.EMPTY_LIST);
}
-
- public void writeWovenBytes(byte[] bytes, List childClasses) throws IOException {
+
+ public void writeWovenBytes(byte[] bytes, List childClasses) throws IOException {
writeChildClasses(childClasses);
-
- //System.err.println("should write: " + getClassName());
-
- //System.err.println("about to write: " + this + ", " + writtenBytes + ", ");
-// + writtenBytes != null + " && " + unchanged(bytes, writtenBytes) );
-
- //if (writtenBytes != null && unchanged(bytes, writtenBytes)) return;
-
- //System.err.println(" actually wrote it");
-
+
+ // System.err.println("should write: " + getClassName());
+
+ // System.err.println("about to write: " + this + ", " + writtenBytes + ", ");
+ // + writtenBytes != null + " && " + unchanged(bytes, writtenBytes) );
+
+ // if (writtenBytes != null && unchanged(bytes, writtenBytes)) return;
+
+ // System.err.println(" actually wrote it");
+
BufferedOutputStream os = FileUtil.makeOutputStream(new File(filename));
os.write(bytes);
os.close();
-
- //writtenBytes = bytes;
+
+ // writtenBytes = bytes;
}
private void writeChildClasses(List childClasses) throws IOException {
- //??? we only really need to delete writtenChildClasses whose
- //??? names aren't in childClasses; however, it's unclear
- //??? how much that will affect performance
+ // ??? we only really need to delete writtenChildClasses whose
+ // ??? names aren't in childClasses; however, it's unclear
+ // ??? how much that will affect performance
deleteAllChildClasses();
- childClasses.removeAll(writtenChildClasses); //XXX is this right
-
+ childClasses.removeAll(writtenChildClasses); // XXX is this right
+
for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
ChildClass childClass = (ChildClass) iter.next();
writeChildClassFile(childClass.name, childClass.bytes);
-
+
}
-
+
writtenChildClasses = childClasses;
-
+
}
private void writeChildClassFile(String innerName, byte[] bytes) throws IOException {
- BufferedOutputStream os =
- FileUtil.makeOutputStream(new File(makeInnerFileName(innerName)));
+ BufferedOutputStream os = FileUtil.makeOutputStream(new File(makeInnerFileName(innerName)));
os.write(bytes);
os.close();
}
-
protected void deleteAllChildClasses() {
for (Iterator iter = writtenChildClasses.iterator(); iter.hasNext();) {
ChildClass childClass = (ChildClass) iter.next();
@@ -138,77 +129,57 @@ public class UnwovenClassFile {
childClassFile.delete();
}
-
-
- /* private */ static boolean unchanged(byte[] b1, byte[] b2) {
+ /* private */static boolean unchanged(byte[] b1, byte[] b2) {
int len = b1.length;
- if (b2.length != len) return false;
- for (int i=0; i < len; i++) {
- if (b1[i] != b2[i]) return false;
+ if (b2.length != len)
+ return false;
+ for (int i = 0; i < len; i++) {
+ if (b1[i] != b2[i])
+ return false;
}
return true;
}
public char[] getClassNameAsChars() {
- if (charfilename==null) {
+ if (charfilename == null) {
charfilename = getClassName().replace('.', '/').toCharArray();
}
return charfilename;
}
-
+
public String getClassName() {
- if (className == null) className = getJavaClass().getClassName(); // OPTIMIZE quicker way to determine name??? surely?
+ if (className == null)
+ className = getJavaClass().getClassName(); // OPTIMIZE quicker way to determine name??? surely?
return className;
}
-
+
public String toString() {
return "UnwovenClassFile(" + filename + ", " + getClassName() + ")";
}
-
- /**
- * delete not just this file, but any files in the same directory that
- * were generated as a result of weaving it (e.g. for an around closure).
- */
- public void deleteRealFile() throws IOException {
- File victim = new File(filename);
- String namePrefix = victim.getName();
- namePrefix = namePrefix.substring(0,namePrefix.lastIndexOf('.'));
- final String targetPrefix = namePrefix + "$Ajc";
- File dir = victim.getParentFile();
- if (dir != null) {
- File[] weaverGenerated = dir.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.startsWith(targetPrefix);
- }});
- if (weaverGenerated!=null) {
- for (int i = 0; i < weaverGenerated.length; i++) {
- weaverGenerated[i].delete();
- }
- }
- }
- victim.delete();
- }
// record
- // OPTIMIZE why is the 'short name' used here (the bit after the dollar) - seems we mess about a lot trimming it off only to put it back on!
+ // OPTIMIZE why is the 'short name' used here (the bit after the dollar) - seems we mess about a lot trimming it off only to put
+ // it back on!
public static class ChildClass {
public final String name;
public final byte[] bytes;
-
+
ChildClass(String name, byte[] bytes) {
this.name = name;
this.bytes = bytes;
}
-
+
public boolean equals(Object other) {
- if (! (other instanceof ChildClass)) return false;
+ if (!(other instanceof ChildClass))
+ return false;
ChildClass o = (ChildClass) other;
return o.name.equals(name) && unchanged(o.bytes, bytes);
}
+
public int hashCode() {
return name.hashCode();
}
-
+
public String toString() {
return "(ChildClass " + name + ")";
}
@@ -218,7 +189,3 @@ public class UnwovenClassFile {
this.charfilename = classNameAsChars;
}
}
-
-
-
-
diff --git a/weaver/src/org/aspectj/weaver/bcel/Utility.java b/weaver/src/org/aspectj/weaver/bcel/Utility.java
index 1fe85e37d..9eb24e9b8 100644
--- a/weaver/src/org/aspectj/weaver/bcel/Utility.java
+++ b/weaver/src/org/aspectj/weaver/bcel/Utility.java
@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.bcel;
import java.io.ByteArrayInputStream;
@@ -63,151 +62,124 @@ import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
public class Utility {
-
+
/*
- * Ensure we report a nice source location - particular in the case
- * where the source info is missing (binary weave).
+ * Ensure we report a nice source location - particular in the case where the source info is missing (binary weave).
*/
public static String beautifyLocation(ISourceLocation isl) {
StringBuffer nice = new StringBuffer();
- if (isl==null || isl.getSourceFile()==null || isl.getSourceFile().getName().indexOf("no debug info available")!=-1) {
+ if (isl == null || isl.getSourceFile() == null || isl.getSourceFile().getName().indexOf("no debug info available") != -1) {
nice.append("no debug info available");
- } else {
- // can't use File.getName() as this fails when a Linux box encounters a path created on Windows and vice-versa
- int takeFrom = isl.getSourceFile().getPath().lastIndexOf('/');
- if (takeFrom == -1) {
- takeFrom = isl.getSourceFile().getPath().lastIndexOf('\\');
- }
- nice.append(isl.getSourceFile().getPath().substring(takeFrom +1));
- if (isl.getLine()!=0) nice.append(":").append(isl.getLine());
+ } else {
+ // can't use File.getName() as this fails when a Linux box encounters a path created on Windows and vice-versa
+ int takeFrom = isl.getSourceFile().getPath().lastIndexOf('/');
+ if (takeFrom == -1) {
+ takeFrom = isl.getSourceFile().getPath().lastIndexOf('\\');
+ }
+ nice.append(isl.getSourceFile().getPath().substring(takeFrom + 1));
+ if (isl.getLine() != 0)
+ nice.append(":").append(isl.getLine());
}
return nice.toString();
}
-
-
- public static Instruction createSuperInvoke(
- InstructionFactory fact,
- BcelWorld world,
- Member signature) {
- short kind;
- if (signature.isInterface()) {
- throw new RuntimeException("bad");
- } else if (signature.isPrivate() || signature.getName().equals("<init>")) {
- throw new RuntimeException("unimplemented, possibly bad");
- } else if (signature.isStatic()) {
- throw new RuntimeException("bad");
- } else {
- kind = Constants.INVOKESPECIAL;
- }
-
- return fact.createInvoke(
- signature.getDeclaringType().getName(),
- signature.getName(),
- BcelWorld.makeBcelType(signature.getReturnType()),
- BcelWorld.makeBcelTypes(signature.getParameterTypes()),
- kind);
- }
-
- // XXX don't need the world now
- public static Instruction createInvoke(
- InstructionFactory fact,
- BcelWorld world,
- Member signature) {
- short kind;
- if (signature.isInterface()) {
- kind = Constants.INVOKEINTERFACE;
- } else if (signature.isStatic()) {
- kind = Constants.INVOKESTATIC;
- } else if (signature.isPrivate() || signature.getName().equals("<init>")) {
- kind = Constants.INVOKESPECIAL;
- } else {
- kind = Constants.INVOKEVIRTUAL;
- }
-
- UnresolvedType targetType = signature.getDeclaringType();
- if (targetType.isParameterizedType()) {
- targetType = targetType.resolve(world).getGenericType();
- }
- return fact.createInvoke(
- targetType.getName(),
- signature.getName(),
- BcelWorld.makeBcelType(signature.getReturnType()),
- BcelWorld.makeBcelTypes(signature.getParameterTypes()),
- kind);
+
+ public static Instruction createSuperInvoke(InstructionFactory fact, BcelWorld world, Member signature) {
+ short kind;
+ if (signature.isInterface()) {
+ throw new RuntimeException("bad");
+ } else if (signature.isPrivate() || signature.getName().equals("<init>")) {
+ throw new RuntimeException("unimplemented, possibly bad");
+ } else if (signature.isStatic()) {
+ throw new RuntimeException("bad");
+ } else {
+ kind = Constants.INVOKESPECIAL;
+ }
+
+ return fact.createInvoke(signature.getDeclaringType().getName(), signature.getName(), BcelWorld.makeBcelType(signature
+ .getReturnType()), BcelWorld.makeBcelTypes(signature.getParameterTypes()), kind);
+ }
+
+ // XXX don't need the world now
+ public static Instruction createInvoke(InstructionFactory fact, BcelWorld world, Member signature) {
+ short kind;
+ if (signature.isInterface()) {
+ kind = Constants.INVOKEINTERFACE;
+ } else if (signature.isStatic()) {
+ kind = Constants.INVOKESTATIC;
+ } else if (signature.isPrivate() || signature.getName().equals("<init>")) {
+ kind = Constants.INVOKESPECIAL;
+ } else {
+ kind = Constants.INVOKEVIRTUAL;
+ }
+
+ UnresolvedType targetType = signature.getDeclaringType();
+ if (targetType.isParameterizedType()) {
+ targetType = targetType.resolve(world).getGenericType();
+ }
+ return fact.createInvoke(targetType.getName(), signature.getName(), BcelWorld.makeBcelType(signature.getReturnType()),
+ BcelWorld.makeBcelTypes(signature.getParameterTypes()), kind);
}
public static Instruction createGet(InstructionFactory fact, Member signature) {
- short kind;
- if (signature.isStatic()) {
- kind = Constants.GETSTATIC;
- } else {
- kind = Constants.GETFIELD;
- }
-
- return fact.createFieldAccess(
- signature.getDeclaringType().getName(),
- signature.getName(),
- BcelWorld.makeBcelType(signature.getReturnType()),
- kind);
- }
-
- /**
- * Creae a field GET instruction
- *
- * @param fact
- * @param signature
- * @param declaringType
- * @return
- */
- public static Instruction createGetOn(InstructionFactory fact, Member signature, UnresolvedType declaringType) {
- short kind;
- if (signature.isStatic()) {
- kind = Constants.GETSTATIC;
- } else {
- kind = Constants.GETFIELD;
- }
-
- return fact.createFieldAccess(
- declaringType.getName(),
- signature.getName(),
- BcelWorld.makeBcelType(signature.getReturnType()),
- kind);
- }
+ short kind;
+ if (signature.isStatic()) {
+ kind = Constants.GETSTATIC;
+ } else {
+ kind = Constants.GETFIELD;
+ }
+
+ return fact.createFieldAccess(signature.getDeclaringType().getName(), signature.getName(), BcelWorld.makeBcelType(signature
+ .getReturnType()), kind);
+ }
+
+ /**
+ * Creae a field GET instruction
+ *
+ * @param fact
+ * @param signature
+ * @param declaringType
+ * @return
+ */
+ public static Instruction createGetOn(InstructionFactory fact, Member signature, UnresolvedType declaringType) {
+ short kind;
+ if (signature.isStatic()) {
+ kind = Constants.GETSTATIC;
+ } else {
+ kind = Constants.GETFIELD;
+ }
+
+ return fact.createFieldAccess(declaringType.getName(), signature.getName(), BcelWorld.makeBcelType(signature
+ .getReturnType()), kind);
+ }
public static Instruction createSet(InstructionFactory fact, Member signature) {
- short kind;
- if (signature.isStatic()) {
- kind = Constants.PUTSTATIC;
- } else {
- kind = Constants.PUTFIELD;
- }
-
- return fact.createFieldAccess(
- signature.getDeclaringType().getName(),
- signature.getName(),
- BcelWorld.makeBcelType(signature.getReturnType()),
- kind);
- }
-
- public static Instruction createInvoke(
- InstructionFactory fact,
- JavaClass declaringClass,
- Method newMethod) {
- short kind;
- if (newMethod.isInterface()) {
- kind = Constants.INVOKEINTERFACE;
- } else if (newMethod.isStatic()) {
- kind = Constants.INVOKESTATIC;
- } else if (newMethod.isPrivate() || newMethod.getName().equals("<init>")) {
- kind = Constants.INVOKESPECIAL;
- } else {
- kind = Constants.INVOKEVIRTUAL;
- }
-
- String sig = newMethod.getSignature();
- return fact.createInvoke(declaringClass.getClassName(),newMethod.getName(),sig,kind);
- }
-
+ short kind;
+ if (signature.isStatic()) {
+ kind = Constants.PUTSTATIC;
+ } else {
+ kind = Constants.PUTFIELD;
+ }
+
+ return fact.createFieldAccess(signature.getDeclaringType().getName(), signature.getName(), BcelWorld.makeBcelType(signature
+ .getReturnType()), kind);
+ }
+
+ public static Instruction createInvoke(InstructionFactory fact, JavaClass declaringClass, Method newMethod) {
+ short kind;
+ if (newMethod.isInterface()) {
+ kind = Constants.INVOKEINTERFACE;
+ } else if (newMethod.isStatic()) {
+ kind = Constants.INVOKESTATIC;
+ } else if (newMethod.isPrivate() || newMethod.getName().equals("<init>")) {
+ kind = Constants.INVOKESPECIAL;
+ } else {
+ kind = Constants.INVOKEVIRTUAL;
+ }
+
+ String sig = newMethod.getSignature();
+ return fact.createInvoke(declaringClass.getClassName(), newMethod.getName(), sig, kind);
+ }
+
public static byte[] stringToUTF(String s) {
try {
ByteArrayOutputStream out0 = new ByteArrayOutputStream();
@@ -219,340 +191,289 @@ public class Utility {
}
}
- public static Instruction createInstanceof(InstructionFactory fact, ReferenceType t) {
- int cpoolEntry =
- (t instanceof ArrayType)
- ? fact.getConstantPool().addArrayClass((ArrayType)t)
- : fact.getConstantPool().addClass((ObjectType)t);
- return new InstructionCP(Constants.INSTANCEOF,cpoolEntry);
- }
-
- public static Instruction createInvoke(
- InstructionFactory fact,
- LazyMethodGen m) {
- short kind;
- if (m.getEnclosingClass().isInterface()) {
- kind = Constants.INVOKEINTERFACE;
- } else if (m.isStatic()) {
- kind = Constants.INVOKESTATIC;
- } else if (m.isPrivate() || m.getName().equals("<init>")) {
- kind = Constants.INVOKESPECIAL;
- } else {
- kind = Constants.INVOKEVIRTUAL;
- }
-
- return fact.createInvoke(
- m.getClassName(),
- m.getName(),
- m.getReturnType(),
- m.getArgumentTypes(),
- kind);
- }
-
- /**
- * Create an invoke instruction
- *
- * @param fact
- * @param kind INVOKEINTERFACE, INVOKEVIRTUAL..
- * @param member
- * @return
- */
- public static Instruction createInvoke(
- InstructionFactory fact,
- short kind,
- Member member) {
- return fact.createInvoke(
- member.getDeclaringType().getName(),
- member.getName(),
- BcelWorld.makeBcelType(member.getReturnType()),
- BcelWorld.makeBcelTypes(member.getParameterTypes()),
- kind);
- }
-
- private static String[] argNames = new String[] { "arg0", "arg1", "arg2", "arg3", "arg4" };
-
- // ??? these should perhaps be cached. Remember to profile this to see if it's a problem.
- public static String[] makeArgNames(int n) {
- String[] ret = new String[n];
- for (int i=0; i<n; i++) {
- if (i < 5) {
- ret[i] = argNames[i];
- } else {
- ret[i] = "arg" + i;
- }
- }
- return ret;
- }
-
- // Lookup table, for converting between pairs of types, it gives
- // us the method name in the Conversions class
- private static Hashtable validBoxing = new Hashtable();
-
- static {
- validBoxing.put("Ljava/lang/Byte;B","byteObject");
- validBoxing.put("Ljava/lang/Character;C","charObject");
- validBoxing.put("Ljava/lang/Double;D","doubleObject");
- validBoxing.put("Ljava/lang/Float;F","floatObject");
- validBoxing.put("Ljava/lang/Integer;I","intObject");
- validBoxing.put("Ljava/lang/Long;J","longObject");
- validBoxing.put("Ljava/lang/Short;S","shortObject");
- validBoxing.put("Ljava/lang/Boolean;Z","booleanObject");
- validBoxing.put("BLjava/lang/Byte;","byteValue");
- validBoxing.put("CLjava/lang/Character;","charValue");
- validBoxing.put("DLjava/lang/Double;","doubleValue");
- validBoxing.put("FLjava/lang/Float;","floatValue");
- validBoxing.put("ILjava/lang/Integer;","intValue");
- validBoxing.put("JLjava/lang/Long;","longValue");
- validBoxing.put("SLjava/lang/Short;","shortValue");
- validBoxing.put("ZLjava/lang/Boolean;","booleanValue");
- }
-
- public static void appendConversion(
- InstructionList il,
- InstructionFactory fact,
- ResolvedType fromType,
- ResolvedType toType)
- {
- if (! toType.isConvertableFrom(fromType) &&
- ! fromType.isConvertableFrom(toType)) {
- throw new BCException("can't convert from " + fromType + " to " + toType);
- }
- // XXX I'm sure this test can be simpler but my brain hurts and this works
- if (!toType.getWorld().isInJava5Mode()) {
- if (toType.needsNoConversionFrom(fromType)) return;
- } else {
- if (toType.needsNoConversionFrom(fromType) && !(toType.isPrimitiveType()^fromType.isPrimitiveType())) return;
- }
- if (toType.equals(ResolvedType.VOID)) {
- // assert fromType.equals(UnresolvedType.OBJECT)
- il.append(InstructionFactory.createPop(fromType.getSize()));
- } else if (fromType.equals(ResolvedType.VOID)) {
- // assert toType.equals(UnresolvedType.OBJECT)
- il.append(InstructionFactory.createNull(Type.OBJECT));
- return;
- } else if (fromType.equals(UnresolvedType.OBJECT)) {
- Type to = BcelWorld.makeBcelType(toType);
- if (toType.isPrimitiveType()) {
- String name = toType.toString() + "Value";
- il.append(
- fact.createInvoke(
- "org.aspectj.runtime.internal.Conversions",
- name,
- to,
- new Type[] { Type.OBJECT },
- Constants.INVOKESTATIC));
- } else {
- il.append(fact.createCheckCast((ReferenceType)to));
- }
- } else if (toType.equals(UnresolvedType.OBJECT)) {
- // assert fromType.isPrimitive()
- Type from = BcelWorld.makeBcelType(fromType);
- String name = fromType.toString() + "Object";
- il.append(
- fact.createInvoke(
- "org.aspectj.runtime.internal.Conversions",
- name,
- Type.OBJECT,
- new Type[] { from },
- Constants.INVOKESTATIC));
- } else if (toType.getWorld().isInJava5Mode() && validBoxing.get(toType.getSignature()+fromType.getSignature())!=null) {
- // XXX could optimize by using any java boxing code that may be just before the call...
- Type from = BcelWorld.makeBcelType(fromType);
- Type to = BcelWorld.makeBcelType(toType);
- String name = (String)validBoxing.get(toType.getSignature()+fromType.getSignature());
- if (toType.isPrimitiveType()) {
- il.append(
- fact.createInvoke(
- "org.aspectj.runtime.internal.Conversions",
- name,
- to,
- new Type[]{Type.OBJECT},
- Constants.INVOKESTATIC));
- } else {
- il.append(
- fact.createInvoke(
- "org.aspectj.runtime.internal.Conversions",
- name,
- Type.OBJECT,
- new Type[] { from },
- Constants.INVOKESTATIC));
- il.append(fact.createCheckCast((ReferenceType) to));
- }
- } else if (fromType.isPrimitiveType()) {
- // assert toType.isPrimitive()
- Type from = BcelWorld.makeBcelType(fromType);
- Type to = BcelWorld.makeBcelType(toType);
- try {
- Instruction i = fact.createCast(from, to);
- if (i!=null) {
- il.append(i);
- } else {
- il.append(fact.createCast(from, Type.INT));
- il.append(fact.createCast(Type.INT, to));
- }
- } catch (RuntimeException e) {
- il.append(fact.createCast(from, Type.INT));
- il.append(fact.createCast(Type.INT, to));
- }
- } else {
- Type to = BcelWorld.makeBcelType(toType);
- // assert ! fromType.isPrimitive() && ! toType.isPrimitive()
- il.append(fact.createCheckCast((ReferenceType) to));
- }
- }
-
- public static InstructionList createConversion(InstructionFactory factory,Type fromType,Type toType) {
- return createConversion(factory,fromType,toType,false);
- }
-
- public static InstructionList createConversion(
- InstructionFactory fact,
- Type fromType,
- Type toType,
- boolean allowAutoboxing) {
- //System.out.println("cast to: " + toType);
-
- InstructionList il = new InstructionList();
-
- //PR71273
- if ((fromType.equals(Type.BYTE) || fromType.equals(Type.CHAR) || fromType.equals(Type.SHORT)) &&
- (toType.equals(Type.INT))) {
- return il;
- }
-
- if (fromType.equals(toType))
- return il;
- if (toType.equals(Type.VOID)) {
- il.append(InstructionFactory.createPop(fromType.getSize()));
- return il;
- }
-
- if (fromType.equals(Type.VOID)) {
- if (toType instanceof BasicType)
- throw new BCException("attempting to cast from void to basic type");
- il.append(InstructionFactory.createNull(Type.OBJECT));
- return il;
- }
-
- if (fromType.equals(Type.OBJECT)) {
- if (toType instanceof BasicType) {
- String name = toType.toString() + "Value";
- il.append(
- fact.createInvoke(
- "org.aspectj.runtime.internal.Conversions",
- name,
- toType,
- new Type[] { Type.OBJECT },
- Constants.INVOKESTATIC));
- return il;
- }
- }
-
- if (toType.equals(Type.OBJECT)) {
- if (fromType instanceof BasicType) {
- String name = fromType.toString() + "Object";
- il.append(
- fact.createInvoke(
- "org.aspectj.runtime.internal.Conversions",
- name,
- Type.OBJECT,
- new Type[] { fromType },
- Constants.INVOKESTATIC));
- return il;
- } else if (fromType instanceof ReferenceType) {
- return il;
- } else {
- throw new RuntimeException();
- }
- }
-
- if (fromType instanceof ReferenceType
- && ((ReferenceType)fromType).isAssignmentCompatibleWith(toType)) {
- return il;
- }
-
- if (allowAutoboxing) {
- if (toType instanceof BasicType && fromType instanceof ReferenceType) {
- // unboxing
- String name = toType.toString() + "Value";
- il.append(
- fact.createInvoke(
- "org.aspectj.runtime.internal.Conversions",
- name,
- toType,
- new Type[] { Type.OBJECT },
- Constants.INVOKESTATIC));
- return il;
- }
-
- if (fromType instanceof BasicType && toType instanceof ReferenceType) {
- // boxing
- String name = fromType.toString() + "Object";
- il.append(
- fact.createInvoke(
- "org.aspectj.runtime.internal.Conversions",
- name,
- Type.OBJECT,
- new Type[] { fromType },
- Constants.INVOKESTATIC));
- il.append(fact.createCast(Type.OBJECT, toType));
- return il;
- }
- }
-
- il.append(fact.createCast(fromType, toType));
- return il;
- }
-
- public static Instruction createConstant(InstructionFactory fact,int value) {
- Instruction inst;
- switch (value) {
- case -1: inst = InstructionConstants.ICONST_M1; break;
- case 0: inst = InstructionConstants.ICONST_0; break;
- case 1: inst = InstructionConstants.ICONST_1; break;
- case 2: inst = InstructionConstants.ICONST_2; break;
- case 3: inst = InstructionConstants.ICONST_3; break;
- case 4: inst = InstructionConstants.ICONST_4; break;
- case 5: inst = InstructionConstants.ICONST_5; break;
- default:
- if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) {
- inst = new InstructionByte(Constants.BIPUSH,(byte)value);
- } else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) {
- inst = new InstructionShort(Constants.SIPUSH,(short)value);
+ public static Instruction createInstanceof(InstructionFactory fact, ReferenceType t) {
+ int cpoolEntry = (t instanceof ArrayType) ? fact.getConstantPool().addArrayClass((ArrayType) t) : fact.getConstantPool()
+ .addClass((ObjectType) t);
+ return new InstructionCP(Constants.INSTANCEOF, cpoolEntry);
+ }
+
+ public static Instruction createInvoke(InstructionFactory fact, LazyMethodGen m) {
+ short kind;
+ if (m.getEnclosingClass().isInterface()) {
+ kind = Constants.INVOKEINTERFACE;
+ } else if (m.isStatic()) {
+ kind = Constants.INVOKESTATIC;
+ } else if (m.isPrivate() || m.getName().equals("<init>")) {
+ kind = Constants.INVOKESPECIAL;
+ } else {
+ kind = Constants.INVOKEVIRTUAL;
+ }
+
+ return fact.createInvoke(m.getClassName(), m.getName(), m.getReturnType(), m.getArgumentTypes(), kind);
+ }
+
+ /**
+ * Create an invoke instruction
+ *
+ * @param fact
+ * @param kind INVOKEINTERFACE, INVOKEVIRTUAL..
+ * @param member
+ * @return
+ */
+ public static Instruction createInvoke(InstructionFactory fact, short kind, Member member) {
+ return fact.createInvoke(member.getDeclaringType().getName(), member.getName(), BcelWorld.makeBcelType(member
+ .getReturnType()), BcelWorld.makeBcelTypes(member.getParameterTypes()), kind);
+ }
+
+ private static String[] argNames = new String[] { "arg0", "arg1", "arg2", "arg3", "arg4" };
+
+ // ??? these should perhaps be cached. Remember to profile this to see if it's a problem.
+ public static String[] makeArgNames(int n) {
+ String[] ret = new String[n];
+ for (int i = 0; i < n; i++) {
+ if (i < 5) {
+ ret[i] = argNames[i];
+ } else {
+ ret[i] = "arg" + i;
+ }
+ }
+ return ret;
+ }
+
+ // Lookup table, for converting between pairs of types, it gives
+ // us the method name in the Conversions class
+ private static Hashtable validBoxing = new Hashtable();
+
+ static {
+ validBoxing.put("Ljava/lang/Byte;B", "byteObject");
+ validBoxing.put("Ljava/lang/Character;C", "charObject");
+ validBoxing.put("Ljava/lang/Double;D", "doubleObject");
+ validBoxing.put("Ljava/lang/Float;F", "floatObject");
+ validBoxing.put("Ljava/lang/Integer;I", "intObject");
+ validBoxing.put("Ljava/lang/Long;J", "longObject");
+ validBoxing.put("Ljava/lang/Short;S", "shortObject");
+ validBoxing.put("Ljava/lang/Boolean;Z", "booleanObject");
+ validBoxing.put("BLjava/lang/Byte;", "byteValue");
+ validBoxing.put("CLjava/lang/Character;", "charValue");
+ validBoxing.put("DLjava/lang/Double;", "doubleValue");
+ validBoxing.put("FLjava/lang/Float;", "floatValue");
+ validBoxing.put("ILjava/lang/Integer;", "intValue");
+ validBoxing.put("JLjava/lang/Long;", "longValue");
+ validBoxing.put("SLjava/lang/Short;", "shortValue");
+ validBoxing.put("ZLjava/lang/Boolean;", "booleanValue");
+ }
+
+ public static void appendConversion(InstructionList il, InstructionFactory fact, ResolvedType fromType, ResolvedType toType) {
+ if (!toType.isConvertableFrom(fromType) && !fromType.isConvertableFrom(toType)) {
+ throw new BCException("can't convert from " + fromType + " to " + toType);
+ }
+ // XXX I'm sure this test can be simpler but my brain hurts and this works
+ if (!toType.getWorld().isInJava5Mode()) {
+ if (toType.needsNoConversionFrom(fromType))
+ return;
+ } else {
+ if (toType.needsNoConversionFrom(fromType) && !(toType.isPrimitiveType() ^ fromType.isPrimitiveType()))
+ return;
+ }
+ if (toType.equals(ResolvedType.VOID)) {
+ // assert fromType.equals(UnresolvedType.OBJECT)
+ il.append(InstructionFactory.createPop(fromType.getSize()));
+ } else if (fromType.equals(ResolvedType.VOID)) {
+ // assert toType.equals(UnresolvedType.OBJECT)
+ il.append(InstructionFactory.createNull(Type.OBJECT));
+ return;
+ } else if (fromType.equals(UnresolvedType.OBJECT)) {
+ Type to = BcelWorld.makeBcelType(toType);
+ if (toType.isPrimitiveType()) {
+ String name = toType.toString() + "Value";
+ il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, to, new Type[] { Type.OBJECT },
+ Constants.INVOKESTATIC));
+ } else {
+ il.append(fact.createCheckCast((ReferenceType) to));
+ }
+ } else if (toType.equals(UnresolvedType.OBJECT)) {
+ // assert fromType.isPrimitive()
+ Type from = BcelWorld.makeBcelType(fromType);
+ String name = fromType.toString() + "Object";
+ il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, Type.OBJECT, new Type[] { from },
+ Constants.INVOKESTATIC));
+ } else if (toType.getWorld().isInJava5Mode() && validBoxing.get(toType.getSignature() + fromType.getSignature()) != null) {
+ // XXX could optimize by using any java boxing code that may be just before the call...
+ Type from = BcelWorld.makeBcelType(fromType);
+ Type to = BcelWorld.makeBcelType(toType);
+ String name = (String) validBoxing.get(toType.getSignature() + fromType.getSignature());
+ if (toType.isPrimitiveType()) {
+ il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, to, new Type[] { Type.OBJECT },
+ Constants.INVOKESTATIC));
+ } else {
+ il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, Type.OBJECT, new Type[] { from },
+ Constants.INVOKESTATIC));
+ il.append(fact.createCheckCast((ReferenceType) to));
+ }
+ } else if (fromType.isPrimitiveType()) {
+ // assert toType.isPrimitive()
+ Type from = BcelWorld.makeBcelType(fromType);
+ Type to = BcelWorld.makeBcelType(toType);
+ try {
+ Instruction i = fact.createCast(from, to);
+ if (i != null) {
+ il.append(i);
} else {
- int ii = fact.getClassGen().getConstantPool().addInteger(value);
- inst = new InstructionCP(value<=Constants.MAX_BYTE?Constants.LDC:Constants.LDC_W,ii);
+ il.append(fact.createCast(from, Type.INT));
+ il.append(fact.createCast(Type.INT, to));
}
- break;
+ } catch (RuntimeException e) {
+ il.append(fact.createCast(from, Type.INT));
+ il.append(fact.createCast(Type.INT, to));
+ }
+ } else {
+ Type to = BcelWorld.makeBcelType(toType);
+ // assert ! fromType.isPrimitive() && ! toType.isPrimitive()
+ il.append(fact.createCheckCast((ReferenceType) to));
+ }
+ }
+
+ public static InstructionList createConversion(InstructionFactory factory, Type fromType, Type toType) {
+ return createConversion(factory, fromType, toType, false);
+ }
+
+ public static InstructionList createConversion(InstructionFactory fact, Type fromType, Type toType, boolean allowAutoboxing) {
+ // System.out.println("cast to: " + toType);
+
+ InstructionList il = new InstructionList();
+
+ // PR71273
+ if ((fromType.equals(Type.BYTE) || fromType.equals(Type.CHAR) || fromType.equals(Type.SHORT)) && (toType.equals(Type.INT))) {
+ return il;
+ }
+
+ if (fromType.equals(toType))
+ return il;
+ if (toType.equals(Type.VOID)) {
+ il.append(InstructionFactory.createPop(fromType.getSize()));
+ return il;
+ }
+
+ if (fromType.equals(Type.VOID)) {
+ if (toType instanceof BasicType)
+ throw new BCException("attempting to cast from void to basic type");
+ il.append(InstructionFactory.createNull(Type.OBJECT));
+ return il;
+ }
+
+ if (fromType.equals(Type.OBJECT)) {
+ if (toType instanceof BasicType) {
+ String name = toType.toString() + "Value";
+ il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, toType, new Type[] { Type.OBJECT },
+ Constants.INVOKESTATIC));
+ return il;
+ }
+ }
+
+ if (toType.equals(Type.OBJECT)) {
+ if (fromType instanceof BasicType) {
+ String name = fromType.toString() + "Object";
+ il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, Type.OBJECT, new Type[] { fromType },
+ Constants.INVOKESTATIC));
+ return il;
+ } else if (fromType instanceof ReferenceType) {
+ return il;
+ } else {
+ throw new RuntimeException();
+ }
+ }
+
+ if (fromType instanceof ReferenceType && ((ReferenceType) fromType).isAssignmentCompatibleWith(toType)) {
+ return il;
+ }
+
+ if (allowAutoboxing) {
+ if (toType instanceof BasicType && fromType instanceof ReferenceType) {
+ // unboxing
+ String name = toType.toString() + "Value";
+ il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, toType, new Type[] { Type.OBJECT },
+ Constants.INVOKESTATIC));
+ return il;
+ }
+
+ if (fromType instanceof BasicType && toType instanceof ReferenceType) {
+ // boxing
+ String name = fromType.toString() + "Object";
+ il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, Type.OBJECT, new Type[] { fromType },
+ Constants.INVOKESTATIC));
+ il.append(fact.createCast(Type.OBJECT, toType));
+ return il;
+ }
+ }
+
+ il.append(fact.createCast(fromType, toType));
+ return il;
+ }
+
+ public static Instruction createConstant(InstructionFactory fact, int value) {
+ Instruction inst;
+ switch (value) {
+ case -1:
+ inst = InstructionConstants.ICONST_M1;
+ break;
+ case 0:
+ inst = InstructionConstants.ICONST_0;
+ break;
+ case 1:
+ inst = InstructionConstants.ICONST_1;
+ break;
+ case 2:
+ inst = InstructionConstants.ICONST_2;
+ break;
+ case 3:
+ inst = InstructionConstants.ICONST_3;
+ break;
+ case 4:
+ inst = InstructionConstants.ICONST_4;
+ break;
+ case 5:
+ inst = InstructionConstants.ICONST_5;
+ break;
+ default:
+ if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) {
+ inst = new InstructionByte(Constants.BIPUSH, (byte) value);
+ } else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) {
+ inst = new InstructionShort(Constants.SIPUSH, (short) value);
+ } else {
+ int ii = fact.getClassGen().getConstantPool().addInteger(value);
+ inst = new InstructionCP(value <= Constants.MAX_BYTE ? Constants.LDC : Constants.LDC_W, ii);
+ }
+ break;
}
return inst;
}
-
+
/** For testing purposes: bit clunky but does work */
- public static int testingParseCounter=0;
+ public static int testingParseCounter = 0;
public static JavaClass makeJavaClass(String filename, byte[] bytes) {
try {
testingParseCounter++;
- ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), filename);
- return parser.parse();
+ ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), filename);
+ return parser.parse();
} catch (IOException e) {
throw new BCException("malformed class file");
- }
- }
-
- public static String arrayToString(int[] a) {
- int len = a.length;
- if (len == 0) return "[]";
- StringBuffer buf = new StringBuffer("[");
- buf.append(a[0]);
- for (int i = 1; i < len; i++) {
- buf.append(", ");
- buf.append(a[i]);
- }
- buf.append("]");
- return buf.toString();
- }
+ }
+ }
+
+ public static String arrayToString(int[] a) {
+ int len = a.length;
+ if (len == 0)
+ return "[]";
+ StringBuffer buf = new StringBuffer("[");
+ buf.append(a[0]);
+ for (int i = 1; i < len; i++) {
+ buf.append(", ");
+ buf.append(a[i]);
+ }
+ buf.append("]");
+ return buf.toString();
+ }
/**
* replace an instruction handle with another instruction, in this case, a branch instruction.
@@ -561,134 +482,121 @@ public class Utility {
* @param branchInstruction the branch instruction to replace ih with
* @param enclosingMethod where to find ih's instruction list.
*/
- public static void replaceInstruction(
- InstructionHandle ih,
- InstructionList replacementInstructions,
- LazyMethodGen enclosingMethod) {
- InstructionList il = enclosingMethod.getBody();
- InstructionHandle fresh = il.append(ih, replacementInstructions);
- deleteInstruction(ih,fresh,enclosingMethod);
- }
-
- /** delete an instruction handle and retarget all targeters of the deleted instruction
- * to the next instruction. Obviously, this should not be used to delete
- * a control transfer instruction unless you know what you're doing.
+ public static void replaceInstruction(InstructionHandle ih, InstructionList replacementInstructions,
+ LazyMethodGen enclosingMethod) {
+ InstructionList il = enclosingMethod.getBody();
+ InstructionHandle fresh = il.append(ih, replacementInstructions);
+ deleteInstruction(ih, fresh, enclosingMethod);
+ }
+
+ /**
+ * delete an instruction handle and retarget all targeters of the deleted instruction to the next instruction. Obviously, this
+ * should not be used to delete a control transfer instruction unless you know what you're doing.
*
* @param ih the instruction handle to delete.
* @param enclosingMethod where to find ih's instruction list.
*/
- public static void deleteInstruction(
- InstructionHandle ih,
- LazyMethodGen enclosingMethod)
- {
- deleteInstruction(ih, ih.getNext(), enclosingMethod);
- }
-
-
- /** delete an instruction handle and retarget all targeters of the deleted instruction
- * to the provided target.
+ public static void deleteInstruction(InstructionHandle ih, LazyMethodGen enclosingMethod) {
+ deleteInstruction(ih, ih.getNext(), enclosingMethod);
+ }
+
+ /**
+ * delete an instruction handle and retarget all targeters of the deleted instruction to the provided target.
*
* @param ih the instruction handle to delete
* @param retargetTo the instruction handle to retarget targeters of ih to.
* @param enclosingMethod where to find ih's instruction list.
*/
- public static void deleteInstruction(
- InstructionHandle ih,
- InstructionHandle retargetTo,
- LazyMethodGen enclosingMethod)
- {
- InstructionList il = enclosingMethod.getBody();
- InstructionTargeter[] targeters = ih.getTargetersArray();
- if (targeters != null) {
- for (int i = targeters.length - 1; i >= 0; i--) {
- InstructionTargeter targeter = targeters[i];
- targeter.updateTarget(ih, retargetTo);
- }
- ih.removeAllTargeters();
- }
- try {
- il.delete(ih);
- } catch (TargetLostException e) {
- throw new BCException("this really can't happen");
- }
- }
-
- /**
- * Fix for Bugzilla #39479, #40109 patch contributed by Andy Clement
- *
- * Need to manually copy Select instructions - if we rely on the the 'fresh' object
- * created by copy(), the InstructionHandle array 'targets' inside the Select
- * object will not have been deep copied, so modifying targets in fresh will modify
- * the original Select - not what we want ! (It is a bug in BCEL to do with cloning
- * Select objects).
- *
- * <pre>
- * declare error:
- * call(* Instruction.copy()) && within(org.aspectj.weaver)
- * && !withincode(* Utility.copyInstruction(Instruction)):
- * "use Utility.copyInstruction to work-around bug in Select.copy()";
- * </pre>
- */
+ public static void deleteInstruction(InstructionHandle ih, InstructionHandle retargetTo, LazyMethodGen enclosingMethod) {
+ InstructionList il = enclosingMethod.getBody();
+ InstructionTargeter[] targeters = ih.getTargetersArray();
+ if (targeters != null) {
+ for (int i = targeters.length - 1; i >= 0; i--) {
+ InstructionTargeter targeter = targeters[i];
+ targeter.updateTarget(ih, retargetTo);
+ }
+ ih.removeAllTargeters();
+ }
+ try {
+ il.delete(ih);
+ } catch (TargetLostException e) {
+ throw new BCException("this really can't happen");
+ }
+ }
+
+ /**
+ * Fix for Bugzilla #39479, #40109 patch contributed by Andy Clement
+ *
+ * Need to manually copy Select instructions - if we rely on the the 'fresh' object created by copy(), the InstructionHandle
+ * array 'targets' inside the Select object will not have been deep copied, so modifying targets in fresh will modify the
+ * original Select - not what we want ! (It is a bug in BCEL to do with cloning Select objects).
+ *
+ * <pre>
+ * declare error:
+ * call(* Instruction.copy()) &amp;&amp; within(org.aspectj.weaver)
+ * &amp;&amp; !withincode(* Utility.copyInstruction(Instruction)):
+ * &quot;use Utility.copyInstruction to work-around bug in Select.copy()&quot;;
+ * </pre>
+ */
public static Instruction copyInstruction(Instruction i) {
if (i instanceof InstructionSelect) {
- InstructionSelect freshSelect = (InstructionSelect)i;
-
+ InstructionSelect freshSelect = (InstructionSelect) i;
+
// Create a new targets array that looks just like the existing one
InstructionHandle[] targets = new InstructionHandle[freshSelect.getTargets().length];
for (int ii = 0; ii < targets.length; ii++) {
- targets[ii] = freshSelect.getTargets()[ii];
+ targets[ii] = freshSelect.getTargets()[ii];
}
-
+
// Create a new select statement with the new targets array
-
- return new SwitchBuilder(freshSelect.getMatchs(), targets, freshSelect.getTarget()).getInstruction();
+
+ return new SwitchBuilder(freshSelect.getMatchs(), targets, freshSelect.getTarget()).getInstruction();
} else {
return i.copy(); // Use clone for shallow copy...
}
}
-
/** returns -1 if no source line attribute */
// this naive version overruns the JVM stack size, if only Java understood tail recursion...
-// public static int getSourceLine(InstructionHandle ih) {
-// if (ih == null) return -1;
-//
-// InstructionTargeter[] ts = ih.getTargeters();
-// if (ts != null) {
-// for (int j = ts.length - 1; j >= 0; j--) {
-// InstructionTargeter t = ts[j];
-// if (t instanceof LineNumberTag) {
-// return ((LineNumberTag)t).getLineNumber();
-// }
-// }
-// }
-// return getSourceLine(ih.getNext());
-// }
-
- public static int getSourceLine(InstructionHandle ih) {//,boolean goforwards) {
- int lookahead=0;
+ // public static int getSourceLine(InstructionHandle ih) {
+ // if (ih == null) return -1;
+ //
+ // InstructionTargeter[] ts = ih.getTargeters();
+ // if (ts != null) {
+ // for (int j = ts.length - 1; j >= 0; j--) {
+ // InstructionTargeter t = ts[j];
+ // if (t instanceof LineNumberTag) {
+ // return ((LineNumberTag)t).getLineNumber();
+ // }
+ // }
+ // }
+ // return getSourceLine(ih.getNext());
+ // }
+ public static int getSourceLine(InstructionHandle ih) {// ,boolean goforwards) {
+ int lookahead = 0;
// arbitrary rule that we will never lookahead more than 100 instructions for a line #
while (lookahead++ < 100) {
- if (ih == null) return -1;
+ if (ih == null)
+ return -1;
Iterator tIter = ih.getTargeters().iterator();
while (tIter.hasNext()) {
- InstructionTargeter t = (InstructionTargeter)tIter.next();
- if (t instanceof LineNumberTag) {
- return ((LineNumberTag)t).getLineNumber();
- }
- }
-// if (goforwards) ih=ih.getNext(); else
- ih=ih.getPrev();
- }
- //System.err.println("no line information available for: " + ih);
- return -1;
- }
-
-// public static int getSourceLine(InstructionHandle ih) {
-// return getSourceLine(ih,false);
-// }
-
- // assumes that there is no already extant source line tag. Otherwise we'll have to be better.
+ InstructionTargeter t = (InstructionTargeter) tIter.next();
+ if (t instanceof LineNumberTag) {
+ return ((LineNumberTag) t).getLineNumber();
+ }
+ }
+ // if (goforwards) ih=ih.getNext(); else
+ ih = ih.getPrev();
+ }
+ // System.err.println("no line information available for: " + ih);
+ return -1;
+ }
+
+ // public static int getSourceLine(InstructionHandle ih) {
+ // return getSourceLine(ih,false);
+ // }
+
+ // assumes that there is no already extant source line tag. Otherwise we'll have to be better.
public static void setSourceLine(InstructionHandle ih, int lineNumber) {
// OPTIMIZE LineNumberTag instances for the same line could be shared throughout a method...
ih.addTargeter(new LineNumberTag(lineNumber));
@@ -697,15 +605,9 @@ public class Utility {
public static int makePublic(int i) {
return i & ~(Modifier.PROTECTED | Modifier.PRIVATE) | Modifier.PUBLIC;
}
- public static int makePrivate(int i) {
- return i & ~(Modifier.PROTECTED | Modifier.PUBLIC) | Modifier.PRIVATE;
- }
- public static BcelVar[] pushAndReturnArrayOfVars(
- ResolvedType[] proceedParamTypes,
- InstructionList il,
- InstructionFactory fact,
- LazyMethodGen enclosingMethod)
- {
+
+ public static BcelVar[] pushAndReturnArrayOfVars(ResolvedType[] proceedParamTypes, InstructionList il, InstructionFactory fact,
+ LazyMethodGen enclosingMethod) {
int len = proceedParamTypes.length;
BcelVar[] ret = new BcelVar[len];
@@ -713,126 +615,129 @@ public class Utility {
ResolvedType typeX = proceedParamTypes[i];
Type type = BcelWorld.makeBcelType(typeX);
int local = enclosingMethod.allocateLocal(type);
-
+
il.append(InstructionFactory.createStore(type, local));
ret[i] = new BcelVar(typeX, local);
- }
+ }
return ret;
}
public static boolean isConstantPushInstruction(Instruction i) {
- long ii= Constants.instFlags[i.opcode];
- return ((ii&Constants.PUSH_INST)!=0 && (ii&Constants.CONSTANT_INST)!=0);
+ long ii = Constants.instFlags[i.opcode];
+ return ((ii & Constants.PUSH_INST) != 0 && (ii & Constants.CONSTANT_INST) != 0);
}
-
+
/**
* Checks for suppression specified on the member or on the declaring type of that member
*/
- public static boolean isSuppressing(Member member,String lintkey) {
+ public static boolean isSuppressing(Member member, String lintkey) {
boolean isSuppressing = Utility.isSuppressing(member.getAnnotations(), lintkey);
- if (isSuppressing) return true;
+ if (isSuppressing)
+ return true;
UnresolvedType type = member.getDeclaringType();
if (type instanceof ResolvedType) {
- return Utility.isSuppressing(((ResolvedType)type).getAnnotations(),lintkey);
+ return Utility.isSuppressing(((ResolvedType) type).getAnnotations(), lintkey);
}
return false;
}
/**
- * Check if the annotations contain a SuppressAjWarnings annotation and
- * if that annotation specifies that the given lint message (identified
- * by its key) should be ignored.
- *
- */
- public static boolean isSuppressing(AnnotationX[] anns,String lintkey) {
- if (anns == null) return false;
- boolean suppressed = false;
- // Go through the annotation types on the advice
- for (int i = 0;!suppressed && i<anns.length;i++) {
- // Check for the SuppressAjWarnings annotation
- if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) {
- // Two possibilities:
- // 1. there are no values specified (i.e. @SuppressAjWarnings)
- // 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
- List vals = anns[i].getBcelAnnotation().getValues();
- if (vals == null || vals.isEmpty()) { // (1)
- suppressed = true;
- } else { // (2)
- // We know the value is an array value
- ArrayElementValueGen array = (ArrayElementValueGen)((ElementNameValuePairGen)vals.get(0)).getValue();
- ElementValueGen[] values = array.getElementValuesArray();
- for (int j = 0; j < values.length; j++) {
- // We know values in the array are strings
- SimpleElementValueGen value = (SimpleElementValueGen)values[j];
- if (value.getValueString().equals(lintkey)) {
- suppressed = true;
+ * Check if the annotations contain a SuppressAjWarnings annotation and if that annotation specifies that the given lint message
+ * (identified by its key) should be ignored.
+ *
+ */
+ public static boolean isSuppressing(AnnotationX[] anns, String lintkey) {
+ if (anns == null)
+ return false;
+ boolean suppressed = false;
+ // Go through the annotation types on the advice
+ for (int i = 0; !suppressed && i < anns.length; i++) {
+ // Check for the SuppressAjWarnings annotation
+ if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) {
+ // Two possibilities:
+ // 1. there are no values specified (i.e. @SuppressAjWarnings)
+ // 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
+ List vals = anns[i].getBcelAnnotation().getValues();
+ if (vals == null || vals.isEmpty()) { // (1)
+ suppressed = true;
+ } else { // (2)
+ // We know the value is an array value
+ ArrayElementValueGen array = (ArrayElementValueGen) ((ElementNameValuePairGen) vals.get(0)).getValue();
+ ElementValueGen[] values = array.getElementValuesArray();
+ for (int j = 0; j < values.length; j++) {
+ // We know values in the array are strings
+ SimpleElementValueGen value = (SimpleElementValueGen) values[j];
+ if (value.getValueString().equals(lintkey)) {
+ suppressed = true;
+ }
}
}
- }
- }
- }
- return suppressed;
- }
-
- public static List/*Lint.Kind*/ getSuppressedWarnings(AnnotationX[] anns, Lint lint) {
- if (anns == null) return Collections.EMPTY_LIST;
- // Go through the annotation types
- List suppressedWarnings = new ArrayList();
- boolean found = false;
- for (int i = 0;!found && i<anns.length;i++) {
- // Check for the SuppressAjWarnings annotation
- if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) {
- found = true;
- // Two possibilities:
- // 1. there are no values specified (i.e. @SuppressAjWarnings)
- // 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
- List vals = anns[i].getBcelAnnotation().getValues();
- if (vals == null || vals.isEmpty()) { // (1)
- suppressedWarnings.addAll(lint.allKinds());
- } else { // (2)
- // We know the value is an array value
- ArrayElementValueGen array = (ArrayElementValueGen)((ElementNameValuePairGen)vals.get(0)).getValue();
- ElementValueGen[] values = array.getElementValuesArray();
- for (int j = 0; j < values.length; j++) {
- // We know values in the array are strings
- SimpleElementValueGen value = (SimpleElementValueGen)values[j];
- Lint.Kind lintKind = lint.getLintKind(value.getValueString());
- if (lintKind != null) suppressedWarnings.add(lintKind);
+ }
+ }
+ return suppressed;
+ }
+
+ public static List/* Lint.Kind */getSuppressedWarnings(AnnotationX[] anns, Lint lint) {
+ if (anns == null)
+ return Collections.EMPTY_LIST;
+ // Go through the annotation types
+ List suppressedWarnings = new ArrayList();
+ boolean found = false;
+ for (int i = 0; !found && i < anns.length; i++) {
+ // Check for the SuppressAjWarnings annotation
+ if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) {
+ found = true;
+ // Two possibilities:
+ // 1. there are no values specified (i.e. @SuppressAjWarnings)
+ // 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"})
+ List vals = anns[i].getBcelAnnotation().getValues();
+ if (vals == null || vals.isEmpty()) { // (1)
+ suppressedWarnings.addAll(lint.allKinds());
+ } else { // (2)
+ // We know the value is an array value
+ ArrayElementValueGen array = (ArrayElementValueGen) ((ElementNameValuePairGen) vals.get(0)).getValue();
+ ElementValueGen[] values = array.getElementValuesArray();
+ for (int j = 0; j < values.length; j++) {
+ // We know values in the array are strings
+ SimpleElementValueGen value = (SimpleElementValueGen) values[j];
+ Lint.Kind lintKind = lint.getLintKind(value.getValueString());
+ if (lintKind != null)
+ suppressedWarnings.add(lintKind);
+ }
}
- }
- }
- }
- return suppressedWarnings;
- }
-
- // not yet used...
-// public static boolean isSimple(Method method) {
-// if (method.getCode()==null) return true;
-// if (method.getCode().getCode().length>10) return false;
-// InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive!
-// InstructionHandle InstrHandle = instrucs.getStart();
-// while (InstrHandle != null) {
-// Instruction Instr = InstrHandle.getInstruction();
-// int opCode = Instr.opcode;
-// // if current instruction is a branch instruction, see if it's a backward branch.
-// // if it is return immediately (can't be trivial)
-// if (Instr instanceof InstructionBranch) {
-// // InstructionBranch BI = (InstructionBranch) Instr;
-// if (Instr.getIndex() < 0) return false;
-// } else if (Instr instanceof InvokeInstruction) {
-// // if current instruction is an invocation, indicate that it can't be trivial
-// return false;
-// }
-// InstrHandle = InstrHandle.getNext();
-// }
-// return true;
-// }
+ }
+ }
+ return suppressedWarnings;
+ }
+
+ // not yet used...
+ // public static boolean isSimple(Method method) {
+ // if (method.getCode()==null) return true;
+ // if (method.getCode().getCode().length>10) return false;
+ // InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive!
+ // InstructionHandle InstrHandle = instrucs.getStart();
+ // while (InstrHandle != null) {
+ // Instruction Instr = InstrHandle.getInstruction();
+ // int opCode = Instr.opcode;
+ // // if current instruction is a branch instruction, see if it's a backward branch.
+ // // if it is return immediately (can't be trivial)
+ // if (Instr instanceof InstructionBranch) {
+ // // InstructionBranch BI = (InstructionBranch) Instr;
+ // if (Instr.getIndex() < 0) return false;
+ // } else if (Instr instanceof InvokeInstruction) {
+ // // if current instruction is an invocation, indicate that it can't be trivial
+ // return false;
+ // }
+ // InstrHandle = InstrHandle.getNext();
+ // }
+ // return true;
+ // }
public static Attribute bcelAttribute(AjAttribute a, ConstantPool pool) {
int nameIndex = pool.addUtf8(a.getNameString());
byte[] bytes = a.getBytes();
int length = bytes.length;
-
+
return new Unknown(nameIndex, length, bytes, pool);
}
} \ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/patterns/FormalBinding.java b/weaver/src/org/aspectj/weaver/patterns/FormalBinding.java
index 201b8a534..73693f07c 100644
--- a/weaver/src/org/aspectj/weaver/patterns/FormalBinding.java
+++ b/weaver/src/org/aspectj/weaver/patterns/FormalBinding.java
@@ -10,7 +10,6 @@
* PARC initial implementation
* ******************************************************************/
-
package org.aspectj.weaver.patterns;
import org.aspectj.weaver.IHasPosition;
@@ -18,37 +17,31 @@ import org.aspectj.weaver.UnresolvedType;
public class FormalBinding implements IHasPosition {
private final UnresolvedType type;
- private final String name;
+ private final String name;
private final int index;
private final int start, end;
- private final String fileName;
-
- public FormalBinding(UnresolvedType type, String name, int index, int start, int end, String fileName) {
+
+ public FormalBinding(UnresolvedType type, String name, int index, int start, int end) {
this.type = type;
- this.name = name;
+ this.name = name;
this.index = index;
this.start = start;
this.end = end;
- this.fileName = fileName;
}
-
- public FormalBinding(UnresolvedType type, int index) {
- this(type, "unknown", index, 0, 0, "unknown");
- }
-
- public FormalBinding(UnresolvedType type, String name, int index) {
- this(type, name, index, 0, 0, "unknown");
- }
-
- // ----
-
+
+ public FormalBinding(UnresolvedType type, int index) {
+ this(type, "unknown", index, 0, 0);
+ }
+
+ public FormalBinding(UnresolvedType type, String name, int index) {
+ this(type, name, index, 0, 0);
+ }
+
+ // ----
+
public String toString() {
return type.toString() + ":" + index;
}
-
- public String getFileName() {
- return fileName;
- }
public int getEnd() {
return end;
@@ -58,32 +51,32 @@ public class FormalBinding implements IHasPosition {
return start;
}
- public int getIndex() {
- return index;
- }
-
- public String getName() {
- return name;
- }
-
- public UnresolvedType getType() {
- return type;
- }
-
- // ----
-
- public static final FormalBinding[] NONE = new FormalBinding[0];
-
- /**
- * A marker class for bindings for which we want to ignore unbound issue and consider
- * them as implicit binding - f.e. to handle JoinPoint in @AJ advices
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
- public static class ImplicitFormalBinding extends FormalBinding {
- public ImplicitFormalBinding(UnresolvedType type, String name, int index) {
- super(type, name, index);
- }
- }
+ public int getIndex() {
+ return index;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public UnresolvedType getType() {
+ return type;
+ }
+
+ // ----
+
+ public static final FormalBinding[] NONE = new FormalBinding[0];
+
+ /**
+ * A marker class for bindings for which we want to ignore unbound issue and consider them as implicit binding - f.e. to handle
+ * JoinPoint in @AJ advices
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+ public static class ImplicitFormalBinding extends FormalBinding {
+ public ImplicitFormalBinding(UnresolvedType type, String name, int index) {
+ super(type, name, index);
+ }
+ }
}
diff --git a/weaver/testsrc/org/aspectj/weaver/TestUtils.java b/weaver/testsrc/org/aspectj/weaver/TestUtils.java
index ca3bb4e6c..9be8f50bb 100644
--- a/weaver/testsrc/org/aspectj/weaver/TestUtils.java
+++ b/weaver/testsrc/org/aspectj/weaver/TestUtils.java
@@ -20,326 +20,330 @@ import org.aspectj.weaver.patterns.FormalBinding;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.SimpleScope;
-
public class TestUtils {
- private static final String[] ZERO_STRINGS = new String[0];
+ private static final String[] ZERO_STRINGS = new String[0];
+
+ // For stringifying a delegate - extracted from AbstractReferenceTypeDelegate, not fixed up
+ // /**
+ // * Create the string representation for a delegate, allowing us to
+ // * more easily compare delegate implementations.
+ // */
+ // public String stringifyDelegate() {
+ //
+ // StringBuffer result = new StringBuffer();
+ // result.append("=== Delegate for "+getResolvedTypeX().getName()+"\n");
+ //
+ // result.append("isAspect?"+isAspect()+"\n");
+ // result.append("isAnnotationStyleAspect?"+isAnnotationStyleAspect()+"\n");
+ // result.append("isInterface?"+isInterface()+"\n");
+ // result.append("isEnum?"+isEnum()+"\n");
+ // result.append("isClass?"+isClass()+"\n");
+ // result.append("-\n");
+ // result.append("isAnnotation?"+isAnnotation()+"\n");
+ // result.append("retentionPolicy="+getRetentionPolicy()+"\n");
+ // result.append("canAnnotationTargetType?"+canAnnotationTargetType()+"\n");
+ // AnnotationTargetKind[] kinds = getAnnotationTargetKinds();
+ // if (kinds!=null && kinds.length>0) {
+ // result.append("annotationTargetKinds:[");
+ // for (int i = 0; i < kinds.length; i++) {
+ // AnnotationTargetKind kind = kinds[i];
+ // result.append(kind);
+ // if ((i+1)<kinds.length) result.append(" ");
+ // }
+ // result.append("]\n");
+ // }
+ // result.append("isAnnotationWithRuntimeRetention?"+isAnnotationWithRuntimeRetention()+"\n");
+ // result.append("-\n");
+ //
+ // result.append("isAnonymous?"+isAnonymous()+"\n");
+ // result.append("isNested?"+isNested()+"\n");
+ // result.append("-\n");
+ //
+ // result.append("isGeneric?"+isGeneric()+"\n");
+ // result.append("declaredGenericSignature="+getDeclaredGenericSignature()+"\n");
+ // result.append("-\n");
+ //
+ // AnnotationX[] axs = getAnnotations();
+ // if (axs!=null && axs.length>0) {
+ // result.append("getAnnotations() returns: "+axs.length+" annotations\n");
+ // for (int i = 0; i < axs.length; i++) {
+ // AnnotationX annotationX = axs[i];
+ // result.append(" #"+i+") "+annotationX+"\n");
+ // }
+ // } else {
+ // result.append("getAnnotations() returns nothing\n");
+ // }
+ // ResolvedType[] axtypes = getAnnotationTypes();
+ // if (axtypes!=null && axtypes.length>0) {
+ // result.append("getAnnotationTypes() returns: "+axtypes.length+" annotations\n");
+ // for (int i = 0; i < axtypes.length; i++) {
+ // ResolvedType annotation = axtypes[i];
+ // result.append(" #"+i+") "+annotation+":"+annotation.getClass()+"\n");
+ // }
+ // } else {
+ // result.append("getAnnotationTypes() returns nothing\n");
+ // }
+ //
+ // result.append("isExposedToWeaver?"+isExposedToWeaver()+"\n");
+ // result.append("getSuperclass?"+getSuperclass()+"\n");
+ // result.append("getResolvedTypeX?"+getResolvedTypeX()+"\n");
+ // result.append("--\n");
+ //
+ // ResolvedMember[] fields = getDeclaredFields();
+ // if (fields!=null && fields.length>0) {
+ // result.append("The fields: "+fields.length+"\n");
+ // for (int i = 0; i < fields.length; i++) {
+ // ResolvedMember member = fields[i];
+ // result.append("f"+i+") "+member.toDebugString()+"\n");
+ // }
+ // }
+ // ResolvedMember[] methods = getDeclaredMethods();
+ // if (methods!=null && methods.length>0) {
+ // result.append("The methods: "+methods.length+"\n");
+ // for (int i = 0; i < methods.length; i++) {
+ // ResolvedMember member = methods[i];
+ // result.append("m"+i+") "+member.toDebugString()+"\n");
+ // }
+ // }
+ // ResolvedType[] interfaces = getDeclaredInterfaces();
+ // if (interfaces!=null && interfaces.length>0) {
+ // result.append("The interfaces: "+interfaces.length+"\n");
+ // for (int i = 0; i < interfaces.length; i++) {
+ // ResolvedType member = interfaces[i];
+ // result.append("i"+i+") "+member+"\n");
+ // }
+ // }
+ //
+ // result.append("getModifiers?"+getModifiers()+"\n");
+ //
+ // result.append("perclause="+getPerClause()+"\n");
+ //
+ // result.append("aj:weaverstate="+getWeaverState()+"\n");
+ //
+ // ResolvedMember[] pointcuts = getDeclaredPointcuts();
+ // if (pointcuts!=null && pointcuts.length>0) {
+ // result.append("The pointcuts: "+pointcuts.length+"\n");
+ //
+ // // Sort the damn things
+ // List sortedSetOfPointcuts = new ArrayList();
+ // for (int i = 0; i < pointcuts.length; i++) {sortedSetOfPointcuts.add(pointcuts[i]);}
+ // Collections.sort(sortedSetOfPointcuts);
+ //
+ // int i =0;
+ // for (Iterator iter = sortedSetOfPointcuts.iterator(); iter.hasNext();) {
+ // ResolvedMember member = (ResolvedMember) iter.next();
+ // result.append("p"+i+") "+member.toDebugString()+"\n");
+ // i++;
+ // }
+ // }
+ //
+ // Collection declares = getDeclares();
+ // if (declares.size()>0) {
+ // result.append("The declares: "+declares.size()+"\n");
+ //
+ // // // Sort the damn things
+ // // List sortedSetOfPointcuts = new ArrayList();
+ // // for (int i = 0; i < pointcuts.length; i++) {sortedSetOfPointcuts.add(pointcuts[i]);}
+ // // Collections.sort(sortedSetOfPointcuts);
+ //
+ // int i=0;
+ // for (Iterator iter = declares.iterator(); iter.hasNext();) {
+ // Declare dec = (Declare) iter.next();
+ // result.append("d"+i+") "+dec.toString()+"\n");
+ // i++;
+ // }
+ // }
+ //
+ // TypeVariable[] tv = getTypeVariables();
+ // if (tv!=null && tv.length>0) {
+ // result.append("The type variables: "+tv.length+"\n");
+ // for (int i = 0; i < tv.length; i++) {
+ // result.append("tv"+i+") "+tv[i]+"\n");
+ // }
+ // }
+ //
+ // Collection tmungers = getTypeMungers();
+ // if (tmungers.size()>0) {
+ // List sorted = new ArrayList();
+ // sorted.addAll(tmungers);
+ // Collections.sort(sorted,new Comparator() {
+ // public int compare(Object arg0, Object arg1) {
+ // return arg0.toString().compareTo(arg1.toString());
+ // }
+ // });
+ // result.append("The type mungers: "+tmungers.size()+"\n");
+ // int i=0;
+ // for (Iterator iter = sorted.iterator(); iter.hasNext();) {
+ // ConcreteTypeMunger mun = (ConcreteTypeMunger) iter.next();
+ // result.append("tm"+i+") "+mun.toString()+"\n");
+ // i++;
+ // }
+ // }
+ //
+ // result.append("doesNotExposeShadowMungers?"+doesNotExposeShadowMungers()+"\n");
+ //
+ // Collection pas = getPrivilegedAccesses();
+ // if (pas!=null && pas.size()>0) {
+ // // List sorted = new ArrayList();
+ // // sorted.addAll(tmungers);
+ // // Collections.sort(sorted,new Comparator() {
+ // // public int compare(Object arg0, Object arg1) {
+ // // return arg0.toString().compareTo(arg1.toString());
+ // // }
+ // // });
+ // result.append("The privileged accesses: "+pas.size()+"\n");
+ // int i=0;
+ // for (Iterator iter = pas.iterator(); iter.hasNext();) {
+ // ResolvedMember mun = (ResolvedMember) iter.next();
+ // result.append("tm"+i+") "+mun.toDebugString()+"\n");
+ // i++;
+ // }
+ // }
+ //
+ // // public Collection getPrivilegedAccesses();
+ // // public boolean hasAnnotation(UnresolvedType ofType);
+ // result.append("===");
+ // return result.toString();
+ // }
+
+ /**
+ * Build a member from a string representation: <blockquote>
+ *
+ * <pre>
+ * static? TypeName TypeName.Id
+ * </pre>
+ *
+ * </blockquote>
+ */
+ public static MemberImpl fieldFromString(String str) {
+ str = str.trim();
+ final int len = str.length();
+ int i = 0;
+ int mods = 0;
+ if (str.startsWith("static", i)) {
+ mods = Modifier.STATIC;
+ i += 6;
+ while (Character.isWhitespace(str.charAt(i)))
+ i++;
+ }
+ int start = i;
+ while (!Character.isWhitespace(str.charAt(i)))
+ i++;
+ UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i));
+
+ start = i;
+ i = str.lastIndexOf('.');
+ UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
+ start = ++i;
+ String name = str.substring(start, len).trim();
+ return new MemberImpl(Member.FIELD, declaringTy, mods, retTy, name, UnresolvedType.NONE);
+ }
+
+ /**
+ * Build a member from a string representation: <blockquote>
+ *
+ * <pre>
+ * (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
+ * </pre>
+ *
+ * </blockquote>
+ */
+
+ public static Member methodFromString(String str) {
+ str = str.trim();
+ // final int len = str.length();
+ int i = 0;
+
+ int mods = 0;
+ if (str.startsWith("static", i)) {
+ mods = Modifier.STATIC;
+ i += 6;
+ } else if (str.startsWith("interface", i)) {
+ mods = Modifier.INTERFACE;
+ i += 9;
+ } else if (str.startsWith("private", i)) {
+ mods = Modifier.PRIVATE;
+ i += 7;
+ }
+ while (Character.isWhitespace(str.charAt(i)))
+ i++;
- // For stringifying a delegate - extracted from AbstractReferenceTypeDelegate, not fixed up
-// /**
-// * Create the string representation for a delegate, allowing us to
-// * more easily compare delegate implementations.
-// */
-// public String stringifyDelegate() {
-//
-// StringBuffer result = new StringBuffer();
-// result.append("=== Delegate for "+getResolvedTypeX().getName()+"\n");
-//
-// result.append("isAspect?"+isAspect()+"\n");
-// result.append("isAnnotationStyleAspect?"+isAnnotationStyleAspect()+"\n");
-// result.append("isInterface?"+isInterface()+"\n");
-// result.append("isEnum?"+isEnum()+"\n");
-// result.append("isClass?"+isClass()+"\n");
-// result.append("-\n");
-// result.append("isAnnotation?"+isAnnotation()+"\n");
-// result.append("retentionPolicy="+getRetentionPolicy()+"\n");
-// result.append("canAnnotationTargetType?"+canAnnotationTargetType()+"\n");
-// AnnotationTargetKind[] kinds = getAnnotationTargetKinds();
-// if (kinds!=null && kinds.length>0) {
-// result.append("annotationTargetKinds:[");
-// for (int i = 0; i < kinds.length; i++) {
-// AnnotationTargetKind kind = kinds[i];
-// result.append(kind);
-// if ((i+1)<kinds.length) result.append(" ");
-// }
-// result.append("]\n");
-// }
-// result.append("isAnnotationWithRuntimeRetention?"+isAnnotationWithRuntimeRetention()+"\n");
-// result.append("-\n");
-//
-// result.append("isAnonymous?"+isAnonymous()+"\n");
-// result.append("isNested?"+isNested()+"\n");
-// result.append("-\n");
-//
-// result.append("isGeneric?"+isGeneric()+"\n");
-// result.append("declaredGenericSignature="+getDeclaredGenericSignature()+"\n");
-// result.append("-\n");
-//
-// AnnotationX[] axs = getAnnotations();
-// if (axs!=null && axs.length>0) {
-// result.append("getAnnotations() returns: "+axs.length+" annotations\n");
-// for (int i = 0; i < axs.length; i++) {
-// AnnotationX annotationX = axs[i];
-// result.append(" #"+i+") "+annotationX+"\n");
-// }
-// } else {
-// result.append("getAnnotations() returns nothing\n");
-// }
-// ResolvedType[] axtypes = getAnnotationTypes();
-// if (axtypes!=null && axtypes.length>0) {
-// result.append("getAnnotationTypes() returns: "+axtypes.length+" annotations\n");
-// for (int i = 0; i < axtypes.length; i++) {
-// ResolvedType annotation = axtypes[i];
-// result.append(" #"+i+") "+annotation+":"+annotation.getClass()+"\n");
-// }
-// } else {
-// result.append("getAnnotationTypes() returns nothing\n");
-// }
-//
-// result.append("isExposedToWeaver?"+isExposedToWeaver()+"\n");
-// result.append("getSuperclass?"+getSuperclass()+"\n");
-// result.append("getResolvedTypeX?"+getResolvedTypeX()+"\n");
-// result.append("--\n");
-//
-// ResolvedMember[] fields = getDeclaredFields();
-// if (fields!=null && fields.length>0) {
-// result.append("The fields: "+fields.length+"\n");
-// for (int i = 0; i < fields.length; i++) {
-// ResolvedMember member = fields[i];
-// result.append("f"+i+") "+member.toDebugString()+"\n");
-// }
-// }
-// ResolvedMember[] methods = getDeclaredMethods();
-// if (methods!=null && methods.length>0) {
-// result.append("The methods: "+methods.length+"\n");
-// for (int i = 0; i < methods.length; i++) {
-// ResolvedMember member = methods[i];
-// result.append("m"+i+") "+member.toDebugString()+"\n");
-// }
-// }
-// ResolvedType[] interfaces = getDeclaredInterfaces();
-// if (interfaces!=null && interfaces.length>0) {
-// result.append("The interfaces: "+interfaces.length+"\n");
-// for (int i = 0; i < interfaces.length; i++) {
-// ResolvedType member = interfaces[i];
-// result.append("i"+i+") "+member+"\n");
-// }
-// }
-//
-// result.append("getModifiers?"+getModifiers()+"\n");
-//
-// result.append("perclause="+getPerClause()+"\n");
-//
-// result.append("aj:weaverstate="+getWeaverState()+"\n");
-//
-// ResolvedMember[] pointcuts = getDeclaredPointcuts();
-// if (pointcuts!=null && pointcuts.length>0) {
-// result.append("The pointcuts: "+pointcuts.length+"\n");
-//
-// // Sort the damn things
-// List sortedSetOfPointcuts = new ArrayList();
-// for (int i = 0; i < pointcuts.length; i++) {sortedSetOfPointcuts.add(pointcuts[i]);}
-// Collections.sort(sortedSetOfPointcuts);
-//
-// int i =0;
-// for (Iterator iter = sortedSetOfPointcuts.iterator(); iter.hasNext();) {
-// ResolvedMember member = (ResolvedMember) iter.next();
-// result.append("p"+i+") "+member.toDebugString()+"\n");
-// i++;
-// }
-// }
-//
-// Collection declares = getDeclares();
-// if (declares.size()>0) {
-// result.append("The declares: "+declares.size()+"\n");
-//
-//// // Sort the damn things
-//// List sortedSetOfPointcuts = new ArrayList();
-//// for (int i = 0; i < pointcuts.length; i++) {sortedSetOfPointcuts.add(pointcuts[i]);}
-//// Collections.sort(sortedSetOfPointcuts);
-//
-// int i=0;
-// for (Iterator iter = declares.iterator(); iter.hasNext();) {
-// Declare dec = (Declare) iter.next();
-// result.append("d"+i+") "+dec.toString()+"\n");
-// i++;
-// }
-// }
-//
-// TypeVariable[] tv = getTypeVariables();
-// if (tv!=null && tv.length>0) {
-// result.append("The type variables: "+tv.length+"\n");
-// for (int i = 0; i < tv.length; i++) {
-// result.append("tv"+i+") "+tv[i]+"\n");
-// }
-// }
-//
-// Collection tmungers = getTypeMungers();
-// if (tmungers.size()>0) {
-// List sorted = new ArrayList();
-// sorted.addAll(tmungers);
-// Collections.sort(sorted,new Comparator() {
-// public int compare(Object arg0, Object arg1) {
-// return arg0.toString().compareTo(arg1.toString());
-// }
-// });
-// result.append("The type mungers: "+tmungers.size()+"\n");
-// int i=0;
-// for (Iterator iter = sorted.iterator(); iter.hasNext();) {
-// ConcreteTypeMunger mun = (ConcreteTypeMunger) iter.next();
-// result.append("tm"+i+") "+mun.toString()+"\n");
-// i++;
-// }
-// }
-//
-// result.append("doesNotExposeShadowMungers?"+doesNotExposeShadowMungers()+"\n");
-//
-// Collection pas = getPrivilegedAccesses();
-// if (pas!=null && pas.size()>0) {
-//// List sorted = new ArrayList();
-//// sorted.addAll(tmungers);
-//// Collections.sort(sorted,new Comparator() {
-//// public int compare(Object arg0, Object arg1) {
-//// return arg0.toString().compareTo(arg1.toString());
-//// }
-//// });
-// result.append("The privileged accesses: "+pas.size()+"\n");
-// int i=0;
-// for (Iterator iter = pas.iterator(); iter.hasNext();) {
-// ResolvedMember mun = (ResolvedMember) iter.next();
-// result.append("tm"+i+") "+mun.toDebugString()+"\n");
-// i++;
-// }
-// }
-//
-//// public Collection getPrivilegedAccesses();
-//// public boolean hasAnnotation(UnresolvedType ofType);
-// result.append("===");
-// return result.toString();
-// }
-
- /**
- * Build a member from a string representation:
- * <blockquote><pre>
- * static? TypeName TypeName.Id
- * </pre></blockquote>
- */
- public static MemberImpl fieldFromString(String str) {
- str = str.trim();
- final int len = str.length();
- int i = 0;
- int mods = 0;
- if (str.startsWith("static", i)) {
- mods = Modifier.STATIC;
- i += 6;
- while (Character.isWhitespace(str.charAt(i))) i++;
- }
- int start = i;
- while (! Character.isWhitespace(str.charAt(i))) i++;
- UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i));
+ int start = i;
+ while (!Character.isWhitespace(str.charAt(i)))
+ i++;
+ UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i));
- start = i;
- i = str.lastIndexOf('.');
- UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
- start = ++i;
- String name = str.substring(start, len).trim();
- return new MemberImpl(
- Member.FIELD,
- declaringTy,
- mods,
- retTy,
- name,
- UnresolvedType.NONE);
- }
+ start = i;
+ i = str.indexOf('(', i);
+ i = str.lastIndexOf('.', i);
+ UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
- /**
- * Build a member from a string representation:
- * <blockquote><pre>
- * (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
- * </pre></blockquote>
- */
-
- public static Member methodFromString(String str) {
- str = str.trim();
- // final int len = str.length();
- int i = 0;
+ start = ++i;
+ i = str.indexOf('(', i);
+ String name = str.substring(start, i).trim();
+ start = ++i;
+ i = str.indexOf(')', i);
- int mods = 0;
- if (str.startsWith("static", i)) {
- mods = Modifier.STATIC;
- i += 6;
- } else if (str.startsWith("interface", i)) {
- mods = Modifier.INTERFACE;
- i += 9;
- } else if (str.startsWith("private", i)) {
- mods = Modifier.PRIVATE;
- i += 7;
- }
- while (Character.isWhitespace(str.charAt(i))) i++;
-
- int start = i;
- while (! Character.isWhitespace(str.charAt(i))) i++;
- UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i));
+ String[] paramTypeNames = parseIds(str.substring(start, i).trim());
- start = i;
- i = str.indexOf('(', i);
- i = str.lastIndexOf('.', i);
- UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
-
- start = ++i;
- i = str.indexOf('(', i);
- String name = str.substring(start, i).trim();
- start = ++i;
- i = str.indexOf(')', i);
-
- String[] paramTypeNames = parseIds(str.substring(start, i).trim());
+ return MemberImpl.method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames));
+ }
- return MemberImpl.method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames));
- }
+ private static String[] parseIds(String str) {
+ if (str.length() == 0)
+ return ZERO_STRINGS;
+ List l = new ArrayList();
+ int start = 0;
+ while (true) {
+ int i = str.indexOf(',', start);
+ if (i == -1) {
+ l.add(str.substring(start).trim());
+ break;
+ }
+ l.add(str.substring(start, i).trim());
+ start = i + 1;
+ }
+ return (String[]) l.toArray(new String[l.size()]);
+ }
- private static String[] parseIds(String str) {
- if (str.length() == 0) return ZERO_STRINGS;
- List l = new ArrayList();
- int start = 0;
- while (true) {
- int i = str.indexOf(',', start);
- if (i == -1) {
- l.add(str.substring(start).trim());
- break;
- }
- l.add(str.substring(start, i).trim());
- start = i+1;
- }
- return (String[]) l.toArray(new String[l.size()]);
- }
+ /**
+ * Moved from BcelWorld to here
+ *
+ * Parse a string into advice.
+ *
+ * <blockquote>
+ *
+ * <pre>
+ * Kind ( Id , ... ) : Pointcut -&gt; MethodSignature
+ * </pre>
+ *
+ * </blockquote>
+ */
+ public static Advice shadowMunger(World w, String str, int extraFlag) {
+ str = str.trim();
+ int start = 0;
+ int i = str.indexOf('(');
+ AdviceKind kind = AdviceKind.stringToKind(str.substring(start, i));
+ start = ++i;
+ i = str.indexOf(')', i);
+ String[] ids = parseIds(str.substring(start, i).trim());
+ // start = ++i;
- /**
- * Moved from BcelWorld to here
- *
- * Parse a string into advice.
- *
- * <blockquote><pre>
- * Kind ( Id , ... ) : Pointcut -> MethodSignature
- * </pre></blockquote>
- */
- public static Advice shadowMunger(World w,String str, int extraFlag) {
- str = str.trim();
- int start = 0;
- int i = str.indexOf('(');
- AdviceKind kind =
- AdviceKind.stringToKind(str.substring(start, i));
- start = ++i;
- i = str.indexOf(')', i);
- String[] ids = parseIds(str.substring(start, i).trim());
- //start = ++i;
-
-
-
- i = str.indexOf(':', i);
- start = ++i;
- i = str.indexOf("->", i);
- Pointcut pointcut = Pointcut.fromString(str.substring(start, i).trim());
- Member m = TestUtils.methodFromString(str.substring(i+2, str.length()).trim());
+ i = str.indexOf(':', i);
+ start = ++i;
+ i = str.indexOf("->", i);
+ Pointcut pointcut = Pointcut.fromString(str.substring(start, i).trim());
+ Member m = TestUtils.methodFromString(str.substring(i + 2, str.length()).trim());
- // now, we resolve
- UnresolvedType[] types = m.getParameterTypes();
- FormalBinding[] bindings = new FormalBinding[ids.length];
- for (int j = 0, len = ids.length; j < len; j++) {
- bindings[j] = new FormalBinding(types[j], ids[j], j, 0, 0, "fromString");
- }
+ // now, we resolve
+ UnresolvedType[] types = m.getParameterTypes();
+ FormalBinding[] bindings = new FormalBinding[ids.length];
+ for (int j = 0, len = ids.length; j < len; j++) {
+ bindings[j] = new FormalBinding(types[j], ids[j], j, 0, 0);
+ }
- Pointcut p =
- pointcut.resolve(new SimpleScope(w, bindings));
+ Pointcut p = pointcut.resolve(new SimpleScope(w, bindings));
- return new BcelAdvice(kind, p, m, extraFlag, 0, 0, null, null);
- }
+ return new BcelAdvice(kind, p, m, extraFlag, 0, 0, null, null);
+ }
}