Search in sources :

Example 1 with LazyValue

use of org.jf.smalidea.debugging.value.LazyValue in project smali by JesusFreke.

the class SmaliCodeFragmentFactory method createCodeFragment.

@Override
public JavaCodeFragment createCodeFragment(TextWithImports item, PsiElement context, Project project) {
    context = wrapContext(project, context);
    JavaCodeFragment fragment = super.createCodeFragment(item, context, project);
    List<LazyValue> lazyValues = context.getUserData(SMALI_LAZY_VALUES_KEY);
    if (lazyValues != null) {
        fragment.putUserData(SMALI_LAZY_VALUES_KEY, lazyValues);
    }
    return fragment;
}
Also used : LazyValue(org.jf.smalidea.debugging.value.LazyValue) JavaCodeFragment(com.intellij.psi.JavaCodeFragment)

Example 2 with LazyValue

use of org.jf.smalidea.debugging.value.LazyValue in project smali by JesusFreke.

the class SmaliCodeFragmentFactory method wrapContext.

private PsiElement wrapContext(final Project project, final PsiElement originalContext) {
    if (project.isDefault())
        return originalContext;
    final List<LazyValue> lazyValues = Lists.newArrayList();
    SmaliInstruction currentInstruction = (SmaliInstruction) PsiUtil.searchBackward(originalContext, PsiMatchers.hasClass(SmaliInstruction.class), PsiMatchers.hasClass(SmaliMethod.class));
    if (currentInstruction == null) {
        currentInstruction = (SmaliInstruction) PsiUtil.searchForward(originalContext, PsiMatchers.hasClass(SmaliInstruction.class), PsiMatchers.hasClass(SmaliMethod.class));
        if (currentInstruction == null) {
            return originalContext;
        }
    }
    final SmaliMethod containingMethod = currentInstruction.getParentMethod();
    AnalyzedInstruction analyzedInstruction = currentInstruction.getAnalyzedInstruction();
    if (analyzedInstruction == null) {
        return originalContext;
    }
    final int firstParameterRegister = containingMethod.getRegisterCount() - containingMethod.getParameterRegisterCount();
    final Map<String, String> registerMap = Maps.newHashMap();
    StringBuilder variablesText = new StringBuilder();
    for (int i = 0; i < containingMethod.getRegisterCount(); i++) {
        int parameterRegisterNumber = i - firstParameterRegister;
        RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(i);
        switch(registerType.category) {
            case RegisterType.UNKNOWN:
            case RegisterType.UNINIT:
            case RegisterType.CONFLICTED:
            case RegisterType.LONG_HI:
            case RegisterType.DOUBLE_HI:
                continue;
            case RegisterType.NULL:
            case RegisterType.ONE:
            case RegisterType.INTEGER:
                variablesText.append("int v").append(i).append(";\n");
                registerMap.put("v" + i, "I");
                if (parameterRegisterNumber >= 0) {
                    variablesText.append("int p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "I");
                }
                break;
            case RegisterType.BOOLEAN:
                variablesText.append("boolean v").append(i).append(";\n");
                registerMap.put("v" + i, "Z");
                if (parameterRegisterNumber >= 0) {
                    variablesText.append("boolean p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "Z");
                }
                break;
            case RegisterType.BYTE:
            case RegisterType.POS_BYTE:
                variablesText.append("byte v").append(i).append(";\n");
                registerMap.put("v" + i, "B");
                if (parameterRegisterNumber >= 0) {
                    variablesText.append("byte p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "B");
                }
                break;
            case RegisterType.SHORT:
            case RegisterType.POS_SHORT:
                variablesText.append("short v").append(i).append(";\n");
                registerMap.put("v" + i, "S");
                if (parameterRegisterNumber >= 0) {
                    variablesText.append("short p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "S");
                }
                break;
            case RegisterType.CHAR:
                variablesText.append("char v").append(i).append(";\n");
                registerMap.put("v" + i, "C");
                if (parameterRegisterNumber >= 0) {
                    variablesText.append("char p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "C");
                }
                break;
            case RegisterType.FLOAT:
                variablesText.append("float v").append(i).append(";\n");
                registerMap.put("v" + i, "F");
                if (parameterRegisterNumber >= 0) {
                    variablesText.append("float p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "F");
                }
                break;
            case RegisterType.LONG_LO:
                variablesText.append("long v").append(i).append(";\n");
                registerMap.put("v" + i, "J");
                if (parameterRegisterNumber >= 0) {
                    variablesText.append("long p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "J");
                }
                break;
            case RegisterType.DOUBLE_LO:
                variablesText.append("double v").append(i).append(";\n");
                registerMap.put("v" + i, "D");
                if (parameterRegisterNumber >= 0) {
                    variablesText.append("double p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "D");
                }
                break;
            case RegisterType.UNINIT_REF:
            case RegisterType.UNINIT_THIS:
            case RegisterType.REFERENCE:
                String smaliType = registerType.type.getType();
                String javaType = NameUtils.smaliToJavaType(smaliType);
                variablesText.append(javaType).append(" v").append(i).append(";\n");
                registerMap.put("v" + i, smaliType);
                if (parameterRegisterNumber >= 0) {
                    variablesText.append(javaType).append(" p").append(parameterRegisterNumber).append(";\n");
                    registerMap.put("p" + parameterRegisterNumber, "Ljava/lang/Object;");
                }
                break;
        }
    }
    final TextWithImportsImpl textWithImports = new TextWithImportsImpl(CodeFragmentKind.CODE_BLOCK, variablesText.toString(), "", getFileType());
    final JavaCodeFragment codeFragment = super.createCodeFragment(textWithImports, originalContext, project);
    codeFragment.accept(new JavaRecursiveElementVisitor() {

        @Override
        public void visitLocalVariable(final PsiLocalVariable variable) {
            final String name = variable.getName();
            if (name != null && registerMap.containsKey(name)) {
                int registerNumber = Integer.parseInt(name.substring(1));
                if (name.charAt(0) == 'p') {
                    registerNumber += ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {

                        @Override
                        public Integer compute() {
                            return containingMethod.getRegisterCount() - containingMethod.getParameterRegisterCount();
                        }
                    });
                }
                LazyValue lazyValue = LazyValue.create(containingMethod, project, registerNumber, registerMap.get(name));
                variable.putUserData(CodeFragmentFactoryContextWrapper.LABEL_VARIABLE_VALUE_KEY, lazyValue);
                lazyValues.add(lazyValue);
            }
        }
    });
    int offset = variablesText.length() - 1;
    final PsiElement newContext = codeFragment.findElementAt(offset);
    if (newContext != null) {
        newContext.putUserData(SMALI_LAZY_VALUES_KEY, lazyValues);
        return newContext;
    }
    return originalContext;
}
Also used : LazyValue(org.jf.smalidea.debugging.value.LazyValue) SmaliInstruction(org.jf.smalidea.psi.impl.SmaliInstruction) PsiLocalVariable(com.intellij.psi.PsiLocalVariable) AnalyzedInstruction(org.jf.dexlib2.analysis.AnalyzedInstruction) SmaliMethod(org.jf.smalidea.psi.impl.SmaliMethod) RegisterType(org.jf.dexlib2.analysis.RegisterType) JavaCodeFragment(com.intellij.psi.JavaCodeFragment) JavaRecursiveElementVisitor(com.intellij.psi.JavaRecursiveElementVisitor) PsiElement(com.intellij.psi.PsiElement)

Example 3 with LazyValue

use of org.jf.smalidea.debugging.value.LazyValue in project smali by JesusFreke.

the class SmaliCodeFragmentFactory method createPresentationCodeFragment.

@Override
public JavaCodeFragment createPresentationCodeFragment(TextWithImports item, PsiElement context, Project project) {
    context = wrapContext(project, context);
    JavaCodeFragment fragment = super.createPresentationCodeFragment(item, context, project);
    List<LazyValue> lazyValues = context.getUserData(SMALI_LAZY_VALUES_KEY);
    if (lazyValues != null) {
        fragment.putUserData(SMALI_LAZY_VALUES_KEY, lazyValues);
    }
    return fragment;
}
Also used : LazyValue(org.jf.smalidea.debugging.value.LazyValue) JavaCodeFragment(com.intellij.psi.JavaCodeFragment)

Aggregations

JavaCodeFragment (com.intellij.psi.JavaCodeFragment)3 LazyValue (org.jf.smalidea.debugging.value.LazyValue)3 JavaRecursiveElementVisitor (com.intellij.psi.JavaRecursiveElementVisitor)1 PsiElement (com.intellij.psi.PsiElement)1 PsiLocalVariable (com.intellij.psi.PsiLocalVariable)1 AnalyzedInstruction (org.jf.dexlib2.analysis.AnalyzedInstruction)1 RegisterType (org.jf.dexlib2.analysis.RegisterType)1 SmaliInstruction (org.jf.smalidea.psi.impl.SmaliInstruction)1 SmaliMethod (org.jf.smalidea.psi.impl.SmaliMethod)1