Example usage for org.objectweb.asm MethodVisitor visitLdcInsn

List of usage examples for org.objectweb.asm MethodVisitor visitLdcInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitLdcInsn.

Prototype

public void visitLdcInsn(final Object value) 

Source Link

Document

Visits a LDC instruction.

Usage

From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java

License:Apache License

private void processClassVariable(final VariableExpression expression) {
    if (passingParams && controller.isInScriptBody()) {
        //TODO: check if this part is actually used
        MethodVisitor mv = controller.getMethodVisitor();
        // let's create a ScriptReference to pass into the closure
        mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/ScriptReference");
        mv.visitInsn(DUP);/*from  w w  w. j a  v  a 2 s .  co m*/

        loadThisOrOwner();
        mv.visitLdcInsn(expression.getName());

        mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/ScriptReference", "<init>",
                "(Lgroovy/lang/Script;Ljava/lang/String;)V", false);
    } else {
        PropertyExpression pexp = new PropertyExpression(new VariableExpression("this"), expression.getName());
        pexp.getObjectExpression().setSourcePosition(expression);
        pexp.getProperty().setSourcePosition(expression);
        pexp.setImplicitThis(true);
        visitPropertyExpression(pexp);
    }
}

From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java

License:Apache License

protected void createSyntheticStaticFields() {
    if (referencedClasses.isEmpty()) {
        return;//  www .  j av  a  2s.c om
    }
    MethodVisitor mv;
    for (Map.Entry<String, ClassNode> entry : referencedClasses.entrySet()) {
        String staticFieldName = entry.getKey();
        ClassNode cn = entry.getValue();
        // generate a field node
        FieldNode fn = controller.getClassNode().getDeclaredField(staticFieldName);
        if (fn != null) {
            boolean type = fn.getType().equals(ClassHelper.CLASS_Type);
            boolean modifiers = fn.getModifiers() == ACC_STATIC + ACC_SYNTHETIC;
            if (!type || !modifiers) {
                String text = "";
                if (!type)
                    text = " with wrong type: " + fn.getType() + " (java.lang.Class needed)";
                if (!modifiers)
                    text = " with wrong modifiers: " + fn.getModifiers() + " (" + (ACC_STATIC + ACC_SYNTHETIC)
                            + " needed)";
                throwException("tried to set a static synthetic field " + staticFieldName + " in "
                        + controller.getClassNode().getName()
                        + " for class resolving, but found already a node of that name " + text);
            }
        } else {
            classVisitor.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, staticFieldName,
                    "Ljava/lang/Class;", null, null);
        }

        mv = classVisitor.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$get$" + staticFieldName,
                "()Ljava/lang/Class;", null, null);
        mv.visitCode();
        mv.visitFieldInsn(GETSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;");
        mv.visitInsn(DUP);
        Label l0 = new Label();
        mv.visitJumpInsn(IFNONNULL, l0);
        mv.visitInsn(POP);
        mv.visitLdcInsn(BytecodeHelper.getClassLoadingTypeDescription(cn));
        mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), "class$",
                "(Ljava/lang/String;)Ljava/lang/Class;", false);
        mv.visitInsn(DUP);
        mv.visitFieldInsn(PUTSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;");
        mv.visitLabel(l0);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    mv = classVisitor.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "class$", "(Ljava/lang/String;)Ljava/lang/Class;",
            null, null);
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
            false);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitInsn(ARETURN);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitVarInsn(ASTORE, 1);
    mv.visitTypeInsn(NEW, "java/lang/NoClassDefFoundError");
    mv.visitInsn(DUP);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassNotFoundException", "getMessage", "()Ljava/lang/String;",
            false);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError", "<init>", "(Ljava/lang/String;)V",
            false);
    mv.visitInsn(ATHROW);
    mv.visitTryCatchBlock(l0, l2, l2, "java/lang/ClassNotFoundException"); // br using l2 as the 2nd param seems create the right table entry
    mv.visitMaxs(3, 2);
}

From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java

License:Apache License

