在 Hack 中嵌入源分析器元数据的一种结构化方式

v0.2.0 2024-01-14 09:18 UTC

This package is auto-updated.

Last update: 2024-09-09 05:55:52 UTC


README

在 Hack 中嵌入源分析器元数据的一种结构化方式。

如何使用

// You must use use statements in exactly this form.
// `use namespace` or use statements with an `as` are not allowed.
use type HTL\Pragma\Pragmas;
use function HTL\Pragma\pragma;

// Apply an effect to an entire file.
<<file: Pragmas(vec['SourceAnalyzer', 'strict_mode=1'])>>

// Apply an effect to a class.
<<Pragmas(vec['PerfAnalyzer', 'hot_code=0'], vec['Ownership', 'maintainer=You'])>>
final class Example implements Printable {
  public function print(): string {
    // Apply an effect to the next line.
    pragma('CodingStandards', 'refused_bequest=ignore');
    throw new Exception();
  }
}

有关传递给 pragma(...)Pragmas(vec[...]) 的字符串的详细信息,请参阅源分析器的文档。

对于实现者

此包包含一个类和一个函数

  • pragma 函数,也称为 pragma 指令。
  • Pragmas 类,也称为 Pragmas 属性。

它们是结构化注释的通用替代品。

// @lint-ignore[unused-pure-expression]
1 + 1;

@lint-ignore 在某些工具的角度来看不是一个正常的注释。它抑制了对于未使用的纯表达式的 lint 错误。

我全心全意地同意以下来自 CppCoreGuidelines 的引言:

Compilers don’t read comments ... and neither do many programmers (consistently).

如果一个项目中的超过一半的注释是为了关闭某些工具,无论是 Hack 类型检查器还是 linter,程序员将更有可能跳过阅读注释。这会让人害怕删除无用的注释,因为某些工具可能依赖于它们。

pragma(...) 指令背后的想法是消除这些注释。以下代码块表达了相同的目的。

pragma('LinterFramework', 'ignore:unused-pure-expression');
1 + 1;

问:为什么基于字符串的系统比实际的属性更好?

  • 答:如果你的源代码分析器是一个开发依赖项,你需要
    • 在不同的包中发布属性,以便在 vendor/ 目录中不包含源分析器的情况下对生产代码进行类型检查。
    • 将源分析器代码部署到生产中。
  • 此标准的第一个用户是 PhaLinters。在编写本文档时,这是一个带有单个指令的开发依赖项。《pragma(...) 指令比 Pragmas 注释更受欢迎。通过提供独立的 pragma,PhaLinters 可以成为一个合适的开发依赖项。

如果您希望在自己的源分析器中接受 pragma(...) 指令和 <<Pragmas(vec[...])>> 属性,请阅读 pragma.hack 了解此非正式标准的详细信息。