Example usage for org.objectweb.asm.tree AbstractInsnNode FIELD_INSN

List of usage examples for org.objectweb.asm.tree AbstractInsnNode FIELD_INSN

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode FIELD_INSN.

Prototype

int FIELD_INSN

To view the source code for org.objectweb.asm.tree AbstractInsnNode FIELD_INSN.

Click Source Link

Document

The type of FieldInsnNode instructions.

Usage

From source file:analysis.ReferenceGenerator.java

License:Open Source License

private void refInstructions(InsnList insnList) {
    AbstractInsnNode insn;//  ww  w .j a va  2  s  .  c om

    insn = insnList.getFirst();

    Object cst;

    while (insn != null) {
        switch (insn.getType()) {
        case AbstractInsnNode.FIELD_INSN:
            //addTypeClassRef(Type.getType(((FieldInsnNode)insn).desc));
            addFieldRef(((FieldInsnNode) insn).owner, ((FieldInsnNode) insn).name);
            break;
        /*case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
                   
           break;*/
        /*case AbstractInsnNode.LDC_INSN:
           cst = ((LdcInsnNode)insn).cst;
           if(cst instanceof Type) {
              addTypeClassRef((Type)cst);
           }
           break;*/
        case AbstractInsnNode.METHOD_INSN:
            addMethodRef(((MethodInsnNode) insn).owner, ((MethodInsnNode) insn).name,
                    ((MethodInsnNode) insn).desc);
            break;
        case AbstractInsnNode.MULTIANEWARRAY_INSN:
            addTypeClassRef(Type.getType(((MultiANewArrayInsnNode) insn).desc));
            break;
        case AbstractInsnNode.TYPE_INSN:
            addTypeClassRef(Type.getType(((TypeInsnNode) insn).desc));
            break;
        }
        insn = insn.getNext();
    }
}

From source file:blockphysics.asm.BPTransformer.java

License:Open Source License

private byte[] transformRenderFallingSand(byte[] bytes) {
    /*try/*from  w  w w  .j  a  va2s  . co  m*/
    {
        FileOutputStream fos = new FileOutputStream("d:/RenderFallingSand.orig.class");
        fos.write(bytes);
      fos.close();
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }*/

    System.out.print("[BlockPhysics] Patching RenderFallingSand.class .......");
    boolean ok = false, ok2 = false, ok4 = false;

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    MethodNode m;
    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        m = methods.next();

        if (m.name.equals("a") && m.desc.equals("(Lsq;DDDFF)V")) {
            InsnList toInject = new InsnList();

            toInject.add(new VarInsnNode(ALOAD, 1));
            toInject.add(new MethodInsnNode(INVOKESTATIC, "blockphysics/BClient", "cancelRender", "(Lsq;)Z"));
            LabelNode l0 = new LabelNode();
            toInject.add(new JumpInsnNode(IFEQ, l0));
            toInject.add(new InsnNode(RETURN));
            toInject.add(l0);

            m.instructions.insertBefore(m.instructions.getFirst(), toInject);

            int index;
            for (index = 0; index < m.instructions.size(); index++) {
                if (m.instructions.get(index).getOpcode() == GETFIELD
                        && m.instructions.get(index).getType() == AbstractInsnNode.FIELD_INSN
                        && ((FieldInsnNode) m.instructions.get(index)).owner.equals("sq")
                        && ((FieldInsnNode) m.instructions.get(index)).name.equals("a")
                        && ((FieldInsnNode) m.instructions.get(index)).desc.equals("I")) {
                    index = index + 3;
                    ok = true;
                    break;
                }
            }

            while (!(m.instructions.get(index).getType() == AbstractInsnNode.METHOD_INSN
                    && ((MethodInsnNode) m.instructions.get(index)).name.equals("glPushMatrix"))) {
                m.instructions.remove(m.instructions.get(index));
                ok2 = true;
            }

            for (index = 0; index < m.instructions.size(); index++) {
                if (m.instructions.get(index).getOpcode() == INVOKEVIRTUAL
                        && m.instructions.get(index).getType() == AbstractInsnNode.METHOD_INSN
                        && ((MethodInsnNode) m.instructions.get(index)).owner.equals("bfo")
                        && ((MethodInsnNode) m.instructions.get(index)).name.equals("a")
                        && ((MethodInsnNode) m.instructions.get(index)).desc.equals("(Laqw;Labv;IIII)V")) {
                    m.instructions.set(m.instructions.get(index), new MethodInsnNode(INVOKESTATIC,
                            "blockphysics/BClient", "renderBlockSandFalling", "(Lbfo;Laqw;Labv;IIII)V"));
                    ok4 = true;
                    break;
                }
            }
        }
    }

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(cw);

    if (ok && ok2 && ok4)
        System.out.println("OK");
    else
        System.out.println("Failed." + ok + ok2 + ok4);

    /*try
    {
       FileOutputStream fos = new FileOutputStream("d:/RenderFallingSand.class");
       fos.write(cw.toByteArray());
     fos.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }*/

    return cw.toByteArray();
}

