use of com.android.tools.klint.detector.api.Location 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.Location in project kotlin by JetBrains.
the class CommentDetector method checkComment.
private static void checkComment(@NonNull JavaContext context, @Nullable UComment node, @NonNull String source, int offset, int start, int end) {
char prev = 0;
char c;
for (int i = start; i < end - 2; i++, prev = c) {
c = source.charAt(i);
if (prev == '\\') {
if (c == 'u' || c == 'U') {
if (source.regionMatches(true, i - 1, ESCAPE_STRING, 0, ESCAPE_STRING.length())) {
Location location = Location.create(context.file, source, offset + i - 1, offset + i - 1 + ESCAPE_STRING.length());
context.report(EASTER_EGG, node, location, "Code might be hidden here; found unicode escape sequence " + "which is interpreted as comment end, compiled code follows");
}
} else {
i++;
}
} else if (prev == 'S' && c == 'T' && source.regionMatches(i - 1, STOPSHIP_COMMENT, 0, STOPSHIP_COMMENT.length())) {
// TODO: Only flag this issue in release mode??
Location location;
if (node != null) {
location = context.getUastLocation(node);
} else {
location = Location.create(context.file, source, offset + i - 1, offset + i - 1 + STOPSHIP_COMMENT.length());
}
context.report(STOP_SHIP, node, location, "`STOPSHIP` comment found; points to code which must be fixed prior " + "to release");
}
}
}
use of com.android.tools.klint.detector.api.Location in project kotlin by JetBrains.
the class JavaScriptInterfaceDetector method visitMethod.
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression call, @NonNull UMethod method) {
if (context.getMainProject().getTargetSdk() < 17) {
return;
}
List<UExpression> arguments = call.getValueArguments();
if (arguments.size() != 2) {
return;
}
JavaEvaluator evaluator = context.getEvaluator();
if (!JavaEvaluator.isMemberInClass(method, WEB_VIEW_CLS)) {
return;
}
UExpression first = arguments.get(0);
PsiType evaluated = TypeEvaluator.evaluate(context, first);
if (evaluated instanceof PsiClassType) {
PsiClassType classType = (PsiClassType) evaluated;
PsiClass cls = classType.resolve();
if (cls == null) {
return;
}
if (isJavaScriptAnnotated(cls)) {
return;
}
Location location = context.getUastNameLocation(call);
String message = String.format("None of the methods in the added interface (%1$s) have been annotated " + "with `@android.webkit.JavascriptInterface`; they will not " + "be visible in API 17", cls.getName());
context.report(ISSUE, call, location, message);
}
}
use of com.android.tools.klint.detector.api.Location in project kotlin by JetBrains.
the class LayoutConsistencyDetector method reportErrors.
private void reportErrors(Context context) {
List<String> layouts = new ArrayList<String>(mLocations.keySet());
Collections.sort(layouts);
for (String layout : layouts) {
Map<String, List<Location>> locationMap = mLocations.get(layout);
Map<String, String> messageMap = mErrorMessages.get(layout);
assert locationMap != null;
assert messageMap != null;
List<String> ids = new ArrayList<String>(locationMap.keySet());
Collections.sort(ids);
for (String id : ids) {
String message = messageMap.get(id);
List<Location> locations = locationMap.get(id);
if (locations != null) {
Location location = chainLocations(locations);
context.report(INCONSISTENT_IDS, location, message);
}
}
}
}
use of com.android.tools.klint.detector.api.Location in project kotlin by JetBrains.
the class LayoutInflationDetector method visitMethod.
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression call, @NonNull UMethod method) {
assert method.getName().equals(INFLATE);
if (call.getReceiver() == null) {
return;
}
List<UExpression> arguments = call.getValueArguments();
if (arguments.size() < 2) {
return;
}
UExpression second = arguments.get(1);
if (!UastLiteralUtils.isNullLiteral(second)) {
return;
}
UExpression first = arguments.get(0);
AndroidReference androidReference = UastLintUtils.toAndroidReferenceViaResolve(first);
if (androidReference == null) {
return;
}
String layoutName = androidReference.getName();
if (context.getScope().contains(Scope.RESOURCE_FILE)) {
// incrementally
if (!context.getDriver().isSuppressed(context, ISSUE, call)) {
if (mPendingErrors == null) {
mPendingErrors = Lists.newArrayList();
}
Location location = context.getUastLocation(second);
mPendingErrors.add(Pair.of(layoutName, location));
}
} else if (hasLayoutParams(context, layoutName)) {
context.report(ISSUE, call, context.getUastLocation(second), ERROR_MESSAGE);
}
}
Aggregations