Search in sources :

Example 1 with FormatCall

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);
}
Also used : ConversionCategory(org.checkerframework.checker.formatter.qual.ConversionCategory) FormatCall(org.checkerframework.checker.formatter.FormatterTreeUtil.FormatCall) InvocationType(org.checkerframework.checker.formatter.FormatterTreeUtil.InvocationType) Result(org.checkerframework.checker.formatter.FormatterTreeUtil.Result) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror)

Aggregations

TypeMirror (javax.lang.model.type.TypeMirror)1 FormatCall (org.checkerframework.checker.formatter.FormatterTreeUtil.FormatCall)1 InvocationType (org.checkerframework.checker.formatter.FormatterTreeUtil.InvocationType)1 Result (org.checkerframework.checker.formatter.FormatterTreeUtil.Result)1 ConversionCategory (org.checkerframework.checker.formatter.qual.ConversionCategory)1 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)1