parent
							
								
									ac9cfefaff
								
							
						
					
					
						commit
						185c2bf5b6
					
				| 
						 | 
				
			
			@ -41,7 +41,7 @@ public abstract class AnnotationVisitor {
 | 
			
		|||
 | 
			
		||||
    /**
 | 
			
		||||
     * The ASM API version implemented by this visitor. The value of this field
 | 
			
		||||
     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    protected final int api;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ public abstract class AnnotationVisitor {
 | 
			
		|||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be one
 | 
			
		||||
     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    public AnnotationVisitor(final int api) {
 | 
			
		||||
        this(api, null);
 | 
			
		||||
| 
						 | 
				
			
			@ -67,13 +67,13 @@ public abstract class AnnotationVisitor {
 | 
			
		|||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be one
 | 
			
		||||
     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     * @param av
 | 
			
		||||
     *            the annotation visitor to which this visitor must delegate
 | 
			
		||||
     *            method calls. May be null.
 | 
			
		||||
     */
 | 
			
		||||
    public AnnotationVisitor(final int api, final AnnotationVisitor av) {
 | 
			
		||||
        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
 | 
			
		||||
        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
 | 
			
		||||
            throw new IllegalArgumentException();
 | 
			
		||||
        }
 | 
			
		||||
        this.api = api;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,7 +104,7 @@ final class AnnotationWriter extends AnnotationVisitor {
 | 
			
		|||
     */
 | 
			
		||||
    AnnotationWriter(final ClassWriter cw, final boolean named,
 | 
			
		||||
            final ByteVector bv, final ByteVector parent, final int offset) {
 | 
			
		||||
        super(Opcodes.ASM5);
 | 
			
		||||
        super(Opcodes.ASM6);
 | 
			
		||||
        this.cw = cw;
 | 
			
		||||
        this.named = named;
 | 
			
		||||
        this.bv = bv;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -222,6 +222,8 @@ public class ClassReader {
 | 
			
		|||
            // case ClassWriter.CLASS:
 | 
			
		||||
            // case ClassWriter.STR:
 | 
			
		||||
            // case ClassWriter.MTYPE
 | 
			
		||||
            // case ClassWriter.PACKAGE:
 | 
			
		||||
            // case ClassWriter.MODULE:
 | 
			
		||||
            default:
 | 
			
		||||
                size = 3;
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -365,7 +367,9 @@ public class ClassReader {
 | 
			
		|||
                break;
 | 
			
		||||
            // case ClassWriter.STR:
 | 
			
		||||
            // case ClassWriter.CLASS:
 | 
			
		||||
            // case ClassWriter.MTYPE
 | 
			
		||||
            // case ClassWriter.MTYPE:
 | 
			
		||||
            // case ClassWriter.MODULE:
 | 
			
		||||
            // case ClassWriter.PACKAGE:
 | 
			
		||||
            default:
 | 
			
		||||
                item.set(tag, readUTF8(index, buf), null, null);
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -572,11 +576,14 @@ public class ClassReader {
 | 
			
		|||
        String enclosingOwner = null;
 | 
			
		||||
        String enclosingName = null;
 | 
			
		||||
        String enclosingDesc = null;
 | 
			
		||||
        String moduleMainClass = null;
 | 
			
		||||
        int anns = 0;
 | 
			
		||||
        int ianns = 0;
 | 
			
		||||
        int tanns = 0;
 | 
			
		||||
        int itanns = 0;
 | 
			
		||||
        int innerClasses = 0;
 | 
			
		||||
        int module = 0;
 | 
			
		||||
        int packages = 0;
 | 
			
		||||
        Attribute attributes = null;
 | 
			
		||||
 | 
			
		||||
        u = getAttributes();
 | 
			
		||||
| 
						 | 
				
			
			@ -617,6 +624,12 @@ public class ClassReader {
 | 
			
		|||
            } else if (ANNOTATIONS
 | 
			
		||||
                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
 | 
			
		||||
                itanns = u + 8;
 | 
			
		||||
            } else if ("Module".equals(attrName)) {
 | 
			
		||||
                module = u + 8;
 | 
			
		||||
            } else if ("ModuleMainClass".equals(attrName)) {
 | 
			
		||||
                moduleMainClass = readClass(u + 8, c);
 | 
			
		||||
            } else if ("ModulePackages".equals(attrName)) {
 | 
			
		||||
                packages = u + 10;
 | 
			
		||||
            } else if ("BootstrapMethods".equals(attrName)) {
 | 
			
		||||
                int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
 | 
			
		||||
                for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -645,6 +658,12 @@ public class ClassReader {
 | 
			
		|||
            classVisitor.visitSource(sourceFile, sourceDebug);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // visits the module info and associated attributes
 | 
			
		||||
        if (module != 0) {
 | 
			
		||||
            readModule(classVisitor, context, module,
 | 
			
		||||
                    moduleMainClass, packages);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // visits the outer class
 | 
			
		||||
        if (enclosingOwner != null) {
 | 
			
		||||
            classVisitor.visitOuterClass(enclosingOwner, enclosingName,
 | 
			
		||||
| 
						 | 
				
			
			@ -714,6 +733,120 @@ public class ClassReader {
 | 
			
		|||
        classVisitor.visitEnd();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads the module attribute and visit it.
 | 
			
		||||
     *
 | 
			
		||||
     * @param classVisitor
 | 
			
		||||
     *           the current class visitor
 | 
			
		||||
     * @param context
 | 
			
		||||
     *           information about the class being parsed.
 | 
			
		||||
     * @param u
 | 
			
		||||
     *           start offset of the module attribute in the class file.
 | 
			
		||||
     * @param mainClass
 | 
			
		||||
     *           name of the main class of a module or null.
 | 
			
		||||
     * @param packages
 | 
			
		||||
     *           start offset of the concealed package attribute.
 | 
			
		||||
     */
 | 
			
		||||
    private void readModule(final ClassVisitor classVisitor,
 | 
			
		||||
            final Context context, int u,
 | 
			
		||||
            final String mainClass, int packages) {
 | 
			
		||||
 | 
			
		||||
        char[] buffer = context.buffer;
 | 
			
		||||
 | 
			
		||||
        // reads module name, flags and version
 | 
			
		||||
        String name = readModule(u, buffer);
 | 
			
		||||
        int flags = readUnsignedShort(u + 2);
 | 
			
		||||
        String version = readUTF8(u + 4, buffer);
 | 
			
		||||
        u += 6;
 | 
			
		||||
 | 
			
		||||
        ModuleVisitor mv = classVisitor.visitModule(name, flags, version);
 | 
			
		||||
        if (mv == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // module attributes (main class, packages)
 | 
			
		||||
        if (mainClass != null) {
 | 
			
		||||
            mv.visitMainClass(mainClass);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (packages != 0) {
 | 
			
		||||
            for (int i = readUnsignedShort(packages - 2); i > 0; --i) {
 | 
			
		||||
                String packaze = readPackage(packages, buffer);
 | 
			
		||||
                mv.visitPackage(packaze);
 | 
			
		||||
                packages += 2;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // reads requires
 | 
			
		||||
        u += 2;
 | 
			
		||||
        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
 | 
			
		||||
            String module = readModule(u, buffer);
 | 
			
		||||
            int access = readUnsignedShort(u + 2);
 | 
			
		||||
            String requireVersion = readUTF8(u + 4, buffer);
 | 
			
		||||
            mv.visitRequire(module, access, requireVersion);
 | 
			
		||||
            u += 6;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // reads exports
 | 
			
		||||
        u += 2;
 | 
			
		||||
        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
 | 
			
		||||
            String export = readPackage(u, buffer);
 | 
			
		||||
            int access = readUnsignedShort(u + 2);
 | 
			
		||||
            int exportToCount = readUnsignedShort(u + 4);
 | 
			
		||||
            u += 6;
 | 
			
		||||
            String[] tos = null;
 | 
			
		||||
            if (exportToCount != 0) {
 | 
			
		||||
                tos = new String[exportToCount];
 | 
			
		||||
                for (int j = 0; j < tos.length; ++j) {
 | 
			
		||||
                    tos[j] = readModule(u, buffer);
 | 
			
		||||
                    u += 2;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            mv.visitExport(export, access, tos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // reads opens
 | 
			
		||||
        u += 2;
 | 
			
		||||
        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
 | 
			
		||||
            String open = readPackage(u, buffer);
 | 
			
		||||
            int access = readUnsignedShort(u + 2);
 | 
			
		||||
            int openToCount = readUnsignedShort(u + 4);
 | 
			
		||||
            u += 6;
 | 
			
		||||
            String[] tos = null;
 | 
			
		||||
            if (openToCount != 0) {
 | 
			
		||||
                tos = new String[openToCount];
 | 
			
		||||
                for (int j = 0; j < tos.length; ++j) {
 | 
			
		||||
                    tos[j] = readModule(u, buffer);
 | 
			
		||||
                    u += 2;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            mv.visitOpen(open, access, tos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // read uses
 | 
			
		||||
        u += 2;
 | 
			
		||||
        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
 | 
			
		||||
            mv.visitUse(readClass(u, buffer));
 | 
			
		||||
            u += 2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // read provides
 | 
			
		||||
        u += 2;
 | 
			
		||||
        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
 | 
			
		||||
            String service = readClass(u, buffer);
 | 
			
		||||
            int provideWithCount = readUnsignedShort(u + 2);
 | 
			
		||||
            u += 4;
 | 
			
		||||
            String[] withs = new String[provideWithCount];
 | 
			
		||||
            for (int j = 0; j < withs.length; ++j) {
 | 
			
		||||
                withs[j] = readClass(u, buffer);
 | 
			
		||||
                u += 2;
 | 
			
		||||
            }
 | 
			
		||||
            mv.visitProvide(service, withs);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mv.visitEnd();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads a field and makes the given visitor visit it.
 | 
			
		||||
     * 
 | 
			
		||||
| 
						 | 
				
			
			@ -1082,6 +1215,7 @@ public class ClassReader {
 | 
			
		|||
                u += 3;
 | 
			
		||||
                break;
 | 
			
		||||
            case ClassWriter.LABELW_INSN:
 | 
			
		||||
            case ClassWriter.ASM_LABELW_INSN:
 | 
			
		||||
                readLabel(offset + readInt(u + 1), labels);
 | 
			
		||||
                u += 5;
 | 
			
		||||
                break;
 | 
			
		||||
| 
						 | 
				
			
			@ -1305,7 +1439,8 @@ public class ClassReader {
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if ((context.flags & EXPAND_ASM_INSNS) != 0) {
 | 
			
		||||
        if ((context.flags & EXPAND_ASM_INSNS) != 0
 | 
			
		||||
            && (context.flags & EXPAND_FRAMES) != 0) {
 | 
			
		||||
            // Expanding the ASM pseudo instructions can introduce F_INSERT
 | 
			
		||||
            // frames, even if the method does not currently have any frame.
 | 
			
		||||
            // Also these inserted frames must be computed by simulating the
 | 
			
		||||
| 
						 | 
				
			
			@ -1322,6 +1457,7 @@ public class ClassReader {
 | 
			
		|||
 | 
			
		||||
        // visits the instructions
 | 
			
		||||
        int opcodeDelta = (context.flags & EXPAND_ASM_INSNS) == 0 ? -33 : 0;
 | 
			
		||||
        boolean insertFrame = false;
 | 
			
		||||
        u = codeStart;
 | 
			
		||||
        while (u < codeEnd) {
 | 
			
		||||
            int offset = u - codeStart;
 | 
			
		||||
| 
						 | 
				
			
			@ -1354,6 +1490,9 @@ public class ClassReader {
 | 
			
		|||
                        mv.visitFrame(frame.mode, frame.localDiff, frame.local,
 | 
			
		||||
                                frame.stackCount, frame.stack);
 | 
			
		||||
                    }
 | 
			
		||||
                    // if there is already a frame for this offset, there is no
 | 
			
		||||
                    // need to insert a new one.
 | 
			
		||||
                    insertFrame = false;
 | 
			
		||||
                }
 | 
			
		||||
                if (frameCount > 0) {
 | 
			
		||||
                    stackMap = readFrame(stackMap, zip, unzip, frame);
 | 
			
		||||
| 
						 | 
				
			
			@ -1362,6 +1501,13 @@ public class ClassReader {
 | 
			
		|||
                    frame = null;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // inserts a frame for this offset, if requested by setting
 | 
			
		||||
            // insertFrame to true during the previous iteration. The actual
 | 
			
		||||
            // frame content will be computed in MethodWriter.
 | 
			
		||||
            if (FRAMES && insertFrame) {
 | 
			
		||||
                mv.visitFrame(ClassWriter.F_INSERT, 0, null, 0, null);
 | 
			
		||||
                insertFrame = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // visits the instruction at this offset
 | 
			
		||||
            int opcode = b[u] & 0xFF;
 | 
			
		||||
| 
						 | 
				
			
			@ -1397,31 +1543,36 @@ public class ClassReader {
 | 
			
		|||
                opcode = opcode < 218 ? opcode - 49 : opcode - 20;
 | 
			
		||||
                Label target = labels[offset + readUnsignedShort(u + 1)];
 | 
			
		||||
                // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
 | 
			
		||||
                // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
 | 
			
		||||
                // <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is
 | 
			
		||||
                // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
 | 
			
		||||
                // and where <l'> designates the instruction just after
 | 
			
		||||
                // and where <L> designates the instruction just after
 | 
			
		||||
                // the GOTO_W.
 | 
			
		||||
                if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
 | 
			
		||||
                    mv.visitJumpInsn(opcode + 33, target);
 | 
			
		||||
                } else {
 | 
			
		||||
                    opcode = opcode <= 166 ? ((opcode + 1) ^ 1) - 1
 | 
			
		||||
                            : opcode ^ 1;
 | 
			
		||||
                    Label endif = new Label();
 | 
			
		||||
                    Label endif = readLabel(offset + 3, labels);
 | 
			
		||||
                    mv.visitJumpInsn(opcode, endif);
 | 
			
		||||
                    mv.visitJumpInsn(200, target); // GOTO_W
 | 
			
		||||
                    mv.visitLabel(endif);
 | 
			
		||||
                    // since we introduced an unconditional jump instruction we
 | 
			
		||||
                    // also need to insert a stack map frame here, unless there
 | 
			
		||||
                    // is already one. The actual frame content will be computed
 | 
			
		||||
                    // in MethodWriter.
 | 
			
		||||
                    if (FRAMES && stackMap != 0
 | 
			
		||||
                            && (frame == null || frame.offset != offset + 3)) {
 | 
			
		||||
                        mv.visitFrame(ClassWriter.F_INSERT, 0, null, 0, null);
 | 
			
		||||
                    }
 | 
			
		||||
                    // endif designates the instruction just after GOTO_W,
 | 
			
		||||
                    // and is visited as part of the next instruction. Since
 | 
			
		||||
                    // it is a jump target, we need to insert a frame here.
 | 
			
		||||
                    insertFrame = true;
 | 
			
		||||
                }
 | 
			
		||||
                u += 3;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ClassWriter.ASM_LABELW_INSN: {
 | 
			
		||||
                // replaces the pseudo GOTO_W instruction with a real one.
 | 
			
		||||
                mv.visitJumpInsn(200, labels[offset + readInt(u + 1)]);
 | 
			
		||||
                // The instruction just after is a jump target (because pseudo
 | 
			
		||||
                // GOTO_W are used in patterns IFNOTxxx <L> GOTO_W <l> L:...,
 | 
			
		||||
                // see MethodWriter), so we need to insert a frame here.
 | 
			
		||||
                insertFrame = true;
 | 
			
		||||
                u += 5;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ClassWriter.WIDE_INSN:
 | 
			
		||||
                opcode = b[u + 1] & 0xFF;
 | 
			
		||||
                if (opcode == Opcodes.IINC) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2516,6 +2667,20 @@ public class ClassReader {
 | 
			
		|||
        return new String(buf, 0, strLen);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read a stringish constant item (CONSTANT_Class, CONSTANT_String,
 | 
			
		||||
     * CONSTANT_MethodType, CONSTANT_Module or CONSTANT_Package
 | 
			
		||||
     * @param index
 | 
			
		||||
     * @param buf
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private String readStringish(final int index, final char[] buf) {
 | 
			
		||||
        // computes the start index of the item in b
 | 
			
		||||
        // and reads the CONSTANT_Utf8 item designated by
 | 
			
		||||
        // the first two bytes of this item
 | 
			
		||||
        return readUTF8(items[readUnsignedShort(index)], buf);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads a class constant pool item in {@link #b b}. <i>This method is
 | 
			
		||||
     * intended for {@link Attribute} sub classes, and is normally not needed by
 | 
			
		||||
| 
						 | 
				
			
			@ -2530,11 +2695,41 @@ public class ClassReader {
 | 
			
		|||
     * @return the String corresponding to the specified class item.
 | 
			
		||||
     */
 | 
			
		||||
    public String readClass(final int index, final char[] buf) {
 | 
			
		||||
        // computes the start index of the CONSTANT_Class item in b
 | 
			
		||||
        // and reads the CONSTANT_Utf8 item designated by
 | 
			
		||||
        // the first two bytes of this CONSTANT_Class item
 | 
			
		||||
        String name = readUTF8(items[readUnsignedShort(index)], buf);
 | 
			
		||||
        return (name != null ? name.intern() : null);
 | 
			
		||||
        return readStringish(index, buf);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads a module constant pool item in {@link #b b}. <i>This method is
 | 
			
		||||
     * intended for {@link Attribute} sub classes, and is normally not needed by
 | 
			
		||||
     * class generators or adapters.</i>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index
 | 
			
		||||
     *            the start index of an unsigned short value in {@link #b b},
 | 
			
		||||
     *            whose value is the index of a module constant pool item.
 | 
			
		||||
     * @param buf
 | 
			
		||||
     *            buffer to be used to read the item. This buffer must be
 | 
			
		||||
     *            sufficiently large. It is not automatically resized.
 | 
			
		||||
     * @return the String corresponding to the specified module item.
 | 
			
		||||
     */
 | 
			
		||||
    public String readModule(final int index, final char[] buf) {
 | 
			
		||||
        return readStringish(index, buf);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads a module constant pool item in {@link #b b}. <i>This method is
 | 
			
		||||
     * intended for {@link Attribute} sub classes, and is normally not needed by
 | 
			
		||||
     * class generators or adapters.</i>
 | 
			
		||||
     *
 | 
			
		||||
     * @param index
 | 
			
		||||
     *            the start index of an unsigned short value in {@link #b b},
 | 
			
		||||
     *            whose value is the index of a module constant pool item.
 | 
			
		||||
     * @param buf
 | 
			
		||||
     *            buffer to be used to read the item. This buffer must be
 | 
			
		||||
     *            sufficiently large. It is not automatically resized.
 | 
			
		||||
     * @return the String corresponding to the specified module item.
 | 
			
		||||
     */
 | 
			
		||||
    public String readPackage(final int index, final char[] buf) {
 | 
			
		||||
        return readStringish(index, buf);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ package org.springframework.asm;
 | 
			
		|||
/**
 | 
			
		||||
 * A visitor to visit a Java class. The methods of this class must be called in
 | 
			
		||||
 * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
 | 
			
		||||
 * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
 | 
			
		||||
 * <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
 | 
			
		||||
 * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
 | 
			
		||||
 * <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
 | 
			
		||||
 * <tt>visitEnd</tt>.
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ public abstract class ClassVisitor {
 | 
			
		|||
 | 
			
		||||
    /**
 | 
			
		||||
     * The ASM API version implemented by this visitor. The value of this field
 | 
			
		||||
     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    protected final int api;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ public abstract class ClassVisitor {
 | 
			
		|||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be one
 | 
			
		||||
     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    public ClassVisitor(final int api) {
 | 
			
		||||
        this(api, null);
 | 
			
		||||
| 
						 | 
				
			
			@ -69,13 +69,13 @@ public abstract class ClassVisitor {
 | 
			
		|||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be one
 | 
			
		||||
     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     * @param cv
 | 
			
		||||
     *            the class visitor to which this visitor must delegate method
 | 
			
		||||
     *            calls. May be null.
 | 
			
		||||
     */
 | 
			
		||||
    public ClassVisitor(final int api, final ClassVisitor cv) {
 | 
			
		||||
        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
 | 
			
		||||
        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
 | 
			
		||||
            throw new IllegalArgumentException();
 | 
			
		||||
        }
 | 
			
		||||
        this.api = api;
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +131,28 @@ public abstract class ClassVisitor {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Visit the module corresponding to the class.
 | 
			
		||||
     * @param name
 | 
			
		||||
     *            module name
 | 
			
		||||
     * @param access
 | 
			
		||||
     *            module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
 | 
			
		||||
     *            and {@code ACC_MANDATED}.
 | 
			
		||||
     * @param version
 | 
			
		||||
     *            module version or null.
 | 
			
		||||
     * @return a visitor to visit the module values, or <tt>null</tt> if
 | 
			
		||||
     *         this visitor is not interested in visiting this module.
 | 
			
		||||
     */
 | 
			
		||||
    public ModuleVisitor visitModule(String name, int access, String version) {
 | 
			
		||||
        if (api < Opcodes.ASM6) {
 | 
			
		||||
            throw new RuntimeException();
 | 
			
		||||
        }
 | 
			
		||||
        if (cv != null) {
 | 
			
		||||
            return cv.visitModule(name, access, version);
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Visits the enclosing class of the class. This method must be called only
 | 
			
		||||
     * if the class has an enclosing class.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -173,6 +173,11 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
     */
 | 
			
		||||
    static final int ASM_LABEL_INSN = 18;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The type of the ASM pseudo instructions with a 4 bytes offset label.
 | 
			
		||||
     */
 | 
			
		||||
    static final int ASM_LABELW_INSN = 19;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Represents a frame inserted between already existing frames. This kind of
 | 
			
		||||
     * frame can only be used if the frame content can be computed from the
 | 
			
		||||
| 
						 | 
				
			
			@ -258,10 +263,20 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
     */
 | 
			
		||||
    static final int INDY = 18;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The type of CONSTANT_Module constant pool items.
 | 
			
		||||
     */
 | 
			
		||||
    static final int MODULE = 19;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The type of CONSTANT_Package constant pool items.
 | 
			
		||||
     */
 | 
			
		||||
    static final int PACKAGE = 20;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The base value for all CONSTANT_MethodHandle constant pool items.
 | 
			
		||||
     * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
 | 
			
		||||
     * different items.
 | 
			
		||||
     * different items (from 21 to 29).
 | 
			
		||||
     */
 | 
			
		||||
    static final int HANDLE_BASE = 20;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -410,6 +425,11 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
     */
 | 
			
		||||
    private ByteVector sourceDebug;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The module attribute of this class.
 | 
			
		||||
     */
 | 
			
		||||
    private ModuleWriter moduleWriter;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The constant pool item that contains the name of the enclosing class of
 | 
			
		||||
     * this class.
 | 
			
		||||
| 
						 | 
				
			
			@ -523,11 +543,11 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
     */
 | 
			
		||||
    static {
 | 
			
		||||
        int i;
 | 
			
		||||
        byte[] b = new byte[220];
 | 
			
		||||
        byte[] b = new byte[221];
 | 
			
		||||
        String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
 | 
			
		||||
                + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
 | 
			
		||||
                + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
 | 
			
		||||
                + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSS";
 | 
			
		||||
                + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSST";
 | 
			
		||||
        for (i = 0; i < b.length; ++i) {
 | 
			
		||||
            b[i] = (byte) (s.charAt(i) - 'A');
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -583,6 +603,7 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
        // for (i = 202; i < 220; ++i) {
 | 
			
		||||
        // b[i] = ASM_LABEL_INSN;
 | 
			
		||||
        // }
 | 
			
		||||
        // b[220] = ASM_LABELW_INSN;
 | 
			
		||||
        //
 | 
			
		||||
        // // LDC(_W) instructions
 | 
			
		||||
        // b[Constants.LDC] = LDC_INSN;
 | 
			
		||||
| 
						 | 
				
			
			@ -615,7 +636,7 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
     *            {@link #COMPUTE_FRAMES}.
 | 
			
		||||
     */
 | 
			
		||||
    public ClassWriter(final int flags) {
 | 
			
		||||
        super(Opcodes.ASM5);
 | 
			
		||||
        super(Opcodes.ASM6);
 | 
			
		||||
        index = 1;
 | 
			
		||||
        pool = new ByteVector();
 | 
			
		||||
        items = new Item[256];
 | 
			
		||||
| 
						 | 
				
			
			@ -703,6 +724,14 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public final ModuleVisitor visitModule(final String name,
 | 
			
		||||
            final int access, final String version) {
 | 
			
		||||
        return moduleWriter = new ModuleWriter(this,
 | 
			
		||||
                newModule(name), access,
 | 
			
		||||
                version == null ? 0 : newUTF8(version));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public final void visitOuterClass(final String owner, final String name,
 | 
			
		||||
            final String desc) {
 | 
			
		||||
| 
						 | 
				
			
			@ -777,7 +806,7 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
        // and equality tests). If so we store the index of this inner class
 | 
			
		||||
        // entry (plus one) in intVal. This hack allows duplicate detection in
 | 
			
		||||
        // O(1) time.
 | 
			
		||||
        Item nameItem = newClassItem(name);
 | 
			
		||||
        Item nameItem = newStringishItem(CLASS, name);
 | 
			
		||||
        if (nameItem.intVal == 0) {
 | 
			
		||||
            ++innerClassesCount;
 | 
			
		||||
            innerClasses.putShort(nameItem.index);
 | 
			
		||||
| 
						 | 
				
			
			@ -904,6 +933,11 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
            size += 8 + itanns.getSize();
 | 
			
		||||
            newUTF8("RuntimeInvisibleTypeAnnotations");
 | 
			
		||||
        }
 | 
			
		||||
        if (moduleWriter != null) {
 | 
			
		||||
            attributeCount += 1 + moduleWriter.attributeCount;
 | 
			
		||||
            size += 6 + moduleWriter.size + moduleWriter.attributesSize;
 | 
			
		||||
            newUTF8("Module");
 | 
			
		||||
        }
 | 
			
		||||
        if (attrs != null) {
 | 
			
		||||
            attributeCount += attrs.getCount();
 | 
			
		||||
            size += attrs.getSize(this, null, 0, -1, -1);
 | 
			
		||||
| 
						 | 
				
			
			@ -951,6 +985,11 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
            out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
 | 
			
		||||
            out.putByteArray(sourceDebug.data, 0, len);
 | 
			
		||||
        }
 | 
			
		||||
        if (moduleWriter != null) {
 | 
			
		||||
            out.putShort(newUTF8("Module"));
 | 
			
		||||
            moduleWriter.put(out);
 | 
			
		||||
            moduleWriter.putAttributes(out);
 | 
			
		||||
        }
 | 
			
		||||
        if (enclosingMethodOwner != 0) {
 | 
			
		||||
            out.putShort(newUTF8("EnclosingMethod")).putInt(4);
 | 
			
		||||
            out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
 | 
			
		||||
| 
						 | 
				
			
			@ -989,18 +1028,26 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
            attrs.put(this, null, 0, -1, -1, out);
 | 
			
		||||
        }
 | 
			
		||||
        if (hasAsmInsns) {
 | 
			
		||||
            boolean hasFrames = false;
 | 
			
		||||
            mb = firstMethod;
 | 
			
		||||
            while (mb != null) {
 | 
			
		||||
                hasFrames |= mb.frameCount > 0;
 | 
			
		||||
                mb = (MethodWriter) mb.mv;
 | 
			
		||||
            }
 | 
			
		||||
            anns = null;
 | 
			
		||||
            ianns = null;
 | 
			
		||||
            attrs = null;
 | 
			
		||||
            moduleWriter = null;
 | 
			
		||||
            innerClassesCount = 0;
 | 
			
		||||
            innerClasses = null;
 | 
			
		||||
            firstField = null;
 | 
			
		||||
            lastField = null;
 | 
			
		||||
            firstMethod = null;
 | 
			
		||||
            lastMethod = null;
 | 
			
		||||
            compute = MethodWriter.INSERTED_FRAMES;
 | 
			
		||||
            compute = hasFrames ? MethodWriter.INSERTED_FRAMES : 0;
 | 
			
		||||
            hasAsmInsns = false;
 | 
			
		||||
            new ClassReader(out.data).accept(this, ClassReader.EXPAND_FRAMES
 | 
			
		||||
            new ClassReader(out.data).accept(this,
 | 
			
		||||
                    (hasFrames ? ClassReader.EXPAND_FRAMES : 0)
 | 
			
		||||
                    | ClassReader.EXPAND_ASM_INSNS);
 | 
			
		||||
            return toByteArray();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1048,16 +1095,16 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
            double val = ((Double) cst).doubleValue();
 | 
			
		||||
            return newDouble(val);
 | 
			
		||||
        } else if (cst instanceof String) {
 | 
			
		||||
            return newString((String) cst);
 | 
			
		||||
            return newStringishItem(STR, (String) cst);
 | 
			
		||||
        } else if (cst instanceof Type) {
 | 
			
		||||
            Type t = (Type) cst;
 | 
			
		||||
            int s = t.getSort();
 | 
			
		||||
            if (s == Type.OBJECT) {
 | 
			
		||||
                return newClassItem(t.getInternalName());
 | 
			
		||||
                return newStringishItem(CLASS, t.getInternalName());
 | 
			
		||||
            } else if (s == Type.METHOD) {
 | 
			
		||||
                return newMethodTypeItem(t.getDescriptor());
 | 
			
		||||
                return newStringishItem(MTYPE, t.getDescriptor());
 | 
			
		||||
            } else { // s == primitive type or array
 | 
			
		||||
                return newClassItem(t.getDescriptor());
 | 
			
		||||
                return newStringishItem(CLASS, t.getDescriptor());
 | 
			
		||||
            }
 | 
			
		||||
        } else if (cst instanceof Handle) {
 | 
			
		||||
            Handle h = (Handle) cst;
 | 
			
		||||
| 
						 | 
				
			
			@ -1106,20 +1153,21 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a class reference to the constant pool of the class being build.
 | 
			
		||||
     * Adds a string reference, a class reference, a method type, a module
 | 
			
		||||
     * or a package to the constant pool of the class being build.
 | 
			
		||||
     * Does nothing if the constant pool already contains a similar item.
 | 
			
		||||
     * <i>This method is intended for {@link Attribute} sub classes, and is
 | 
			
		||||
     * normally not needed by class generators or adapters.</i>
 | 
			
		||||
     * 
 | 
			
		||||
     * @param type
 | 
			
		||||
     *            a type among STR, CLASS, MTYPE, MODULE or PACKAGE
 | 
			
		||||
     * @param value
 | 
			
		||||
     *            the internal name of the class.
 | 
			
		||||
     * @return a new or already existing class reference item.
 | 
			
		||||
     *            string value of the reference.
 | 
			
		||||
     * @return a new or already existing reference item.
 | 
			
		||||
     */
 | 
			
		||||
    Item newClassItem(final String value) {
 | 
			
		||||
        key2.set(CLASS, value, null, null);
 | 
			
		||||
    Item newStringishItem(final int type, final String value) {
 | 
			
		||||
        key2.set(type, value, null, null);
 | 
			
		||||
        Item result = get(key2);
 | 
			
		||||
        if (result == null) {
 | 
			
		||||
            pool.put12(CLASS, newUTF8(value));
 | 
			
		||||
            pool.put12(type, newUTF8(value));
 | 
			
		||||
            result = new Item(index++, key2);
 | 
			
		||||
            put(result);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1137,28 +1185,7 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
     * @return the index of a new or already existing class reference item.
 | 
			
		||||
     */
 | 
			
		||||
    public int newClass(final String value) {
 | 
			
		||||
        return newClassItem(value).index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a method type reference to the constant pool of the class being
 | 
			
		||||
     * build. Does nothing if the constant pool already contains a similar item.
 | 
			
		||||
     * <i>This method is intended for {@link Attribute} sub classes, and is
 | 
			
		||||
     * normally not needed by class generators or adapters.</i>
 | 
			
		||||
     * 
 | 
			
		||||
     * @param methodDesc
 | 
			
		||||
     *            method descriptor of the method type.
 | 
			
		||||
     * @return a new or already existing method type reference item.
 | 
			
		||||
     */
 | 
			
		||||
    Item newMethodTypeItem(final String methodDesc) {
 | 
			
		||||
        key2.set(MTYPE, methodDesc, null, null);
 | 
			
		||||
        Item result = get(key2);
 | 
			
		||||
        if (result == null) {
 | 
			
		||||
            pool.put12(MTYPE, newUTF8(methodDesc));
 | 
			
		||||
            result = new Item(index++, key2);
 | 
			
		||||
            put(result);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
        return newStringishItem(CLASS, value).index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -1173,7 +1200,37 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
     *         item.
 | 
			
		||||
     */
 | 
			
		||||
    public int newMethodType(final String methodDesc) {
 | 
			
		||||
        return newMethodTypeItem(methodDesc).index;
 | 
			
		||||
        return newStringishItem(MTYPE, methodDesc).index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a module reference to the constant pool of the class being
 | 
			
		||||
     * build. Does nothing if the constant pool already contains a similar item.
 | 
			
		||||
     * <i>This method is intended for {@link Attribute} sub classes, and is
 | 
			
		||||
     * normally not needed by class generators or adapters.</i>
 | 
			
		||||
     * 
 | 
			
		||||
     * @param moduleName
 | 
			
		||||
     *            name of the module.
 | 
			
		||||
     * @return the index of a new or already existing module reference
 | 
			
		||||
     *         item.
 | 
			
		||||
     */
 | 
			
		||||
    public int newModule(final String moduleName) {
 | 
			
		||||
        return newStringishItem(MODULE, moduleName).index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a package reference to the constant pool of the class being
 | 
			
		||||
     * build. Does nothing if the constant pool already contains a similar item.
 | 
			
		||||
     * <i>This method is intended for {@link Attribute} sub classes, and is
 | 
			
		||||
     * normally not needed by class generators or adapters.</i>
 | 
			
		||||
     *
 | 
			
		||||
     * @param packageName
 | 
			
		||||
     *            name of the package in its internal form.
 | 
			
		||||
     * @return the index of a new or already existing module reference
 | 
			
		||||
     *         item.
 | 
			
		||||
     */
 | 
			
		||||
    public int newPackage(final String packageName) {
 | 
			
		||||
        return newStringishItem(PACKAGE, packageName).index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -1554,25 +1611,6 @@ public class ClassWriter extends ClassVisitor {
 | 
			
		|||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a string to the constant pool of the class being build. Does nothing
 | 
			
		||||
     * if the constant pool already contains a similar item.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param value
 | 
			
		||||
     *            the String value.
 | 
			
		||||
     * @return a new or already existing string item.
 | 
			
		||||
     */
 | 
			
		||||
    private Item newString(final String value) {
 | 
			
		||||
        key2.set(STR, value, null, null);
 | 
			
		||||
        Item result = get(key2);
 | 
			
		||||
        if (result == null) {
 | 
			
		||||
            pool.put12(STR, newUTF8(value));
 | 
			
		||||
            result = new Item(index++, key2);
 | 
			
		||||
            put(result);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a name and type to the constant pool of the class being build. Does
 | 
			
		||||
     * nothing if the constant pool already contains a similar item. <i>This
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ public abstract class FieldVisitor {
 | 
			
		|||
 | 
			
		||||
    /**
 | 
			
		||||
     * The ASM API version implemented by this visitor. The value of this field
 | 
			
		||||
     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    protected final int api;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ public abstract class FieldVisitor {
 | 
			
		|||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be one
 | 
			
		||||
     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    public FieldVisitor(final int api) {
 | 
			
		||||
        this(api, null);
 | 
			
		||||
| 
						 | 
				
			
			@ -66,13 +66,13 @@ public abstract class FieldVisitor {
 | 
			
		|||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be one
 | 
			
		||||
     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     * @param fv
 | 
			
		||||
     *            the field visitor to which this visitor must delegate method
 | 
			
		||||
     *            calls. May be null.
 | 
			
		||||
     */
 | 
			
		||||
    public FieldVisitor(final int api, final FieldVisitor fv) {
 | 
			
		||||
        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
 | 
			
		||||
        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
 | 
			
		||||
            throw new IllegalArgumentException();
 | 
			
		||||
        }
 | 
			
		||||
        this.api = api;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ final class FieldWriter extends FieldVisitor {
 | 
			
		|||
     */
 | 
			
		||||
    FieldWriter(final ClassWriter cw, final int access, final String name,
 | 
			
		||||
            final String desc, final String signature, final Object value) {
 | 
			
		||||
        super(Opcodes.ASM5);
 | 
			
		||||
        super(Opcodes.ASM6);
 | 
			
		||||
        if (cw.firstField == null) {
 | 
			
		||||
            cw.firstField = this;
 | 
			
		||||
        } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,7 @@ final class Item {
 | 
			
		|||
     * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
 | 
			
		||||
     * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
 | 
			
		||||
     * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
 | 
			
		||||
     * {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
 | 
			
		||||
     * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
 | 
			
		||||
     * 
 | 
			
		||||
     * MethodHandle constant 9 variations are stored using a range of 9 values
 | 
			
		||||
| 
						 | 
				
			
			@ -214,6 +215,8 @@ final class Item {
 | 
			
		|||
        case ClassWriter.UTF8:
 | 
			
		||||
        case ClassWriter.STR:
 | 
			
		||||
        case ClassWriter.MTYPE:
 | 
			
		||||
        case ClassWriter.MODULE:
 | 
			
		||||
        case ClassWriter.PACKAGE:
 | 
			
		||||
        case ClassWriter.TYPE_NORMAL:
 | 
			
		||||
            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
 | 
			
		||||
            return;
 | 
			
		||||
| 
						 | 
				
			
			@ -282,6 +285,8 @@ final class Item {
 | 
			
		|||
        case ClassWriter.UTF8:
 | 
			
		||||
        case ClassWriter.STR:
 | 
			
		||||
        case ClassWriter.CLASS:
 | 
			
		||||
        case ClassWriter.MODULE:
 | 
			
		||||
        case ClassWriter.PACKAGE:
 | 
			
		||||
        case ClassWriter.MTYPE:
 | 
			
		||||
        case ClassWriter.TYPE_NORMAL:
 | 
			
		||||
            return i.strVal1.equals(strVal1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ public abstract class MethodVisitor {
 | 
			
		|||
 | 
			
		||||
    /**
 | 
			
		||||
     * The ASM API version implemented by this visitor. The value of this field
 | 
			
		||||
     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    protected final int api;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ public abstract class MethodVisitor {
 | 
			
		|||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be one
 | 
			
		||||
     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    public MethodVisitor(final int api) {
 | 
			
		||||
        this(api, null);
 | 
			
		||||
| 
						 | 
				
			
			@ -83,13 +83,13 @@ public abstract class MethodVisitor {
 | 
			
		|||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be one
 | 
			
		||||
     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
 | 
			
		||||
     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 | 
			
		||||
     * @param mv
 | 
			
		||||
     *            the method visitor to which this visitor must delegate method
 | 
			
		||||
     *            calls. May be null.
 | 
			
		||||
     */
 | 
			
		||||
    public MethodVisitor(final int api, final MethodVisitor mv) {
 | 
			
		||||
        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
 | 
			
		||||
        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
 | 
			
		||||
            throw new IllegalArgumentException();
 | 
			
		||||
        }
 | 
			
		||||
        this.api = api;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -260,7 +260,7 @@ class MethodWriter extends MethodVisitor {
 | 
			
		|||
    /**
 | 
			
		||||
     * Number of stack map frames in the StackMapTable attribute.
 | 
			
		||||
     */
 | 
			
		||||
    private int frameCount;
 | 
			
		||||
    int frameCount;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The StackMapTable attribute.
 | 
			
		||||
| 
						 | 
				
			
			@ -456,7 +456,7 @@ class MethodWriter extends MethodVisitor {
 | 
			
		|||
    MethodWriter(final ClassWriter cw, final int access, final String name,
 | 
			
		||||
            final String desc, final String signature,
 | 
			
		||||
            final String[] exceptions, final int compute) {
 | 
			
		||||
        super(Opcodes.ASM5);
 | 
			
		||||
        super(Opcodes.ASM6);
 | 
			
		||||
        if (cw.firstMethod == null) {
 | 
			
		||||
            cw.firstMethod = this;
 | 
			
		||||
        } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -848,7 +848,7 @@ class MethodWriter extends MethodVisitor {
 | 
			
		|||
    @Override
 | 
			
		||||
    public void visitTypeInsn(final int opcode, final String type) {
 | 
			
		||||
        lastCodeOffset = code.length;
 | 
			
		||||
        Item i = cw.newClassItem(type);
 | 
			
		||||
        Item i = cw.newStringishItem(ClassWriter.CLASS, type);
 | 
			
		||||
        // Label currentBlock = this.currentBlock;
 | 
			
		||||
        if (currentBlock != null) {
 | 
			
		||||
            if (compute == FRAMES || compute == INSERTED_FRAMES) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1050,8 +1050,8 @@ class MethodWriter extends MethodVisitor {
 | 
			
		|||
            /*
 | 
			
		||||
             * case of a backward jump with an offset < -32768. In this case we
 | 
			
		||||
             * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
 | 
			
		||||
             * <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the
 | 
			
		||||
             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <l'>
 | 
			
		||||
             * <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is the
 | 
			
		||||
             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <L>
 | 
			
		||||
             * designates the instruction just after the GOTO_W.
 | 
			
		||||
             */
 | 
			
		||||
            if (opcode == Opcodes.GOTO) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1067,7 +1067,11 @@ class MethodWriter extends MethodVisitor {
 | 
			
		|||
                code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
 | 
			
		||||
                        : opcode ^ 1);
 | 
			
		||||
                code.putShort(8); // jump offset
 | 
			
		||||
                code.putByte(200); // GOTO_W
 | 
			
		||||
                // ASM pseudo GOTO_W insn, see ClassReader. We don't use a real
 | 
			
		||||
                // GOTO_W because we might need to insert a frame just after (as
 | 
			
		||||
                // the target of the IFNOTxxx jump instruction).
 | 
			
		||||
                code.putByte(220);
 | 
			
		||||
                cw.hasAsmInsns = true;
 | 
			
		||||
            }
 | 
			
		||||
            label.put(this, code, code.length - 1, true);
 | 
			
		||||
        } else if (isWide) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1291,7 +1295,7 @@ class MethodWriter extends MethodVisitor {
 | 
			
		|||
    @Override
 | 
			
		||||
    public void visitMultiANewArrayInsn(final String desc, final int dims) {
 | 
			
		||||
        lastCodeOffset = code.length;
 | 
			
		||||
        Item i = cw.newClassItem(desc);
 | 
			
		||||
        Item i = cw.newStringishItem(ClassWriter.CLASS, desc);
 | 
			
		||||
        // Label currentBlock = this.currentBlock;
 | 
			
		||||
        if (currentBlock != null) {
 | 
			
		||||
            if (compute == FRAMES || compute == INSERTED_FRAMES) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,178 @@
 | 
			
		|||
/***
 | 
			
		||||
 * ASM: a very small and fast Java bytecode manipulation framework
 | 
			
		||||
 * Copyright (c) 2000-2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.asm;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A visitor to visit a Java module. The methods of this class must be called in
 | 
			
		||||
 * the following order: <tt>visitVersion</tt> | <tt>visitMainClass</tt> |
 | 
			
		||||
 * <tt>visitTargetPlatform</tt> | ( <tt>visitConcealedPackage</tt> | <tt>visitRequire</tt> |
 | 
			
		||||
 * <tt>visitExport</tt> | <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Remi Forax
 | 
			
		||||
 */
 | 
			
		||||
public abstract class ModuleVisitor {
 | 
			
		||||
    /**
 | 
			
		||||
     * The ASM API version implemented by this visitor. The value of this field
 | 
			
		||||
     * must be {@link Opcodes#ASM6}.
 | 
			
		||||
     */
 | 
			
		||||
    protected final int api;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * The module visitor to which this visitor must delegate method calls. May
 | 
			
		||||
     * be null.
 | 
			
		||||
     */
 | 
			
		||||
    protected ModuleVisitor mv;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    public ModuleVisitor(final int api) {
 | 
			
		||||
        this(api, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new {@link MethodVisitor}.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param api
 | 
			
		||||
     *            the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
 | 
			
		||||
     * @param mv
 | 
			
		||||
     *            the method visitor to which this visitor must delegate method
 | 
			
		||||
     *            calls. May be null.
 | 
			
		||||
     */
 | 
			
		||||
    public ModuleVisitor(final int api, final ModuleVisitor mv) {
 | 
			
		||||
        if (api != Opcodes.ASM6) {
 | 
			
		||||
            throw new IllegalArgumentException();
 | 
			
		||||
        }
 | 
			
		||||
        this.api = api;
 | 
			
		||||
        this.mv = mv;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Visit the main class of the current module.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param mainClass the main class of the current module.
 | 
			
		||||
     */
 | 
			
		||||
    public void visitMainClass(String mainClass) {
 | 
			
		||||
        if (mv != null) {
 | 
			
		||||
            mv.visitMainClass(mainClass);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Visit a concealed package of the current module.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param packaze name of a concealed package
 | 
			
		||||
     */
 | 
			
		||||
    public void visitPackage(String packaze) {
 | 
			
		||||
        if (mv != null) {
 | 
			
		||||
            mv.visitPackage(packaze);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Visits a dependence of the current module.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param module the module name of the dependence
 | 
			
		||||
     * @param access the access flag of the dependence among
 | 
			
		||||
     *        ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC
 | 
			
		||||
     *        and ACC_MANDATED.
 | 
			
		||||
     * @param version the module version at compile time or null.
 | 
			
		||||
     */
 | 
			
		||||
    public void visitRequire(String module, int access, String version) {
 | 
			
		||||
        if (mv != null) {
 | 
			
		||||
            mv.visitRequire(module, access, version);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Visit an exported package of the current module.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param packaze the name of the exported package.
 | 
			
		||||
     * @param access the access flag of the exported package,
 | 
			
		||||
     *        valid values are among {@code ACC_SYNTHETIC} and
 | 
			
		||||
     *        {@code ACC_MANDATED}.
 | 
			
		||||
     * @param modules names of the modules that can access to
 | 
			
		||||
     *        the public classes of the exported package or
 | 
			
		||||
     *        <tt>null</tt>.
 | 
			
		||||
     */
 | 
			
		||||
    public void visitExport(String packaze, int access, String... modules) {
 | 
			
		||||
        if (mv != null) {
 | 
			
		||||
            mv.visitExport(packaze, access, modules);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Visit an open package of the current module.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param packaze the name of the opened package.
 | 
			
		||||
     * @param access the access flag of the opened package,
 | 
			
		||||
     *        valid values are among {@code ACC_SYNTHETIC} and
 | 
			
		||||
     *        {@code ACC_MANDATED}.
 | 
			
		||||
     * @param modules names of the modules that can use deep
 | 
			
		||||
     *        reflection to the classes of the open package or
 | 
			
		||||
     *        <tt>null</tt>.
 | 
			
		||||
     */
 | 
			
		||||
    public void visitOpen(String packaze, int access, String... modules) {
 | 
			
		||||
        if (mv != null) {
 | 
			
		||||
            mv.visitOpen(packaze, access, modules);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Visit a service used by the current module.
 | 
			
		||||
     * The name must be the name of an interface or an
 | 
			
		||||
     * abstract class.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param service the internal name of the service.
 | 
			
		||||
     */
 | 
			
		||||
    public void visitUse(String service) {
 | 
			
		||||
        if (mv != null) {
 | 
			
		||||
            mv.visitUse(service);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Visit an implementation of a service.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param service the internal name of the service
 | 
			
		||||
     * @param providers the internal names of the implementations
 | 
			
		||||
     *        of the service (there is at least one provider).
 | 
			
		||||
     */
 | 
			
		||||
    public void visitProvide(String service, String... providers) {
 | 
			
		||||
        if (mv != null) {
 | 
			
		||||
            mv.visitProvide(service, providers);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public void visitEnd() {
 | 
			
		||||
        if (mv != null) {
 | 
			
		||||
            mv.visitEnd();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,293 @@
 | 
			
		|||
/***
 | 
			
		||||
 * ASM: a very small and fast Java bytecode manipulation framework
 | 
			
		||||
 * Copyright (c) 2000-2011 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.asm;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Remi Forax
 | 
			
		||||
 */
 | 
			
		||||
final class ModuleWriter extends ModuleVisitor {
 | 
			
		||||
    /**
 | 
			
		||||
     * The class writer to which this Module attribute must be added.
 | 
			
		||||
     */
 | 
			
		||||
    private final ClassWriter cw;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * size in byte of the Module attribute.
 | 
			
		||||
     */
 | 
			
		||||
    int size;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Number of attributes associated with the current module
 | 
			
		||||
     * (Version, ConcealPackages, etc) 
 | 
			
		||||
     */
 | 
			
		||||
    int attributeCount;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Size in bytes of the attributes associated with the current module
 | 
			
		||||
     */
 | 
			
		||||
    int attributesSize;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * module name index in the constant pool
 | 
			
		||||
     */
 | 
			
		||||
    private final int name;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * module access flags
 | 
			
		||||
     */
 | 
			
		||||
    private final int access;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * module version index in the constant pool or 0
 | 
			
		||||
     */
 | 
			
		||||
    private final int version;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * module main class index in the constant pool or 0
 | 
			
		||||
     */
 | 
			
		||||
    private int mainClass;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * number of packages
 | 
			
		||||
     */
 | 
			
		||||
    private int packageCount;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * The packages in bytecode form. This byte vector only contains
 | 
			
		||||
     * the items themselves, the number of items is store in packageCount
 | 
			
		||||
     */
 | 
			
		||||
    private ByteVector packages;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * number of requires items
 | 
			
		||||
     */
 | 
			
		||||
    private int requireCount;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * The requires items in bytecode form. This byte vector only contains
 | 
			
		||||
     * the items themselves, the number of items is store in requireCount
 | 
			
		||||
     */
 | 
			
		||||
    private ByteVector requires;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * number of exports items
 | 
			
		||||
     */
 | 
			
		||||
    private int exportCount;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * The exports items in bytecode form. This byte vector only contains
 | 
			
		||||
     * the items themselves, the number of items is store in exportCount
 | 
			
		||||
     */
 | 
			
		||||
    private ByteVector exports;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * number of opens items
 | 
			
		||||
     */
 | 
			
		||||
    private int openCount;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * The opens items in bytecode form. This byte vector only contains
 | 
			
		||||
     * the items themselves, the number of items is store in openCount
 | 
			
		||||
     */
 | 
			
		||||
    private ByteVector opens;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * number of uses items
 | 
			
		||||
     */
 | 
			
		||||
    private int useCount;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * The uses items in bytecode form. This byte vector only contains
 | 
			
		||||
     * the items themselves, the number of items is store in useCount
 | 
			
		||||
     */
 | 
			
		||||
    private ByteVector uses;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * number of provides items
 | 
			
		||||
     */
 | 
			
		||||
    private int provideCount;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * The uses provides in bytecode form. This byte vector only contains
 | 
			
		||||
     * the items themselves, the number of items is store in provideCount
 | 
			
		||||
     */
 | 
			
		||||
    private ByteVector provides;
 | 
			
		||||
    
 | 
			
		||||
    ModuleWriter(final ClassWriter cw, final int name,
 | 
			
		||||
            final int access, final int version) {
 | 
			
		||||
        super(Opcodes.ASM6);
 | 
			
		||||
        this.cw = cw;
 | 
			
		||||
        this.size = 16;  // name + access + version + 5 counts
 | 
			
		||||
        this.name = name;
 | 
			
		||||
        this.access = access;
 | 
			
		||||
        this.version = version;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitMainClass(String mainClass) {
 | 
			
		||||
        if (this.mainClass == 0) { // protect against several calls to visitMainClass
 | 
			
		||||
            cw.newUTF8("ModuleMainClass");
 | 
			
		||||
            attributeCount++;
 | 
			
		||||
            attributesSize += 8;
 | 
			
		||||
        }
 | 
			
		||||
        this.mainClass = cw.newClass(mainClass);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitPackage(String packaze) {
 | 
			
		||||
        if (packages == null) { 
 | 
			
		||||
            // protect against several calls to visitPackage
 | 
			
		||||
            cw.newUTF8("ModulePackages");
 | 
			
		||||
            packages = new ByteVector();
 | 
			
		||||
            attributeCount++;
 | 
			
		||||
            attributesSize += 8;
 | 
			
		||||
        }
 | 
			
		||||
        packages.putShort(cw.newPackage(packaze));
 | 
			
		||||
        packageCount++;
 | 
			
		||||
        attributesSize += 2;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitRequire(String module, int access, String version) {
 | 
			
		||||
        if (requires == null) {
 | 
			
		||||
            requires = new ByteVector();
 | 
			
		||||
        }
 | 
			
		||||
        requires.putShort(cw.newModule(module))
 | 
			
		||||
                .putShort(access)
 | 
			
		||||
                .putShort(version == null? 0: cw.newUTF8(version));
 | 
			
		||||
        requireCount++;
 | 
			
		||||
        size += 6;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitExport(String packaze, int access, String... modules) {
 | 
			
		||||
        if (exports == null) {
 | 
			
		||||
            exports = new ByteVector();
 | 
			
		||||
        }
 | 
			
		||||
        exports.putShort(cw.newPackage(packaze)).putShort(access);
 | 
			
		||||
        if (modules == null) {
 | 
			
		||||
            exports.putShort(0);
 | 
			
		||||
            size += 6;
 | 
			
		||||
        } else {
 | 
			
		||||
            exports.putShort(modules.length);
 | 
			
		||||
            for(String module: modules) {
 | 
			
		||||
                exports.putShort(cw.newModule(module));
 | 
			
		||||
            }    
 | 
			
		||||
            size += 6 + 2 * modules.length; 
 | 
			
		||||
        }
 | 
			
		||||
        exportCount++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitOpen(String packaze, int access, String... modules) {
 | 
			
		||||
        if (opens == null) {
 | 
			
		||||
            opens = new ByteVector();
 | 
			
		||||
        }
 | 
			
		||||
        opens.putShort(cw.newPackage(packaze)).putShort(access);
 | 
			
		||||
        if (modules == null) {
 | 
			
		||||
            opens.putShort(0);
 | 
			
		||||
            size += 6;
 | 
			
		||||
        } else {
 | 
			
		||||
            opens.putShort(modules.length);
 | 
			
		||||
            for(String module: modules) {
 | 
			
		||||
                opens.putShort(cw.newModule(module));
 | 
			
		||||
            }    
 | 
			
		||||
            size += 6 + 2 * modules.length; 
 | 
			
		||||
        }
 | 
			
		||||
        openCount++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitUse(String service) {
 | 
			
		||||
        if (uses == null) {
 | 
			
		||||
            uses = new ByteVector();
 | 
			
		||||
        }
 | 
			
		||||
        uses.putShort(cw.newClass(service));
 | 
			
		||||
        useCount++;
 | 
			
		||||
        size += 2;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitProvide(String service, String... providers) {
 | 
			
		||||
        if (provides == null) {
 | 
			
		||||
            provides = new ByteVector();
 | 
			
		||||
        }
 | 
			
		||||
        provides.putShort(cw.newClass(service));
 | 
			
		||||
        provides.putShort(providers.length);
 | 
			
		||||
        for(String provider: providers) {
 | 
			
		||||
            provides.putShort(cw.newClass(provider));
 | 
			
		||||
        }
 | 
			
		||||
        provideCount++;
 | 
			
		||||
        size += 4 + 2 * providers.length; 
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitEnd() {
 | 
			
		||||
        // empty
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void putAttributes(ByteVector out) {
 | 
			
		||||
        if (mainClass != 0) {
 | 
			
		||||
            out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass);
 | 
			
		||||
        }
 | 
			
		||||
        if (packages != null) {
 | 
			
		||||
            out.putShort(cw.newUTF8("ModulePackages"))
 | 
			
		||||
               .putInt(2 + 2 * packageCount)
 | 
			
		||||
               .putShort(packageCount)
 | 
			
		||||
               .putByteArray(packages.data, 0, packages.length);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void put(ByteVector out) {
 | 
			
		||||
        out.putInt(size);
 | 
			
		||||
        out.putShort(name).putShort(access).putShort(version);
 | 
			
		||||
        out.putShort(requireCount);
 | 
			
		||||
        if (requires != null) {
 | 
			
		||||
            out.putByteArray(requires.data, 0, requires.length);
 | 
			
		||||
        }
 | 
			
		||||
        out.putShort(exportCount);
 | 
			
		||||
        if (exports != null) {
 | 
			
		||||
            out.putByteArray(exports.data, 0, exports.length);
 | 
			
		||||
        }
 | 
			
		||||
        out.putShort(openCount);
 | 
			
		||||
        if (opens != null) {
 | 
			
		||||
            out.putByteArray(opens.data, 0, opens.length);
 | 
			
		||||
        }
 | 
			
		||||
        out.putShort(useCount);
 | 
			
		||||
        if (uses != null) {
 | 
			
		||||
            out.putByteArray(uses.data, 0, uses.length);
 | 
			
		||||
        }
 | 
			
		||||
        out.putShort(provideCount);
 | 
			
		||||
        if (provides != null) {
 | 
			
		||||
            out.putByteArray(provides.data, 0, provides.length);
 | 
			
		||||
        }
 | 
			
		||||
    }    
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +47,7 @@ public interface Opcodes {
 | 
			
		|||
 | 
			
		||||
    int ASM4 = 4 << 16 | 0 << 8 | 0;
 | 
			
		||||
    int ASM5 = 5 << 16 | 0 << 8 | 0;
 | 
			
		||||
    int ASM6 = 6 << 16 | 0 << 8 | 0;
 | 
			
		||||
 | 
			
		||||
    // versions
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +59,7 @@ public interface Opcodes {
 | 
			
		|||
    int V1_6 = 0 << 16 | 50;
 | 
			
		||||
    int V1_7 = 0 << 16 | 51;
 | 
			
		||||
    int V1_8 = 0 << 16 | 52;
 | 
			
		||||
    int V1_9 = 0 << 16 | 53;
 | 
			
		||||
 | 
			
		||||
    // access flags
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -68,18 +70,23 @@ public interface Opcodes {
 | 
			
		|||
    int ACC_FINAL = 0x0010; // class, field, method, parameter
 | 
			
		||||
    int ACC_SUPER = 0x0020; // class
 | 
			
		||||
    int ACC_SYNCHRONIZED = 0x0020; // method
 | 
			
		||||
    int ACC_OPEN = 0x0020; // module
 | 
			
		||||
    int ACC_TRANSITIVE = 0x0020; // module requires
 | 
			
		||||
    int ACC_VOLATILE = 0x0040; // field
 | 
			
		||||
    int ACC_BRIDGE = 0x0040; // method
 | 
			
		||||
    int ACC_STATIC_PHASE = 0x0040; // module requires
 | 
			
		||||
    int ACC_VARARGS = 0x0080; // method
 | 
			
		||||
    int ACC_TRANSIENT = 0x0080; // field
 | 
			
		||||
    int ACC_NATIVE = 0x0100; // method
 | 
			
		||||
    int ACC_INTERFACE = 0x0200; // class
 | 
			
		||||
    int ACC_ABSTRACT = 0x0400; // class, method
 | 
			
		||||
    int ACC_STRICT = 0x0800; // method
 | 
			
		||||
    int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
 | 
			
		||||
    int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
 | 
			
		||||
    int ACC_ANNOTATION = 0x2000; // class
 | 
			
		||||
    int ACC_ENUM = 0x4000; // class(?) field inner
 | 
			
		||||
    int ACC_MANDATED = 0x8000; // parameter
 | 
			
		||||
    int ACC_MANDATED = 0x8000; // parameter, module, module *
 | 
			
		||||
    int ACC_MODULE = 0x8000; // class
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // ASM specific pseudo access flags
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2002-2014 the original author or authors.
 | 
			
		||||
 * Copyright 2002-2017 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
| 
						 | 
				
			
			@ -30,8 +30,8 @@ public final class SpringAsmInfo {
 | 
			
		|||
 | 
			
		||||
	/**
 | 
			
		||||
	 * The ASM compatibility version for Spring's ASM visitor implementations:
 | 
			
		||||
	 * currently {@link Opcodes#ASM5}.
 | 
			
		||||
	 * currently {@link Opcodes#ASM6}.
 | 
			
		||||
	 */
 | 
			
		||||
	public static final int ASM_VERSION = Opcodes.ASM5;
 | 
			
		||||
	public static final int ASM_VERSION = Opcodes.ASM6;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue