All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.jscomp.SuppressDocWarningsGuard Maven / Gradle / Ivy

/*
 * Copyright 2010 The Closure Compiler Authors.
 *
 * 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.javascript.rhino.JSDocInfo;
import com.google.javascript.rhino.Node;
import java.util.HashMap;
import java.util.Map;

/**
 * Filters warnings based on in-code {@code @suppress} annotations.
 *
 * 

Works by looking at the AST node associated with the warning, and looking at parents of the * node until it finds a node declaring a symbol (class, function, variable, property, assignment, * object literal key) or a script. For this reason, it doesn't work for warnings without an * associated AST node, eg, the ones in parsing/IRFactory. They can be turned off with jscomp_off. */ class SuppressDocWarningsGuard extends FileAwareWarningsGuard { private static final long serialVersionUID = 1L; /** Warnings guards for each suppressible warnings group, indexed by name. */ private final Map suppressors = new HashMap<>(); /** The suppressible groups, indexed by name. */ SuppressDocWarningsGuard( AbstractCompiler compiler, Map suppressibleGroups) { super(compiler); for (Map.Entry entry : suppressibleGroups.entrySet()) { suppressors.put( entry.getKey(), new DiagnosticGroupWarningsGuard( entry.getValue(), CheckLevel.OFF)); } // Hack: Allow "@suppress {missingRequire}" to also cover strictMissingRequire, // stricterMissingRequire and stricterMissingRequireType. // TODO(tjgq): Delete this when all of these checks are unified under `missingRequire`. suppressors.put( "missingRequire", new DiagnosticGroupWarningsGuard( new DiagnosticGroup( DiagnosticGroups.STRICT_MISSING_REQUIRE, DiagnosticGroups.STRICTER_MISSING_REQUIRE, DiagnosticGroups.STRICTER_MISSING_REQUIRE_TYPE, DiagnosticGroups.STRICTER_MISSING_REQUIRE_IN_PROVIDES_FILE, DiagnosticGroups.STRICTER_MISSING_REQUIRE_TYPE_IN_PROVIDES_FILE), CheckLevel.OFF)); // Hack: Allow "@suppress {missingProperties}" to mean // "@suppress {strictmissingProperties}". // TODO(johnlenz): Delete this when it is enabled with missingProperties suppressors.put( "missingProperties", new DiagnosticGroupWarningsGuard( new DiagnosticGroup( DiagnosticGroups.MISSING_PROPERTIES, DiagnosticGroups.STRICT_MISSING_PROPERTIES), CheckLevel.OFF)); // Hack: Allow "@suppress {checkTypes}" to include // "strictmissingProperties". // TODO(johnlenz): Delete this when it is enabled with missingProperties suppressors.put( "checkTypes", new DiagnosticGroupWarningsGuard( new DiagnosticGroup( DiagnosticGroups.CHECK_TYPES, DiagnosticGroups.STRICT_CHECK_TYPES), CheckLevel.OFF)); } @Override public CheckLevel level(JSError error) { Node node = error.getNode(); if (node == null) { node = getScriptNodeForError(error); } if (node == null) { return null; } CheckLevel level = getCheckLevelFromAncestors(error, node); if (level != null) { return level; } // Some errors are on nodes that do not have the script as a parent. // Look up the script node by filename. Node scriptNode = getScriptNodeForError(error); if (scriptNode != null) { JSDocInfo info = scriptNode.getJSDocInfo(); if (info != null) { return getCheckLevelFromInfo(error, info); } } return null; } /** * Searches for @suppress tags on nodes introducing symbols: * *

class & function declarations, variables, assignments, object literal keys, and the top * level script node. */ private CheckLevel getCheckLevelFromAncestors(JSError error, Node node) { for (Node current = node; current != null; current = current.getParent()) { JSDocInfo info = null; if (current.isFunction() || current.isClass()) { info = NodeUtil.getBestJSDocInfo(current); } else if (current.isScript()) { info = current.getJSDocInfo(); } else if (NodeUtil.isNameDeclaration(current) || (NodeUtil.isAssignmentOp(current) && current.getParent().isExprResult()) || (current.isGetProp() && current.getParent().isExprResult()) || NodeUtil.mayBeObjectLitKey(current) || current.isComputedProp()) { info = NodeUtil.getBestJSDocInfo(current); } if (info != null) { CheckLevel level = getCheckLevelFromInfo(error, info); if (level != null) { return level; } } } return null; } /** If the given JSDocInfo has an @suppress for the given JSError, returns the new level. */ private CheckLevel getCheckLevelFromInfo(JSError error, JSDocInfo info) { for (String suppressor : info.getSuppressions()) { WarningsGuard guard = suppressors.get(suppressor); // Some @suppress tags are for other tools, and // may not have a warnings guard. if (guard != null) { CheckLevel newLevel = guard.level(error); if (newLevel != null) { return newLevel; } } } return null; } @Override public int getPriority() { // Happens after path-based filtering, but before other times // of filtering. return WarningsGuard.Priority.SUPPRESS_DOC.value; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy