use of com.android.tools.klint.detector.api.XmlContext in project kotlin by JetBrains.
the class LintDriver method checkIndividualResources.
/** Checks individual resources */
private void checkIndividualResources(@NonNull Project project, @Nullable Project main, @NonNull List<ResourceXmlDetector> xmlDetectors, @Nullable List<Detector> dirChecks, @Nullable List<Detector> binaryChecks, @NonNull List<File> files) {
for (File file : files) {
if (file.isDirectory()) {
// Is it a resource folder?
ResourceFolderType type = ResourceFolderType.getFolderType(file.getName());
if (type != null && new File(file.getParentFile(), RES_FOLDER).exists()) {
// Yes.
checkResourceFolder(project, main, file, type, xmlDetectors, dirChecks, binaryChecks);
} else if (file.getName().equals(RES_FOLDER)) {
// Is it the res folder?
// Yes
checkResFolder(project, main, file, xmlDetectors, dirChecks, binaryChecks);
} else {
mClient.log(null, "Unexpected folder %1$s; should be project, " + "\"res\" folder or resource folder", file.getPath());
}
} else if (file.isFile() && LintUtils.isXmlFile(file)) {
// Yes, find out its resource type
String folderName = file.getParentFile().getName();
ResourceFolderType type = ResourceFolderType.getFolderType(folderName);
if (type != null) {
ResourceVisitor visitor = getVisitor(type, xmlDetectors, binaryChecks);
if (visitor != null) {
XmlContext context = new XmlContext(this, project, main, file, type, visitor.getParser());
fireEvent(EventType.SCANNING_FILE, context);
visitor.visitFile(context, file);
}
}
} else if (binaryChecks != null && file.isFile() && LintUtils.isBitmapFile(file)) {
// Yes, find out its resource type
String folderName = file.getParentFile().getName();
ResourceFolderType type = ResourceFolderType.getFolderType(folderName);
if (type != null) {
ResourceVisitor visitor = getVisitor(type, xmlDetectors, binaryChecks);
if (visitor != null) {
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.XmlContext in project kotlin by JetBrains.
the class AppIndexingApiDetector method getActivitiesToCheck.
/**
* Gets names of activities which needs app indexing. i.e. the activities have data tag in their
* intent filters.
* TODO: Cache the activities to speed up batch lint.
*
* @param context The context to check in.
*/
private static Set<String> getActivitiesToCheck(Context context) {
Set<String> activitiesToCheck = Sets.newHashSet();
List<File> manifestFiles = context.getProject().getManifestFiles();
XmlParser xmlParser = context.getDriver().getClient().getXmlParser();
if (xmlParser != null) {
// TODO: Avoid visit all manifest files before enable this check by default.
for (File manifest : manifestFiles) {
XmlContext xmlContext = new XmlContext(context.getDriver(), context.getProject(), null, manifest, null, xmlParser);
Document doc = xmlParser.parseXml(xmlContext);
if (doc != null) {
List<Element> children = LintUtils.getChildren(doc);
for (Element child : children) {
if (child.getNodeName().equals(NODE_MANIFEST)) {
List<Element> apps = extractChildrenByName(child, NODE_APPLICATION);
for (Element app : apps) {
List<Element> acts = extractChildrenByName(app, NODE_ACTIVITY);
for (Element act : acts) {
List<Element> intents = extractChildrenByName(act, NODE_INTENT);
for (Element intent : intents) {
List<Element> data = extractChildrenByName(intent, NODE_DATA);
if (!data.isEmpty() && act.hasAttributeNS(ANDROID_URI, ATTRIBUTE_NAME)) {
Attr attr = act.getAttributeNodeNS(ANDROID_URI, ATTRIBUTE_NAME);
String activityName = attr.getValue();
int dotIndex = activityName.indexOf('.');
if (dotIndex <= 0) {
String pkg = context.getMainProject().getPackage();
if (pkg != null) {
if (dotIndex == 0) {
activityName = pkg + activityName;
} else {
activityName = pkg + '.' + activityName;
}
}
}
activitiesToCheck.add(activityName);
}
}
}
}
}
}
}
}
}
return activitiesToCheck;
}
use of com.android.tools.klint.detector.api.XmlContext in project kotlin by JetBrains.
the class AlwaysShowActionDetector method afterCheckFile.
@Override
public void afterCheckFile(@NonNull Context context) {
if (mIgnoreFile) {
mFileAttributes = null;
return;
}
if (mFileAttributes != null) {
// mFileAttributes is only set in XML files
assert context instanceof XmlContext;
List<Attr> always = new ArrayList<Attr>();
List<Attr> ifRoom = new ArrayList<Attr>();
for (Attr attribute : mFileAttributes) {
String value = attribute.getValue();
if (value.equals(VALUE_ALWAYS)) {
always.add(attribute);
} else if (value.equals(VALUE_IF_ROOM)) {
ifRoom.add(attribute);
} else if (value.indexOf('|') != -1) {
//$NON-NLS-1$
String[] flags = value.split("\\|");
for (String flag : flags) {
if (flag.equals(VALUE_ALWAYS)) {
always.add(attribute);
break;
} else if (flag.equals(VALUE_IF_ROOM)) {
ifRoom.add(attribute);
break;
}
}
}
}
if (!always.isEmpty() && mFileAttributes.size() > 1) {
// have more than a single item)
if (always.size() > 2 || ifRoom.isEmpty()) {
XmlContext xmlContext = (XmlContext) context;
Location location = null;
for (int i = always.size() - 1; i >= 0; i--) {
Location next = location;
location = xmlContext.getLocation(always.get(i));
if (next != null) {
location.setSecondary(next);
}
}
if (location != null) {
context.report(ISSUE, location, "Prefer \"`ifRoom`\" instead of \"`always`\"");
}
}
}
}
}
use of com.android.tools.klint.detector.api.XmlContext 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.XmlContext 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);
}
}
Aggregations