use of org.checkerframework.checker.formatter.FormatterTreeUtil.FormatCall in project checker-framework by typetools.
the class FormatterVisitor method visitMethodInvocation.
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
FormatterTreeUtil tu = atypeFactory.treeUtil;
if (tu.isFormatCall(node, atypeFactory)) {
FormatCall fc = atypeFactory.treeUtil.new FormatCall(node, atypeFactory);
Result<String> err_missing_format = fc.hasFormatAnnotation();
if (err_missing_format != null) {
// The string's type has no @Format annotation.
if (isWrappedFormatCall(fc)) {
// Nothing to do, because call is legal.
} else {
// I.1
tu.failure(err_missing_format, "format.string.invalid", err_missing_format.value());
}
} else {
// The string has a @Format annotation.
Result<InvocationType> invc = fc.getInvocationType();
ConversionCategory[] formatCats = fc.getFormatCategories();
switch(invc.value()) {
case VARARG:
Result<TypeMirror>[] paramTypes = fc.getParamTypes();
int paraml = paramTypes.length;
int formatl = formatCats.length;
if (paraml < formatl) {
// For assignments, format.missing.arguments is issued
// from commonAssignmentCheck.
// II.1
tu.failure(invc, "format.missing.arguments", formatl, paraml);
} else {
if (paraml > formatl) {
// II.2
tu.warning(invc, "format.excess.arguments", formatl, paraml);
}
for (int i = 0; i < formatl; ++i) {
ConversionCategory formatCat = formatCats[i];
Result<TypeMirror> param = paramTypes[i];
TypeMirror paramType = param.value();
switch(formatCat) {
case UNUSED:
// I.2
tu.warning(param, "format.argument.unused", " " + (1 + i));
break;
case NULL:
// I.3
tu.failure(param, "format.specifier.null", " " + (1 + i));
break;
case GENERAL:
break;
default:
if (!fc.isValidParameter(formatCat, paramType)) {
// II.3
tu.failure(param, "argument.type.incompatible", paramType, formatCat);
}
break;
}
}
}
break;
case NULLARRAY:
/* continue */
case ARRAY:
for (ConversionCategory cat : formatCats) {
if (cat == ConversionCategory.NULL) {
// I.3
tu.failure(invc, "format.specifier.null", "");
}
if (cat == ConversionCategory.UNUSED) {
// I.2
tu.warning(invc, "format.argument.unused", "");
}
}
// III
tu.warning(invc, "format.indirect.arguments");
break;
}
}
}
return super.visitMethodInvocation(node, p);
}
Aggregations