You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2010/03/01 16:54:50 UTC

svn commit: r917562 - in /myfaces/extensions/scripting/trunk/core/core/src: main/java/org/apache/myfaces/scripting/core/dependencyScan/core/ test/java/org/apache/myfaces/extensions/scripting/dependencyScan/ test/java/org/apache/myfaces/extensions/scrip...

Author: werpu
Date: Mon Mar  1 15:54:49 2010
New Revision: 917562

URL: http://svn.apache.org/viewvc?rev=917562&view=rev
Log:
https://issues.apache.org/jira/browse/EXTSCRIPT-70

Fixed the generics issue, however there are still cornercases which cannot be covered (ASM simply does not allow it)
like

((new HashMap<Probe>())).size()

this is one of those 1% corner cases which for now are impossible to cover until ASM gets it right in this area.
It is probably the best to file a bugreport against ASM.

I will close this issue for now since all is done which I can do from my side

Added:
    myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes/GenericsProbe.java   (with props)
    myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes2/
    myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes2/Probe5.java   (with props)
Modified:
    myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/ClassScanVisitor.java
    myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/MethodScanVisitor.java
    myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/DependencyScannerTest.java

Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/ClassScanVisitor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/ClassScanVisitor.java?rev=917562&r1=917561&r2=917562&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/ClassScanVisitor.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/ClassScanVisitor.java Mon Mar  1 15:54:49 2010
@@ -21,7 +21,9 @@
 import org.apache.myfaces.scripting.core.dependencyScan.api.DependencyRegistry;
 import org.apache.myfaces.scripting.core.dependencyScan.registry.ExternalFilterDependencyRegistry;
 import org.objectweb.asm.*;
+import org.objectweb.asm.signature.SignatureReader;
 
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
@@ -45,9 +47,9 @@
     public ClassScanVisitor() {
     }
 
