Search in sources :

Example 1 with ProblemData

use of org.jetbrains.android.inspections.lint.ProblemData in project android by JetBrains.

the class TemplateTest method assertLintsCleanly.

private static void assertLintsCleanly(@NotNull Project project, @NotNull Severity maxSeverity, @NotNull Set<Issue> ignored) throws Exception {
    BuiltinIssueRegistry registry = new LintIdeIssueRegistry();
    Map<Issue, Map<File, List<ProblemData>>> map = new HashMap<>();
    LintIdeClient client = LintIdeClient.forBatch(project, map, new AnalysisScope(project), registry.getIssues());
    LintDriver driver = new LintDriver(registry, client);
    List<Module> modules = Arrays.asList(ModuleManager.getInstance(project).getModules());
    LintRequest request = new LintIdeRequest(client, project, null, modules, false);
    EnumSet<Scope> scope = EnumSet.allOf(Scope.class);
    scope.remove(Scope.CLASS_FILE);
    scope.remove(Scope.ALL_CLASS_FILES);
    scope.remove(Scope.JAVA_LIBRARIES);
    request.setScope(scope);
    driver.analyze(request);
    if (!map.isEmpty()) {
        for (Map<File, List<ProblemData>> fileListMap : map.values()) {
            for (Map.Entry<File, List<ProblemData>> entry : fileListMap.entrySet()) {
                File file = entry.getKey();
                List<ProblemData> problems = entry.getValue();
                for (ProblemData problem : problems) {
                    Issue issue = problem.getIssue();
                    if (ignored.contains(issue)) {
                        continue;
                    }
                    if (issue.getDefaultSeverity().compareTo(maxSeverity) < 0) {
                        fail("Found lint issue " + issue.getId() + " with severity " + issue.getDefaultSeverity() + " in " + file + " at " + problem.getTextRange() + ": " + problem.getMessage());
                    }
                }
            }
        }
    }
}
Also used : Issue(com.android.tools.lint.detector.api.Issue) LintIdeClient(com.android.tools.idea.lint.LintIdeClient) ProblemData(org.jetbrains.android.inspections.lint.ProblemData) AnalysisScope(com.intellij.analysis.AnalysisScope) LintRequest(com.android.tools.lint.client.api.LintRequest) Scope(com.android.tools.lint.detector.api.Scope) AnalysisScope(com.intellij.analysis.AnalysisScope) BuiltinIssueRegistry(com.android.tools.lint.checks.BuiltinIssueRegistry) Module(com.intellij.openapi.module.Module) VirtualFile(com.intellij.openapi.vfs.VirtualFile) VfsUtilCore.virtualToIoFile(com.intellij.openapi.vfs.VfsUtilCore.virtualToIoFile) File(java.io.File) LintIdeIssueRegistry(com.android.tools.idea.lint.LintIdeIssueRegistry) LintIdeRequest(com.android.tools.idea.lint.LintIdeRequest) LintDriver(com.android.tools.lint.client.api.LintDriver)

Example 2 with ProblemData

use of org.jetbrains.android.inspections.lint.ProblemData in project android by JetBrains.

the class UnusedResourcesProcessor method computeUnusedMap.

@NotNull
private Map<Issue, Map<File, List<ProblemData>>> computeUnusedMap() {
    Map<Issue, Map<File, List<ProblemData>>> map = Maps.newHashMap();
    List<Issue> issues = Lists.newArrayListWithExpectedSize(2);
    issues.add(UnusedResourceDetector.ISSUE);
    if (myIncludeIds) {
        issues.add(UnusedResourceDetector.ISSUE_IDS);
    }
    AnalysisScope scope = new AnalysisScope(myProject);
    boolean unusedWasEnabled = UnusedResourceDetector.ISSUE.isEnabledByDefault();
    boolean unusedIdsWasEnabled = UnusedResourceDetector.ISSUE_IDS.isEnabledByDefault();
    UnusedResourceDetector.ISSUE.setEnabledByDefault(true);
    UnusedResourceDetector.ISSUE_IDS.setEnabledByDefault(myIncludeIds);
    try {
        LintIdeClient client = LintIdeClient.forBatch(myProject, map, scope, issues);
        LintRequest request = new LintIdeRequest(client, myProject, null, Arrays.asList(myModules), false);
        request.setScope(Scope.ALL);
        LintDriver lint = new LintDriver(new LintIdeIssueRegistry(), client);
        lint.analyze(request);
    } finally {
        UnusedResourceDetector.ISSUE.setEnabledByDefault(unusedWasEnabled);
        UnusedResourceDetector.ISSUE_IDS.setEnabledByDefault(unusedIdsWasEnabled);
    }
    return map;
}
Also used : AnalysisScope(com.intellij.analysis.AnalysisScope) LintRequest(com.android.tools.lint.client.api.LintRequest) Issue(com.android.tools.lint.detector.api.Issue) LintIdeClient(com.android.tools.idea.lint.LintIdeClient) Map(java.util.Map) LintIdeRequest(com.android.tools.idea.lint.LintIdeRequest) LintIdeIssueRegistry(com.android.tools.idea.lint.LintIdeIssueRegistry) ProblemData(org.jetbrains.android.inspections.lint.ProblemData) LintDriver(com.android.tools.lint.client.api.LintDriver) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with ProblemData

