|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  */ | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  */ | 
|  | package jdk.internal.org.objectweb.asm.util; | 
|  |  | 
|  | import jdk.internal.org.objectweb.asm.Opcodes; | 
|  | import jdk.internal.org.objectweb.asm.signature.SignatureVisitor; | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  */ | 
|  | public final class TraceSignatureVisitor extends SignatureVisitor { | 
|  |  | 
|  |     private final StringBuilder declaration; | 
|  |  | 
|  |     private boolean isInterface; | 
|  |  | 
|  |     private boolean seenFormalParameter; | 
|  |  | 
|  |     private boolean seenInterfaceBound; | 
|  |  | 
|  |     private boolean seenParameter; | 
|  |  | 
|  |     private boolean seenInterface; | 
|  |  | 
|  |     private StringBuilder returnType; | 
|  |  | 
|  |     private StringBuilder exceptions; | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private int argumentStack; | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private int arrayStack; | 
|  |  | 
|  |     private String separator = ""; | 
|  |  | 
|  |     public TraceSignatureVisitor(final int access) { | 
|  |         super(Opcodes.ASM6); | 
|  |         isInterface = (access & Opcodes.ACC_INTERFACE) != 0; | 
|  |         this.declaration = new StringBuilder(); | 
|  |     } | 
|  |  | 
|  |     private TraceSignatureVisitor(final StringBuilder buf) { | 
|  |         super(Opcodes.ASM6); | 
|  |         this.declaration = buf; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void visitFormalTypeParameter(final String name) { | 
|  |         declaration.append(seenFormalParameter ? ", " : "<").append(name); | 
|  |         seenFormalParameter = true; | 
|  |         seenInterfaceBound = false; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitClassBound() { | 
|  |         separator = " extends "; | 
|  |         startType(); | 
|  |         return this; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitInterfaceBound() { | 
|  |         separator = seenInterfaceBound ? ", " : " extends "; | 
|  |         seenInterfaceBound = true; | 
|  |         startType(); | 
|  |         return this; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitSuperclass() { | 
|  |         endFormals(); | 
|  |         separator = " extends "; | 
|  |         startType(); | 
|  |         return this; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitInterface() { | 
|  |         separator = seenInterface ? ", " : isInterface ? " extends " | 
|  |                 : " implements "; | 
|  |         seenInterface = true; | 
|  |         startType(); | 
|  |         return this; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitParameterType() { | 
|  |         endFormals(); | 
|  |         if (seenParameter) { | 
|  |             declaration.append(", "); | 
|  |         } else { | 
|  |             seenParameter = true; | 
|  |             declaration.append('('); | 
|  |         } | 
|  |         startType(); | 
|  |         return this; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitReturnType() { | 
|  |         endFormals(); | 
|  |         if (seenParameter) { | 
|  |             seenParameter = false; | 
|  |         } else { | 
|  |             declaration.append('('); | 
|  |         } | 
|  |         declaration.append(')'); | 
|  |         returnType = new StringBuilder(); | 
|  |         return new TraceSignatureVisitor(returnType); | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitExceptionType() { | 
|  |         if (exceptions == null) { | 
|  |             exceptions = new StringBuilder(); | 
|  |         } else { | 
|  |             exceptions.append(", "); | 
|  |         } | 
|  |          | 
|  |         return new TraceSignatureVisitor(exceptions); | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void visitBaseType(final char descriptor) { | 
|  |         switch (descriptor) { | 
|  |         case 'V': | 
|  |             declaration.append("void"); | 
|  |             break; | 
|  |         case 'B': | 
|  |             declaration.append("byte"); | 
|  |             break; | 
|  |         case 'J': | 
|  |             declaration.append("long"); | 
|  |             break; | 
|  |         case 'Z': | 
|  |             declaration.append("boolean"); | 
|  |             break; | 
|  |         case 'I': | 
|  |             declaration.append("int"); | 
|  |             break; | 
|  |         case 'S': | 
|  |             declaration.append("short"); | 
|  |             break; | 
|  |         case 'C': | 
|  |             declaration.append("char"); | 
|  |             break; | 
|  |         case 'F': | 
|  |             declaration.append("float"); | 
|  |             break; | 
|  |          | 
|  |         default: | 
|  |             declaration.append("double"); | 
|  |             break; | 
|  |         } | 
|  |         endType(); | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void visitTypeVariable(final String name) { | 
|  |         declaration.append(name); | 
|  |         endType(); | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitArrayType() { | 
|  |         startType(); | 
|  |         arrayStack |= 1; | 
|  |         return this; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void visitClassType(final String name) { | 
|  |         if ("java/lang/Object".equals(name)) { | 
|  |             // Map<java.lang.Object,java.util.List> | 
|  |             // or | 
|  |             // abstract public V get(Object key); (seen in Dictionary.class) | 
|  |             // should have Object | 
|  |              | 
|  |             boolean needObjectClass = argumentStack % 2 != 0 || seenParameter; | 
|  |             if (needObjectClass) { | 
|  |                 declaration.append(separator).append(name.replace('/', '.')); | 
|  |             } | 
|  |         } else { | 
|  |             declaration.append(separator).append(name.replace('/', '.')); | 
|  |         } | 
|  |         separator = ""; | 
|  |         argumentStack *= 2; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void visitInnerClassType(final String name) { | 
|  |         if (argumentStack % 2 != 0) { | 
|  |             declaration.append('>'); | 
|  |         } | 
|  |         argumentStack /= 2; | 
|  |         declaration.append('.'); | 
|  |         declaration.append(separator).append(name.replace('/', '.')); | 
|  |         separator = ""; | 
|  |         argumentStack *= 2; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void visitTypeArgument() { | 
|  |         if (argumentStack % 2 == 0) { | 
|  |             ++argumentStack; | 
|  |             declaration.append('<'); | 
|  |         } else { | 
|  |             declaration.append(", "); | 
|  |         } | 
|  |         declaration.append('?'); | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public SignatureVisitor visitTypeArgument(final char tag) { | 
|  |         if (argumentStack % 2 == 0) { | 
|  |             ++argumentStack; | 
|  |             declaration.append('<'); | 
|  |         } else { | 
|  |             declaration.append(", "); | 
|  |         } | 
|  |  | 
|  |         if (tag == EXTENDS) { | 
|  |             declaration.append("? extends "); | 
|  |         } else if (tag == SUPER) { | 
|  |             declaration.append("? super "); | 
|  |         } | 
|  |  | 
|  |         startType(); | 
|  |         return this; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void visitEnd() { | 
|  |         if (argumentStack % 2 != 0) { | 
|  |             declaration.append('>'); | 
|  |         } | 
|  |         argumentStack /= 2; | 
|  |         endType(); | 
|  |     } | 
|  |  | 
|  |     public String getDeclaration() { | 
|  |         return declaration.toString(); | 
|  |     } | 
|  |  | 
|  |     public String getReturnType() { | 
|  |         return returnType == null ? null : returnType.toString(); | 
|  |     } | 
|  |  | 
|  |     public String getExceptions() { | 
|  |         return exceptions == null ? null : exceptions.toString(); | 
|  |     } | 
|  |  | 
|  |     // ----------------------------------------------- | 
|  |  | 
|  |     private void endFormals() { | 
|  |         if (seenFormalParameter) { | 
|  |             declaration.append('>'); | 
|  |             seenFormalParameter = false; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     private void startType() { | 
|  |         arrayStack *= 2; | 
|  |     } | 
|  |  | 
|  |     private void endType() { | 
|  |         if (arrayStack % 2 == 0) { | 
|  |             arrayStack /= 2; | 
|  |         } else { | 
|  |             while (arrayStack % 2 != 0) { | 
|  |                 arrayStack /= 2; | 
|  |                 declaration.append("[]"); | 
|  |             } | 
|  |         } | 
|  |     } | 
|  | } |