/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.compiler.assembler; import java.io.PrintWriter; import java.io.StringWriter; import org.objectweb.asm.Handle; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.util.Textifier; /** * Modified {@link Textifier} to strip package names from class names. */ public final class SimpleTypeTextifier extends Textifier { public SimpleTypeTextifier() { super(Opcodes.ASM5); } @Override public String toString() { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); this.print(pw); pw.flush(); return sw.toString(); } @Override protected Textifier createTextifier() { return new SimpleTypeTextifier(); } @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { buf.setLength(0); buf.append(tab2).append("INVOKEDYNAMIC").append(' ').append(name); appendDescriptor(METHOD_DESCRIPTOR, desc); if (bsmArgs.length != 0) { buf.append(" ["); for (int i = 0; i < bsmArgs.length; ++i) { Object arg = bsmArgs[i]; if (arg instanceof String) { appendString(buf, (String) arg); } else if (arg instanceof Type) { Type type = (Type) arg; if (type.getSort() == Type.METHOD) { appendDescriptor(METHOD_DESCRIPTOR, type.getDescriptor()); } else { appendDescriptor(INTERNAL_NAME, type.getDescriptor()); } } else if (arg instanceof Handle) { Handle handle = (Handle) arg; appendDescriptor(HANDLE_DESCRIPTOR, getMethodDescriptor(handle.getDesc())); } else { buf.append(arg); } if (i + 1 < bsmArgs.length) { buf.append(", "); } } buf.append("]"); } buf.append("\n"); text.add(buf.toString()); } @Override public void visitLdcInsn(Object cst) { if (cst instanceof Handle) { Handle handle = (Handle) cst; handle = new Handle(handle.getTag(), handle.getOwner(), handle.getName(), getMethodDescriptor(handle.getDesc())); buf.setLength(0); buf.append(tab2).append("LDC "); buf.append(handle.getOwner()).append('.').append(handle.getName()).append(handle.getDesc()); buf.append('\n'); text.add(buf.toString()); return; } super.visitLdcInsn(cst); } @Override protected void appendDescriptor(int type, String desc) { switch (type) { case INTERNAL_NAME: if (desc != null) { desc = getInternalName(desc); } break; case FIELD_DESCRIPTOR: desc = getDescriptor(desc); break; case METHOD_DESCRIPTOR: desc = getMethodDescriptor(desc); break; case HANDLE_DESCRIPTOR: desc = getMethodDescriptor(desc); break; } super.appendDescriptor(type, desc); } private String getDescriptor(Type type) { if (type.getSort() == Type.OBJECT) { String name = type.getInternalName(); int index = name.lastIndexOf('/'); return name.substring(index + 1); } if (type.getSort() == Type.ARRAY) { StringBuilder sb = new StringBuilder(getDescriptor(type.getElementType())); for (int dim = type.getDimensions(); dim > 0; --dim) { sb.append("[]"); } return sb.toString(); } return type.getClassName(); } private String getInternalName(String internalName) { return getDescriptor(Type.getObjectType(internalName)); } private String getDescriptor(String typeDescriptor) { return getDescriptor(Type.getType(typeDescriptor)); } private String getMethodDescriptor(String methodDescriptor) { Type[] argumentTypes = Type.getArgumentTypes(methodDescriptor); Type returnType = Type.getReturnType(methodDescriptor); StringBuilder sb = new StringBuilder(); sb.append('('); for (int i = 0; i < argumentTypes.length; i++) { sb.append(getDescriptor(argumentTypes[i])); if (i + 1 < argumentTypes.length) { sb.append(", "); } } sb.append(')').append(getDescriptor(returnType)); return sb.toString(); } }