use of org.jetbrains.android.inspections.lint.ProblemData in project android by JetBrains.

the class UnusedResourcesProcessor method findUsages.

@Override
@NotNull
protected UsageInfo[] findUsages() {
    Map<Issue, Map<File, List<ProblemData>>> map = computeUnusedMap();
    List<PsiElement> elements = computeUnusedDeclarationElements(map);
    myElements = elements.toArray(new PsiElement[elements.size()]);
    UsageInfo[] result = new UsageInfo[myElements.length];
    for (int i = 0, n = myElements.length; i < n; i++) {
        PsiElement element = myElements[i];
        if (element instanceof PsiBinaryFile) {
            // The usage view doesn't handle binaries at all. Work around this (for example,
            // the UsageInfo class asserts in the constructor if the element doesn't have
            // a text range.)
            SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
            SmartPsiElementPointer<PsiElement> smartPointer = smartPointerManager.createSmartPsiElementPointer(element);
            SmartPsiFileRange smartFileRange = smartPointerManager.createSmartPsiFileRangePointer((PsiBinaryFile) element, TextRange.EMPTY_RANGE);
            result[i] = new UsageInfo(smartPointer, smartFileRange, false, false) {

                @Override
                public boolean isValid() {
                    return true;
                }

                @Override
                @Nullable
                public Segment getSegment() {
                    return null;
                }
            };
        } else {
            result[i] = new UsageInfo(element);
        }
    }
    return UsageViewUtil.removeDuplicatedUsages(result);
}
Also used : Issue(com.android.tools.lint.detector.api.Issue) Segment(com.intellij.openapi.util.Segment) ProblemData(org.jetbrains.android.inspections.lint.ProblemData) Map(java.util.Map) UsageInfo(com.intellij.usageView.UsageInfo) Nullable(org.jetbrains.annotations.Nullable) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with ProblemData

use of org.jetbrains.android.inspections.lint.ProblemData in project android by JetBrains.

the class UnusedResourcesProcessor method addElementsInFile.

