com.google.javascript.jscomp.Diagnostics.java Source code

Java tutorial

Introduction

Here is the source code for com.google.javascript.jscomp.Diagnostics.java

Source

/*
 * Copyright 2016 The Closure Rules Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.javascript.jscomp;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.javascript.jscomp.lint.CheckJSDocStyle;
import com.google.javascript.jscomp.lint.CheckMissingSemicolon;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

final class Diagnostics {

    static final DiagnosticType SUPERFLUOUS_SUPPRESS = DiagnosticType.error("CR_SUPERFLUOUS_SUPPRESS",
            "Build rule ({0}) contains superfluous suppress codes: {1}");

    static {
        DiagnosticGroups.registerGroup("superfluousSuppress", SUPERFLUOUS_SUPPRESS);
        DiagnosticGroups.registerGroup("setTestOnly", CheckSetTestOnly.INVALID_SETTESTONLY);
        DiagnosticGroups.registerGroup("strictDependencies", CheckStrictDeps.DUPLICATE_PROVIDES,
                CheckStrictDeps.REDECLARED_PROVIDES, CheckStrictDeps.NOT_PROVIDED);
    }

    static final DiagnosticGroups GROUPS = new DiagnosticGroups();

    /**
     * Diagnostic groups {@link JsChecker} will check and {@link JsCompiler} will ignore.
     *
     * <p>These are the simpler checks, e.g. linting, that can be examined on a per-file basis.
     */
    static final ImmutableSet<String> JSCHECKER_ONLY_ERRORS = ImmutableSet.of("deprecatedAnnotations", "lintChecks",
            "nonStandardJsDocs", "setTestOnly", "strictDependencies", "strictMissingRequire", "superfluousSuppress",
            "useOfGoogBase");

    /** Legal values for a {@code @suppress {foo}} JSDoc tag. */
    // Keep in sync with com/google/javascript/jscomp/parsing/ParserConfig.properties
    private static final ImmutableSet<String> LEGAL_JSDOC_SUPPRESSIONS = ImmutableSet.of("accessControls",
            "ambiguousFunctionDecl", "checkDebuggerStatement", "checkRegExp", "checkTypes", "checkVars",
            "closureDepMethodUsageChecks", "const", "constantProperty", "deprecated", "duplicate", "es5Strict",
            "externsValidation", "extraRequire", "fileoverviewTags", "globalThis", "invalidCasts", "lateProvide",
            "legacyGoogScopeRequire", "messageConventions", "misplacedTypeAnnotation", "missingOverride",
            "missingPolyfill", "missingProperties", "missingProvide", "missingRequire", "missingReturn",
            "newCheckTypes", "newCheckTypesAllChecks", "nonStandardJsDocs", "reportUnknownTypes",
            "strictModuleDepCheck", "suspiciousCode", "transitionalSuspiciousCodeWarnings", "undefinedNames",
            "undefinedVars", "underscore", "unknownDefines", "unnecessaryCasts", "unusedLocalVariables",
            "unusedPrivateMembers", "uselessCode", "visibility", "with");

    /** Diagnostic groups both {@link JsChecker} and {@link JsCompiler} will check. */
    static final ImmutableSet<String> JSCHECKER_EXTRA_ERRORS = ImmutableSet.of(
            // Even though we're not running the typechecker, enable the checkTypes DiagnosticGroup,
            // since it contains some warnings we do want to report, such as JSDoc parse warnings.
            "checkTypes");

    /** Checks to suppress if closure_js_library convention is not GOOGLE. */
    static final ImmutableSet<DiagnosticType> GOOGLE_LINTER_CHECKS = ImmutableSet.of(CheckJSDocStyle.MISSING_JSDOC,
            CheckJSDocStyle.MISSING_PARAMETER_JSDOC, CheckJSDocStyle.MISSING_RETURN_JSDOC,
            CheckJSDocStyle.OPTIONAL_PARAM_NOT_MARKED_OPTIONAL, CheckMissingSemicolon.MISSING_SEMICOLON);

    /** Checks to suppress if closure_js_library convention is not CLOSURE. */
    static final ImmutableSet<DiagnosticType> CLOSURE_LINTER_CHECKS = new ImmutableSet.Builder<DiagnosticType>()
            .addAll(GOOGLE_LINTER_CHECKS).add(CheckJSDocStyle.MUST_BE_PRIVATE)
            .add(CheckJSDocStyle.MUST_HAVE_TRAILING_UNDERSCORE)
            .add(CheckMissingAndExtraRequires.MISSING_REQUIRE_FOR_GOOG_SCOPE)
            .add(CheckMissingAndExtraRequires.MISSING_REQUIRE_STRICT_WARNING)
            .add(CheckMissingAndExtraRequires.MISSING_REQUIRE_WARNING).add(ClosureCheckModule.LET_GOOG_REQUIRE)
            .add(ClosureRewriteModule.USELESS_USE_STRICT_DIRECTIVE)
            .add(ImplicitNullabilityCheck.IMPLICITLY_NULLABLE_JSDOC).add(RhinoErrorReporter.BAD_JSDOC_ANNOTATION)
            .build();

    /**
     * Errors that should be ignored entirely if encountered in synthetic code.
     *
     * <p>Code generated by compiler passes currently does a poor job conforming to these checks.
     * They've been listed here because: a) the user can't do anything about it; and b) they would be
     * very noisy otherwise.
     */
    static final ImmutableSet<DiagnosticType> IGNORE_FOR_SYNTHETIC = ImmutableSet
            .of(ImplicitNullabilityCheck.IMPLICITLY_NULLABLE_JSDOC, TypeCheck.UNKNOWN_EXPR_TYPE);

    static final ImmutableSet<DiagnosticType> IGNORE_FOR_LEGACY = ImmutableSet
            .of(ImplicitNullabilityCheck.IMPLICITLY_NULLABLE_JSDOC, TypeCheck.UNKNOWN_EXPR_TYPE);

    /** Compiler checks that Closure Rules will always ignore. */
    static final ImmutableSet<DiagnosticType> IGNORE_ALWAYS = ImmutableSet.of(
            // TODO(hochhaus): Make unknownDefines an error for user supplied defines.
            // https://github.com/bazelbuild/rules_closure/issues/79
            ProcessDefines.UNKNOWN_DEFINE_WARNING,
            // TODO(jart): Remove these when regression is fixed relating to jscomp being able to
            //             identify externs files that were passed via srcs.
            CheckJSDoc.INVALID_MODIFIES_ANNOTATION, CheckJSDoc.INVALID_NO_SIDE_EFFECT_ANNOTATION);

    static final ImmutableMap<String, DiagnosticType> DIAGNOSTIC_TYPES = initDiagnosticTypes();
    static final ImmutableMultimap<DiagnosticType, String> DIAGNOSTIC_GROUPS = initDiagnosticGroups();
    static final ImmutableSet<String> JSCHECKER_ONLY_SUPPRESS_CODES = initJscheckerSuppressCodes();
    static final ImmutableSet<DiagnosticGroup> JSCHECKER_ONLY_GROUPS = initJscheckerGroups();
    static final ImmutableMap<DiagnosticType, String> JSDOC_SUPPRESS_CODES = initJsdocSuppressCodes();

    static ImmutableSet<DiagnosticType> getDiagnosticTypesForSuppressCode(String code) {
        DiagnosticGroup group = GROUPS.forName(code);
        if (group != null) {
            return ImmutableSet.copyOf(group.getTypes());
        }
        DiagnosticType type = DIAGNOSTIC_TYPES.get(code);
        if (type == null) {
            return ImmutableSet.of();
        }
        return ImmutableSet.of(type);
    }

    private static ImmutableMap<String, DiagnosticType> initDiagnosticTypes() {
        Map<String, DiagnosticType> builder = new HashMap<>();
        for (DiagnosticGroup group : GROUPS.getRegisteredGroups().values()) {
            for (DiagnosticType type : group.getTypes()) {
                builder.put(type.key, type);
            }
        }
        return ImmutableMap.copyOf(builder);
    }

    private static ImmutableMultimap<DiagnosticType, String> initDiagnosticGroups() {
        Multimap<DiagnosticType, String> builder = HashMultimap.create();
        for (Map.Entry<String, DiagnosticGroup> group : GROUPS.getRegisteredGroups().entrySet()) {
            for (DiagnosticType type : group.getValue().getTypes()) {
                builder.put(type, group.getKey());
            }
        }
        return ImmutableMultimap.copyOf(builder);
    }

    private static ImmutableSet<String> initJscheckerSuppressCodes() {
        Set<String> builder = new HashSet<>();
        for (String groupName : JSCHECKER_ONLY_ERRORS) {
            builder.add(groupName);
            for (DiagnosticType type : GROUPS.forName(groupName).getTypes()) {
                builder.add(type.key);
            }
        }
        return ImmutableSet.copyOf(builder);
    }

    private static ImmutableSet<DiagnosticGroup> initJscheckerGroups() {
        ImmutableSet.Builder<DiagnosticGroup> builder = new ImmutableSet.Builder<>();
        for (String groupName : JSCHECKER_ONLY_ERRORS) {
            builder.add(GROUPS.forName(groupName));
        }
        return builder.build();
    }

    private static ImmutableMap<DiagnosticType, String> initJsdocSuppressCodes() {
        Map<DiagnosticType, String> builder = new HashMap<>();
        builder.put(StrictModeCheck.USE_OF_WITH, "with");
        for (String suppress : LEGAL_JSDOC_SUPPRESSIONS) {
            if (GROUPS.forName(suppress) == null) {
                continue;
            }
            for (DiagnosticType type : GROUPS.forName(suppress).getTypes()) {
                builder.put(type, suppress);
            }
        }
        return ImmutableMap.copyOf(builder);
    }

    private Diagnostics() {
    }
}