@Override
public void visitClosureListExpression(final ClosureListExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    controller.getCompileStack().pushVariableScope(expression.getVariableScope());

    List<Expression> expressions = expression.getExpressions();
    final int size = expressions.size();
    // init declarations
    for (int i = 0; i < size; i += 1) {
        Expression expr = expressions.get(i);
        if (expr instanceof DeclarationExpression) {
            DeclarationExpression de = (DeclarationExpression) expr;
            BinaryExpression be = new BinaryExpression(de.getLeftExpression(), de.getOperation(),
                    de.getRightExpression());
            expressions.set(i, be);//from  w w w  .j  a v a  2  s  . co m
            de.setRightExpression(ConstantExpression.NULL);
            visitDeclarationExpression(de);
        }
    }

    List<Object> instructions = new LinkedList<>();
    BytecodeSequence seq = new BytecodeSequence(instructions);
    BlockStatement bs = new BlockStatement();
    bs.addStatement(seq);
    Parameter closureIndex = new Parameter(ClassHelper.int_TYPE, "__closureIndex");
    ClosureExpression ce = new ClosureExpression(new Parameter[] { closureIndex }, bs);
    ce.setVariableScope(expression.getVariableScope());

    // to keep stack height put a null on stack
    instructions.add(ConstantExpression.NULL);

    // init table
    final Label dflt = new Label();
    final Label tableEnd = new Label();
    final Label[] labels = new Label[size];
    instructions.add(new BytecodeInstruction() {
        public void visit(MethodVisitor mv) {
            mv.visitVarInsn(ILOAD, 1);
            mv.visitTableSwitchInsn(0, size - 1, dflt, labels);
        }
    });

    // visit cases
    for (int i = 0; i < size; i += 1) {
        Label label = new Label();
        Expression expr = expressions.get(i);
        labels[i] = label;
        instructions.add(new BytecodeInstruction() {
            public void visit(MethodVisitor mv) {
                mv.visitLabel(label);
                // expressions will leave a value on stack, so need to pop the alibi null
                mv.visitInsn(POP);
            }
        });
        instructions.add(expr);
        instructions.add(new BytecodeInstruction() {
            public void visit(MethodVisitor mv) {
                mv.visitJumpInsn(GOTO, tableEnd);
            }
        });
    }

    // default case
    instructions.add(new BytecodeInstruction() {
        public void visit(MethodVisitor mv) {
            mv.visitLabel(dflt);
        }
    });
    ConstantExpression text = new ConstantExpression("invalid index for closure");
    ConstructorCallExpression cce = new ConstructorCallExpression(
            ClassHelper.make(IllegalArgumentException.class), text);
    ThrowStatement ts = new ThrowStatement(cce);
    instructions.add(ts);

    // return
    instructions.add(new BytecodeInstruction() {
        public void visit(MethodVisitor mv) {
            mv.visitLabel(tableEnd);
            mv.visitInsn(ARETURN);
        }
    });

    // load main Closure
    visitClosureExpression(ce);

    // we need later an array to store the curried
    // closures, so we create it here and ave it
    // in a temporary variable
    BytecodeHelper.pushConstant(mv, size);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    int listArrayVar = controller.getCompileStack().defineTemporaryVariable("_listOfClosures", true);

    // add curried versions
    for (int i = 0; i < size; i += 1) {
        // stack: closure

        // we need to create a curried closure version
        // so we store the type on stack
        mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/CurriedClosure");
        // stack: closure, type
        // for a constructor call we need the type two times

        // and the closure after them
        mv.visitInsn(DUP2);
        mv.visitInsn(SWAP);
        // stack: closure,type,type,closure

        // so we can create the curried closure
        mv.visitInsn(ICONST_1);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitLdcInsn(i);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/CurriedClosure", "<init>",
                "(Lgroovy/lang/Closure;[Ljava/lang/Object;)V", false);
        // stack: closure,curriedClosure

        // we need to save the result
        mv.visitVarInsn(ALOAD, listArrayVar);
        mv.visitInsn(SWAP);
        BytecodeHelper.pushConstant(mv, i);
        mv.visitInsn(SWAP);
        mv.visitInsn(AASTORE);
        // stack: closure
    }

    // we don't need the closure any longer, so remove it
    mv.visitInsn(POP);
    // we load the array and create a list from it
    mv.visitVarInsn(ALOAD, listArrayVar);
    createListMethod.call(mv);

    // remove the temporary variable to keep the
    // stack clean
    controller.getCompileStack().removeVar(listArrayVar);
    controller.getOperandStack().pop();
}

From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java

License:Apache License

