Search in sources :

Example 6 with Issue

use of com.android.tools.lint.detector.api.Issue in project android by JetBrains.

the class AndroidLintExternalAnnotator method collectInformation.

@Override
public State collectInformation(@NotNull PsiFile file) {
    final Module module = ModuleUtilCore.findModuleForPsiElement(file);
    if (module == null) {
        return null;
    }
    final AndroidFacet facet = AndroidFacet.getInstance(module);
    if (facet == null && !LintIdeProject.hasAndroidModule(module.getProject())) {
        return null;
    }
    final VirtualFile vFile = file.getVirtualFile();
    if (vFile == null) {
        return null;
    }
    final FileType fileType = file.getFileType();
    if (fileType == StdFileTypes.XML) {
        if (facet == null || facet.getLocalResourceManager().getFileResourceFolderType(file) == null && !ANDROID_MANIFEST_XML.equals(vFile.getName())) {
            return null;
        }
    } else if (fileType == FileTypes.PLAIN_TEXT) {
        if (!AndroidCommonUtils.PROGUARD_CFG_FILE_NAME.equals(file.getName()) && !AndroidCompileUtil.OLD_PROGUARD_CFG_FILE_NAME.equals(file.getName())) {
            return null;
        }
    } else if (fileType == GroovyFileType.GROOVY_FILE_TYPE) {
        if (!SdkUtils.endsWithIgnoreCase(file.getName(), DOT_GRADLE)) {
            return null;
        }
        // Ensure that we're listening to the PSI structure for Gradle file edit notifications
        Project project = file.getProject();
        if (AndroidProjectInfo.getInstance(project).requiresAndroidModel()) {
            PsiProjectListener.getInstance(project);
        }
    } else if (fileType != StdFileTypes.JAVA && fileType != StdFileTypes.PROPERTIES) {
        return null;
    }
    final List<Issue> issues = getIssuesFromInspections(file.getProject(), file);
    if (issues.size() == 0) {
        return null;
    }
    return new State(module, vFile, file.getText(), issues);
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Project(com.intellij.openapi.project.Project) Issue(com.android.tools.lint.detector.api.Issue) GroovyFileType(org.jetbrains.plugins.groovy.GroovyFileType) FileType(com.intellij.openapi.fileTypes.FileType) Module(com.intellij.openapi.module.Module) AndroidFacet(org.jetbrains.android.facet.AndroidFacet)

Example 7 with Issue

use of com.android.tools.lint.detector.api.Issue in project android by JetBrains.

the class AndroidLintGlobalInspectionContext method performPreRunActivities.

@Override
public void performPreRunActivities(@NotNull List<Tools> globalTools, @NotNull List<Tools> localTools, @NotNull final GlobalInspectionContext context) {
    final Project project = context.getProject();
    // Running a single inspection that's not lint? If so don't run lint
    if (localTools.isEmpty() && globalTools.size() == 1) {
        Tools tool = globalTools.get(0);
        if (!tool.getShortName().startsWith(LINT_INSPECTION_PREFIX)) {
            return;
        }
    }
    if (!ProjectFacetManager.getInstance(project).hasFacets(AndroidFacet.ID)) {
        return;
    }
    List<Issue> issues = AndroidLintExternalAnnotator.getIssuesFromInspections(project, null);
    if (issues.size() == 0) {
        return;
    }
    // If running a single check by name, turn it on if it's off by default.
    if (localTools.isEmpty() && globalTools.size() == 1) {
        Tools tool = globalTools.get(0);
        String id = tool.getShortName().substring(LINT_INSPECTION_PREFIX.length());
        Issue issue = new LintIdeIssueRegistry().getIssue(id);
        if (issue != null && !issue.isEnabledByDefault()) {
            issues = Collections.singletonList(issue);
            issue.setEnabledByDefault(true);
            // And turn it back off again in cleanup
            myEnabledIssue = issue;
        }
    }
    final Map<Issue, Map<File, List<ProblemData>>> problemMap = new HashMap<>();
    AnalysisScope scope = context.getRefManager().getScope();
    if (scope == null) {
        scope = AndroidLintLintBaselineInspection.ourRerunScope;
        if (scope == null) {
            return;
        }
    }
    final LintIdeClient client = LintIdeClient.forBatch(project, problemMap, scope, issues);
    final LintDriver lint = new LintDriver(new LintIdeIssueRegistry(), client);
    final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
    if (indicator != null) {
        ProgressWrapper.unwrap(indicator).setText("Running Android Lint");
    }
    EnumSet<Scope> lintScope;
    //noinspection ConstantConditions
    if (!LintIdeProject.SUPPORT_CLASS_FILES) {
        lintScope = EnumSet.copyOf(Scope.ALL);
        // Can't run class file based checks
        lintScope.remove(Scope.CLASS_FILE);
        lintScope.remove(Scope.ALL_CLASS_FILES);
        lintScope.remove(Scope.JAVA_LIBRARIES);
    } else {
        lintScope = Scope.ALL;
    }
    List<VirtualFile> files = null;
    final List<Module> modules = Lists.newArrayList();
    int scopeType = scope.getScopeType();
    switch(scopeType) {
        case AnalysisScope.MODULE:
            {
                SearchScope searchScope = ReadAction.compute(scope::toSearchScope);
                if (searchScope instanceof ModuleWithDependenciesScope) {
                    ModuleWithDependenciesScope s = (ModuleWithDependenciesScope) searchScope;
                    if (!s.isSearchInLibraries()) {
                        modules.add(s.getModule());
                    }
                }
                break;
            }
        case AnalysisScope.FILE:
        case AnalysisScope.VIRTUAL_FILES:
        case AnalysisScope.UNCOMMITTED_FILES:
            {
                files = Lists.newArrayList();
                SearchScope searchScope = scope.toSearchScope();
                if (searchScope instanceof LocalSearchScope) {
                    final LocalSearchScope localSearchScope = (LocalSearchScope) searchScope;
                    final PsiElement[] elements = localSearchScope.getScope();
                    final List<VirtualFile> finalFiles = files;
                    ApplicationManager.getApplication().runReadAction(() -> {
                        for (PsiElement element : elements) {
                            if (element instanceof PsiFile) {
                                // should be the case since scope type is FILE
                                Module module = ModuleUtilCore.findModuleForPsiElement(element);
                                if (module != null && !modules.contains(module)) {
                                    modules.add(module);
                                }
                                VirtualFile virtualFile = ((PsiFile) element).getVirtualFile();
                                if (virtualFile != null) {
                                    if (virtualFile instanceof StringsVirtualFile) {
                                        StringsVirtualFile f = (StringsVirtualFile) virtualFile;
                                        if (!modules.contains(f.getFacet().getModule())) {
                                            modules.add(f.getFacet().getModule());
                                        }
                                    } else {
                                        finalFiles.add(virtualFile);
                                    }
                                }
                            }
                        }
                    });
                } else {
                    final List<VirtualFile> finalList = files;
                    scope.accept(new PsiElementVisitor() {

                        @Override
                        public void visitFile(PsiFile file) {
                            VirtualFile virtualFile = file.getVirtualFile();
                            if (virtualFile != null) {
                                finalList.add(virtualFile);
                            }
                        }
                    });
                }
                if (files.isEmpty()) {
                    files = null;
                } else {
                    // Lint will compute it lazily based on actual files in the request
                    lintScope = null;
                }
                break;
            }
        case AnalysisScope.PROJECT:
            {
                modules.addAll(Arrays.asList(ModuleManager.getInstance(project).getModules()));
                break;
            }
        case AnalysisScope.CUSTOM:
        case AnalysisScope.MODULES:
        case AnalysisScope.DIRECTORY:
            {
                // Handled by the getNarrowedComplementaryScope case below
                break;
            }
        case AnalysisScope.INVALID:
            break;
        default:
            Logger.getInstance(this.getClass()).warn("Unexpected inspection scope " + scope + ", " + scopeType);
    }
    if (modules.isEmpty()) {
        for (Module module : ModuleManager.getInstance(project).getModules()) {
            if (scope.containsModule(module)) {
                modules.add(module);
            }
        }
        if (modules.isEmpty() && files != null) {
            for (VirtualFile file : files) {
                Module module = ModuleUtilCore.findModuleForFile(file, project);
                if (module != null && !modules.contains(module)) {
                    modules.add(module);
                }
            }
        }
        if (modules.isEmpty()) {
            AnalysisScope narrowed = scope.getNarrowedComplementaryScope(project);
            for (Module module : ModuleManager.getInstance(project).getModules()) {
                if (narrowed.containsModule(module)) {
                    modules.add(module);
                }
            }
        }
    }
    LintRequest request = new LintIdeRequest(client, project, files, modules, false);
    request.setScope(lintScope);
    // Baseline analysis?
    myBaseline = null;
    for (Module module : modules) {
        AndroidModuleModel model = AndroidModuleModel.get(module);
        if (model != null) {
            GradleVersion version = model.getModelVersion();
            if (version != null && version.isAtLeast(2, 3, 0, "beta", 2, true)) {
                LintOptions options = model.getAndroidProject().getLintOptions();
                try {
                    File baselineFile = options.getBaselineFile();
                    if (baselineFile != null && !AndroidLintLintBaselineInspection.ourSkipBaselineNextRun) {
                        if (!baselineFile.isAbsolute()) {
                            String path = module.getProject().getBasePath();
                            if (path != null) {
                                baselineFile = new File(FileUtil.toSystemDependentName(path), baselineFile.getPath());
                            }
                        }
                        myBaseline = new LintBaseline(client, baselineFile);
                        lint.setBaseline(myBaseline);
                        if (!baselineFile.isFile()) {
                            myBaseline.setWriteOnClose(true);
                        } else if (AndroidLintLintBaselineInspection.ourUpdateBaselineNextRun) {
                            myBaseline.setRemoveFixed(true);
                            myBaseline.setWriteOnClose(true);
                        }
                    }
                } catch (Throwable unsupported) {
                // During 2.3 development some builds may have this method, others may not
                }
            }
            break;
        }
    }
    lint.analyze(request);
    AndroidLintLintBaselineInspection.clearNextRunState();
    myResults = problemMap;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) StringsVirtualFile(com.android.tools.idea.editors.strings.StringsVirtualFile) Issue(com.android.tools.lint.detector.api.Issue) HashMap(com.intellij.util.containers.HashMap) LintOptions(com.android.builder.model.LintOptions) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) AnalysisScope(com.intellij.analysis.AnalysisScope) LintRequest(com.android.tools.lint.client.api.LintRequest) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) PsiFile(com.intellij.psi.PsiFile) GradleVersion(com.android.ide.common.repository.GradleVersion) PsiElement(com.intellij.psi.PsiElement) LintDriver(com.android.tools.lint.client.api.LintDriver) LocalSearchScope(com.intellij.psi.search.LocalSearchScope) ModuleWithDependenciesScope(com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope) Tools(com.intellij.codeInspection.ex.Tools) LintBaseline(com.android.tools.lint.client.api.LintBaseline) com.android.tools.idea.lint(com.android.tools.idea.lint) Project(com.intellij.openapi.project.Project) ModuleWithDependenciesScope(com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope) SearchScope(com.intellij.psi.search.SearchScope) LocalSearchScope(com.intellij.psi.search.LocalSearchScope) Scope(com.android.tools.lint.detector.api.Scope) AnalysisScope(com.intellij.analysis.AnalysisScope) StringsVirtualFile(com.android.tools.idea.editors.strings.StringsVirtualFile) SearchScope(com.intellij.psi.search.SearchScope) LocalSearchScope(com.intellij.psi.search.LocalSearchScope) AndroidModuleModel(com.android.tools.idea.gradle.project.model.AndroidModuleModel) Module(com.intellij.openapi.module.Module) HashMap(com.intellij.util.containers.HashMap) VirtualFile(com.intellij.openapi.vfs.VirtualFile) PsiFile(com.intellij.psi.PsiFile) File(java.io.File) StringsVirtualFile(com.android.tools.idea.editors.strings.StringsVirtualFile)

