Search in sources :

Example 1 with XmlContext

use of com.android.tools.klint.detector.api.XmlContext in project kotlin by JetBrains.

the class LintDriver method checkIndividualResources.

/** Checks individual resources */
private void checkIndividualResources(@NonNull Project project, @Nullable Project main, @NonNull List<ResourceXmlDetector> xmlDetectors, @Nullable List<Detector> dirChecks, @Nullable List<Detector> binaryChecks, @NonNull List<File> files) {
    for (File file : files) {
        if (file.isDirectory()) {
            // Is it a resource folder?
            ResourceFolderType type = ResourceFolderType.getFolderType(file.getName());
            if (type != null && new File(file.getParentFile(), RES_FOLDER).exists()) {
                // Yes.
                checkResourceFolder(project, main, file, type, xmlDetectors, dirChecks, binaryChecks);
            } else if (file.getName().equals(RES_FOLDER)) {
                // Is it the res folder?
                // Yes
                checkResFolder(project, main, file, xmlDetectors, dirChecks, binaryChecks);
            } else {
                mClient.log(null, "Unexpected folder %1$s; should be project, " + "\"res\" folder or resource folder", file.getPath());
            }
        } else if (file.isFile() && LintUtils.isXmlFile(file)) {
            // Yes, find out its resource type
            String folderName = file.getParentFile().getName();
            ResourceFolderType type = ResourceFolderType.getFolderType(folderName);
            if (type != null) {
                ResourceVisitor visitor = getVisitor(type, xmlDetectors, binaryChecks);
                if (visitor != null) {
                    XmlContext context = new XmlContext(this, project, main, file, type, visitor.getParser());
                    fireEvent(EventType.SCANNING_FILE, context);
                    visitor.visitFile(context, file);
                }
            }
        } else if (binaryChecks != null && file.isFile() && LintUtils.isBitmapFile(file)) {
            // Yes, find out its resource type
            String folderName = file.getParentFile().getName();
            ResourceFolderType type = ResourceFolderType.getFolderType(folderName);
            if (type != null) {
                ResourceVisitor visitor = getVisitor(type, xmlDetectors, binaryChecks);
                if (visitor != null) {
                    ResourceContext context = new ResourceContext(this, project, main, file, type);
                    fireEvent(EventType.SCANNING_FILE, context);
                    visitor.visitBinaryResource(context);
                    if (mCanceled) {
                        return;
                    }
                }
            }
        }
    }
}
Also used : ResourceContext(com.android.tools.klint.detector.api.ResourceContext) ResourceFolderType(com.android.resources.ResourceFolderType) XmlContext(com.android.tools.klint.detector.api.XmlContext) File(java.io.File) PsiFile(com.intellij.psi.PsiFile)

Example 2 with XmlContext

use of com.android.tools.klint.detector.api.XmlContext in project kotlin by JetBrains.

the class AppIndexingApiDetector method getActivitiesToCheck.

/**
     * Gets names of activities which needs app indexing. i.e. the activities have data tag in their
     * intent filters.
     * TODO: Cache the activities to speed up batch lint.
     *
     * @param context The context to check in.
     */