-    public ClassScanVisitor(String _scanIdentifier, String rootClass, ExternalFilterDependencyRegistry registry) {
+    public ClassScanVisitor(Integer engineType, String rootClass, ExternalFilterDependencyRegistry registry) {
         _dependencyRegistry = registry;
-        _scanIdentifier = _scanIdentifier;
+        _engineType = engineType;
         _rootClass = rootClass;
     }
 
@@ -55,6 +57,8 @@
                       String signature, String superName, String[] interfaces) {
         _currentlyVistedClass = Type.getObjectType(name).getClassName();
         registerDependency(Type.getObjectType(superName), "Super name[" + superName + "]");
+        handleGenerics(signature, true);
+
         if (interfaces != null && interfaces.length > 0) {
             for (String currInterface : interfaces) {
                 registerDependency(Type.getObjectType(currInterface), "interface [" + superName + "]");
@@ -63,12 +67,14 @@
     }
 
     public void visitSource(String source, String debug) {
-        //_log._log(Level.INFO, "source: {0}", source);
+        _log.log(Level.FINEST, "visitSource: {0}", source);
     }
 
     public void visitOuterClass(String owner, String name, String description) {
         //nothing has to be done here I guess because
         //we only try to fetch the dependencies
+        _log.log(Level.FINEST, "visitOuterClass: {0} {1} {2}", new String [] {owner, name, description});
+
     }
 
     public AnnotationVisitor visitAnnotation(String description,
@@ -86,11 +92,13 @@
     public void visitInnerClass(String name, String outerName,
                                 String innerName, int access) {
         //same as outer class
+        _log.log(Level.FINEST, "visitInnerClass: {0}  {1} {2} ", new String [] {name, outerName, innerName});
     }
 
     public FieldVisitor visitField(int access, String name, String description,
                                    String signature, Object value) {
         //_log._log(Level.INFO, "Field:{0} {1} ", new Object[]{description, name});
+        handleGenerics(signature, false);
         registerDependency(Type.getType(description), "field type  [" + description + "]");
 
         return null;
@@ -113,12 +121,24 @@
 
         registerDependency(Type.getReturnType(description), "Return type of the method [" + name + "]");
 
+        handleGenerics(signature, true);
+
         for (Type argumentType : Type.getArgumentTypes(description)) {
             registerDependency(argumentType, "Argument type of the method [" + name + "]");
         }
         return new MethodScanVisitor(_engineType, _rootClass, _currentlyVistedClass, _dependencyRegistry);
     }
 
+    private void handleGenerics(String signature, boolean accept) {
+        if(signature != null && signature.contains("<")) {
+            SignatureReader reader = new SignatureReader(signature);
+            if(accept)
+                reader.accept(new DependencySignatureVisitor(_dependencyRegistry,_engineType, _rootClass, _currentlyVistedClass));
+            else
+                reader.acceptType(new DependencySignatureVisitor(_dependencyRegistry,_engineType, _rootClass, _currentlyVistedClass));
+        }
+    }
+
     public void visitEnd() {
         //_log.info("}");
     }

Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/MethodScanVisitor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/MethodScanVisitor.java?rev=917562&r1=917561&r2=917562&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/MethodScanVisitor.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/scripting/core/dependencyScan/core/MethodScanVisitor.java Mon Mar  1 15:54:49 2010
@@ -20,6 +20,10 @@
 
 import org.apache.myfaces.scripting.core.dependencyScan.api.DependencyRegistry;
 import org.objectweb.asm.*;
+import org.objectweb.asm.signature.SignatureReader;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * @author Werner Punz (latest modification by $Author$)
@@ -35,6 +39,8 @@
     Integer _engineType = null;
     DependencyRegistry _dependencyRegistry = null;
 
+    static Logger _log = Logger.getLogger(MethodScanVisitor.class.getName());
+
     public MethodScanVisitor(Integer engineType, String rootClass, String currentlyVisitedClass, DependencyRegistry registry) {
         _currentlyVisitedClass = currentlyVisitedClass;
         _dependencyRegistry = registry;
@@ -52,37 +58,43 @@
         return null;
     }
 
-    public AnnotationVisitor visitParameterAnnotation(int i, String description, boolean b) {
+    public AnnotationVisitor visitParameterAnnotation(int opCode, String description, boolean b) {
         registerDependency(Type.getType(description), "registering annotation [" + description + "]");
 
         return null;
     }
 
     public void visitAttribute(Attribute attribute) {
-        //log.log(Level.INFO, "MethodAttr {0}:", attribute.type);
-        //System.out.println(attribute.type);
+        if (_log.isLoggable(Level.FINEST))
+            _log.log(Level.FINEST, "visitAttribute {0}", attribute.type);
     }
 
     public void visitCode() {
         //log.log(Level.INFO, "Method code");
     }
 
-    public void visitFrame(int i, int i1, Object[] objects, int i2, Object[] objects1) {
+    public void visitFrame(int opCode1, int opCode2, Object[] objects, int opCode3, Object[] objects1) {
+        if (_log.isLoggable(Level.FINEST))
+            _log.log(Level.FINEST, "visitFrame {0}", "");
+
     }
 
-    public void visitInsn(int i) {
+    public void visitInsn(int opCode) {
     }
 
-    public void visitIntInsn(int i, int i1) {
+    public void visitIntInsn(int opCode1, int opCode2) {
     }
 
-    public void visitVarInsn(int i, int i1) {
+    public void visitVarInsn(int opCode1, int opCode2) {
     }
 
-    public void visitTypeInsn(int i, String castType) {
+    public void visitTypeInsn(int opCode, String castType) {
         //cast
         // log.log(Level.INFO, "TypeInsn: {0} ", new String[]{castType});
         registerDependency(Type.getObjectType(castType), "cast registered type[" + castType + "]");
+        if (_log.isLoggable(Level.FINEST))
+            _log.log(Level.FINEST, "visitTypeInsn {0}", castType);
+
     }
 
     private void registerDependency(Type dependency, String desc) {
@@ -98,47 +110,52 @@
     }
 
     /**
-     * @param i
-     * @param s  hosting classname of field (always the calling class afaik)
-     * @param s1 internal descriptor TODO check if it needs treatment, but I assume static imports need it
-     * @param s2 field type
+     * @param opCode
+     * @param owner      hosting classname of field (always the calling class afaik)
+     * @param name       internal descriptor
+     * @param descriptor field type
      */
-    public void visitFieldInsn(int i, String s, String s1, String s2) {
-        //    log.log(Level.INFO, "visitFieldInsn {0} {1} {2}", new Object[]{s, s1, s2});
+    public void visitFieldInsn(int opCode, String owner, String name, String descriptor) {
+        //    log.log(Level.INFO, "visitFieldInsn {0} {1} {2}", new Object[]{owner, name, descriptor});
         //we have to deal with static imports as special case of field insertions
-        if (s1 != null && s1.length() > 6 && s1.startsWith("class$")) {
+        if (name != null && name.length() > 6 && name.startsWith("class$")) {
             //special fallback for groovy static imports which are added as fields
-            s1 = "L" + s1.substring(6).replaceAll("\\$", ".") + ";";
-            registerDependency(Type.getType(s1), "field insn s1 [" + s1 + "]");
+            name = "L" + name.substring(6).replaceAll("\\$", ".") + ";";
+            registerDependency(Type.getType(name), "field insn name [" + name + "]");
         }
-        if (s2 != null) {
-            registerDependency(Type.getType(s2), "field insn s2 [" + s2 + "]");
+        if (descriptor != null) {
+            registerDependency(Type.getType(descriptor), "field insn descriptor [" + descriptor + "]");
         }
+
+        if (_log.isLoggable(Level.FINEST))
+            _log.log(Level.FINEST, "visitFieldInsn {0}", descriptor);
+
     }
 
     /**
      * Method call
      *
-     * @param i  internal counter
-     * @param s  hosting classname of the method
-     * @param s1 method name
-     * @param s2 params list
+     * @param opc   internal opcode
+     * @param owner hosting classname of the method
+     * @param name  method name
+     * @param desc  descriptor string
      */
-    public void visitMethodInsn(int i, String s, String s1, String s2) {
+    public void visitMethodInsn(int opc, String owner, String name, String desc) {
         //s2 arguments list
-        if (s2 != null) {
-            registerDependency(Type.getReturnType(s2), "Registering return type [" + s2 + "]");
-            Type[] argumentTypes = Type.getArgumentTypes(s2);
+        if (desc != null) {
+            registerDependency(Type.getReturnType(desc), "Registering return type [" + desc + "]");
+            Type[] argumentTypes = Type.getArgumentTypes(desc);
             if (argumentTypes != null) {
                 for (Type argumentType : argumentTypes) {
-                    registerDependency(argumentType, "Registering argument type [" + s2 + "]");
+                    registerDependency(argumentType, "Registering argument type [" + desc + "]");
                 }
             }
         }
+
         //s1 method name, can be ignored
         //   s hosting classname
-        if (s != null)
-            registerDependency(Type.getObjectType(s), "registering callee type [" + s + "]");
+        if (owner != null)
+            registerDependency(Type.getObjectType(owner), "registering callee type [" + owner + "]");
 
     }
 
@@ -167,7 +184,8 @@
     }
 
     public void visitMultiANewArrayInsn(String s, int i) {
-        //log.log(Level.INFO, "visitMultiANewArrayInsn: {0}", new Object[]{s});
+        if (_log.isLoggable(Level.FINEST))
+            _log.log(Level.FINEST, "visitMultiANewArrayInsn {0}", s);
     }
 
     public void visitTryCatchBlock(Label label, Label label1, Label label2, String catchType) {
@@ -177,9 +195,10 @@
 
     }
 
-    public void visitLocalVariable(String s, String referenceType, String s2, Label label, Label label1, int i) {
+    public void visitLocalVariable(String name, String description, String signature, Label label, Label label1, int i) {
         //local variable on method level
-        registerDependency(Type.getType(referenceType), "local variable registered type[" + referenceType + "]");
+        registerDependency(Type.getType(description), "local variable registered type[" + description + "]");
+        handleGenerics(signature);
     }
 
     public void visitLineNumber(int i, Label label) {
@@ -193,4 +212,11 @@
     public void visitEnd() {
 
     }
+
+    private void handleGenerics(String signature) {
+        if (signature != null && signature.contains("<")) {
+            SignatureReader reader = new SignatureReader(signature);
+            reader.acceptType(new DependencySignatureVisitor(_dependencyRegistry, _engineType, _rootClass, _currentlyVisitedClass));
+        }
+    }
 }

Modified: myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/DependencyScannerTest.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/DependencyScannerTest.java?rev=917562&r1=917561&r2=917562&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/DependencyScannerTest.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/DependencyScannerTest.java Mon Mar  1 15:54:49 2010
@@ -44,11 +44,16 @@
     private static final String PROBE2 = "org.apache.myfaces.extensions.scripting.dependencyScan.probes.Probe2";
     private static final String PROBE3 = "org.apache.myfaces.extensions.scripting.dependencyScan.probes.Probe3";
     private static final String PROBE4 = "org.apache.myfaces.extensions.scripting.dependencyScan.probes.Probe4";
+    private static final String GENERICS_PROBE = "org.apache.myfaces.extensions.scripting.dependencyScan.probes.GenericsProbe";
+
     private static final String PROBE_PAR = "org.apache.myfaces.extensions.scripting.dependencyScan.probes.ProbeParent";
     private static final String DUMMY = "org.apache.xxx";
     private static final String PROBE_NAMESPACE = "org.apache.myfaces.extensions.scripting";
 
-
+    /**
+     * Basic dependency scanning test, which tests
+     * for basic intra class relationships
+     */
     @Test
     public void testClassDependencies2() {
         ClassDependencies dependencyMap = new ClassDependencies();
@@ -66,4 +71,21 @@
 
     }
 
+    /**
+     * Test for
+     * https://issues.apache.org/jira/browse/EXTSCRIPT-70
+     */
+    @Test
+    public void testGenerics() {
+        ClassDependencies dependencyMap = new ClassDependencies();
+        ExternalFilterDependencyRegistry testRegistry = new DependencyRegistryImpl(ScriptingConst.ENGINE_TYPE_JAVA, dependencyMap);
+        testRegistry.addFilter(new WhitelistFilter(DUMMY, PROBE_NAMESPACE));
+        long before = System.currentTimeMillis();
+        (new StandardDependencyScanner()).fetchDependencies(Thread.currentThread().getContextClassLoader(), ScriptingConst.ENGINE_TYPE_JAVA, GENERICS_PROBE, testRegistry);
+        long after = System.currentTimeMillis();
+        log.info("Execution time registry based scan" + (after - before));
+
+        assertTrue("GenericsDependencyTest 1", dependencyMap.getReferringClasses(PROBE1).contains(GENERICS_PROBE));
+        assertTrue("GenericsDependencyTest 2", dependencyMap.getReferringClasses(PROBE2).contains(GENERICS_PROBE));
+    }
 }

Added: myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes/GenericsProbe.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes/GenericsProbe.java?rev=917562&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes/GenericsProbe.java (added)
+++ myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes/GenericsProbe.java Mon Mar  1 15:54:49 2010
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.extensions.scripting.dependencyScan.probes;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class GenericsProbe {
+    Set<Probe> _testProbe = new HashSet<Probe>();
+
+    public Set<Probe> getTestProbe() {
+        return _testProbe;
+    }
+
+    public void setTestProbe(Set<Probe> testProbe) {
+        //TODO generic case with generic only right hand side not handled
+        Collection<Probe2> mySet = new HashSet<Probe2>();
+        System.out.println(mySet.size());
+        _testProbe = testProbe;
+    }
+
+
+    public void setTestProbe3() {
+        System.out.println("boogaloo");
+    }
+}

Propchange: myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes/GenericsProbe.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes/GenericsProbe.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes2/Probe5.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes2/Probe5.java?rev=917562&view=auto
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes2/Probe5.java (added)
+++ myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes2/Probe5.java Mon Mar  1 15:54:49 2010
@@ -0,0 +1,8 @@
+package org.apache.myfaces.extensions.scripting.dependencyScan.probes2;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public interface Probe5 {
+}

Propchange: myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes2/Probe5.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/dependencyScan/probes2/Probe5.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL