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);
}
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;
}
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;
}
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());
}
}
}
}
}
}
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);
}
}
}
}
}
}
Aggregations