use of com.android.tools.klint.detector.api.Detector in project kotlin by JetBrains.
the class LintDriver method checkResourceFolder.
private void checkResourceFolder(@NonNull Project project, @Nullable Project main, @NonNull File dir, @NonNull ResourceFolderType type, @NonNull List<ResourceXmlDetector> xmlChecks, @Nullable List<Detector> dirChecks, @Nullable List<Detector> binaryChecks) {
if (dirChecks != null && !dirChecks.isEmpty()) {
ResourceContext context = new ResourceContext(this, project, main, dir, type);
String folderName = dir.getName();
fireEvent(EventType.SCANNING_FILE, context);
for (Detector check : dirChecks) {
if (check.appliesTo(type)) {
check.beforeCheckFile(context);
check.checkFolder(context, folderName);
check.afterCheckFile(context);
}
}
if (binaryChecks == null && xmlChecks.isEmpty()) {
return;
}
}
File[] files = dir.listFiles();
if (files == null || files.length <= 0) {
return;
}
ResourceVisitor visitor = getVisitor(type, xmlChecks, binaryChecks);
if (visitor != null) {
// if not, there are no applicable rules in this folder
// Process files in alphabetical order, to ensure stable output
// (for example for the duplicate resource detector)
Arrays.sort(files);
for (File file : files) {
if (LintUtils.isXmlFile(file)) {
XmlContext context = new XmlContext(this, project, main, file, type, visitor.getParser());
fireEvent(EventType.SCANNING_FILE, context);
visitor.visitFile(context, file);
} else if (binaryChecks != null && (LintUtils.isBitmapFile(file) || type == ResourceFolderType.RAW)) {
ResourceContext context = new ResourceContext(this, project, main, file, type);
fireEvent(EventType.SCANNING_FILE, context);
visitor.visitBinaryResource(context);
}
if (mCanceled) {
return;
}
}
}
}
use of com.android.tools.klint.detector.api.Detector in project kotlin by JetBrains.
the class LintDriver method runClassDetectors.
private void runClassDetectors(Scope scope, List<ClassEntry> entries, Project project, Project main) {
if (mScope.contains(scope)) {
List<Detector> classDetectors = mScopeDetectors.get(scope);
if (classDetectors != null && !classDetectors.isEmpty() && !entries.isEmpty()) {
AsmVisitor visitor = new AsmVisitor(mClient, classDetectors);
String sourceContents = null;
String sourceName = "";
mOuterClasses = new ArrayDeque<ClassNode>();
ClassEntry prev = null;
for (ClassEntry entry : entries) {
if (prev != null && prev.compareTo(entry) == 0) {
// Duplicate entries for some reason: ignore
continue;
}
prev = entry;
ClassReader reader;
ClassNode classNode;
try {
reader = new ClassReader(entry.bytes);
classNode = new ClassNode();
reader.accept(classNode, 0);
} catch (Throwable t) {
mClient.log(null, "Error processing %1$s: broken class file?", entry.path());
continue;
}
ClassNode peek;
while ((peek = mOuterClasses.peek()) != null) {
if (classNode.name.startsWith(peek.name)) {
break;
} else {
mOuterClasses.pop();
}
}
mOuterClasses.push(classNode);
if (isSuppressed(null, classNode)) {
// Class was annotated with suppress all -- no need to look any further
continue;
}
if (sourceContents != null) {
// Attempt to reuse the source buffer if initialized
// This means making sure that the source files
// foo/bar/MyClass and foo/bar/MyClass$Bar
// and foo/bar/MyClass$3 and foo/bar/MyClass$3$1 have the same prefix.
String newName = classNode.name;
int newRootLength = newName.indexOf('$');
if (newRootLength == -1) {
newRootLength = newName.length();
}
int oldRootLength = sourceName.indexOf('$');
if (oldRootLength == -1) {
oldRootLength = sourceName.length();
}
if (newRootLength != oldRootLength || !sourceName.regionMatches(0, newName, 0, newRootLength)) {
sourceContents = null;
}
}
ClassContext context = new ClassContext(this, project, main, entry.file, entry.jarFile, entry.binDir, entry.bytes, classNode, scope == Scope.JAVA_LIBRARIES, /*fromLibrary*/
sourceContents);
try {
visitor.runClassDetectors(context);
} catch (Exception e) {
mClient.log(e, null);
}
if (mCanceled) {
return;
}
sourceContents = context.getSourceContents(false);
sourceName = classNode.name;
}
mOuterClasses = null;
}
}
}
use of com.android.tools.klint.detector.api.Detector in project kotlin by JetBrains.
the class LintDriver method runFileDetectors.
private void runFileDetectors(@NonNull Project project, @Nullable Project main) {
// Look up manifest information (but not for library projects)
if (project.isAndroidProject()) {
for (File manifestFile : project.getManifestFiles()) {
XmlParser parser = mClient.getXmlParser();
if (parser != null) {
XmlContext context = new XmlContext(this, project, main, manifestFile, null, parser);
context.document = parser.parseXml(context);
if (context.document != null) {
try {
project.readManifest(context.document);
if ((!project.isLibrary() || (main != null && main.isMergingManifests())) && mScope.contains(Scope.MANIFEST)) {
List<Detector> detectors = mScopeDetectors.get(Scope.MANIFEST);
if (detectors != null) {
ResourceVisitor v = new ResourceVisitor(parser, detectors, null);
fireEvent(EventType.SCANNING_FILE, context);
v.visitFile(context, manifestFile);
}
}
} finally {
if (context.document != null) {
// else: freed by XmlVisitor above
parser.dispose(context, context.document);
}
}
}
}
}
// in a single pass through the resource directories.
if (mScope.contains(Scope.ALL_RESOURCE_FILES) || mScope.contains(Scope.RESOURCE_FILE) || mScope.contains(Scope.RESOURCE_FOLDER) || mScope.contains(Scope.BINARY_RESOURCE_FILE)) {
List<Detector> dirChecks = mScopeDetectors.get(Scope.RESOURCE_FOLDER);
List<Detector> binaryChecks = mScopeDetectors.get(Scope.BINARY_RESOURCE_FILE);
List<Detector> checks = union(mScopeDetectors.get(Scope.RESOURCE_FILE), mScopeDetectors.get(Scope.ALL_RESOURCE_FILES));
boolean haveXmlChecks = checks != null && !checks.isEmpty();
List<ResourceXmlDetector> xmlDetectors;
if (haveXmlChecks) {
xmlDetectors = new ArrayList<ResourceXmlDetector>(checks.size());
for (Detector detector : checks) {
if (detector instanceof ResourceXmlDetector) {
xmlDetectors.add((ResourceXmlDetector) detector);
}
}
haveXmlChecks = !xmlDetectors.isEmpty();
} else {
xmlDetectors = Collections.emptyList();
}
if (haveXmlChecks || dirChecks != null && !dirChecks.isEmpty() || binaryChecks != null && !binaryChecks.isEmpty()) {
List<File> files = project.getSubset();
if (files != null) {
checkIndividualResources(project, main, xmlDetectors, dirChecks, binaryChecks, files);
} else {
List<File> resourceFolders = project.getResourceFolders();
if (!resourceFolders.isEmpty()) {
for (File res : resourceFolders) {
checkResFolder(project, main, res, xmlDetectors, dirChecks, binaryChecks);
}
}
}
}
}
if (mCanceled) {
return;
}
}
if (mScope.contains(Scope.JAVA_FILE) || mScope.contains(Scope.ALL_JAVA_FILES)) {
List<Detector> checks = union(mScopeDetectors.get(Scope.JAVA_FILE), mScopeDetectors.get(Scope.ALL_JAVA_FILES));
if (checks != null && !checks.isEmpty()) {
List<File> files = project.getSubset();
if (files != null) {
checkIndividualJavaFiles(project, main, checks, files);
} else {
List<File> sourceFolders = project.getJavaSourceFolders();
if (mScope.contains(Scope.TEST_SOURCES)) {
List<File> testFolders = project.getTestSourceFolders();
if (!testFolders.isEmpty()) {
List<File> combined = Lists.newArrayListWithExpectedSize(sourceFolders.size() + testFolders.size());
combined.addAll(sourceFolders);
combined.addAll(testFolders);
sourceFolders = combined;
}
}
checkJava(project, main, sourceFolders, checks);
}
}
}
if (mCanceled) {
return;
}
if (mScope.contains(Scope.CLASS_FILE) || mScope.contains(Scope.ALL_CLASS_FILES) || mScope.contains(Scope.JAVA_LIBRARIES)) {
checkClasses(project, main);
}
if (mCanceled) {
return;
}
if (mScope.contains(Scope.GRADLE_FILE)) {
checkBuildScripts(project, main);
}
if (mCanceled) {
return;
}
if (mScope.contains(Scope.OTHER)) {
List<Detector> checks = mScopeDetectors.get(Scope.OTHER);
if (checks != null) {
OtherFileVisitor visitor = new OtherFileVisitor(checks);
visitor.scan(this, project, main);
}
}
if (mCanceled) {
return;
}
if (project == main && mScope.contains(Scope.PROGUARD_FILE) && project.isAndroidProject()) {
checkProGuard(project, main);
}
if (project == main && mScope.contains(Scope.PROPERTY_FILE)) {
checkProperties(project, main);
}
}
use of com.android.tools.klint.detector.api.Detector in project kotlin by JetBrains.
the class LintDriver method visitJavaFiles.
private void visitJavaFiles(@NonNull List<Detector> checks, JavaParser javaParser, List<JavaContext> contexts) {
// Temporary: we still have some builtin checks that aren't migrated to
// PSI. Until that's complete, remove them from the list here
//List<Detector> scanners = checks;
List<Detector> scanners = Lists.newArrayListWithCapacity(0);
List<Detector> uastScanners = Lists.newArrayListWithCapacity(checks.size());
for (Detector detector : checks) {
if (detector instanceof Detector.JavaPsiScanner) {
scanners.add(detector);
} else if (detector instanceof Detector.UastScanner) {
uastScanners.add(detector);
}
}
if (!scanners.isEmpty()) {
JavaPsiVisitor visitor = new JavaPsiVisitor(javaParser, scanners);
visitor.prepare(contexts);
for (JavaContext context : contexts) {
fireEvent(EventType.SCANNING_FILE, context);
visitor.visitFile(context);
if (mCanceled) {
return;
}
}
visitor.dispose();
}
if (!uastScanners.isEmpty()) {
final UElementVisitor uElementVisitor = new UElementVisitor(javaParser, uastScanners);
uElementVisitor.prepare(contexts);
for (final JavaContext context : contexts) {
fireEvent(EventType.SCANNING_FILE, context);
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
uElementVisitor.visitFile(context);
}
});
if (mCanceled) {
return;
}
}
uElementVisitor.dispose();
}
//noinspection ConstantConditions
if (mRunCompatChecks) {
// Filter the checks to only those that implement JavaScanner
List<Detector> filtered = Lists.newArrayListWithCapacity(checks.size());
for (Detector detector : checks) {
if (detector instanceof Detector.JavaScanner) {
filtered.add(detector);
}
}
if (!filtered.isEmpty()) {
List<String> detectorNames = Lists.newArrayListWithCapacity(filtered.size());
for (Detector detector : filtered) {
detectorNames.add(detector.getClass().getName());
}
Collections.sort(detectorNames);
/* Let's not complain quite yet
String message = String.format("Lint found one or more custom checks using its "
+ "older Java API; these checks are still run in compatibility mode, "
+ "but this causes duplicated parsing, and in the next version lint "
+ "will no longer include this legacy mode. Make sure the following "
+ "lint detectors are upgraded to the new API: %1$s",
Joiner.on(", ").join(detectorNames));
JavaContext first = contexts.get(0);
Project project = first.getProject();
Location location = Location.create(project.getDir());
mClient.report(first,
IssueRegistry.LINT_ERROR,
project.getConfiguration(this).getSeverity(IssueRegistry.LINT_ERROR),
location, message, TextFormat.RAW);
*/
JavaVisitor oldVisitor = new JavaVisitor(javaParser, filtered);
oldVisitor.prepare(contexts);
for (JavaContext context : contexts) {
fireEvent(EventType.SCANNING_FILE, context);
oldVisitor.visitFile(context);
if (mCanceled) {
return;
}
}
oldVisitor.dispose();
}
}
}
use of com.android.tools.klint.detector.api.Detector in project kotlin by JetBrains.
the class LintDriver method checkPropertyFile.
private void checkPropertyFile(Project project, Project main, List<Detector> detectors, String relativePath) {
File file = new File(project.getDir(), relativePath);
if (file.exists()) {
Context context = new Context(this, project, main, file);
fireEvent(EventType.SCANNING_FILE, context);
for (Detector detector : detectors) {
if (detector.appliesTo(context, file)) {
detector.beforeCheckFile(context);
detector.run(context);
detector.afterCheckFile(context);
}
}
}
}
Aggregations