RE: ASM 5.2 annotation

Rob Kenworthy <[email protected]> Thu, 21 Sep 2017 01:57:19 +0000
Newsgroups gmane.comp.java.objectweb.asm
Message-ID <CY1PR18MB06327A5842FE9CB0DCA7E0CFD2660@CY1PR18MB0632.namprd18.prod.outlook.com>
No problem. I just ran the following test:

@Entity(name = "vehicles")
public class AnnotationTest {

    public static void main(String[] args) throws IOException {
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(AnnotationTest.class.getName().replace(".","/") + ".class");
        ClassReader cr = new ClassReader(is);
        ClassNode classNode = new ClassNode();
        cr.accept(classNode, ClassReader.SKIP_CODE);
        String text = AsmUtil.toAnnotationString(classNode.visibleAnnotations.iterator().next().desc);
        System.out.println(text);
    }
}

And my output was not exactly as I expected: @javax.persistence.Entity()

It should have output the name = "vehicles" text as well. Give me a sec and I'll see if I can figure out what went wrong.
________________________________________
From: [email protected] [[email protected]] on behalf of Li Sui [[email protected]]
Sent: September 20, 2017 9:36 PM
To: Rob Kenworthy
Cc: [email protected]
Subject: Re: [asm] ASM 5.2 annotation

Hi Rob

Thanks for your quick response!

The code looks nice but it is not what I am looking for. I want to get the attribute or parameter of an annotation.  @Entity(tableName = "vehicles"). Is the information [tableName= "vehicles"] available through ASM?

Cheers
Lee

On Thu, Sep 21, 2017 at 1:12 PM, Rob Kenworthy <[email protected]<mailto:[email protected]>> wrote:
Hi Lee and ASM maintainers,

