Search in sources :

Example 1 with InvocationType

use of org.checkerframework.checker.formatter.FormatterTreeUtil.InvocationType in project checker-framework by typetools.

the class I18nFormatterVisitor method checkInvocationFormatFor.

private void checkInvocationFormatFor(I18nFormatCall fc) {
    I18nFormatterTreeUtil tu = atypeFactory.treeUtil;
    Result<FormatType> type = fc.getFormatType();
    Result<InvocationType> invc;
    I18nConversionCategory[] formatCats;
    switch(type.value()) {
        case I18NINVALID:
            tu.failure(type, "i18nformat.string.invalid", fc.getInvalidError());
            break;
        case I18NFORMATFOR:
            if (!fc.isValidFormatForInvocation()) {
                Result<FormatType> failureType = fc.getInvalidInvocationType();
                tu.failure(failureType, "i18nformat.invalid.formatfor");
            }
            break;
        case I18NFORMAT:
            invc = fc.getInvocationType();
            formatCats = fc.getFormatCategories();
            switch(invc.value()) {
                case VARARG:
                    Result<TypeMirror>[] paramTypes = fc.getParamTypes();
                    int paraml = paramTypes.length;
                    int formatl = formatCats.length;
                    // from commonAssignmentCheck.
                    if (paraml < formatl) {
                        tu.warning(invc, "i18nformat.missing.arguments", formatl, paraml);
                    }
                    if (paraml > formatl) {
                        tu.warning(invc, "i18nformat.excess.arguments", formatl, paraml);
                    }
                    for (int i = 0; i < formatl && i < paraml; ++i) {
                        I18nConversionCategory formatCat = formatCats[i];
                        Result<TypeMirror> param = paramTypes[i];
                        TypeMirror paramType = param.value();
                        switch(formatCat) {
                            case UNUSED:
                                tu.warning(param, "i18nformat.argument.unused", " " + (1 + i));
                                break;
                            case GENERAL:
                                break;
                            default:
                                if (!fc.isValidParameter(formatCat, paramType)) {
                                    tu.failure(param, "argument.type.incompatible", paramType, formatCat);
                                }
                        }
                    }
                    break;
                case NULLARRAY:
                // fall-through
                case ARRAY:
                    for (I18nConversionCategory cat : formatCats) {
                        if (cat == I18nConversionCategory.UNUSED) {
                            tu.warning(invc, "i18nformat.argument.unused", "");
                        }
                    }
                    tu.warning(invc, "i18nformat.indirect.arguments");
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
}
Also used : AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) InvocationType(org.checkerframework.checker.formatter.FormatterTreeUtil.InvocationType) FormatType(org.checkerframework.checker.i18nformatter.I18nFormatterTreeUtil.FormatType) I18nConversionCategory(org.checkerframework.checker.i18nformatter.qual.I18nConversionCategory) Result(org.checkerframework.checker.formatter.FormatterTreeUtil.Result)

Example 2 with InvocationType

use of org.checkerframework.checker.formatter.FormatterTreeUtil.InvocationType 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)2 InvocationType (org.checkerframework.checker.formatter.FormatterTreeUtil.InvocationType)2 Result (org.checkerframework.checker.formatter.FormatterTreeUtil.Result)2 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)2 FormatCall (org.checkerframework.checker.formatter.FormatterTreeUtil.FormatCall)1 ConversionCategory (org.checkerframework.checker.formatter.qual.ConversionCategory)1 FormatType (org.checkerframework.checker.i18nformatter.I18nFormatterTreeUtil.FormatType)1 I18nConversionCategory (org.checkerframework.checker.i18nformatter.qual.I18nConversionCategory)1