@Override
public void visitListExpression(final ListExpression expression) {
    onLineNumber(expression, "ListExpression");

    int size = expression.getExpressions().size();
    boolean containsSpreadExpression = containsSpreadExpression(expression);
    boolean containsOnlyConstants = !containsSpreadExpression && containsOnlyConstants(expression);
    OperandStack operandStack = controller.getOperandStack();
    if (!containsSpreadExpression) {
        MethodVisitor mv = controller.getMethodVisitor();
        BytecodeHelper.pushConstant(mv, size);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        int maxInit = 1000;
        if (size < maxInit || !containsOnlyConstants) {
            for (int i = 0; i < size; i += 1) {
                mv.visitInsn(DUP);//from   w w  w .  j  av  a  2  s .  co  m
                BytecodeHelper.pushConstant(mv, i);
                expression.getExpression(i).visit(this);
                operandStack.box();
                mv.visitInsn(AASTORE);
            }
            controller.getOperandStack().remove(size);
        } else {
            List<Expression> expressions = expression.getExpressions();
            List<String> methods = new ArrayList<>();
            MethodVisitor oldMv = mv;
            int index = 0;
            while (index < size) {
                String methodName = "$createListEntry_" + controller.getNextHelperMethodIndex();
                methods.add(methodName);
                mv = controller.getClassVisitor().visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC,
                        methodName, "([Ljava/lang/Object;)V", null, null);
                controller.setMethodVisitor(mv);
                mv.visitCode();
                int methodBlockSize = Math.min(size - index, maxInit);
                int methodBlockEnd = index + methodBlockSize;
                for (; index < methodBlockEnd; index += 1) {
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitLdcInsn(index);
                    expressions.get(index).visit(this);
                    operandStack.box();
                    mv.visitInsn(AASTORE);
                }
                operandStack.remove(methodBlockSize);
                mv.visitInsn(RETURN);
                mv.visitMaxs(0, 0);
                mv.visitEnd();
            }
            mv = oldMv;
            controller.setMethodVisitor(mv);
            for (String methodName : methods) {
                mv.visitInsn(DUP);
                mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), methodName,
                        "([Ljava/lang/Object;)V", false);
            }
        }
    } else {
        despreadList(expression.getExpressions(), false);
    }
    createListMethod.call(controller.getMethodVisitor());
    operandStack.push(ClassHelper.LIST_TYPE);
}

From source file:org.codehaus.groovy.runtime.ProxyGeneratorAdapter.java

License:Apache License

/**
 * Generate a call to the delegate object.
 *//*from w w w . j  ava 2 s  .com*/
protected MethodVisitor makeDelegateCall(final String name, final String desc, final String signature,
        final String[] exceptions, final int accessFlags) {
    MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
    mv.visitVarInsn(ALOAD, 0); // load this
    mv.visitFieldInsn(GETFIELD, proxyName, DELEGATE_OBJECT_FIELD,
            BytecodeHelper.getTypeDescription(delegateClass)); // load delegate
    // using InvokerHelper to allow potential intercepted calls
    int size;
    mv.visitLdcInsn(name); // method name
    Type[] args = Type.getArgumentTypes(desc);
    BytecodeHelper.pushConstant(mv, args.length);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    size = 6;
    int idx = 1;
    for (int i = 0; i < args.length; i++) {
        Type arg = args[i];
        mv.visitInsn(DUP);
        BytecodeHelper.pushConstant(mv, i);
        // primitive types must be boxed
        boxPrimitiveType(mv, idx, arg);
        size = Math.max(size, 5 + registerLen(arg));
        idx += registerLen(arg);
        mv.visitInsn(AASTORE); // store value into array
    }
    mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/InvokerHelper", "invokeMethod",
            "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", false);
    unwrapResult(mv, desc);
    mv.visitMaxs(size, registerLen(args) + 1);

    return mv;
}

From source file:org.codehaus.groovy.runtime.ProxyGeneratorAdapter.java

License:Apache License

