You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Peter Firmstone <ji...@zeus.net.au> on 2010/11/01 01:12:40 UTC

Re: svn commit: r1029112 - in /incubator/river/jtsk/trunk/src: com/sun/jini/jeri/internal/http/ com/sun/jini/jeri/internal/mux/ com/sun/jini/jeri/internal/runtime/ net/jini/jeri/ net/jini/jeri/connection/ net/jini/jeri/kerberos/ net/jini/jeri/ssl/

Jonathan Costers wrote:
> Also, removing these imports could have infuence on classdep operations?
> So removing a seemingly unused import could cause certain classes not being
> picked up by classdep.
> Not 100% sure about this though ...
>
> 2010/10/31 Sim IJskes - QCG <si...@qcg.nl>
>
>   
>> On 10/31/2010 07:23 AM, Peter Firmstone wrote:
>>
>>     
>>> Remind: When removing unused imports don't forget to check for javadoc
>>> references too. I haven't checked your work, just something I remembered
>>> since Jonathan recently added a lot of imports required by javadoc.
>>>
>>>       
>> OK, what commit revision are you talking about? And how does it manifest
>> itself when i've removed to much imports?
>>
>> Gr. Sim
>>
>>
>>     
>
>   

I can clarify this for you, the following code responsible for 
discovering dependencies, it comes with comments from Tim Blackman and 
myself, it was based on an original example from ASM.

Unused imports aren't included.

Cheers,

Peter.

package com.sun.jini.tool.classdepend;

/***
 * ASM examples: examples showing how ASM can be used
 * Copyright (c) 2000-2005 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
"AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor;

/**
 *
 *
 */
abstract class AbstractDependencyVisitor extends AbstractVisitor {

    AbstractDependencyVisitor() { }

    abstract protected void addName(String name);

    /* -- ClassVisitor -- */

    public void visit(int version, int access, String name, String 
signature,
              String superName, String[] interfaces)
    {
    if (signature == null) {
        addNameInternal(superName);
        addNames(interfaces);
    } else {
        addSignature(signature);
    }
    }
   
    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
    addDesc(desc);
    return this;
    }

    public FieldVisitor visitField(int access, String name, String desc,
                   String signature, Object value)
    {
    if (signature == null) {
        addDesc(desc);
    } else {
        addTypeSignature(signature);
    }
    if (value instanceof Type) {
            addType((Type) value);
        }
    return this;
    }
   
    public MethodVisitor visitMethod(int access, String name, String desc,
                     String signature, String[] exceptions)
    {
        if (signature == null) {
            addMethodDesc(desc);
        } else {
            addSignature(signature);
        }
        addNames(exceptions);
        return this;
    }

    public void visitInnerClass(String name, String outerName,
                String innerName, int access)
    {
    /* XXX: Do we need to consider inner classes?
         * Yes the old ClassDep tool includes them */
        addNameInternal(outerName);
    addNameInternal(name);
    }

    /* -- MethodVisitor -- */

    public AnnotationVisitor visitParameterAnnotation(int parameter,
                              String desc,
                              boolean visible)
    {
        addDesc(desc);
        return this;
    }

    public void visitTypeInsn(int opcode, String desc) {
        if (desc.charAt(0) == '[') {
            addDesc(desc);
        } else {
            addNameInternal(desc);
    }
    }

    public void visitFieldInsn(int opcode, String owner, String name,
                   String desc)
    {
        addNameInternal(owner);
        addDesc(desc);
    }
   
    String pattern = "^\\[{0,2}L{0,1}(\\w+[/.]{1}[\\w$\\d/.]+);{0,1}$";
    Pattern arrayOfObjects = Pattern.compile(pattern);
    public void visitMethodInsn(int opcode, String owner, String name,
                String desc)
    {
        /* This filters out Generic's and primitive owners.
         *
         * Also when the owner is an array, containing Objects and
         * the method name is clone(), (I think it's got something to do
         * with cloning array's, this must be a new java 5 language feature
         * I tested 1.4 code without this ever occurring)     
         * we can't get the Object's type
         * using Type.getType(owner) due to the nature of
         * the ASM Core API requiring bytecode be read sequentially.
         * This only occurs with clone() which returns java.lang.Object
         */
        Matcher match = arrayOfObjects.matcher(owner);
        while (match.find()){
            String object = match.group(1);
            addNameInternal(object);
        }
        addMethodDesc(desc);
    }

    public void visitLdcInsn(Object cst) {
        if (cst instanceof Type) {
            addType((Type) cst);
    }
    }

    public void visitMultiANewArrayInsn(String desc, int dims) {
        addDesc(desc);
    }

    public void visitLocalVariable(String name, String desc, String 
signature,
                   Label start, Label end, int index)
    {
    if (signature != null) {
        addTypeSignature(signature);
    }
    }

    public void visitTryCatchBlock(Label start, Label end, Label handler,
                   String type)
    {
        addNameInternal(type);
    }

    /* -- AnnotationVisitor -- */

    public void visit(String name, Object value) {
        if (value instanceof Type) {
            addType((Type) value);
    }
    }

    public void visitEnum(String name, String desc, String value) {
        addDesc(desc);
    }

    public AnnotationVisitor visitAnnotation(String name, String desc) {
        addDesc(desc);
        return this;
    }

    /* -- SignatureVisitor -- */

    public void visitTypeVariable(String name) {
        /* XXX: Need to do something? */
        //System.out.println(name);
    }

    public void visitClassType(String name) {
        addNameInternal(name);
    }

    public void visitInnerClassType(String name) {
        // This is not a fully qualified class name, ignore.
    }

    /* -- Utilities -- */

    private void addNameInternal(String name) {
        if (name != null) {
        addName(name.replace('/', '.'));
    }
    }

    private void addNames(String[] names) {
    if (names != null) {
            int l = names.length;
        for (int i = 0; i < l; i++) {
                String name = names[i];
        addNameInternal(name);
        }
    }
    }

    private void addDesc(String desc) {
        addType(Type.getType(desc));
    }

    private void addMethodDesc(String desc) {
        addType(Type.getReturnType(desc));
        Type [] type = Type.getArgumentTypes(desc);
        int l = type.length;
    for (int i = 0; i < l; i++) {           
            addType(type[i]);
    }
    }

    private void addType(Type t) {
        switch (t.getSort()) {
            case Type.ARRAY:
                addType(t.getElementType());
                break;
            case Type.OBJECT:
                addNameInternal(t.getClassName());
                break;
        }
    }

    private void addSignature(String signature) {
    new SignatureReader(signature).accept(this);
    }

    private void addTypeSignature(String signature) {
    new SignatureReader(signature).acceptType(this);
    }
}