Example 8 with Issue

use of com.android.tools.lint.detector.api.Issue in project android by JetBrains.

the class NlLintHighlightingPass method getAnnotations.

@NotNull
private static LintAnnotationsModel getAnnotations(@NotNull NlModel model, @NotNull ProgressIndicator progress) {
    ApplicationManager.getApplication().assertReadAccessAllowed();
    LintAnnotationsModel lintModel = new LintAnnotationsModel();
    XmlFile xmlFile = model.getFile();
    AndroidLintExternalAnnotator annotator = new AndroidLintExternalAnnotator();
    State state = annotator.collectInformation(xmlFile);
    if (state != null) {
        state = annotator.doAnnotate(state);
    }
    if (state == null) {
        return lintModel;
    }
    for (ProblemData problemData : state.getProblems()) {
        if (progress.isCanceled()) {
            break;
        }
        TextRange range = problemData.getTextRange();
        final PsiElement startElement = xmlFile.findElementAt(range.getStartOffset());
        final PsiElement endElement = xmlFile.findElementAt(range.getEndOffset());
        if (startElement == null || endElement == null) {
            continue;
        }
        NlComponent component = model.findViewByPsi(startElement);
        if (component == null) {
            continue;
        }
        Issue issue = problemData.getIssue();
        Pair<AndroidLintInspectionBase, HighlightDisplayLevel> pair = AndroidLintUtil.getHighlighLevelAndInspection(xmlFile.getProject(), issue, xmlFile);
        if (pair == null) {
            continue;
        }
        AndroidLintInspectionBase inspection = pair.getFirst();
        if (inspection == null) {
            continue;
        }
        HighlightDisplayLevel level = pair.getSecond();
        HighlightDisplayKey key = HighlightDisplayKey.find(inspection.getShortName());
        if (key == null) {
            continue;
        }
        lintModel.addIssue(component, issue, problemData.getMessage(), inspection, level, startElement, endElement);
    }
    return lintModel;
}
Also used : Issue(com.android.tools.lint.detector.api.Issue) HighlightDisplayLevel(com.intellij.codeHighlighting.HighlightDisplayLevel) XmlFile(com.intellij.psi.xml.XmlFile) HighlightDisplayKey(com.intellij.codeInsight.daemon.HighlightDisplayKey) TextRange(com.intellij.openapi.util.TextRange) NlComponent(com.android.tools.idea.uibuilder.model.NlComponent) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 9 with Issue