From source file:blockphysics.asm.BPTransformer.java

License:Open Source License

private byte[] transformNetClientHandler(byte[] bytes) {
    /*try/*w  w  w  . j a va2 s . c o m*/
    {
        FileOutputStream fos = new FileOutputStream("d:/NetClientHandler.orig.class");
        fos.write(bytes);
      fos.close();
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }*/

    System.out.print("[BlockPhysics] Patching NetClientHandler.class ........");
    boolean ok = false;

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    MethodNode m;
    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        m = methods.next();

        if (m.name.equals("a") && m.desc.equals("(Ldc;)V")) {
            InsnList toInject = new InsnList();

            toInject.add(new VarInsnNode(ALOAD, 0));
            toInject.add(new FieldInsnNode(GETFIELD, "bct", "i", "Lbda;"));
            toInject.add(new VarInsnNode(DLOAD, 2));
            toInject.add(new VarInsnNode(DLOAD, 4));
            toInject.add(new VarInsnNode(DLOAD, 6));
            toInject.add(new VarInsnNode(ALOAD, 1));
            toInject.add(new MethodInsnNode(INVOKESTATIC, "blockphysics/BlockPhysics", "createFallingsand",
                    "(Labv;DDDLdc;)Lsq;"));
            toInject.add(new VarInsnNode(ASTORE, 8));
            toInject.add(new VarInsnNode(ALOAD, 1));
            toInject.add(new InsnNode(ICONST_1));
            toInject.add(new FieldInsnNode(PUTFIELD, "dc", "k", "I"));

            for (int index = 0; index < m.instructions.size(); index++) {
                if (m.instructions.get(index).getOpcode() == INVOKESPECIAL
                        && m.instructions.get(index).getType() == AbstractInsnNode.METHOD_INSN
                        && ((MethodInsnNode) m.instructions.get(index)).owner.equals("sq")
                        && ((MethodInsnNode) m.instructions.get(index)).name.equals("<init>")) {
                    while (m.instructions.get(index).getType() != AbstractInsnNode.FIELD_INSN
                            || m.instructions.get(index).getOpcode() != PUTFIELD
                            || !((FieldInsnNode) m.instructions.get(index)).owner.equals("dc")
                            || !((FieldInsnNode) m.instructions.get(index)).name.equals("k")) {
                        index++;
                    }

                    while (m.instructions.get(index).getType() != AbstractInsnNode.TYPE_INSN
                            || !((TypeInsnNode) m.instructions.get(index)).desc.equals("sq")) {
                        m.instructions.remove(m.instructions.get(index));
                        index--;
                        ok = true;
                    }

                    if (ok) {
                        m.instructions.remove(m.instructions.get(index));
                        m.instructions.insertBefore(m.instructions.get(index), toInject);
                    }

                    break;
                }
            }
        }
    }

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(cw);

    if (ok)
        System.out.println("OK");
    else
        System.out.println("Failed." + ok);

    /*try
    {
       FileOutputStream fos = new FileOutputStream("d:/NetClientHandler.class");
       fos.write(cw.toByteArray());
     fos.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }*/

    return cw.toByteArray();
}

