use of lombok.ast.MethodInvocation in project wire-android by wireapp.
the class WrongTimberUsageDetector method getType.
private Class<?> getType(JavaContext context, Expression expression) {
if (expression == null) {
return null;
}
if (expression instanceof MethodInvocation) {
MethodInvocation method = (MethodInvocation) expression;
String methodName = method.astName().astValue();
if (methodName.equals(GET_STRING_METHOD)) {
return String.class;
}
} else if (expression instanceof StringLiteral) {
return String.class;
} else if (expression instanceof IntegralLiteral) {
return Integer.TYPE;
} else if (expression instanceof FloatingPointLiteral) {
return Float.TYPE;
} else if (expression instanceof CharLiteral) {
return Character.TYPE;
} else if (expression instanceof BooleanLiteral) {
return Boolean.TYPE;
} else if (expression instanceof NullLiteral) {
return Object.class;
}
if (context != null) {
JavaParser.TypeDescriptor type = context.getType(expression);
if (type != null) {
Class<?> typeClass = getTypeClass(type);
if (typeClass != null) {
return typeClass;
} else {
return Object.class;
}
}
}
return null;
}
use of lombok.ast.MethodInvocation in project android-priority-jobqueue by yigit.
the class NotifyOnObjectDetector method createJavaVisitor.
@Override
public AstVisitor createJavaVisitor(@NonNull final JavaContext context) {
return new ForwardingAstVisitor() {
@Override
public boolean visitMethodInvocation(MethodInvocation node) {
Expression operand = node.astOperand();
String methodName = node.astName().toString();
if (BAD_METHODS.contains(methodName) && !context.isSuppressedWithComment(node, ISSUE)) {
context.report(ISSUE, context.getLocation(node), "Don't call " + methodName + " directly. Use" + " Timer instead.");
}
return super.visitMethodInvocation(node);
}
};
}
use of lombok.ast.MethodInvocation in project android-priority-jobqueue by yigit.
the class SystemTimeDetector method createJavaVisitor.
@Override
public AstVisitor createJavaVisitor(@NonNull final JavaContext context) {
return new ForwardingAstVisitor() {
@Override
public boolean visitMethodInvocation(MethodInvocation node) {
Expression operand = node.astOperand();
String methodName = node.astName().toString();
if (BAD_METHODS.contains(methodName) && operand.toString().equals("System") && !context.isSuppressedWithComment(node, ISSUE)) {
context.report(ISSUE, context.getLocation(node), "Don't call " + methodName + " on system. Use" + " Timer instead.");
}
return super.visitMethodInvocation(node);
}
};
}
use of lombok.ast.MethodInvocation in project wire-android by wireapp.
the class ObjectAnimatorPropertyDetector method visitMethod.
@Override
public void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node) {
if (!(node.astOperand() instanceof VariableReference)) {
return;
}
final VariableReference ref = (VariableReference) node.astOperand();
if (!"ObjectAnimator".equals(ref.astIdentifier().astValue())) {
return;
}
final StrictListAccessor<Expression, MethodInvocation> astArguments = node.astArguments();
if (astArguments.size() <= 2) {
return;
}
final Iterator<Expression> iterator = astArguments.iterator();
// ignored to get the second
iterator.next();
final Expression property = iterator.next();
if (property instanceof StringLiteral) {
context.report(ISSUE, context.getLocation(node), String.format("String '%s' should be replaced", ((StringLiteral) property).astValue()));
return;
}
if (context.resolve(property) == null) {
return;
}
if (property instanceof VariableReference) {
if (!isSubclassOf(context, (VariableReference) property, "android.util.Property") && !isSubclassOf(context, (VariableReference) property, "com.nineoldandroids.util.Property")) {
context.report(ISSUE, context.getLocation(node), String.format("'%s' should be replaced with a property", ((VariableReference) property).astIdentifier().astValue()));
}
}
}
use of lombok.ast.MethodInvocation in project wire-android by wireapp.
the class WrongTimberUsageDetector method checkArguments.
private void checkArguments(JavaContext context, MethodInvocation node) {
StrictListAccessor<Expression, MethodInvocation> astArguments = node.astArguments();
Iterator<Expression> iterator = astArguments.iterator();
if (!iterator.hasNext()) {
return;
}
int startIndexOfArguments = 1;
Expression formatStringArg = iterator.next();
if (formatStringArg instanceof VariableReference) {
if (isSubclassOf(context, (VariableReference) formatStringArg, Exception.class)) {
formatStringArg = iterator.next();
startIndexOfArguments++;
}
}
String formatString = findLiteralValue(context, formatStringArg);
// We passed for example a method call
if (formatString == null) {
return;
}
int argumentCount = getFormatArgumentCount(formatString);
int passedArgCount = astArguments.size() - startIndexOfArguments;
if (argumentCount < passedArgCount) {
context.report(ISSUE_ARG_COUNT, node, context.getLocation(node), String.format("Wrong argument count, format string `%1$s` requires `%2$d` but format " + "call supplies `%3$d`", formatString, argumentCount, passedArgCount));
return;
}
if (argumentCount == 0) {
return;
}
List<String> types = getStringArgumentTypes(formatString);
Expression argument = null;
boolean valid = true;
for (int i = 0; i < types.size(); i++) {
String formatType = types.get(i);
if (iterator.hasNext()) {
argument = iterator.next();
} else {
context.report(ISSUE_ARG_COUNT, node, context.getLocation(node), String.format("Wrong argument count, format string `%1$s` requires `%2$d` but format " + "call supplies `%3$d`", formatString, argumentCount, passedArgCount));
}
char last = formatType.charAt(formatType.length() - 1);
if (formatType.length() >= 2 && Character.toLowerCase(formatType.charAt(formatType.length() - 2)) == 't') {
// TODO
continue;
}
Class type = getType(context, argument);
if (type != null) {
switch(last) {
// unusual and probably not intended.
case 'b':
case 'B':
valid = type == Boolean.TYPE;
break;
// Numeric: integer and floats in various formats
case 'x':
case 'X':
case 'd':
case 'o':
case 'e':
case 'E':
case 'f':
case 'g':
case 'G':
case 'a':
case 'A':
valid = type == Integer.TYPE || type == Float.TYPE || type == Double.TYPE || type == Long.TYPE || type == Byte.TYPE || type == Short.TYPE;
break;
case 'c':
case 'C':
// Unicode character
valid = type == Character.TYPE;
break;
case 'h':
// Hex print of hash code of objects
case 'H':
case 's':
case 'S':
// String. Can pass anything, but warn about
// numbers since you may have meant more
// specific formatting. Use special issue
// explanation for this?
valid = type != Boolean.TYPE && !Number.class.isAssignableFrom(type);
break;
}
if (!valid) {
String message = String.format("Wrong argument type for formatting argument '#%1$d' " + "in `%2$s`: conversion is '`%3$s`', received `%4$s` " + "(argument #%5$d in method call)", i, formatString, formatType, type.getSimpleName(), startIndexOfArguments + i + 1);
context.report(ISSUE_ARG_TYPES, node, context.getLocation(argument), message);
}
}
}
}
Aggregations