Search in sources :

Example 6 with ClassNode

use of org.jetbrains.org.objectweb.asm.tree.ClassNode in project kotlin by JetBrains.

the class AsmVisitor method runClassDetectors.

// ASM API uses raw types
@SuppressWarnings("rawtypes")
void runClassDetectors(ClassContext context) {
    ClassNode classNode = context.getClassNode();
    for (Detector detector : mAllDetectors) {
        detector.beforeCheckFile(context);
    }
    for (Detector detector : mFullClassChecks) {
        Detector.ClassScanner scanner = (Detector.ClassScanner) detector;
        scanner.checkClass(context, classNode);
        detector.afterCheckFile(context);
    }
    if (!mMethodNameToChecks.isEmpty() || !mMethodOwnerToChecks.isEmpty() || mNodeTypeDetectors != null && mNodeTypeDetectors.length > 0) {
        List methodList = classNode.methods;
        for (Object m : methodList) {
            MethodNode method = (MethodNode) m;
            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.METHOD_INSN) {
                    MethodInsnNode call = (MethodInsnNode) instruction;
                    String owner = call.owner;
                    List<ClassScanner> scanners = mMethodOwnerToChecks.get(owner);
                    if (scanners != null) {
                        for (ClassScanner scanner : scanners) {
                            scanner.checkCall(context, classNode, method, call);
                        }
                    }
                    String name = call.name;
                    scanners = mMethodNameToChecks.get(name);
                    if (scanners != null) {
                        for (ClassScanner scanner : scanners) {
                            scanner.checkCall(context, classNode, method, call);
                        }
                    }
                }
                if (mNodeTypeDetectors != null && type < mNodeTypeDetectors.length) {
                    List<ClassScanner> scanners = mNodeTypeDetectors[type];
                    if (scanners != null) {
                        for (ClassScanner scanner : scanners) {
                            scanner.checkInstruction(context, classNode, method, instruction);
                        }
                    }
                }
            }
        }
    }
    for (Detector detector : mAllDetectors) {
        detector.afterCheckFile(context);
    }
}
Also used : ClassNode(org.jetbrains.org.objectweb.asm.tree.ClassNode) ClassScanner(com.android.tools.klint.detector.api.Detector.ClassScanner) InsnList(org.jetbrains.org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode) Detector(com.android.tools.klint.detector.api.Detector) ClassScanner(com.android.tools.klint.detector.api.Detector.ClassScanner) MethodNode(org.jetbrains.org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.jetbrains.org.objectweb.asm.tree.MethodInsnNode) ArrayList(java.util.ArrayList) List(java.util.List) InsnList(org.jetbrains.org.objectweb.asm.tree.InsnList)

Example 7 with ClassNode

use of org.jetbrains.org.objectweb.asm.tree.ClassNode in project kotlin by JetBrains.

the class LintDriver method runClassDetectors.