use of com.android.tools.lint.detector.api.Issue 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 10 with Issue

use of com.android.tools.lint.detector.api.Issue in project android by JetBrains.

the class SuppressLintIntentionAction method invoke.

@Override
public void invoke(@NotNull Project project, @Nullable Editor editor, @NotNull PsiFile file) throws IncorrectOperationException {
    if (file instanceof XmlFile) {
        final XmlTag element = PsiTreeUtil.getParentOfType(myElement, XmlTag.class);
        if (element == null) {
            return;
        }
        String lintId = getLintId(myId);
        addSuppressAttribute(project, (XmlFile) file, element, lintId);
    } else if (file instanceof PsiJavaFile) {
        final PsiModifierListOwner container = PsiTreeUtil.getParentOfType(myElement, PsiModifierListOwner.class);
        if (container == null) {
            return;
        }
        final PsiModifierList modifierList = container.getModifierList();
        if (modifierList != null) {
            String lintId = getLintId(myId);
            addSuppressAnnotation(project, container, container, lintId);
        }
    } else if (file instanceof GroovyFile) {
        Document document = PsiDocumentManager.getInstance(myElement.getProject()).getDocument(file);
        if (document != null) {
            int offset = myElement.getTextOffset();
            int line = document.getLineNumber(offset);
            int lineStart = document.getLineStartOffset(line);
            if (lineStart > 0) {
                int prevLineStart = document.getLineStartOffset(line - 1);
                int prevLineEnd = document.getLineEndOffset(line - 1);
                String prevLine = document.getText(new TextRange(prevLineStart, prevLineEnd));
                int index = prevLine.indexOf(NO_INSPECTION_PREFIX);
                if (index != -1) {
                    document.insertString(prevLineStart + index + NO_INSPECTION_PREFIX.length(), getLintId(myId) + ",");
                    return;
                }
            }
            String linePrefix = document.getText(new TextRange(lineStart, offset));
            int nonSpace = 0;
            for (; nonSpace < linePrefix.length(); nonSpace++) {
                if (!Character.isWhitespace(linePrefix.charAt(nonSpace))) {
                    break;
                }
            }
            ApplicationManager.getApplication().assertWriteAccessAllowed();
            document.insertString(lineStart + nonSpace, NO_INSPECTION_PREFIX + getLintId(myId) + "\n" + linePrefix.substring(0, nonSpace));
        }
    } else if (file instanceof PsiBinaryFile) {
        VirtualFile virtualFile = file.getVirtualFile();
        if (virtualFile != null) {
            File binaryFile = VfsUtilCore.virtualToIoFile(virtualFile);
            // Can't suppress lint checks inside a binary file (typically an icon): use
            // the lint XML facility instead
            Module module = ModuleUtilCore.findModuleForPsiElement(file);
            if (module != null) {
                //LintIdeRequest
                File dir = LintIdeProject.getLintProjectDirectory(module, AndroidFacet.getInstance(module));
                if (dir != null) {
                    LintIdeClient client = new LintIdeClient(project);
                    com.android.tools.lint.detector.api.Project lintProject = client.getProject(dir, dir);
                    Configuration configuration = client.getConfiguration(lintProject, null);
                    Issue issue = getIssue();
                    if (issue != null) {
                        configuration.ignore(issue, binaryFile);
                    }
                }
            }
        }
    }
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Issue(com.android.tools.lint.detector.api.Issue) XmlFile(com.intellij.psi.xml.XmlFile) Configuration(com.android.tools.lint.client.api.Configuration) TextRange(com.intellij.openapi.util.TextRange) Document(com.intellij.openapi.editor.Document) Project(com.intellij.openapi.project.Project) Module(com.intellij.openapi.module.Module) 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) XmlTag(com.intellij.psi.xml.XmlTag)

Aggregations

Issue (com.android.tools.lint.detector.api.Issue)14 NotNull (org.jetbrains.annotations.NotNull)6 Project (com.intellij.openapi.project.Project)5 VirtualFile (com.intellij.openapi.vfs.VirtualFile)5 Module (com.intellij.openapi.module.Module)4 XmlFile (com.intellij.psi.xml.XmlFile)4 File (java.io.File)4 ProblemData (org.jetbrains.android.inspections.lint.ProblemData)4 BuiltinIssueRegistry (com.android.tools.lint.checks.BuiltinIssueRegistry)3 LintDriver (com.android.tools.lint.client.api.LintDriver)3 LintRequest (com.android.tools.lint.client.api.LintRequest)3 AnalysisScope (com.intellij.analysis.AnalysisScope)3 HighlightDisplayLevel (com.intellij.codeHighlighting.HighlightDisplayLevel)3 HighlightDisplayKey (com.intellij.codeInsight.daemon.HighlightDisplayKey)3 PsiElement (com.intellij.psi.PsiElement)3 PsiFile (com.intellij.psi.PsiFile)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 Scope (com.android.tools.lint.detector.api.Scope)2