In many of my ASM based projects, I end up reusing the same or similar utility classes for converting ASM types to Java language types. I have often wondered if the ASM community does the same thing. Lee, the following code will output an annotation. I think you should be able to sort out your problem by following the code (just follow the toAnnotationString(...) method). And I am happy to contribute this code to ASM if anyone is interested (BTW it contains some options for HTML markup, which I frequently use, but may not suit everyone's needs).

Thanks,
Rob

public class AsmUtil {

    public static String toMethodSignature(String methodName, String desc) {
        return toMethodSignature(methodName, desc, false, true, false);
    }

    public static String toMethodSignature(String methodName, String desc, boolean escapeHtml) {
        return toMethodSignature(methodName, desc, false, escapeHtml, false);
    }

    public static String toMethodSignature(String methodName, String desc, boolean includeReturnType, boolean escapeHtml) {
        return toMethodSignature(methodName, desc, includeReturnType, escapeHtml, false);
    }

    public static String toMethodSignature(String methodName, String desc, boolean includeReturnType, boolean escapeHtml, boolean bold) {
                StringBuilder b = new StringBuilder();

                Type methodType = Type.getMethodType(desc);
                Type returnType = methodType.getReturnType();

                if (includeReturnType) {
                b.append(escapeHtml ? TextUtil.escapeToHtml(toString(returnType)) : toString(returnType));
                b.append(" ");
                }

            String name = escapeHtml ? TextUtil.escapeToHtml(methodName) : methodName;
                name = bold ? "<b>" + name + "</b>" : name;

                b.append(name);
                b.append('(');
                b.append(
                        escapeHtml ?
                                TextUtil.escapeToHtml(toTypeString(methodType.getArgumentTypes())) :
                                    toTypeString(methodType.getArgumentTypes())
                );
                b.append(')');

                return b.toString();
        }

   public static String toParameterTypesString(String desc) {
       Type type = Type.getType(desc);
       return toTypeString(type.getArgumentTypes());
   }

   public static String toReturnTypeString(String desc) {
       Type type = Type.getType(desc);
       return toString(type.getReturnType());
   }

        public static String toTypeString(Type argTypes[]) {
            StringBuilder buffer = new StringBuilder();

            for (int i=0; i<argTypes.length; i++) {
                buffer.append(toString(argTypes[i]));
                if (i<argTypes.length-1)
                    buffer.append(',');
            }

            return buffer.toString();
        }

        public static String toTypeString(String desc) {
            Type type = Type.getType(desc);
            return toString(type);
        }

        public static String toString(Type type) {
            StringBuilder buffer = new StringBuilder();
            if (type.getSort() == Type.ARRAY) {
                buffer.append(type.getElementType().getClassName());
                int size = type.getDimensions();
                for (int i=0; i<size; i++) {
                    buffer.append("[]");
                }
            }
            else
                buffer.append(type.getClassName());
            return buffer.toString();
        }

        public static String toAnnotationString(String desc) {
            return new AnnotationOutputVisitor(desc).toString();
        }

        public static class AnnotationOutputVisitor extends AnnotationNode {

            boolean boldAnnotations = false;
            boolean addHtmlBreakingSpaces = false;

            public AnnotationOutputVisitor(String desc) {
                super(Opcodes.ASM5, desc);
            }

            public void setBoldAnnotations(boolean boldAnnotations) {
                this.boldAnnotations = boldAnnotations;
            }

            public void setAddHtmlBreakingSpaces(boolean addHtmlBreakingSpaces) {
                this.addHtmlBreakingSpaces = addHtmlBreakingSpaces;
            }

            public String toString() {
                StringBuilder buffer = new StringBuilder();

                buffer.append('@');
                if (boldAnnotations)
                    buffer.append("<b>");
                buffer.append(AsmUtil.toTypeString(desc));
                if (boldAnnotations)
                    buffer.append("</b>");
                buffer.append("(");

                printAnnotationList(buffer, values);

                buffer.append(")");

                return buffer.toString();
            }

            void printAnnotationList(StringBuilder buffer, List list) {
                if (list != null) {

                    Iterator it = list.listIterator();
                    Object name;
                    int size = list.size();
                    while (it.hasNext()) {
                        name = it.next();

                        if (size > 2) {
                            buffer.append(name);
                            if (addHtmlBreakingSpaces)
                                buffer.append(" = ");
                            else
                                buffer.append('=');
                        }

                        printValue(buffer, it.next());

                        if (it.hasNext())
                            buffer.append(", ");
                    }
                }
            }

            void printValueList(StringBuilder buffer, List list) {
                Iterator it = list.listIterator();
                Object value;
                while (it.hasNext()) {
                    value = it.next();
                    printValue(buffer, value);
                    if (it.hasNext())
                        buffer.append(", ");
                }
            }

            void printValue(StringBuilder buffer, Object value) {
                if (value instanceof String)
                    buffer.append("\"" + value + "\"");
                else if (value instanceof Type)
                    buffer.append(AsmUtil.toString( (Type) value));
                else if (value instanceof AnnotationNode) {
                    AnnotationNode node = (AnnotationNode) value;
                    AnnotationOutputVisitor mav = new AnnotationOutputVisitor(node.desc);
                    node.accept(mav);
                    buffer.append(mav);
                }
                else if (value instanceof String[]) {
                    String array[] = (String[]) value;
                    buffer.append(AsmUtil.toTypeString( array[0]));
                    buffer.append('.');
                    buffer.append(array[1]);
                }
                else if (value instanceof List) {
                    buffer.append('{');
                    printValueList(buffer, (List) value);
                    buffer.append('}');
                }
                else
                    buffer.append(value);
            }
        }
}

________________________________________
From: [email protected]<mailto:[email protected]> [[email protected]<mailto:[email protected]>] on behalf of Li Sui [[email protected]<mailto:[email protected]>]
Sent: September 20, 2017 8:38 PM
To: [email protected]<mailto:[email protected]>
Subject: [asm] ASM 5.2 annotation

Dear community

I am using ASM 5.2 to scan annotations. In MethodVisitor, visitAnnotation(desc, visible) can get the descriptor of an annotation. But I want to get more information about this annotation. For instance, @Test(expected = IndexOutOfBoundsException.class). I want to know the part inside the parentheses. What method should I override? I tried visitInsnAnnotation(), visitParameterAnnotation() and visitTypeAnnotation(), none of them produced results.

regards

Lee


-- 
You receive this message as a subscriber of the [email protected] mailing list.
To unsubscribe: mailto:[email protected]
For general help: mailto:[email protected]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws