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