use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.
the class IntellijLintProject method findAndroidModule.
/** Find an Android module that depends on this module; prefer app modules over library modules */
@Nullable
private static Module findAndroidModule(@NonNull final Module module) {
// Search for dependencies of this module
Graph<Module> graph = ApplicationManager.getApplication().runReadAction(new Computable<Graph<Module>>() {
@Override
public Graph<Module> compute() {
com.intellij.openapi.project.Project project = module.getProject();
if (project.isDisposed()) {
return null;
}
return ModuleManager.getInstance(project).moduleGraph();
}
});
if (graph == null) {
return null;
}
Set<AndroidFacet> facets = Sets.newHashSet();
HashSet<Module> seen = Sets.newHashSet();
seen.add(module);
addAndroidModules(facets, seen, graph, module);
// Prefer Android app modules
for (AndroidFacet facet : facets) {
if (!facet.isLibraryProject()) {
return facet.getModule();
}
}
// Resort to library modules if no app module depends directly on it
if (!facets.isEmpty()) {
return facets.iterator().next().getModule();
}
return null;
}
use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.
the class OverdrawDetector method getTheme.
/** Return the theme to be used for the given layout */
private String getTheme(Context context, String layoutName) {
if (mActivityToTheme != null && mLayoutToActivity != null) {
List<String> activities = mLayoutToActivity.get(layoutName);
if (activities != null) {
for (String activity : activities) {
String theme = mActivityToTheme.get(activity);
if (theme != null) {
return theme;
}
}
}
}
if (mManifestTheme != null) {
return mManifestTheme;
}
Project project = context.getMainProject();
int apiLevel = project.getTargetSdk();
if (apiLevel == -1) {
apiLevel = project.getMinSdk();
}
if (apiLevel >= 11) {
//$NON-NLS-1$
return "@android:style/Theme.Holo";
} else {
//$NON-NLS-1$
return "@android:style/Theme";
}
}
use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.
the class LayoutInflationDetector method hasLayoutParams.
private static boolean hasLayoutParams(@NonNull JavaContext context, String name) {
LintClient client = context.getClient();
if (!client.supportsProjectResources()) {
// not certain
return true;
}
Project project = context.getProject();
AbstractResourceRepository resources = client.getProjectResources(project, true);
if (resources == null) {
// not certain
return true;
}
List<ResourceItem> items = resources.getResourceItem(ResourceType.LAYOUT, name);
if (items == null || items.isEmpty()) {
return false;
}
for (ResourceItem item : items) {
ResourceFile source = item.getSource();
if (source == null) {
// not certain
return true;
}
File file = source.getFile();
if (file.exists()) {
try {
String s = context.getClient().readFile(file);
if (hasLayoutParams(new StringReader(s))) {
return true;
}
} catch (Exception e) {
context.log(e, "Could not read/parse inflated layout");
// not certain
return true;
}
}
}
return false;
}
use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.
the class AppIndexingApiDetector method replaceUrlWithValue.
private static String replaceUrlWithValue(@NonNull XmlContext context, @NonNull String str) {
Project project = context.getProject();
LintClient client = context.getClient();
if (!client.supportsProjectResources()) {
return str;
}
ResourceUrl style = ResourceUrl.parse(str);
if (style == null || style.type != ResourceType.STRING || style.framework) {
return str;
}
AbstractResourceRepository resources = client.getProjectResources(project, true);
if (resources == null) {
return str;
}
List<ResourceItem> items = resources.getResourceItem(ResourceType.STRING, style.name);
if (items == null || items.isEmpty()) {
return str;
}
ResourceValue resourceValue = items.get(0).getResourceValue(false);
if (resourceValue == null) {
return str;
}
return resourceValue.getValue() == null ? str : resourceValue.getValue();
}
use of com.android.tools.klint.detector.api.Project in project kotlin by JetBrains.
the class RtlDetector method visitAttribute.
@Override
public void visitAttribute(@NonNull XmlContext context, @NonNull Attr attribute) {
Project project = context.getMainProject();
String value = attribute.getValue();
if (!ANDROID_URI.equals(attribute.getNamespaceURI())) {
// the MissingPrefixDetector)
return;
}
String name = attribute.getLocalName();
assert name != null : attribute.getName();
if (name.equals(ATTR_SUPPORTS_RTL)) {
mEnabledRtlSupport = Boolean.valueOf(value);
if (!attribute.getOwnerElement().getTagName().equals(TAG_APPLICATION)) {
context.report(ENABLED, attribute, context.getLocation(attribute), String.format("Wrong declaration: `%1$s` should be defined on the `<application>` element", attribute.getName()));
}
int targetSdk = project.getTargetSdk();
if (mEnabledRtlSupport && targetSdk < RTL_API) {
String message = String.format("You must set `android:targetSdkVersion` to at least %1$d when " + "enabling RTL support (is %2$d)", RTL_API, project.getTargetSdk());
context.report(ENABLED, attribute, context.getValueLocation(attribute), message);
}
return;
}
if (!rtlApplies(context)) {
return;
}
if (name.equals(ATTR_TEXT_ALIGNMENT)) {
if (context.getProject().getReportIssues()) {
mUsesRtlAttributes = true;
}
Element element = attribute.getOwnerElement();
final String gravity;
final Attr gravityNode;
if (element.hasAttributeNS(ANDROID_URI, ATTR_GRAVITY)) {
gravityNode = element.getAttributeNodeNS(ANDROID_URI, ATTR_GRAVITY);
gravity = gravityNode.getValue();
} else if (element.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_GRAVITY)) {
gravityNode = element.getAttributeNodeNS(ANDROID_URI, ATTR_LAYOUT_GRAVITY);
gravity = gravityNode.getValue();
} else if (project.getMinSdk() < RTL_API) {
int folderVersion = context.getFolderVersion();
if (folderVersion < RTL_API && context.isEnabled(COMPAT)) {
String expectedGravity = getTextAlignmentToGravity(value);
if (expectedGravity != null) {
String message = String.format("To support older versions than API 17 (project specifies %1$d) " + "you must *also* specify `gravity` or `layout_gravity=\"%2$s\"`", project.getMinSdk(), expectedGravity);
context.report(COMPAT, attribute, context.getNameLocation(attribute), message);
}
}
return;
} else {
return;
}
String expectedGravity = getTextAlignmentToGravity(value);
if (expectedGravity != null && !gravity.contains(expectedGravity) && context.isEnabled(COMPAT)) {
String message = String.format("Inconsistent alignment specification between " + "`textAlignment` and `gravity` attributes: was `%1$s`, expected `%2$s`", gravity, expectedGravity);
Location location = context.getValueLocation(attribute);
context.report(COMPAT, attribute, location, message);
Location secondary = context.getValueLocation(gravityNode);
secondary.setMessage("Incompatible direction here");
location.setSecondary(secondary);
}
return;
}
if (name.equals(ATTR_GRAVITY) || name.equals(ATTR_LAYOUT_GRAVITY)) {
boolean isLeft = value.contains(GRAVITY_VALUE_LEFT);
boolean isRight = value.contains(GRAVITY_VALUE_RIGHT);
if (!isLeft && !isRight) {
if ((value.contains(GRAVITY_VALUE_START) || value.contains(GRAVITY_VALUE_END)) && context.getProject().getReportIssues()) {
mUsesRtlAttributes = true;
}
return;
}
String message = String.format("Use \"`%1$s`\" instead of \"`%2$s`\" to ensure correct behavior in " + "right-to-left locales", isLeft ? GRAVITY_VALUE_START : GRAVITY_VALUE_END, isLeft ? GRAVITY_VALUE_LEFT : GRAVITY_VALUE_RIGHT);
if (context.isEnabled(USE_START)) {
context.report(USE_START, attribute, context.getValueLocation(attribute), message);
}
return;
}
// Some other left/right/start/end attribute
int targetSdk = project.getTargetSdk();
// TODO: If attribute is drawableLeft or drawableRight, add note that you might
// want to consider adding a specialized image in the -ldrtl folder as well
Element element = attribute.getOwnerElement();
boolean isPaddingAttribute = isPaddingAttribute(name);
if (isPaddingAttribute || isMarginAttribute(name)) {
String opposite = convertToOppositeDirection(name);
if (element.hasAttributeNS(ANDROID_URI, opposite)) {
String oldValue = element.getAttributeNS(ANDROID_URI, opposite);
if (value.equals(oldValue)) {
return;
}
} else if (isPaddingAttribute && !element.hasAttributeNS(ANDROID_URI, isOldAttribute(opposite) ? convertOldToNew(opposite) : convertNewToOld(opposite)) && context.isEnabled(SYMMETRY)) {
String message = String.format("When you define `%1$s` you should probably also define `%2$s` for " + "right-to-left symmetry", name, opposite);
context.report(SYMMETRY, attribute, context.getNameLocation(attribute), message);
}
}
boolean isOld = isOldAttribute(name);
if (isOld) {
if (!context.isEnabled(USE_START)) {
return;
}
String rtl = convertOldToNew(name);
if (element.hasAttributeNS(ANDROID_URI, rtl)) {
if (project.getMinSdk() >= RTL_API || context.getFolderVersion() >= RTL_API) {
// Warn that left/right isn't needed
String message = String.format("Redundant attribute `%1$s`; already defining `%2$s` with " + "`targetSdkVersion` %3$s", name, rtl, targetSdk);
context.report(USE_START, attribute, context.getNameLocation(attribute), message);
}
} else {
String message;
if (project.getMinSdk() >= RTL_API || context.getFolderVersion() >= RTL_API) {
message = String.format("Consider replacing `%1$s` with `%2$s:%3$s=\"%4$s\"` to better support " + "right-to-left layouts", attribute.getName(), attribute.getPrefix(), rtl, value);
} else {
message = String.format("Consider adding `%1$s:%2$s=\"%3$s\"` to better support " + "right-to-left layouts", attribute.getPrefix(), rtl, value);
}
context.report(USE_START, attribute, context.getNameLocation(attribute), message);
}
} else {
if (project.getMinSdk() >= RTL_API || !context.isEnabled(COMPAT)) {
// Only supporting 17+: no need to define older attributes
return;
}
int folderVersion = context.getFolderVersion();
if (folderVersion >= RTL_API) {
// In a -v17 folder or higher: no need to define older attributes
return;
}
String old = convertNewToOld(name);
if (element.hasAttributeNS(ANDROID_URI, old)) {
return;
}
String message = String.format("To support older versions than API 17 (project specifies %1$d) " + "you should *also* add `%2$s:%3$s=\"%4$s\"`", project.getMinSdk(), attribute.getPrefix(), old, convertNewToOld(value));
context.report(COMPAT, attribute, context.getNameLocation(attribute), message);
}
}
Aggregations