RE: ASM 5.2 annotation

Rob Kenworthy <[email protected]> Thu, 21 Sep 2017 01:12:46 +0000
Newsgroups gmane.comp.java.objectweb.asm
Message-ID <CY1PR18MB063241E621C7DC840DC28D67D2660@CY1PR18MB0632.namprd18.prod.outlook.com>
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] [[email protected]] on behalf of Li Sui [[email protected]]
Sent: September 20, 2017 8:38 PM
To: [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