From source file:blockphysics.asm.BPTransformer.java

License:Open Source License

private byte[] transformGuiCreateWorld(byte[] bytes) {
    /*try//from   w  ww .j a v  a2 s .  c o m
    {
        FileOutputStream fos = new FileOutputStream("d:/GuiCreateWorld.orig.class");
        fos.write(bytes);
      fos.close();
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }*/

    System.out.print("[BlockPhysics] Patching GuiCreateWorld.class ..........");
    boolean ok = false, ok2 = false;

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    MethodNode m;
    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        m = methods.next();

        if (m.name.equals("A_") && m.desc.equals("()V")) {
            InsnList toInject = new InsnList();

            toInject.add(new VarInsnNode(ALOAD, 0));
            toInject.add(new InsnNode(ICONST_0));
            toInject.add(new FieldInsnNode(PUTFIELD, "auy", "v", "Z"));

            for (int index = m.instructions.size() - 1; index >= 0; index--) {
                if (m.instructions.get(index).getOpcode() == RETURN) {
                    m.instructions.insertBefore(m.instructions.get(index), toInject);
                    ok = true;
                    break;
                }
            }
        } else if (m.name.equals("a") && m.desc.equals("(Lauq;)V")) {
            for (int index = 0; index < m.instructions.size(); index++) {
                if (m.instructions.get(index).getOpcode() == INVOKEVIRTUAL
                        && m.instructions.get(index).getType() == AbstractInsnNode.METHOD_INSN
                        && ((MethodInsnNode) m.instructions.get(index)).owner.equals("ats")
                        && ((MethodInsnNode) m.instructions.get(index)).name.equals("a")
                        && ((MethodInsnNode) m.instructions.get(index)).desc
                                .equals("(Ljava/lang/String;Ljava/lang/String;Lacc;)V")) {
                    m.instructions.remove(m.instructions.get(index));

                    InsnList toInject = new InsnList();

                    toInject.add(new InsnNode(ICONST_1));
                    toInject.add(new MethodInsnNode(INVOKESPECIAL, "blockphysics/BGui", "<init>",
                            "(Lawb;Ljava/lang/String;Ljava/lang/String;Lacc;Z)V"));
                    toInject.add(new MethodInsnNode(INVOKEVIRTUAL, "ats", "a", "(Lawb;)V"));

                    m.instructions.insertBefore(m.instructions.get(index), toInject);

                    while (m.instructions.get(index).getOpcode() != GETFIELD
                            || m.instructions.get(index).getType() != AbstractInsnNode.FIELD_INSN
                            || !((FieldInsnNode) m.instructions.get(index)).owner.equals("auy")
                            || !((FieldInsnNode) m.instructions.get(index)).name.equals("f")
                            || !((FieldInsnNode) m.instructions.get(index)).desc.equals("Lats;")) {
                        index--;
                    }

                    toInject = new InsnList();

                    toInject.add(new TypeInsnNode(NEW, "blockphysics/BGui"));
                    toInject.add(new InsnNode(DUP));
                    toInject.add(new VarInsnNode(ALOAD, 0));

                    m.instructions.insert(m.instructions.get(index), toInject);

                    ok2 = true;
                    break;
                }
            }
        }
    }

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(cw);

    if (ok && ok2)
        System.out.println("OK");
    else
        System.out.println("Failed." + ok + ok2);

    /*try
    {
       FileOutputStream fos = new FileOutputStream("d:/GuiCreateWorld.class");
       fos.write(cw.toByteArray());
     fos.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }*/

    return cw.toByteArray();
}

From source file:cl.inria.stiq.instrumenter.BCIUtils.java

License:Open Source License

