/** * Returns the issue for the given id, or null if it's not a valid id * * @param id the id to be checked * @return the corresponding issue, or null */ @Nullable public final Issue getIssue(@NonNull String id) { if (sIdToIssue == null) { List<Issue> issues = getIssues(); sIdToIssue = new HashMap<String, Issue>(issues.size()); for (Issue issue : issues) { sIdToIssue.put(issue.getId(), issue); } sIdToIssue.put(PARSER_ERROR.getId(), PARSER_ERROR); sIdToIssue.put(LINT_ERROR.getId(), LINT_ERROR); } return sIdToIssue.get(id); }
@Override public boolean isIgnored( @NonNull Context context, @NonNull Issue issue, @Nullable Location location, @NonNull String message, @Nullable Object data) { ensureInitialized(); String id = issue.getId(); List<String> paths = mSuppressed.get(id); if (paths == null) { paths = mSuppressed.get(VALUE_ALL); } if (paths != null && location != null) { File file = location.getFile(); String relativePath = context.getProject().getRelativePath(file); for (String suppressedPath : paths) { if (suppressedPath.equals(relativePath)) { return true; } // Also allow a prefix if (relativePath.startsWith(suppressedPath)) { return true; } } } if (mRegexps != null) { List<Pattern> regexps = mRegexps.get(id); if (regexps == null) { regexps = mRegexps.get(VALUE_ALL); } if (regexps != null && location != null) { File file = location.getFile(); String relativePath = context.getProject().getRelativePath(file); boolean checkUnixPath = false; for (Pattern regexp : regexps) { Matcher matcher = regexp.matcher(relativePath); if (matcher.find()) { return true; } else if (regexp.pattern().indexOf('/') != -1) { checkUnixPath = true; } } if (checkUnixPath && CURRENT_PLATFORM == PLATFORM_WINDOWS) { relativePath = relativePath.replace('\\', '/'); for (Pattern regexp : regexps) { Matcher matcher = regexp.matcher(relativePath); if (matcher.find()) { return true; } } } } } return mParent != null && mParent.isIgnored(context, issue, location, message, data); }
/** * Marks the given issue and file combination as being ignored. * * @param issue the issue to be ignored in the given file * @param file the file to ignore the issue in */ public void ignore(@NonNull Issue issue, @NonNull File file) { ensureInitialized(); String path = mProject != null ? mProject.getRelativePath(file) : file.getPath(); List<String> paths = mSuppressed.get(issue.getId()); if (paths == null) { paths = new ArrayList<String>(); mSuppressed.put(issue.getId(), paths); } paths.add(path); // Keep paths sorted alphabetically; makes XML output stable Collections.sort(paths); if (!mBulkEditing) { writeConfig(); } }
@Override public void setSeverity(@NonNull Issue issue, @Nullable Severity severity) { ensureInitialized(); String id = issue.getId(); if (severity == null) { mSeverity.remove(id); } else { mSeverity.put(id, severity); } if (!mBulkEditing) { writeConfig(); } }
@Override @NonNull public Severity getSeverity(@NonNull Issue issue) { ensureInitialized(); Severity severity = mSeverity.get(issue.getId()); if (severity == null) { severity = mSeverity.get(VALUE_ALL); } if (severity != null) { return severity; } if (mParent != null) { return mParent.getSeverity(issue); } return getDefaultSeverity(issue); }
/** * Sorts the detectors alphabetically by id. This is intended to make it convenient to store * settings for detectors in a fixed order. It is not intended as the order to be shown to the * user; for that, a tool embedding lint might consider the priorities, categories, severities etc * of the various detectors. * * @param other the {@link com.android.tools.lint.detector.api.Issue} to compare this issue to */ @Override public int compareTo(Issue other) { return getId().compareTo(other.getId()); }
/** * Creates a list of detectors applicable to the given cope, and with the given configuration. * * @param client the client to report errors to * @param configuration the configuration to look up which issues are enabled etc from * @param scope the scope for the analysis, to filter out detectors that require wider analysis * than is currently being performed * @param scopeToDetectors an optional map which (if not null) will be filled by this method to * contain mappings from each scope to the applicable detectors for that scope * @return a list of new detector instances */ @NonNull final List<? extends Detector> createDetectors( @NonNull LintClient client, @NonNull Configuration configuration, @NonNull EnumSet<Scope> scope, @Nullable Map<Scope, List<Detector>> scopeToDetectors) { List<Issue> issues = getIssues(); Set<Class<? extends Detector>> detectorClasses = new HashSet<Class<? extends Detector>>(); Map<Class<? extends Detector>, EnumSet<Scope>> detectorToScope = new HashMap<Class<? extends Detector>, EnumSet<Scope>>(); for (Issue issue : issues) { Class<? extends Detector> detectorClass = issue.getDetectorClass(); EnumSet<Scope> issueScope = issue.getScope(); if (!detectorClasses.contains(detectorClass)) { // Determine if the issue is enabled if (!configuration.isEnabled(issue)) { continue; } // Determine if the scope matches if (!issue.isAdequate(scope)) { continue; } detectorClass = client.replaceDetector(detectorClass); assert detectorClass != null : issue.getId(); detectorClasses.add(detectorClass); } if (scopeToDetectors != null) { EnumSet<Scope> s = detectorToScope.get(detectorClass); if (s == null) { detectorToScope.put(detectorClass, issueScope); } else if (!s.containsAll(issueScope)) { EnumSet<Scope> union = EnumSet.copyOf(s); union.addAll(issueScope); detectorToScope.put(detectorClass, union); } } } List<Detector> detectors = new ArrayList<Detector>(detectorClasses.size()); for (Class<? extends Detector> clz : detectorClasses) { try { Detector detector = clz.newInstance(); detectors.add(detector); if (scopeToDetectors != null) { EnumSet<Scope> union = detectorToScope.get(clz); for (Scope s : union) { List<Detector> list = scopeToDetectors.get(s); if (list == null) { list = new ArrayList<Detector>(); scopeToDetectors.put(s, list); } list.add(detector); } } } catch (Throwable t) { client.log(t, "Can't initialize detector %1$s", clz.getName()); // $NON-NLS-1$ } } return detectors; }