Solve a bug about local variable inside constructor manipulation.
Update the iPOJO Archetype (Felix-311)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@553232 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java
index a3d954b..40397b4 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java
@@ -19,148 +19,159 @@
package org.apache.felix.ipojo.manipulation;
import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.commons.GeneratorAdapter;
+
/**
* Constructor Adapter : add a component manager argument inside a constructor.
- *
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-public class ConstructorCodeAdapter extends GeneratorAdapter implements Opcodes {
+public class ConstructorCodeAdapter extends MethodAdapter implements Opcodes {
- /**
- * The owner class of the field.
+ /** The owner class of the field.
* m_owner : String
*/
private String m_owner;
-
+
/**
- * Is the super call already detected ?
+ * Is the super call detected ?
*/
private boolean m_superDetected;
- /**
- * ConstructorCodeAdapter constructor.
- * @param mv : method visitor.
- * @param access : access level of the method.
- * @param desc : descriptor of the constructor.
- * @param owner : onwer class
+ /** PropertyCodeAdapter constructor.
+ * A new FiledCodeAdapter should be create for each method visit.
+ * @param mv MethodVisitor
+ * @param owner Name of the class
*/
- public ConstructorCodeAdapter(final MethodVisitor mv, int access,
- String desc, final String owner) {
- super(mv, access, "<init>", desc);
+ public ConstructorCodeAdapter(final MethodVisitor mv, final String owner) {
+ super(mv);
m_owner = owner;
- // m_superDetected = false;
+ m_superDetected = false;
}
- /**
- * Visit a method instruction.
- * Inject the _setComponentManager invocation just of the super invocation.
- * @param opcode : opcode
- * @param owner : method owner class
- * @param name : method name
- * @param desc : method description
- * @see org.objectweb.asm.commons.AdviceAdapter#visitMethodInsn(int, java.lang.String, java.lang.String, java.lang.String)
- */
- public void visitMethodInsn(int opcode, String owner, String name, String desc) {
- // A method call is detected, check if it is the super call :
- if (!m_superDetected) {
- m_superDetected = true;
- // The first invocation is the super call
- // 1) Visit the super constructor :
- mv.visitVarInsn(ALOAD, 0);
- mv.visitMethodInsn(opcode, owner, name, desc); // Super constructor
- // invocation
- // 2) Load the object and the component manager argument
- mv.visitVarInsn(ALOAD, 0);
- // mv.visitVarInsn(ALOAD,
- // Type.getArgumentTypes(m_constructorDesc).length);
- mv.visitVarInsn(ALOAD, 1); // CM is always the first argument
- // 3) Initialize the field
- mv.visitMethodInsn(INVOKESPECIAL, m_owner, "_setComponentManager",
- "(Lorg/apache/felix/ipojo/InstanceManager;)V");
- // insertion finished
- } else {
- mv.visitMethodInsn(opcode, owner, name, desc);
- }
- }
-
- /**
- * Visit an instruction modifying a local variable.
- * Increment the variable number if != 0.
- * @param opcode : opcode of the instruction.
- * @param var : variable number.
- * @see org.objectweb.asm.commons.AdviceAdapter#visitVarInsn(int, int)
- */
- public void visitVarInsn(int opcode, int var) {
- if (var == 0) {
- mv.visitVarInsn(opcode, var); // ALOAD 0 (THIS)
- } else {
- mv.visitVarInsn(opcode, var + 1); // All other variable count
- }
- }
-
- /**
- * Visit an increment instruction.
- * Increment the variable number.
- * @param var : incremented variable number.
- * @param increment : increment.
- * @see org.objectweb.asm.commons.LocalVariablesSorter#visitIincInsn(int, int)
- */
- public void visitIincInsn(int var, int increment) {
- if (var != 0) {
- mv.visitIincInsn(var + 1, increment);
- } else {
- mv.visitIincInsn(var, increment);
- }
- }
-
- /**
- * Visit local variable.
- * @param name : name of the variable.
- * @param desc : description of the variable.
- * @param signature : signature of the variable.
- * @param start : starting label.
- * @param end : ending label.
- * @param index : variable index.
- * @see org.objectweb.asm.commons.LocalVariablesSorter#visitLocalVariable(java.lang.String, java.lang.String, java.lang.String, org.objectweb.asm.Label, org.objectweb.asm.Label, int)
- */
- public void visitLocalVariable(String name, String desc, String signature,
- Label start, Label end, int index) {
- if (index == 0) {
- mv.visitLocalVariable(name, desc, signature, start, end, index);
- mv.visitLocalVariable("_manager", "Lorg/apache/felix/ipojo/InstanceManager;", null, start, end, 1);
- } else {
- mv.visitLocalVariable(name, desc, signature, start, end, index + 1);
- }
- }
-
- /**
- * Manage a field operation.
- * Replace GETFIELD and PUTFILED by getter and setter invocation.
- *
+ /** Visit Method for Field instance (GETFIELD).
+ * @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int, String, String, String)
* @param opcode : visited operation code
* @param owner : owner of the field
* @param name : name of the field
* @param desc : decriptor of the field
- * @see org.objectweb.asm.commons.AdviceAdapter#visitFieldInsn(int, java.lang.String, java.lang.String, java.lang.String)
*/
- public void visitFieldInsn(final int opcode, final String owner,
- final String name, final String desc) {
+ public void visitFieldInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc) {
if (owner.equals(m_owner)) {
if (opcode == GETFIELD) {
String gDesc = "()" + desc;
visitMethodInsn(INVOKEVIRTUAL, owner, "_get" + name, gDesc);
return;
- } else if (opcode == PUTFIELD) {
- String sDesc = "(" + desc + ")V";
- visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);
- return;
- }
+ } else
+ if (opcode == PUTFIELD) {
+ String sDesc = "(" + desc + ")V";
+ visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);
+ return;
+ }
}
super.visitFieldInsn(opcode, owner, name, desc);
}
+
+ /**
+ * Vist a method invocation insruction.
+ * After the super constructor invocation, insert the _setComponentManager invocation.
+ * @param opcode : opcode
+ * @param owner : method owning class
+ * @param name : method name
+ * @param desc : method descriptor
+ * @see org.objectweb.asm.MethodAdapter#visitMethodInsn(int, java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+ // A method call is detected, check if it is the super call :
+ if (!m_superDetected) {
+ m_superDetected = true;
+ // The first invocation is the super call
+ // 1) Visit the super constructor :
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(opcode, owner, name, desc); // Super constructor invocation
+
+ // 2) Load the object and the component manager argument
+ mv.visitVarInsn(ALOAD, 0);
+ //mv.visitVarInsn(ALOAD, Type.getArgumentTypes(m_constructorDesc).length);
+ mv.visitVarInsn(ALOAD, 1); // CM is always the first argument
+ // 3) Initialize the field
+ mv.visitMethodInsn(INVOKESPECIAL, m_owner, "_setComponentManager", "(Lorg/apache/felix/ipojo/InstanceManager;)V");
+ // insertion finished
+ } else {
+ mv.visitMethodInsn(opcode, owner, name, desc);
+ }
+ }
+
+ /**
+ * Visit an instruction implying a variable.
+ * For all non-this variable, increment the variable index.
+ * @param opcode : opcode
+ * @param var : variable index
+ * @see org.objectweb.asm.MethodAdapter#visitVarInsn(int, int)
+ */
+ public void visitVarInsn(int opcode, int var) {
+ if (!m_superDetected) {
+ return; // Do nothing the ALOAD 0 will be injected by visitMethodInsn
+ } else {
+ if (var == 0) {
+ mv.visitVarInsn(opcode, var); // ALOAD 0 (THIS)
+ } else {
+ mv.visitVarInsn(opcode, var + 1); // All other variable count
+ }
+ }
+ }
+
+ /**
+ * Visit an increment instruction.
+ * If incrementing a varialbe, increment the variable index.
+ * @param var : variable index
+ * @param increment : increment
+ * @see org.objectweb.asm.MethodAdapter#visitIincInsn(int, int)
+ */
+ public void visitIincInsn(int var, int increment) {
+ if (var != 0) {
+ mv.visitIincInsn(var + 1, increment);
+ } else {
+ mv.visitIincInsn(var, increment); // Increment the current object ???
+ }
+ }
+
+ /**
+ * Visit a local variable.
+ * Add _manager and increment variable index.
+ * @param name : variable name
+ * @param desc : variable descriptor
+ * @param signature : variable signature
+ * @param start : beginning label
+ * @param end : endind label
+ * @param index :variable index
+ * @see org.objectweb.asm.MethodAdapter#visitLocalVariable(java.lang.String, java.lang.String, java.lang.String, org.objectweb.asm.Label, org.objectweb.asm.Label, int)
+ */
+ public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
+ if (index == 0) {
+ mv.visitLocalVariable(name, desc, signature, start, end, index);
+ mv.visitLocalVariable("_manager", "Lorg/apache/felix/ipojo/InstanceManager;", null, start, end, 1);
+ }
+ mv.visitLocalVariable(name, desc, signature, start, end, index + 1);
+ }
+
+ /**
+ * Visit max method.
+ * @param maxStack : stack size.
+ * @param maxLocals : local number.
+ * @see org.objectweb.asm.MethodAdapter#visitMaxs(int, int)
+ */
+ public void visitMaxs(int maxStack, int maxLocals) {
+ mv.visitMaxs(maxStack, maxLocals + 1);
+ }
}
+
+
+
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
index 863b82b..d9c2095 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
@@ -186,7 +186,8 @@
if (mv == null) {
return null;
} else {
- return new ConstructorCodeAdapter(mv, access, desc, m_owner);
+ //return new ConstructorCodeAdapter(mv, access, desc, m_owner);
+ return new ConstructorCodeAdapter(mv, m_owner);
}
} else {
Type[] args = Type.getArgumentTypes(desc);
diff --git a/ipojo/plugin/src/main/resources/archetype-resources/pom.xml b/ipojo/plugin/src/main/resources/archetype-resources/pom.xml
index faa7477..90f46b4 100644
--- a/ipojo/plugin/src/main/resources/archetype-resources/pom.xml
+++ b/ipojo/plugin/src/main/resources/archetype-resources/pom.xml
@@ -1,6 +1,6 @@
<project>
<modelVersion>4.0.0</modelVersion>
- <packaging>ipojo-bundle</packaging>
+ <packaging>bundle</packaging>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>