private void runClassDetectors(Scope scope, List<ClassEntry> entries, Project project, Project main) {
    if (mScope.contains(scope)) {
        List<Detector> classDetectors = mScopeDetectors.get(scope);
        if (classDetectors != null && !classDetectors.isEmpty() && !entries.isEmpty()) {
            AsmVisitor visitor = new AsmVisitor(mClient, classDetectors);
            String sourceContents = null;
            String sourceName = "";
            mOuterClasses = new ArrayDeque<ClassNode>();
            ClassEntry prev = null;
            for (ClassEntry entry : entries) {
                if (prev != null && prev.compareTo(entry) == 0) {
                    // Duplicate entries for some reason: ignore
                    continue;
                }
                prev = entry;
                ClassReader reader;
                ClassNode classNode;
                try {
                    reader = new ClassReader(entry.bytes);
                    classNode = new ClassNode();
                    reader.accept(classNode, 0);
                } catch (Throwable t) {
                    mClient.log(null, "Error processing %1$s: broken class file?", entry.path());
                    continue;
                }
                ClassNode peek;
                while ((peek = mOuterClasses.peek()) != null) {
                    if (classNode.name.startsWith(peek.name)) {
                        break;
                    } else {
                        mOuterClasses.pop();
                    }
                }
                mOuterClasses.push(classNode);
                if (isSuppressed(null, classNode)) {
                    // Class was annotated with suppress all -- no need to look any further
                    continue;
                }
                if (sourceContents != null) {
                    // Attempt to reuse the source buffer if initialized
                    // This means making sure that the source files
                    //    foo/bar/MyClass and foo/bar/MyClass$Bar
                    //    and foo/bar/MyClass$3 and foo/bar/MyClass$3$1 have the same prefix.
                    String newName = classNode.name;
                    int newRootLength = newName.indexOf('$');
                    if (newRootLength == -1) {
                        newRootLength = newName.length();
                    }
                    int oldRootLength = sourceName.indexOf('$');
                    if (oldRootLength == -1) {
                        oldRootLength = sourceName.length();
                    }
                    if (newRootLength != oldRootLength || !sourceName.regionMatches(0, newName, 0, newRootLength)) {
                        sourceContents = null;
                    }
                }
                ClassContext context = new ClassContext(this, project, main, entry.file, entry.jarFile, entry.binDir, entry.bytes, classNode, scope == Scope.JAVA_LIBRARIES, /*fromLibrary*/
                sourceContents);
                try {
                    visitor.runClassDetectors(context);
                } catch (Exception e) {
                    mClient.log(e, null);
                }
                if (mCanceled) {
                    return;
                }
                sourceContents = context.getSourceContents(false);
                sourceName = classNode.name;
            }
            mOuterClasses = null;
        }
    }
}
Also used : ClassNode(org.jetbrains.org.objectweb.asm.tree.ClassNode) ResourceXmlDetector(com.android.tools.klint.detector.api.ResourceXmlDetector) Detector(com.android.tools.klint.detector.api.Detector) ClassContext(com.android.tools.klint.detector.api.ClassContext) ClassReader(org.jetbrains.org.objectweb.asm.ClassReader) IOException(java.io.IOException)

Example 8 with ClassNode

use of org.jetbrains.org.objectweb.asm.tree.ClassNode in project kotlin by JetBrains.

the class LintDriver method findClass.

/**
     * Returns the {@link ClassNode} corresponding to the given type, if possible, or null
     *
     * @param type the fully qualified type, using JVM signatures (/ and $, not . as path
     *             separators)
     * @param flags the ASM flags to pass to the {@link ClassReader}, normally 0 but can
     *              for example be {@link ClassReader#SKIP_CODE} and/oor
     *              {@link ClassReader#SKIP_DEBUG}
     * @return the class node for the type, or null
     */
@Nullable
public ClassNode findClass(@NonNull ClassContext context, @NonNull String type, int flags) {
    String relative = type.replace('/', File.separatorChar) + DOT_CLASS;
    File classFile = findClassFile(context.getProject(), relative);
    if (classFile != null) {
        if (classFile.getPath().endsWith(DOT_JAR)) {
            // TODO: Handle .jar files
            return null;
        }
        try {
            byte[] bytes = mClient.readBytes(classFile);
            ClassReader reader = new ClassReader(bytes);
            ClassNode classNode = new ClassNode();
            reader.accept(classNode, flags);
            return classNode;
        } catch (Throwable t) {
            mClient.log(null, "Error processing %1$s: broken class file?", classFile.getPath());
        }
    }
    return null;
}
Also used : ClassNode(org.jetbrains.org.objectweb.asm.tree.ClassNode) ClassReader(org.jetbrains.org.objectweb.asm.ClassReader) File(java.io.File) PsiFile(com.intellij.psi.PsiFile) Nullable(com.android.annotations.Nullable)

Aggregations

ClassNode (org.jetbrains.org.objectweb.asm.tree.ClassNode)8 MethodNode (org.jetbrains.org.objectweb.asm.tree.MethodNode)4 ClassReader (org.jetbrains.org.objectweb.asm.ClassReader)3 Detector (com.android.tools.klint.detector.api.Detector)2 List (java.util.List)2 MethodInsnNode (org.jetbrains.org.objectweb.asm.tree.MethodInsnNode)2 Nullable (com.android.annotations.Nullable)1 ClassContext (com.android.tools.klint.detector.api.ClassContext)1 ClassScanner (com.android.tools.klint.detector.api.Detector.ClassScanner)1 ResourceXmlDetector (com.android.tools.klint.detector.api.ResourceXmlDetector)1 PsiFile (com.intellij.psi.PsiFile)1 File (java.io.File)1 IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 AbstractInsnNode (org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode)1 AnnotationNode (org.jetbrains.org.objectweb.asm.tree.AnnotationNode)1 InsnList (org.jetbrains.org.objectweb.asm.tree.InsnList)1 Analyzer (org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer)1