private static void printFrames(MethodNode aNode, Frame[] aFrames) {
    int bcIndex = 1;

    for (int i = 0; i < aFrames.length; i++) {
        Frame theFrame = aFrames[i];
        AbstractInsnNode theInsn = aNode.instructions.get(i);

        switch (theInsn.getType()) {
        case AbstractInsnNode.INSN:
        case AbstractInsnNode.INT_INSN:
        case AbstractInsnNode.VAR_INSN:
        case AbstractInsnNode.TYPE_INSN:
        case AbstractInsnNode.FIELD_INSN:
        case AbstractInsnNode.METHOD_INSN:
        case AbstractInsnNode.JUMP_INSN:
        case AbstractInsnNode.LDC_INSN:
        case AbstractInsnNode.IINC_INSN:
        case AbstractInsnNode.TABLESWITCH_INSN:
        case AbstractInsnNode.LOOKUPSWITCH_INSN:
        case AbstractInsnNode.MULTIANEWARRAY_INSN:
            TraceMethodVisitor theTraceVisitor = new TraceMethodVisitor();
            theInsn.accept(theTraceVisitor);
            StringWriter theWriter = new StringWriter();
            theTraceVisitor.print(new PrintWriter(theWriter));
            String theTraced = theWriter.toString().replace("\n", "");
            System.out.println(bcIndex + "\t" + frameString(theFrame) + " |\t" + theTraced);
            bcIndex++;//from ww w  . java2 s .c o m
            break;

        case AbstractInsnNode.FRAME:
        case AbstractInsnNode.LINE:
        case AbstractInsnNode.LABEL:
            break;
        }
    }
}

From source file:com.android.ide.eclipse.apt.internal.analysis.InnerClassAnalyzer.java

License:Apache License

@Override
protected Collection<Problem> analyzeMethod(MethodNode methodNode) {
    final LinkedList<Problem> problems = new LinkedList<Problem>();
    final InsnList instructions = methodNode.instructions;
    for (int i = 0; i < instructions.size(); i++) {
        final AbstractInsnNode insnNode = instructions.get(i);
        if (insnNode.getOpcode() == Opcodes.INVOKESTATIC) {
            final MethodInsnNode method = (MethodInsnNode) insnNode;
            if (isStaticAccess(method)) {
                if (confirmParentClassAccess(methodNode, method)) {
                    final AbstractInsnNode inst = retrieveMethodOrField(method);
                    final int type = inst.getType();
                    if (type == AbstractInsnNode.FIELD_INSN || type == AbstractInsnNode.METHOD_INSN) {
                        final Problem problem = new Problem(inst);
                        problems.add(problem);
                    }/*ww w  . j a  va2s  .c  o m*/
                }
            }
        }
    }
    return problems;
}

From source file:com.android.tools.klint.client.api.LintDriver.java

License:Apache License

/**
 * Returns whether the given issue is suppressed in the given method.
 *
 * @param issue the issue to be checked, or null to just check for "all"
 * @param classNode the class containing the issue
 * @param method the method containing the issue
 * @param instruction the instruction within the method, if any
 * @return true if there is a suppress annotation covering the specific
 *         issue on this method/*from w  w w.  j  ava  2 s. com*/
 */
public boolean isSuppressed(@Nullable Issue issue, @NonNull ClassNode classNode, @NonNull MethodNode method,
        @Nullable AbstractInsnNode instruction) {
    if (method.invisibleAnnotations != null) {
        @SuppressWarnings("unchecked")
        List<AnnotationNode> annotations = method.invisibleAnnotations;
        return isSuppressed(issue, annotations);
    }

    // Initializations of fields end up placed in generated methods (<init>
    // for members and <clinit> for static fields).
    if (instruction != null && method.name.charAt(0) == '<') {
        AbstractInsnNode next = LintUtils.getNextInstruction(instruction);
        if (next != null && next.getType() == AbstractInsnNode.FIELD_INSN) {
            FieldInsnNode fieldRef = (FieldInsnNode) next;
            FieldNode field = findField(classNode, fieldRef.owner, fieldRef.name);
            if (field != null && isSuppressed(issue, field)) {
                return true;
            }
        } else if (classNode.outerClass != null && classNode.outerMethod == null
                && LintUtils.isAnonymousClass(classNode)) {
            if (isSuppressed(issue, classNode)) {
                return true;
            }
        }
    }

    return false;
}

From source file:com.android.tools.lint.checks.ApiDetector.java

License:Apache License