protected MethodVisitor makeDelegateToClosureCall(final String name, final String desc, final String signature,
        final String[] exceptions, final int accessFlags) {
    MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions);
    //        TraceMethodVisitor tmv = new TraceMethodVisitor(mv);
    //        mv = tmv;
    mv.visitCode();/*w w w.j  a  va 2 s .c om*/
    int stackSize = 0;
    // method body should be:
    //  this.$delegate$closure$methodName.call(new Object[] { method arguments })
    Type[] args = Type.getArgumentTypes(desc);
    int arrayStore = args.length + 1;
    BytecodeHelper.pushConstant(mv, args.length);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); // stack size = 1
    stackSize = 1;
    int idx = 1;
    for (int i = 0; i < args.length; i++) {
        Type arg = args[i];
        mv.visitInsn(DUP); // stack size = 2
        BytecodeHelper.pushConstant(mv, i); // array index, stack size = 3
        // primitive types must be boxed
        boxPrimitiveType(mv, idx, arg);
        idx += registerLen(arg);
        stackSize = Math.max(4, 3 + registerLen(arg));
        mv.visitInsn(AASTORE); // store value into array
    }
    mv.visitVarInsn(ASTORE, arrayStore); // store array
    int arrayIndex = arrayStore;
    mv.visitVarInsn(ALOAD, 0); // load this
    mv.visitFieldInsn(GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;"); // load closure map
    mv.visitLdcInsn(name); // load method name
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
    arrayStore++;
    mv.visitVarInsn(ASTORE, arrayStore);
    // if null, test if wildcard exists
    Label notNull = new Label();
    mv.visitIntInsn(ALOAD, arrayStore);
    mv.visitJumpInsn(IFNONNULL, notNull);
    mv.visitVarInsn(ALOAD, 0); // load this
    mv.visitFieldInsn(GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;"); // load closure map
    mv.visitLdcInsn("*"); // load wildcard
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
    mv.visitVarInsn(ASTORE, arrayStore);
    mv.visitLabel(notNull);
    mv.visitVarInsn(ALOAD, arrayStore);
    mv.visitMethodInsn(INVOKESTATIC, BytecodeHelper.getClassInternalName(this.getClass()), "ensureClosure",
            "(Ljava/lang/Object;)Lgroovy/lang/Closure;", false);
    mv.visitVarInsn(ALOAD, arrayIndex); // load argument array
    stackSize++;
    mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Closure", "call", "([Ljava/lang/Object;)Ljava/lang/Object;",
            false); // call closure
    unwrapResult(mv, desc);
    mv.visitMaxs(stackSize, arrayStore + 1);
    mv.visitEnd();
    //        System.out.println("tmv.getText() = " + tmv.getText());
    return null;
}

From source file:org.eclipse.core.databinding.pojo.bindable.internal.asm.ClassBindable.java

License:Open Source License

/**
 * Generate the fire event for the dependsOn field.
 * /*from w w  w.  java  2 s  . c om*/
 * Example :
 * 
 * _bindable_getPropertyChangeSupport().firePropertyChange("ratio",
 * Double.valueOf(_bindable_setBuyingPrice_ratio),
 * Double.valueOf(getRatio()));
 * 
 * @param setterMethodBindable
 * @param getterMethodBindable
 * @param mv
 */
private void addAfterFireEventsMethod(FireEventsMethodBindable fireEventsMethodBindable,
        GetterMethodBindable getterMethodBindable, MethodVisitor mv) {

    String propertyName = getterMethodBindable.getPropertyName();
    String propertyDesc = getterMethodBindable.getPropertyDesc();
    Type propertyType = Type.getType(propertyDesc);
    String getterMethodName = getterMethodBindable.getMethodName();

    /*
     * Example :
     * _bindable_getPropertyChangeSupport().firePropertyChange("ratio",
     * Double.valueOf(_bindable_setBuyingPrice_ratio),
     * Double.valueOf(getRatio()));
     */

    String fireEventsFieldName = getFireEventsFieldName(fireEventsMethodBindable.getMethodName(),
            getterMethodBindable.getPropertyName());

    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, className, "_bindable_getPropertyChangeSupport",
            "()Ljava/beans/PropertyChangeSupport;");
    mv.visitLdcInsn(propertyName);
    mv.visitVarInsn(ALOAD, 0);

    mv.visitFieldInsn(GETFIELD, className, fireEventsFieldName, propertyDesc);
    ASMUtils.convertPrimitiveTypeToObjectTypeIfNeeded(mv, propertyType);

    mv.visitVarInsn(ALOAD, 0);

    mv.visitMethodInsn(INVOKEVIRTUAL, getClassName(), getterMethodName, getterMethodBindable.getMethodDesc());
    ASMUtils.convertPrimitiveTypeToObjectTypeIfNeeded(mv, propertyType);

    mv.visitMethodInsn(INVOKEVIRTUAL, "java/beans/PropertyChangeSupport", "firePropertyChange",
            FPC_DESC_OBJECT /*
                            * "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V")
                            */);

}

From source file:org.eclipse.core.databinding.pojo.bindable.internal.asm.ClassBindable.java

License:Open Source License

/**
 * Generate the fire event for the dependsOn field.
 * /*from   w  ww. j ava 2  s .co  m*/
 * Example :
 * 
 * _bindable_getPropertyChangeSupport().firePropertyChange("ratio",
 * Double.valueOf(_bindable_setBuyingPrice_ratio),
 * Double.valueOf(getRatio()));
 * 
 * @param setterMethodBindable
 * @param getterMethodBindable
 * @param mv
 */
