Search in sources :

Example 51 with Type

use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.

the class StringPropertyCodeGenerator method generateCustomSetValue.

public boolean generateCustomSetValue(final LwComponent lwComponent, final InstrumentationClassFinder.PseudoClass componentClass, final LwIntrospectedProperty property, final GeneratorAdapter generator, final int componentLocal, final String formClassName) throws IOException, ClassNotFoundException {
    final InstrumentationClassFinder.PseudoClass abstractButtonClass = componentClass.getFinder().loadClass(AbstractButton.class.getName());
    final InstrumentationClassFinder.PseudoClass jLabelClass = componentClass.getFinder().loadClass(JLabel.class.getName());
    if ("text".equals(property.getName()) && (abstractButtonClass.isAssignableFrom(componentClass) || jLabelClass.isAssignableFrom(componentClass))) {
        final StringDescriptor propertyValue = (StringDescriptor) lwComponent.getPropertyValue(property);
        if (propertyValue.getValue() != null) {
            final SupportCode.TextWithMnemonic textWithMnemonic = SupportCode.parseText(propertyValue.getValue());
            if (textWithMnemonic.myMnemonicIndex >= 0) {
                generator.loadLocal(componentLocal);
                generator.push(textWithMnemonic.myText);
                generator.invokeVirtual(Type.getType(componentClass.getDescriptor()), new Method(property.getWriteMethodName(), Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
                String setMnemonicMethodName;
                if (abstractButtonClass.isAssignableFrom(componentClass)) {
                    setMnemonicMethodName = "setMnemonic";
                } else {
                    setMnemonicMethodName = "setDisplayedMnemonic";
                }
                generator.loadLocal(componentLocal);
                generator.push(textWithMnemonic.getMnemonicChar());
                generator.invokeVirtual(Type.getType(componentClass.getDescriptor()), new Method(setMnemonicMethodName, Type.VOID_TYPE, new Type[] { Type.CHAR_TYPE }));
                if (myHaveSetDisplayedMnemonicIndex) {
                    generator.loadLocal(componentLocal);
                    generator.push(textWithMnemonic.myMnemonicIndex);
                    generator.invokeVirtual(Type.getType(componentClass.getDescriptor()), new Method("setDisplayedMnemonicIndex", Type.VOID_TYPE, new Type[] { Type.INT_TYPE }));
                }
                return true;
            }
        } else {
            Method method;
            if (abstractButtonClass.isAssignableFrom(componentClass)) {
                myClassesRequiringLoadButtonText.add(formClassName);
                method = myLoadButtonTextMethod;
            } else {
                myClassesRequiringLoadLabelText.add(formClassName);
                method = myLoadLabelTextMethod;
            }
            generator.loadThis();
            generator.loadLocal(componentLocal);
            generator.push(propertyValue.getBundleName());
            generator.invokeStatic(myResourceBundleType, myGetBundleMethod);
            generator.push(propertyValue.getKey());
            generator.invokeVirtual(myResourceBundleType, myGetStringMethod);
            generator.invokeVirtual(Type.getType("L" + formClassName + ";"), method);
            return true;
        }
    }
    return false;
}
Also used : Type(org.jetbrains.org.objectweb.asm.Type) SupportCode(com.intellij.uiDesigner.core.SupportCode) InstrumentationClassFinder(com.intellij.compiler.instrumentation.InstrumentationClassFinder) StringDescriptor(com.intellij.uiDesigner.lw.StringDescriptor) Method(org.jetbrains.org.objectweb.asm.commons.Method)

Example 52 with Type

use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.

the class TypeRepr method getType.

public static AbstractType getType(InternedString descr) {
    final DependencyContext context = descr.getContext();
    final Type t = Type.getType(descr.asString());
    switch(t.getSort()) {
        case Type.OBJECT:
            return context.getType(new ClassType(context.get(StringUtil.replaceChar(t.getClassName(), '.', '/'))));
        case Type.ARRAY:
            return context.getType(new ArrayType(getType(context, t.getElementType())));
        default:
            return context.getType(new PrimitiveType(descr.asInt()));
    }
}
Also used : Type(org.jetbrains.org.objectweb.asm.Type)

Example 53 with Type

use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.

the class NegationInterpreter method createStartFrame.

final Frame<BasicValue> createStartFrame() {
    Frame<BasicValue> frame = new Frame<>(methodNode.maxLocals, methodNode.maxStack);
    Type returnType = Type.getReturnType(methodNode.desc);
    BasicValue returnValue = Type.VOID_TYPE.equals(returnType) ? null : new BasicValue(returnType);
    frame.setReturn(returnValue);
    Type[] args = Type.getArgumentTypes(methodNode.desc);
    int local = 0;
    if ((methodNode.access & ACC_STATIC) == 0) {
        frame.setLocal(local++, ThisValue);
    }
    for (int i = 0; i < args.length; i++) {
        BasicValue value = new NthParamValue(args[i], i);
        frame.setLocal(local++, value);
        if (args[i].getSize() == 2) {
            frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
        }
    }
    while (local < methodNode.maxLocals) {
        frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
    }
    return frame;
}
Also used : Frame(org.jetbrains.org.objectweb.asm.tree.analysis.Frame) Type(org.jetbrains.org.objectweb.asm.Type) BasicValue(org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue)

Example 54 with Type

use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.

the class InOutInterpreter method naryOperation.

@Override
public BasicValue naryOperation(AbstractInsnNode insn, List<? extends BasicValue> values) throws AnalyzerException {
    boolean propagate = resultOrigins[insns.indexOf(insn)];
    int opCode = insn.getOpcode();
    int shift = opCode == INVOKESTATIC ? 0 : 1;
    switch(opCode) {
        case INVOKESPECIAL:
        case INVOKEINTERFACE:
        case INVOKEVIRTUAL:
            if (nullAnalysis && values.get(0) instanceof ParamValue) {
                deReferenced = true;
                return super.naryOperation(insn, values);
            }
    }
    if (propagate) {
        switch(opCode) {
            case INVOKESTATIC:
            case INVOKESPECIAL:
            case INVOKEVIRTUAL:
            case INVOKEINTERFACE:
                boolean stable = opCode == INVOKESTATIC || opCode == INVOKESPECIAL;
                MethodInsnNode mNode = (MethodInsnNode) insn;
                Method method = new Method(mNode.owner, mNode.name, mNode.desc);
                Type retType = Type.getReturnType(mNode.desc);
                boolean isRefRetType = retType.getSort() == Type.OBJECT || retType.getSort() == Type.ARRAY;
                if (!Type.VOID_TYPE.equals(retType)) {
                    if (direction instanceof InOut) {
                        InOut inOut = (InOut) direction;
                        HashSet<Key> keys = new HashSet<>();
                        for (int i = shift; i < values.size(); i++) {
                            if (values.get(i) instanceof ParamValue) {
                                keys.add(new Key(method, new InOut(i - shift, inOut.inValue), stable));
                            }
                        }
                        if (isRefRetType) {
                            keys.add(new Key(method, Out, stable));
                        }
                        if (!keys.isEmpty()) {
                            return new CallResultValue(retType, keys);
                        }
                    } else if (isRefRetType) {
                        HashSet<Key> keys = new HashSet<>();
                        keys.add(new Key(method, Out, stable));
                        return new CallResultValue(retType, keys);
                    }
                }
                break;
            case MULTIANEWARRAY:
                return new NotNullValue(super.naryOperation(insn, values).getType());
            default:
        }
    }
    return super.naryOperation(insn, values);
}
Also used : Type(org.jetbrains.org.objectweb.asm.Type) InOut(com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut) HashSet(java.util.HashSet)

Example 55 with Type

use of org.jetbrains.org.objectweb.asm.Type in project intellij-community by JetBrains.

the class AnalyzerExt method analyze.

public Frame<V>[] analyze(final String owner, final MethodNode m) throws AnalyzerException {
    if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
        frames = (Frame<V>[]) new Frame<?>[0];
        return frames;
    }
    final V refV = (V) BasicValue.REFERENCE_VALUE;
    n = m.instructions.size();
    insns = m.instructions;
    handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
    frames = (Frame<V>[]) new Frame<?>[n];
    subroutines = new Subroutine[n];
    queued = new boolean[n];
    queue = new int[n];
    top = 0;
    // computes exception handlers for each instruction
    for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
        TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
        int begin = insns.indexOf(tcb.start);
        int end = insns.indexOf(tcb.end);
        for (int j = begin; j < end; ++j) {
            List<TryCatchBlockNode> insnHandlers = handlers[j];
            if (insnHandlers == null) {
                insnHandlers = new ArrayList<>();
                handlers[j] = insnHandlers;
            }
            insnHandlers.add(tcb);
        }
    }
    // computes the subroutine for each instruction:
    Subroutine main = new Subroutine(null, m.maxLocals, null);
    List<AbstractInsnNode> subroutineCalls = new ArrayList<>();
    Map<LabelNode, Subroutine> subroutineHeads = new HashMap<>();
    findSubroutine(0, main, subroutineCalls);
    while (!subroutineCalls.isEmpty()) {
        JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0);
        Subroutine sub = subroutineHeads.get(jsr.label);
        if (sub == null) {
            sub = new Subroutine(jsr.label, m.maxLocals, jsr);
            subroutineHeads.put(jsr.label, sub);
            findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls);
        } else {
            sub.callers.add(jsr);
        }
    }
    for (int i = 0; i < n; ++i) {
        if (subroutines[i] != null && subroutines[i].start == null) {
            subroutines[i] = null;
        }
    }
    // initializes the data structures for the control flow analysis
    Frame<V> current = newFrame(m.maxLocals, m.maxStack);
    Frame<V> handler = newFrame(m.maxLocals, m.maxStack);
    current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)));
    Type[] args = Type.getArgumentTypes(m.desc);
    int local = 0;
    if ((m.access & ACC_STATIC) == 0) {
        Type ctype = Type.getObjectType(owner);
        current.setLocal(local++, interpreter.newValue(ctype));
    }
    for (int i = 0; i < args.length; ++i) {
        current.setLocal(local++, interpreter.newValue(args[i]));
        if (args[i].getSize() == 2) {
            current.setLocal(local++, interpreter.newValue(null));
        }
    }
    while (local < m.maxLocals) {
        current.setLocal(local++, interpreter.newValue(null));
    }
    interpreter.init(data[0]);
    merge(0, current, null);
    init(owner, m);
    // control flow analysis
    while (top > 0) {
        int insn = queue[--top];
        Frame<V> f = frames[insn];
        Subroutine subroutine = subroutines[insn];
        queued[insn] = false;
        AbstractInsnNode insnNode = null;
        try {
            insnNode = m.instructions.get(insn);
            int insnOpcode = insnNode.getOpcode();
            int insnType = insnNode.getType();
            if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
                interpreter.init(data[insn]);
                merge(insn + 1, f, subroutine);
                newControlFlowEdge(insn, insn + 1);
            } else {
                // delta
                interpreter.init(data[insn]);
                current.init(f).execute(insnNode, interpreter);
                subroutine = subroutine == null ? null : subroutine.copy();
                if (insnNode instanceof JumpInsnNode) {
                    JumpInsnNode j = (JumpInsnNode) insnNode;
                    if (insnOpcode != GOTO && insnOpcode != JSR) {
                        merge(insn + 1, current, subroutine);
                        newControlFlowEdge(insn, insn + 1);
                    }
                    int jump = insns.indexOf(j.label);
                    if (insnOpcode == JSR) {
                        merge(jump, current, new Subroutine(j.label, m.maxLocals, j));
                    } else {
                        merge(jump, current, subroutine);
                    }
                    newControlFlowEdge(insn, jump);
                } else if (insnNode instanceof LookupSwitchInsnNode) {
                    LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
                    int jump = insns.indexOf(lsi.dflt);
                    merge(jump, current, subroutine);
                    newControlFlowEdge(insn, jump);
                    for (int j = 0; j < lsi.labels.size(); ++j) {
                        LabelNode label = lsi.labels.get(j);
                        jump = insns.indexOf(label);
                        merge(jump, current, subroutine);
                        newControlFlowEdge(insn, jump);
                    }
                } else if (insnNode instanceof TableSwitchInsnNode) {
                    TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
                    int jump = insns.indexOf(tsi.dflt);
                    merge(jump, current, subroutine);
                    newControlFlowEdge(insn, jump);
                    for (int j = 0; j < tsi.labels.size(); ++j) {
                        LabelNode label = tsi.labels.get(j);
                        jump = insns.indexOf(label);
                        merge(jump, current, subroutine);
                        newControlFlowEdge(insn, jump);
                    }
                } else if (insnOpcode == RET) {
                    if (subroutine == null) {
                        throw new AnalyzerException(insnNode, "RET instruction outside of a sub routine");
                    }
                    for (int i = 0; i < subroutine.callers.size(); ++i) {
                        JumpInsnNode caller = subroutine.callers.get(i);
                        int call = insns.indexOf(caller);
                        if (frames[call] != null) {
                            merge(call + 1, frames[call], current, subroutines[call], subroutine.access);
                            newControlFlowEdge(insn, call + 1);
                        }
                    }
                } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
                    if (subroutine != null) {
                        if (insnNode instanceof VarInsnNode) {
                            int var = ((VarInsnNode) insnNode).var;
                            subroutine.access[var] = true;
                            if (insnOpcode == LLOAD || insnOpcode == DLOAD || insnOpcode == LSTORE || insnOpcode == DSTORE) {
                                subroutine.access[var + 1] = true;
                            }
                        } else if (insnNode instanceof IincInsnNode) {
                            int var = ((IincInsnNode) insnNode).var;
                            subroutine.access[var] = true;
                        }
                    }
                    merge(insn + 1, current, subroutine);
                    newControlFlowEdge(insn, insn + 1);
                }
            }
            List<TryCatchBlockNode> insnHandlers = handlers[insn];
            if (insnHandlers != null) {
                for (int i = 0; i < insnHandlers.size(); ++i) {
                    TryCatchBlockNode tcb = insnHandlers.get(i);
                    int jump = insns.indexOf(tcb.handler);
                    if (newControlFlowExceptionEdge(insn, tcb)) {
                        handler.init(f);
                        handler.clearStack();
                        handler.push(refV);
                        merge(jump, handler, subroutine);
                    }
                }
            }
        } catch (AnalyzerException e) {
            throw new AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.getMessage(), e);
        } catch (Exception e) {
            throw new AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.getMessage(), e);
        }
    }
    return frames;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Type(org.jetbrains.org.objectweb.asm.Type) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

Type (org.jetbrains.org.objectweb.asm.Type)104 KotlinType (org.jetbrains.kotlin.types.KotlinType)66 IElementType (com.intellij.psi.tree.IElementType)45 NotNull (org.jetbrains.annotations.NotNull)23 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)16 Label (org.jetbrains.org.objectweb.asm.Label)12 Type.getObjectType (org.jetbrains.org.objectweb.asm.Type.getObjectType)10 Method (org.jetbrains.org.objectweb.asm.commons.Method)9 Unit (kotlin.Unit)8 LocalVariableDescriptor (org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor)7 ArrayList (java.util.ArrayList)5 JavaClassDescriptor (org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor)5 MethodVisitor (org.jetbrains.org.objectweb.asm.MethodVisitor)5 PrimitiveType (org.jetbrains.kotlin.builtins.PrimitiveType)4 ValueParameterDescriptor (org.jetbrains.kotlin.descriptors.ValueParameterDescriptor)4 List (java.util.List)3 Nullable (org.jetbrains.annotations.Nullable)3 ScriptDescriptor (org.jetbrains.kotlin.descriptors.ScriptDescriptor)3 InOut (com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut)2 FunctionClassDescriptor (org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor)2