@SuppressWarnings("rawtypes") // ASM API
@Override/*from   ww w.  jav a 2 s.  c om*/
public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) {
    if (mApiDatabase == null) {
        return;
    }

    if (AOSP_BUILD && classNode.name.startsWith("android/support/")) { //$NON-NLS-1$
        return;
    }

    // Requires util package (add prebuilts/tools/common/asm-tools/asm-debug-all-4.0.jar)
    //classNode.accept(new TraceClassVisitor(new PrintWriter(System.out)));

    int classMinSdk = getClassMinSdk(context, classNode);
    if (classMinSdk == -1) {
        classMinSdk = getMinSdk(context);
    }

    List methodList = classNode.methods;
    if (methodList.isEmpty()) {
        return;
    }

    boolean checkCalls = context.isEnabled(UNSUPPORTED) || context.isEnabled(INLINED);
    boolean checkMethods = context.isEnabled(OVERRIDE) && context.getMainProject().getBuildSdk() >= 1;
    String frameworkParent = null;
    if (checkMethods) {
        LintDriver driver = context.getDriver();
        String owner = classNode.superName;
        while (owner != null) {
            // For virtual dispatch, walk up the inheritance chain checking
            // each inherited method
            if ((owner.startsWith("android/") //$NON-NLS-1$
                    && !owner.startsWith("android/support/")) //$NON-NLS-1$
                    || owner.startsWith("java/") //$NON-NLS-1$
                    || owner.startsWith("javax/")) { //$NON-NLS-1$
                frameworkParent = owner;
                break;
            }
            owner = driver.getSuperClass(owner);
        }
        if (frameworkParent == null) {
            checkMethods = false;
        }
    }

    if (checkCalls) { // Check implements/extends
        if (classNode.superName != null) {
            String signature = classNode.superName;
            checkExtendsClass(context, classNode, classMinSdk, signature);
        }
        if (classNode.interfaces != null) {
            @SuppressWarnings("unchecked") // ASM API
            List<String> interfaceList = classNode.interfaces;
            for (String signature : interfaceList) {
                checkExtendsClass(context, classNode, classMinSdk, signature);
            }
        }
    }

    for (Object m : methodList) {
        MethodNode method = (MethodNode) m;

        int minSdk = getLocalMinSdk(method.invisibleAnnotations);
        if (minSdk == -1) {
            minSdk = classMinSdk;
        }

        InsnList nodes = method.instructions;

        if (checkMethods && Character.isJavaIdentifierStart(method.name.charAt(0))) {
            int buildSdk = context.getMainProject().getBuildSdk();
            String name = method.name;
            assert frameworkParent != null;
            int api = mApiDatabase.getCallVersion(frameworkParent, name, method.desc);
            if (api > buildSdk && buildSdk != -1) {
                // TODO: Don't complain if it's annotated with @Override; that means
                // somehow the build target isn't correct.
                String fqcn;
                String owner = classNode.name;
                if (CONSTRUCTOR_NAME.equals(name)) {
                    fqcn = "new " + ClassContext.getFqcn(owner); //$NON-NLS-1$
                } else {
                    fqcn = ClassContext.getFqcn(owner) + '#' + name;
                }
                String message = String.format(
                        "This method is not overriding anything with the current build "
                                + "target, but will in API level %1$d (current target is %2$d): %3$s",
                        api, buildSdk, fqcn);

                Location location = context.getLocation(method, classNode);
                context.report(OVERRIDE, method, null, location, message, null);
            }
        }

        if (!checkCalls) {
            continue;
        }

        if (CHECK_DECLARATIONS) {
            // Check types in parameter list and types of local variables
            List localVariables = method.localVariables;
            if (localVariables != null) {
                for (Object v : localVariables) {
                    LocalVariableNode var = (LocalVariableNode) v;
                    String desc = var.desc;
                    if (desc.charAt(0) == 'L') {
                        // "Lpackage/Class;" => "package/Bar"
                        String className = desc.substring(1, desc.length() - 1);
                        int api = mApiDatabase.getClassVersion(className);
                        if (api > minSdk) {
                            String fqcn = ClassContext.getFqcn(className);
                            String message = String.format(
                                    "Class requires API level %1$d (current min is %2$d): %3$s", api, minSdk,
                                    fqcn);
                            report(context, message, var.start, method,
                                    className.substring(className.lastIndexOf('/') + 1), null,
                                    SearchHints.create(NEAREST).matchJavaSymbol());
                        }
                    }
                }
            }

            // Check return type
            // The parameter types are already handled as local variables so we can skip
            // right to the return type.
            // Check types in parameter list
            String signature = method.desc;
            if (signature != null) {
                int args = signature.indexOf(')');
                if (args != -1 && signature.charAt(args + 1) == 'L') {
                    String type = signature.substring(args + 2, signature.length() - 1);
                    int api = mApiDatabase.getClassVersion(type);
                    if (api > minSdk) {
                        String fqcn = ClassContext.getFqcn(type);
                        String message = String.format(
                                "Class requires API level %1$d (current min is %2$d): %3$s", api, minSdk, fqcn);
                        AbstractInsnNode first = nodes.size() > 0 ? nodes.get(0) : null;
                        report(context, message, first, method, method.name, null,
                                SearchHints.create(BACKWARD).matchJavaSymbol());
                    }
                }
            }
        }

        for (int i = 0, n = nodes.size(); i < n; i++) {
            AbstractInsnNode instruction = nodes.get(i);
            int type = instruction.getType();
            if (type == AbstractInsnNode.METHOD_INSN) {
                MethodInsnNode node = (MethodInsnNode) instruction;
                String name = node.name;
                String owner = node.owner;
                String desc = node.desc;

                // No need to check methods in this local class; we know they
                // won't be an API match
                if (node.getOpcode() == Opcodes.INVOKEVIRTUAL && owner.equals(classNode.name)) {
                    owner = classNode.superName;
                }

                boolean checkingSuperClass = false;
                while (owner != null) {
                    int api = mApiDatabase.getCallVersion(owner, name, desc);
                    if (api > minSdk) {
                        if (method.name.startsWith(SWITCH_TABLE_PREFIX)) {
                            // We're in a compiler-generated method to generate an
                            // array indexed by enum ordinal values to enum values. The enum
                            // itself must be requiring a higher API number than is
                            // currently used, but the call site for the switch statement
                            // will also be referencing it, so no need to report these
                            // calls.
                            break;
                        }

                        if (!checkingSuperClass && node.getOpcode() == Opcodes.INVOKEVIRTUAL
                                && methodDefinedLocally(classNode, name, desc)) {
                            break;
                        }

                        String fqcn;
                        if (CONSTRUCTOR_NAME.equals(name)) {
                            fqcn = "new " + ClassContext.getFqcn(owner); //$NON-NLS-1$
                        } else {
                            fqcn = ClassContext.getFqcn(owner) + '#' + name;
                        }
                        String message = String.format(
                                "Call requires API level %1$d (current min is %2$d): %3$s", api, minSdk, fqcn);

                        if (name.equals(ORDINAL_METHOD) && instruction.getNext() != null
                                && instruction.getNext().getNext() != null
                                && instruction.getNext().getOpcode() == Opcodes.IALOAD
                                && instruction.getNext().getNext().getOpcode() == Opcodes.TABLESWITCH) {
                            message = String.format(
                                    "Enum for switch requires API level %1$d " + "(current min is %2$d): %3$s",
                                    api, minSdk, ClassContext.getFqcn(owner));
                        }

                        report(context, message, node, method, name, null,
                                SearchHints.create(FORWARD).matchJavaSymbol());
                    }

                    // For virtual dispatch, walk up the inheritance chain checking
                    // each inherited method
                    if (owner.startsWith("android/") //$NON-NLS-1$
                            || owner.startsWith("javax/")) { //$NON-NLS-1$
                        // The API map has already inlined all inherited methods
                        // so no need to keep checking up the chain
                        // -- unless it's the support library which is also in
                        // the android/ namespace:
                        if (owner.startsWith("android/support/")) { //$NON-NLS-1$
                            owner = context.getDriver().getSuperClass(owner);
                        } else {
                            owner = null;
                        }
                    } else if (owner.startsWith("java/")) { //$NON-NLS-1$
                        if (owner.equals(LocaleDetector.DATE_FORMAT_OWNER)) {
                            checkSimpleDateFormat(context, method, node, minSdk);
                        }
                        // Already inlined; see comment above
                        owner = null;
                    } else if (node.getOpcode() == Opcodes.INVOKEVIRTUAL) {
                        owner = context.getDriver().getSuperClass(owner);
                    } else if (node.getOpcode() == Opcodes.INVOKESTATIC && api == -1) {
                        // Inherit through static classes as well
                        owner = context.getDriver().getSuperClass(owner);
                    } else {
                        owner = null;
                    }

                    checkingSuperClass = true;
                }
            } else if (type == AbstractInsnNode.FIELD_INSN) {
                FieldInsnNode node = (FieldInsnNode) instruction;
                String name = node.name;
                String owner = node.owner;
                int api = mApiDatabase.getFieldVersion(owner, name);
                if (api > minSdk) {
                    if (method.name.startsWith(SWITCH_TABLE_PREFIX)) {
                        checkSwitchBlock(context, classNode, node, method, name, owner, api, minSdk);
                        continue;
                    }
                    String fqcn = ClassContext.getFqcn(owner) + '#' + name;
                    if (mPendingFields != null) {
                        mPendingFields.remove(fqcn);
                    }
                    String message = String.format("Field requires API level %1$d (current min is %2$d): %3$s",
                            api, minSdk, fqcn);
                    report(context, message, node, method, name, null,
                            SearchHints.create(FORWARD).matchJavaSymbol());
                }
            } else if (type == AbstractInsnNode.LDC_INSN) {
                LdcInsnNode node = (LdcInsnNode) instruction;
                if (node.cst instanceof Type) {
                    Type t = (Type) node.cst;
                    String className = t.getInternalName();

                    int api = mApiDatabase.getClassVersion(className);
                    if (api > minSdk) {
                        String fqcn = ClassContext.getFqcn(className);
                        String message = String.format(
                                "Class requires API level %1$d (current min is %2$d): %3$s", api, minSdk, fqcn);
                        report(context, message, node, method,
                                className.substring(className.lastIndexOf('/') + 1), null,
                                SearchHints.create(FORWARD).matchJavaSymbol());
                    }
                }
            }
        }
    }
}