private void addAfterDependsOnMethod(SetterMethodBindable setterMethodBindable,
        GetterMethodBindable getterMethodBindable, MethodVisitor mv) {

    String propertyName = getterMethodBindable.getPropertyName();
    String propertyDesc = getterMethodBindable.getPropertyDesc();
    Type propertyType = Type.getType(propertyDesc);
    String getterMethodName = getterMethodBindable.getMethodName();
    String setterMethodName = setterMethodBindable.getMethodName();

    /*
     * Example :
     * _bindable_getPropertyChangeSupport().firePropertyChange("ratio",
     * Double.valueOf(_bindable_setBuyingPrice_ratio),
     * Double.valueOf(getRatio()));
     */

    String dependsOnFieldName = getDependsOnFieldName(setterMethodName, propertyName);

    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, className, "_bindable_getPropertyChangeSupport",
            "()Ljava/beans/PropertyChangeSupport;");
    mv.visitLdcInsn(propertyName);
    mv.visitVarInsn(ALOAD, 0);

    mv.visitFieldInsn(GETFIELD, className, dependsOnFieldName, propertyDesc);
    ASMUtils.convertPrimitiveTypeToObjectTypeIfNeeded(mv, propertyType);

    mv.visitVarInsn(ALOAD, 0);

    mv.visitMethodInsn(INVOKEVIRTUAL, getClassName(), getterMethodName, getterMethodBindable.getMethodDesc());
    ASMUtils.convertPrimitiveTypeToObjectTypeIfNeeded(mv, propertyType);

    mv.visitMethodInsn(INVOKEVIRTUAL, "java/beans/PropertyChangeSupport", "firePropertyChange",
            FPC_DESC_OBJECT /*
                            * "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V")
                            */);

}

From source file:org.eclipse.golo.compiler.JavaBytecodeGenerationGoloIrVisitor.java

License:Open Source License

private void writeMetaData(String name, String[] data) {
    MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, "$" + name,
            "()[Ljava/lang/String;", null, null);
    mv.visitCode();/*  w  ww. ja v a2 s.co m*/
    loadInteger(mv, data.length);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
    for (int i = 0; i < data.length; i++) {
        mv.visitInsn(DUP);
        loadInteger(mv, i);
        mv.visitLdcInsn(data[i]);
        mv.visitInsn(AASTORE);
    }
    mv.visitInsn(ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.eclipse.golo.compiler.JavaBytecodeGenerationGoloIrVisitor.java

License:Open Source License

private void writeAugmentationApplicationsMetaData() {
    /* create a metadata method that given a target class name hashcode
     * returns a String array containing the names of applied
     * augmentations// w w  w . java  2s .  c o  m
     */
    List<Augmentation> applications = new ArrayList<>(this.currentModule.getAugmentations());
    int applicationsSize = applications.size();
    writeMetaData("augmentationApplications", applications.stream().map(Augmentation::getTarget)
            .map(PackageAndClass::toString).toArray(String[]::new));
    Label defaultLabel = new Label();
    Label[] labels = new Label[applicationsSize];
    int[] keys = new int[applicationsSize];
    String[][] namesArrays = new String[applicationsSize][];
    // cases of the switch statement MUST be sorted
    applications.sort(Comparator.comparingInt(o -> o.getTarget().toString().hashCode()));
    int i = 0;
    for (Augmentation application : applications) {
        labels[i] = new Label();
        keys[i] = application.getTarget().toString().hashCode();
        namesArrays[i] = application.getNames().toArray(new String[application.getNames().size()]);
        i++;
    }
    MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC,
            "$augmentationApplications", "(I)[Ljava/lang/String;", null, null);
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 0);
    mv.visitLookupSwitchInsn(defaultLabel, keys, labels);
    for (i = 0; i < applicationsSize; i++) {
        mv.visitLabel(labels[i]);
        loadInteger(mv, namesArrays[i].length);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
        for (int j = 0; j < namesArrays[i].length; j++) {
            mv.visitInsn(DUP);
            loadInteger(mv, j);
            mv.visitLdcInsn(namesArrays[i][j]);
            mv.visitInsn(AASTORE);
        }
        mv.visitInsn(ARETURN);
    }
    mv.visitLabel(defaultLabel);
    loadInteger(mv, 0);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
    mv.visitInsn(ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}