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>