private void addElementsInFile(List<PsiElement> elements, PsiFile psiFile, List<ProblemData> problems) {
    // Delete all the resources in the given file
    if (psiFile instanceof XmlFile) {
        List<Integer> starts = Lists.newArrayListWithCapacity(problems.size());
        for (ProblemData problem : problems) {
            if (matchesFilter(problem)) {
                starts.add(problem.getTextRange().getStartOffset());
            }
        }
        starts.sort(Collections.<Integer>reverseOrder());
        for (Integer offset : starts) {
            if (psiFile.isValid()) {
                XmlAttribute attribute = PsiTreeUtil.findElementOfClassAtOffset(psiFile, offset, XmlAttribute.class, false);
                PsiElement remove = attribute;
                if (attribute == null) {
                    remove = PsiTreeUtil.findElementOfClassAtOffset(psiFile, offset, XmlTag.class, false);
                } else if (!ATTR_ID.equals(attribute.getLocalName())) {
                    // If deleting a resource, delete the whole resource element, except for attribute android:id="" declarations
                    // where we remove the attribute, not the tag
                    remove = PsiTreeUtil.getParentOfType(attribute, XmlTag.class);
                }
                if (remove != null) {
                    elements.add(remove);
                }
            }
        }
    }
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlFile(com.intellij.psi.xml.XmlFile) ProblemData(org.jetbrains.android.inspections.lint.ProblemData) XmlTag(com.intellij.psi.xml.XmlTag)

Example 5 with ProblemData

use of org.jetbrains.android.inspections.lint.ProblemData in project android by JetBrains.

the class UnusedResourcesProcessor method computeUnusedDeclarationElements.

@NotNull
private List<PsiElement> computeUnusedDeclarationElements(Map<Issue, Map<File, List<ProblemData>>> map) {
    final List<PsiElement> elements = Lists.newArrayList();
    // Make sure lint didn't put extra issues into the map
    for (Issue issue : Lists.newArrayList(map.keySet())) {
        if (issue != UnusedResourceDetector.ISSUE && issue != UnusedResourceDetector.ISSUE_IDS) {
            map.remove(issue);
        }
    }
    ApplicationManager.getApplication().assertReadAccessAllowed();
    PsiManager manager = PsiManager.getInstance(myProject);
    for (Issue issue : new Issue[] { UnusedResourceDetector.ISSUE, UnusedResourceDetector.ISSUE_IDS }) {
        Map<File, List<ProblemData>> fileListMap = map.get(issue);
        if (fileListMap != null && !fileListMap.isEmpty()) {
            Map<File, PsiFile> files = Maps.newHashMap();
            for (File file : fileListMap.keySet()) {
                VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file);
                if (virtualFile != null) {
                    if (!virtualFile.isDirectory()) {
                        // Gradle model errors currently don't have source positions
                        PsiFile psiFile = manager.findFile(virtualFile);
                        if (psiFile != null) {
                            files.put(file, psiFile);
                        }
                    }
                }
            }
            if (!files.isEmpty()) {
                for (File file : files.keySet()) {
                    PsiFile psiFile = files.get(file);
                    if (psiFile == null) {
                        // where we only had the project directory as the location from the Gradle model
                        continue;
                    }
                    if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, psiFile)) {
                        continue;
                    }
                    List<ProblemData> problems = fileListMap.get(file);
                    if (psiFile.getFileType().isBinary()) {
                        // Delete the whole file
                        if (matchesFilter(fileListMap, file)) {
                            elements.add(psiFile);
                        }
                    } else {
                        ResourceFolderType folderType = ResourceHelper.getFolderType(psiFile);
                        if (folderType == null) {
                            // file; see for example http://b.android.com/220069.)
                            if (psiFile.getFileType() == GroovyFileType.GROOVY_FILE_TYPE && psiFile instanceof GroovyFile) {
                                ((GroovyFile) psiFile).accept(new GroovyRecursiveElementVisitor() {

                                    @Override
                                    public void visitApplicationStatement(GrApplicationStatement applicationStatement) {
                                        super.visitApplicationStatement(applicationStatement);
                                        PsiMethod method = applicationStatement.resolveMethod();
                                        if (method != null && method.getName().equals("resValue")) {
                                            GrExpression[] args = applicationStatement.getArgumentList().getExpressionArguments();
                                            if (args.length >= 3) {
                                                Object typeString = GroovyConstantExpressionEvaluator.evaluate(args[0]);
                                                Object nameString = GroovyConstantExpressionEvaluator.evaluate(args[1]);
                                                // See if this is one of the unused resources
                                                if (typeString != null && nameString != null) {
                                                    List<ProblemData> problems = fileListMap.get(VfsUtilCore.virtualToIoFile(psiFile.getVirtualFile()));
                                                    if (problems != null) {
                                                        for (ProblemData problem : problems) {
                                                            String unusedResource = UnusedResourceDetector.getUnusedResource(problem.getMessage(), TextFormat.RAW);
                                                            if (unusedResource != null && unusedResource.equals(SdkConstants.R_PREFIX + typeString + '.' + nameString)) {
                                                                elements.add(applicationStatement);
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                });
                            }
                            continue;
                        }
                        if (folderType != ResourceFolderType.VALUES) {
                            // also being deleted as unused
                            if (issue == UnusedResourceDetector.ISSUE_IDS) {
                                Map<File, List<ProblemData>> m = map.get(UnusedResourceDetector.ISSUE);
                                if (m != null && m.containsKey(file)) {
                                    // Yes - skip
                                    continue;
                                }
                                // Delete ranges within the file
                                addElementsInFile(elements, psiFile, problems);
                            } else {
                                // Unused non-value resource file: Delete the whole file
                                if (matchesFilter(fileListMap, file)) {
                                    elements.add(psiFile);
                                }
                            }
                        } else {
                            addElementsInFile(elements, psiFile, problems);
                        }
                    }
                }
            }
        }
    }
    return elements;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Issue(com.android.tools.lint.detector.api.Issue) GroovyRecursiveElementVisitor(org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor) GrApplicationStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement) ProblemData(org.jetbrains.android.inspections.lint.ProblemData) ResourceFolderType(com.android.resources.ResourceFolderType) List(java.util.List) XmlFile(com.intellij.psi.xml.XmlFile) VirtualFile(com.intellij.openapi.vfs.VirtualFile) GroovyFile(org.jetbrains.plugins.groovy.lang.psi.GroovyFile) File(java.io.File) GroovyFile(org.jetbrains.plugins.groovy.lang.psi.GroovyFile) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

ProblemData (org.jetbrains.android.inspections.lint.ProblemData)5 Issue (com.android.tools.lint.detector.api.Issue)4 NotNull (org.jetbrains.annotations.NotNull)3 LintIdeClient (com.android.tools.idea.lint.LintIdeClient)2 LintIdeIssueRegistry (com.android.tools.idea.lint.LintIdeIssueRegistry)2 LintIdeRequest (com.android.tools.idea.lint.LintIdeRequest)2 LintDriver (com.android.tools.lint.client.api.LintDriver)2 LintRequest (com.android.tools.lint.client.api.LintRequest)2 AnalysisScope (com.intellij.analysis.AnalysisScope)2 VirtualFile (com.intellij.openapi.vfs.VirtualFile)2 XmlFile (com.intellij.psi.xml.XmlFile)2 File (java.io.File)2 Map (java.util.Map)2 ResourceFolderType (com.android.resources.ResourceFolderType)1 BuiltinIssueRegistry (com.android.tools.lint.checks.BuiltinIssueRegistry)1 Scope (com.android.tools.lint.detector.api.Scope)1 Module (com.intellij.openapi.module.Module)1 Segment (com.intellij.openapi.util.Segment)1 VfsUtilCore.virtualToIoFile (com.intellij.openapi.vfs.VfsUtilCore.virtualToIoFile)1 XmlAttribute (com.intellij.psi.xml.XmlAttribute)1