javascript - Google Closure Annotating 不会告诉我我错了

标签 javascript compiler-warnings google-closure-compiler google-closure

我正在试用 Google Closure,特别是用于强制类型安全的注释内容。为了测试我做错了什么,尽管编译器不会告诉我这是...

代码如下:

// ==ClosureCompiler==
// @output_file_name default.js
// @compilation_level SIMPLE_OPTIMIZATIONS
// ==/ClosureCompiler==

/**
 * A card.
 * @constructor
 * @param {String} cardName The exact name of the card
 * @param {Kinetic.Layer} layer The layer for the card
 */
function CardObject(cardName, layer)
{
    /** @type {Number} */
    var number = cardName;
}

因此,我有一个变量 number,我说它是一个 Number,我尝试为其分配一个字符串。这应该不可能吧?虽然编译器不会告诉我...

为什么它不告诉我这是错误的?

最佳答案

闭包编译器使用 warning levels以确定在编译过程中启用了哪些检查。三个警告级别是:

  • 安静
  • 默认
  • 详细

例如,使用编译级别 SIMPLE_OPTIMIZATIONS,您仍然会收到警告级别设置为 VERBOSE 的类型检查警告。

// ==ClosureCompiler==
// @output_file_name default.js
// @compilation_level SIMPLE_OPTIMIZATIONS
// @warning_level VERBOSE
// ==/ClosureCompiler==

/**
 * A card.
 * @constructor
 * @param {String} cardName The exact name of the card
 * @param {Kinetic.Layer} layer The layer for the card
 */
function CardObject(cardName, layer)
{
    /** @type {Number} */
    var number = cardName;
}

输出

Number of warnings: 2

JSC_TYPE_PARSE_ERROR: Bad type annotation. Unknown type Kinetic.Layer at line 5
character 10  
* @param {Kinetic.Layer} layer The layer for the card
          ^
JSC_TYPE_MISMATCH: initializing variable
found   : (String|null|undefined)
required: (Number|null) at line 10 character 13
var number = cardName;
             ^

要准确了解哪些检查与每个警告级别相关联,这里是 WarningLevels.java 中的相关代码。

安静

/**
 * Silence all non-essential warnings.
 */
private static void silenceAllWarnings(CompilerOptions options) {
  // Just use a ShowByPath warnings guard, so that we don't have
  // to maintain a separate class of warnings guards for silencing warnings.
  options.addWarningsGuard(
      new ShowByPathWarningsGuard(
          "the_longest_path_that_cannot_be_expressed_as_a_string"));

  // Allow passes that aren't going to report anything to be skipped.

  options.checkRequires = CheckLevel.OFF;
  options.checkProvides = CheckLevel.OFF;
  options.checkMissingGetCssNameLevel = CheckLevel.OFF;
  options.aggressiveVarCheck = CheckLevel.OFF;
  options.checkTypes = false;
  options.setWarningLevel(DiagnosticGroups.CHECK_TYPES, CheckLevel.OFF);
  options.checkUnreachableCode = CheckLevel.OFF;
  options.checkMissingReturn = CheckLevel.OFF;
  options.setWarningLevel(DiagnosticGroups.ACCESS_CONTROLS, CheckLevel.OFF);
  options.setWarningLevel(DiagnosticGroups.CONST, CheckLevel.OFF);
  options.setWarningLevel(DiagnosticGroups.CONSTANT_PROPERTY, CheckLevel.OFF);
  options.checkGlobalNamesLevel = CheckLevel.OFF;
  options.checkSuspiciousCode = false;
  options.checkGlobalThisLevel = CheckLevel.OFF;
  options.setWarningLevel(DiagnosticGroups.GLOBAL_THIS, CheckLevel.OFF);
  options.setWarningLevel(DiagnosticGroups.ES5_STRICT, CheckLevel.OFF);
  options.checkCaja = false;
}

默认

/**
 * Add the default checking pass to the compilation options.
 * @param options The CompilerOptions object to set the options on.
 */
private static void addDefaultWarnings(CompilerOptions options) {
  options.checkSuspiciousCode = true;
  options.checkUnreachableCode = CheckLevel.WARNING;
  options.checkControlStructures = true;
}

冗长

/**
 * Add all the check pass that are possibly relevant to a non-googler.
 * @param options The CompilerOptions object to set the options on.
 */
private static void addVerboseWarnings(CompilerOptions options) {
  addDefaultWarnings(options);

  // checkSuspiciousCode needs to be enabled for CheckGlobalThis to get run.
  options.checkSuspiciousCode = true;
  options.checkGlobalThisLevel = CheckLevel.WARNING;
  options.checkSymbols = true;
  options.checkMissingReturn = CheckLevel.WARNING;

  // checkTypes has the side-effect of asserting that the
  // correct number of arguments are passed to a function.
  // Because the CodingConvention used with the web service does not provide a
  // way for optional arguments to be specified, these warnings may result in
  // false positives.
  options.checkTypes = true;
  options.checkGlobalNamesLevel = CheckLevel.WARNING;
  options.aggressiveVarCheck = CheckLevel.WARNING;
  options.setWarningLevel(
      DiagnosticGroups.MISSING_PROPERTIES, CheckLevel.WARNING);
  options.setWarningLevel(
      DiagnosticGroups.DEPRECATED, CheckLevel.WARNING);
}

请注意,options.checkTypes = true; 仅为 VERBOSE 警告级别设置。作为Speransky Danil指出,使用编译级别 ADVANCED_OPTIMIZATIONS 时也会启用类型检查。

此外,可以使用编译器标志通过 Closure 编译器应用程序(jar 文件)单独控制警告类别:

  • --jscomp_off
  • --jscomp_warning
  • --jscomp_error

可以指定的警告类如下:

  • 访问控制
  • 模棱两可的函数声明
  • 检查正则表达式
  • 检查类型
  • 检查变量
  • 常量
  • 常量属性
  • 已弃用
  • 复制消息
  • es5严格
  • 外部验证
  • 文件概览标签
  • globalThis
  • internetExplorerChecks
  • 无效的转换
  • 缺少属性
  • 非StandardJsDocs
  • strictModuleDepCheck
  • 类型失效
  • undefinedNames
  • undefined variable
  • 未知定义
  • 无用代码
  • 知名度

例如,可以单独启用类型检查警告:

--jscomp_warning=checkTypes

关于javascript - Google Closure Annotating 不会告诉我我错了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12236862/

相关文章:

c - 关于添加错误标志的问题

c++ - SFINAE 给出 "Inheriting constructor does not inherit ellipsis"警告

javascript - 包含构造函数的对象的闭包编译器注释

javascript - Modernizr.load (Yepnope) 是否用于 <head>

javascript - 您可以使用 document.getElementById 检索属性吗?

javascript - 手机间隙 : flexible iOS app update (No AppStore)

javascript - 数据没有进入 MySql 数据库

c++ - 无法在 VS2015 中禁用编译器警告

javascript - 为什么闭包编译器创建 void 0 而不是更短的替代方案?

google-closure-compiler - 为什么 Closure Compiler 不重命名具有特定名称的对象?