private static Set<String> getActivitiesToCheck(Context context) {
    Set<String> activitiesToCheck = Sets.newHashSet();
    List<File> manifestFiles = context.getProject().getManifestFiles();
    XmlParser xmlParser = context.getDriver().getClient().getXmlParser();
    if (xmlParser != null) {
        // TODO: Avoid visit all manifest files before enable this check by default.
        for (File manifest : manifestFiles) {
            XmlContext xmlContext = new XmlContext(context.getDriver(), context.getProject(), null, manifest, null, xmlParser);
            Document doc = xmlParser.parseXml(xmlContext);
            if (doc != null) {
                List<Element> children = LintUtils.getChildren(doc);
                for (Element child : children) {
                    if (child.getNodeName().equals(NODE_MANIFEST)) {
                        List<Element> apps = extractChildrenByName(child, NODE_APPLICATION);
                        for (Element app : apps) {
                            List<Element> acts = extractChildrenByName(app, NODE_ACTIVITY);
                            for (Element act : acts) {
                                List<Element> intents = extractChildrenByName(act, NODE_INTENT);
                                for (Element intent : intents) {
                                    List<Element> data = extractChildrenByName(intent, NODE_DATA);
                                    if (!data.isEmpty() && act.hasAttributeNS(ANDROID_URI, ATTRIBUTE_NAME)) {
                                        Attr attr = act.getAttributeNodeNS(ANDROID_URI, ATTRIBUTE_NAME);
                                        String activityName = attr.getValue();
                                        int dotIndex = activityName.indexOf('.');
                                        if (dotIndex <= 0) {
                                            String pkg = context.getMainProject().getPackage();
                                            if (pkg != null) {
                                                if (dotIndex == 0) {
                                                    activityName = pkg + activityName;
                                                } else {
                                                    activityName = pkg + '.' + activityName;
                                                }
                                            }
                                        }
                                        activitiesToCheck.add(activityName);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return activitiesToCheck;
}
Also used : XmlParser(com.android.tools.klint.client.api.XmlParser) UElement(org.jetbrains.uast.UElement) PsiElement(com.intellij.psi.PsiElement) Element(org.w3c.dom.Element) XmlContext(com.android.tools.klint.detector.api.XmlContext) Document(org.w3c.dom.Document) File(java.io.File) Attr(org.w3c.dom.Attr)

Example 3 with XmlContext

use of com.android.tools.klint.detector.api.XmlContext in project kotlin by JetBrains.

the class AlwaysShowActionDetector method afterCheckFile.

@Override
public void afterCheckFile(@NonNull Context context) {
    if (mIgnoreFile) {
        mFileAttributes = null;
        return;
    }
    if (mFileAttributes != null) {
        // mFileAttributes is only set in XML files
        assert context instanceof XmlContext;
        List<Attr> always = new ArrayList<Attr>();
        List<Attr> ifRoom = new ArrayList<Attr>();
        for (Attr attribute : mFileAttributes) {
            String value = attribute.getValue();
            if (value.equals(VALUE_ALWAYS)) {
                always.add(attribute);
            } else if (value.equals(VALUE_IF_ROOM)) {
                ifRoom.add(attribute);
            } else if (value.indexOf('|') != -1) {
                //$NON-NLS-1$
                String[] flags = value.split("\\|");
                for (String flag : flags) {
                    if (flag.equals(VALUE_ALWAYS)) {
                        always.add(attribute);
                        break;
                    } else if (flag.equals(VALUE_IF_ROOM)) {
                        ifRoom.add(attribute);
                        break;
                    }
                }
            }
        }
        if (!always.isEmpty() && mFileAttributes.size() > 1) {
            // have more than a single item)
            if (always.size() > 2 || ifRoom.isEmpty()) {
                XmlContext xmlContext = (XmlContext) context;
                Location location = null;
                for (int i = always.size() - 1; i >= 0; i--) {
                    Location next = location;
                    location = xmlContext.getLocation(always.get(i));
                    if (next != null) {
                        location.setSecondary(next);
                    }
                }
                if (location != null) {
                    context.report(ISSUE, location, "Prefer \"`ifRoom`\" instead of \"`always`\"");
                }
            }
        }
    }
}
Also used : XmlContext(com.android.tools.klint.detector.api.XmlContext) ArrayList(java.util.ArrayList) Attr(org.w3c.dom.Attr) Location(com.android.tools.klint.detector.api.Location)

Example 4 with XmlContext

use of com.android.tools.klint.detector.api.XmlContext in project kotlin by JetBrains.

the class LintDriver method checkResourceFolder.

private void checkResourceFolder(@NonNull Project project, @Nullable Project main, @NonNull File dir, @NonNull ResourceFolderType type, @NonNull List<ResourceXmlDetector> xmlChecks, @Nullable List<Detector> dirChecks, @Nullable List<Detector> binaryChecks) {
    if (dirChecks != null && !dirChecks.isEmpty()) {
        ResourceContext context = new ResourceContext(this, project, main, dir, type);
        String folderName = dir.getName();
        fireEvent(EventType.SCANNING_FILE, context);
        for (Detector check : dirChecks) {
            if (check.appliesTo(type)) {
                check.beforeCheckFile(context);
                check.checkFolder(context, folderName);
                check.afterCheckFile(context);
            }
        }
        if (binaryChecks == null && xmlChecks.isEmpty()) {
            return;
        }
    }
    File[] files = dir.listFiles();
    if (files == null || files.length <= 0) {
        return;
    }
    ResourceVisitor visitor = getVisitor(type, xmlChecks, binaryChecks);
    if (visitor != null) {
        // if not, there are no applicable rules in this folder
        // Process files in alphabetical order, to ensure stable output
        // (for example for the duplicate resource detector)
        Arrays.sort(files);
        for (File file : files) {
            if (LintUtils.isXmlFile(file)) {
                XmlContext context = new XmlContext(this, project, main, file, type, visitor.getParser());
                fireEvent(EventType.SCANNING_FILE, context);
                visitor.visitFile(context, file);
            } else if (binaryChecks != null && (LintUtils.isBitmapFile(file) || type == ResourceFolderType.RAW)) {
                ResourceContext context = new ResourceContext(this, project, main, file, type);
                fireEvent(EventType.SCANNING_FILE, context);
                visitor.visitBinaryResource(context);
            }
            if (mCanceled) {
                return;
            }
        }
    }
}
Also used : ResourceContext(com.android.tools.klint.detector.api.ResourceContext) ResourceXmlDetector(com.android.tools.klint.detector.api.ResourceXmlDetector) Detector(com.android.tools.klint.detector.api.Detector) XmlContext(com.android.tools.klint.detector.api.XmlContext) File(java.io.File) PsiFile(com.intellij.psi.PsiFile)

Example 5 with XmlContext

use of com.android.tools.klint.detector.api.XmlContext in project kotlin by JetBrains.

the class LintDriver method runFileDetectors.

private void runFileDetectors(@NonNull Project project, @Nullable Project main) {
    // Look up manifest information (but not for library projects)
    if (project.isAndroidProject()) {
        for (File manifestFile : project.getManifestFiles()) {
            XmlParser parser = mClient.getXmlParser();
            if (parser != null) {
                XmlContext context = new XmlContext(this, project, main, manifestFile, null, parser);
                context.document = parser.parseXml(context);
                if (context.document != null) {
                    try {
                        project.readManifest(context.document);
                        if ((!project.isLibrary() || (main != null && main.isMergingManifests())) && mScope.contains(Scope.MANIFEST)) {
                            List<Detector> detectors = mScopeDetectors.get(Scope.MANIFEST);
                            if (detectors != null) {
                                ResourceVisitor v = new ResourceVisitor(parser, detectors, null);
                                fireEvent(EventType.SCANNING_FILE, context);
                                v.visitFile(context, manifestFile);
                            }
                        }
                    } finally {
                        if (context.document != null) {
                            // else: freed by XmlVisitor above
                            parser.dispose(context, context.document);
                        }
                    }
                }
            }
        }
        // in a single pass through the resource directories.
        if (mScope.contains(Scope.ALL_RESOURCE_FILES) || mScope.contains(Scope.RESOURCE_FILE) || mScope.contains(Scope.RESOURCE_FOLDER) || mScope.contains(Scope.BINARY_RESOURCE_FILE)) {
            List<Detector> dirChecks = mScopeDetectors.get(Scope.RESOURCE_FOLDER);
            List<Detector> binaryChecks = mScopeDetectors.get(Scope.BINARY_RESOURCE_FILE);
            List<Detector> checks = union(mScopeDetectors.get(Scope.RESOURCE_FILE), mScopeDetectors.get(Scope.ALL_RESOURCE_FILES));
            boolean haveXmlChecks = checks != null && !checks.isEmpty();
            List<ResourceXmlDetector> xmlDetectors;
            if (haveXmlChecks) {
                xmlDetectors = new ArrayList<ResourceXmlDetector>(checks.size());
                for (Detector detector : checks) {
                    if (detector instanceof ResourceXmlDetector) {
                        xmlDetectors.add((ResourceXmlDetector) detector);
                    }
                }
                haveXmlChecks = !xmlDetectors.isEmpty();
            } else {
                xmlDetectors = Collections.emptyList();
            }
            if (haveXmlChecks || dirChecks != null && !dirChecks.isEmpty() || binaryChecks != null && !binaryChecks.isEmpty()) {
                List<File> files = project.getSubset();
                if (files != null) {
                    checkIndividualResources(project, main, xmlDetectors, dirChecks, binaryChecks, files);
                } else {
                    List<File> resourceFolders = project.getResourceFolders();
                    if (!resourceFolders.isEmpty()) {
                        for (File res : resourceFolders) {
                            checkResFolder(project, main, res, xmlDetectors, dirChecks, binaryChecks);
                        }
                    }
                }
            }
        }
        if (mCanceled) {
            return;
        }
    }
    if (mScope.contains(Scope.JAVA_FILE) || mScope.contains(Scope.ALL_JAVA_FILES)) {
        List<Detector> checks = union(mScopeDetectors.get(Scope.JAVA_FILE), mScopeDetectors.get(Scope.ALL_JAVA_FILES));
        if (checks != null && !checks.isEmpty()) {
            List<File> files = project.getSubset();
            if (files != null) {
                checkIndividualJavaFiles(project, main, checks, files);
            } else {
                List<File> sourceFolders = project.getJavaSourceFolders();
                if (mScope.contains(Scope.TEST_SOURCES)) {
                    List<File> testFolders = project.getTestSourceFolders();
                    if (!testFolders.isEmpty()) {
                        List<File> combined = Lists.newArrayListWithExpectedSize(sourceFolders.size() + testFolders.size());
                        combined.addAll(sourceFolders);
                        combined.addAll(testFolders);
                        sourceFolders = combined;
                    }
                }
                checkJava(project, main, sourceFolders, checks);
            }
        }
    }
    if (mCanceled) {
        return;
    }
    if (mScope.contains(Scope.CLASS_FILE) || mScope.contains(Scope.ALL_CLASS_FILES) || mScope.contains(Scope.JAVA_LIBRARIES)) {
        checkClasses(project, main);
    }
    if (mCanceled) {
        return;
    }
    if (mScope.contains(Scope.GRADLE_FILE)) {
        checkBuildScripts(project, main);
    }
    if (mCanceled) {
        return;
    }
    if (mScope.contains(Scope.OTHER)) {
        List<Detector> checks = mScopeDetectors.get(Scope.OTHER);
        if (checks != null) {
            OtherFileVisitor visitor = new OtherFileVisitor(checks);
            visitor.scan(this, project, main);
        }
    }
    if (mCanceled) {
        return;
    }
    if (project == main && mScope.contains(Scope.PROGUARD_FILE) && project.isAndroidProject()) {
        checkProGuard(project, main);
    }
    if (project == main && mScope.contains(Scope.PROPERTY_FILE)) {
        checkProperties(project, main);
    }
}
Also used : ResourceXmlDetector(com.android.tools.klint.detector.api.ResourceXmlDetector) Detector(com.android.tools.klint.detector.api.Detector) XmlContext(com.android.tools.klint.detector.api.XmlContext) ResourceXmlDetector(com.android.tools.klint.detector.api.ResourceXmlDetector) File(java.io.File) PsiFile(com.intellij.psi.PsiFile)

Aggregations

XmlContext (com.android.tools.klint.detector.api.XmlContext)5 File (java.io.File)4 PsiFile (com.intellij.psi.PsiFile)3 Detector (com.android.tools.klint.detector.api.Detector)2 ResourceContext (com.android.tools.klint.detector.api.ResourceContext)2 ResourceXmlDetector (com.android.tools.klint.detector.api.ResourceXmlDetector)2 Attr (org.w3c.dom.Attr)2 ResourceFolderType (com.android.resources.ResourceFolderType)1 XmlParser (com.android.tools.klint.client.api.XmlParser)1 Location (com.android.tools.klint.detector.api.Location)1 PsiElement (com.intellij.psi.PsiElement)1 ArrayList (java.util.ArrayList)1 UElement (org.jetbrains.uast.UElement)1 Document (org.w3c.dom.Document)1 Element (org.w3c.dom.Element)1