From source file:com.android.tools.lint.checks.CordovaVersionDetector.java

License:Apache License

@Override
public void checkClass(@NonNull ClassContext context, @NonNull ClassNode classNode) {
    //noinspection VariableNotUsedInsideIf
    if (mCordovaVersion != null) {
        // Exit early if we have already found the cordova version in the JS file.
        // This will be the case for all versions > 3.x.x
        return;//w ww  .j a  v  a  2 s. c om
    }

    // For cordova versions such as 2.7.1, the version is a static *non-final* field in
    // a class named Device. Since it is non-final, it is initialized in the <clinit> method.
    // Example:
    //
    // ldc           #5                  // String 2.7.1
    // putstatic     #6                  // Field cordovaVersion:Ljava/lang/String;
    // ...
    if (classNode.name.equals(FQN_CORDOVA_DEVICE)) {
        //noinspection unchecked ASM api.
        List<MethodNode> methods = classNode.methods;
        for (MethodNode method : methods) {
            if (SdkConstants.CLASS_CONSTRUCTOR.equals(method.name)) {
                InsnList nodes = method.instructions;
                for (int i = 0, n = nodes.size(); i < n; i++) {
                    AbstractInsnNode instruction = nodes.get(i);
                    int type = instruction.getType();
                    if (type == AbstractInsnNode.FIELD_INSN) {
                        checkInstructionInternal(context, classNode, instruction);
                        break;
                    }
                }
            }
        }
    } else if (classNode.name.equals(FQN_CORDOVA_WEBVIEW)) {
        // For versions > 3.x.x, the version string is stored as a static final String in
        // CordovaWebView.
        // Note that this is also stored in the cordova.js.* but from a lint api perspective,
        // it's much faster to look it up here than load and check in the JS file.
        // e.g.
        //   public static final java.lang.String CORDOVA_VERSION;
        //      descriptor: Ljava/lang/String;
        //      flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
        //      ConstantValue: String 4.1.1
        //
        //noinspection unchecked ASM api.
        List<FieldNode> fields = classNode.fields;
        for (FieldNode node : fields) {
            if (FIELD_NAME_CORDOVA_VERSION_WEBVIEW.equals(node.name)
                    && (node.access & Opcodes.ACC_FINAL) == Opcodes.ACC_FINAL // is final
                    && (node.access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC // is static
                    && node.value instanceof String) {
                mCordovaVersion = createVersion((String) node.value);
                if (mCordovaVersion != null) {
                    validateCordovaVersion(context, mCordovaVersion, context.getLocation(classNode));
                }
            }
        }
    }
}

From source file:com.android.tools.lint.checks.InvalidPackageDetector.java

License:Apache License

@SuppressWarnings("rawtypes") // ASM API
@Override/*from   w ww.  j a v  a  2  s .co  m*/
public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) {
    if (!context.isFromClassLibrary() || shouldSkip(context.file)) {
        return;
    }

    if (mApiDatabase == null) {
        return;
    }

    if (classNode.name.startsWith(JAVAX_PKG_PREFIX)) {
        mJavaxLibraryClasses.add(classNode.name);
    }

    List methodList = classNode.methods;
    for (Object m : methodList) {
        MethodNode method = (MethodNode) m;

        InsnList nodes = method.instructions;

        // Check return type
        // The parameter types are already handled as local variables so we can skip
        // right to the return type.
        // Check types in parameter list
        String signature = method.desc;
        if (signature != null) {
            int args = signature.indexOf(')');
            if (args != -1 && signature.charAt(args + 1) == 'L') {
                String type = signature.substring(args + 2, signature.length() - 1);
                if (isInvalidPackage(type)) {
                    AbstractInsnNode first = nodes.size() > 0 ? nodes.get(0) : null;
                    record(context, method, first, type);
                }
            }
        }

        for (int i = 0, n = nodes.size(); i < n; i++) {
            AbstractInsnNode instruction = nodes.get(i);
            int type = instruction.getType();
            if (type == AbstractInsnNode.METHOD_INSN) {
                MethodInsnNode node = (MethodInsnNode) instruction;
                String owner = node.owner;

                // No need to check methods in this local class; we know they
                // won't be an API match
                if (node.getOpcode() == Opcodes.INVOKEVIRTUAL && owner.equals(classNode.name)) {
                    owner = classNode.superName;
                }

                while (owner != null) {
                    if (isInvalidPackage(owner)) {
                        record(context, method, instruction, owner);
                    }

                    // For virtual dispatch, walk up the inheritance chain checking
                    // each inherited method
                    if (owner.startsWith("android/") //$NON-NLS-1$
                            || owner.startsWith(JAVA_PKG_PREFIX) || owner.startsWith(JAVAX_PKG_PREFIX)) {
                        owner = null;
                    } else if (node.getOpcode() == Opcodes.INVOKEVIRTUAL) {
                        owner = context.getDriver().getSuperClass(owner);
                    } else if (node.getOpcode() == Opcodes.INVOKESTATIC) {
                        // Inherit through static classes as well
                        owner = context.getDriver().getSuperClass(owner);
                    } else {
                        owner = null;
                    }
                }
            } else if (type == AbstractInsnNode.FIELD_INSN) {
                FieldInsnNode node = (FieldInsnNode) instruction;
                String owner = node.owner;
                if (isInvalidPackage(owner)) {
                    record(context, method, instruction, owner);
                }
            } else if (type == AbstractInsnNode.LDC_INSN) {
                LdcInsnNode node = (LdcInsnNode) instruction;
                if (node.cst instanceof Type) {
                    Type t = (Type) node.cst;
                    String className = t.getInternalName();
                    if (isInvalidPackage(className)) {
                        record(context, method, instruction, className);
                    }
                }
            }
        }
    }
}