Typechecker运行
运行Typechecker很简单。对于大多数用户和大多数用途,它是一个单行命令,称为hh_client。
hh_client
hh_client对于所有意图和目的,是类型检查器。假设您已正确安装所有内容,并且已将.hhconfig文件添加到代码库的根目录,然后启动typechecking:
%(root of codebase) hh_client
这是一些Hack代码的例子,它是如何被检查的。
<?hh
namespace Hack\UserDocumentation\TypeChecker\Running\Examples\Simple;
function a(int $x): int {
return x + 1;
}
function main(): void {
// simple-check.php:13:14,16: Invalid argument (Typing[4110])
// simple-check.php:5:12,14: This is an int
// simple-check.php:13:14,16: It is incompatible with a string
a("5");
// No errors!
a(5);
}
main();
Output
Catchable fatal error: Argument 1 passed to Hack\UserDocumentation\TypeChecker\Running\Examples\Simple\a() must be an instance of int, string given in /data/users/joelm/user-documentation/guides/hack/25-typechecker/04-running-examples/simple-check.php.type-errors on line 7
我们来检查调用的错误消息a("5"):
simple-check.php:13:14,16: Invalid argument (Typing[4110])
simple-check.php:5:12,14: This is an int
simple-check.php:13:14,16: It is incompatible with a string
该Invalid argument行告诉您发现实际错误的位置。在我们的情况下,调用a("5")是什么导致错误。
注意:这Typing[4110]是服务器的状态码。这个代码可以用于这样的东西HH_FIXME
这一This is an int行让你知道typechecker预期你要做什么。基本上说你的电话a()应该提供一个int。
该It is incompatible with a string行让你知道你做了什么导致typechecker错误。在这种情况下,你通过了string以a()代替int。
hh_server
运行时hh_client,它会检查Typechecker服务器hh_server是否正在运行。如果没有,服务器将被转移。否则,将使用服务器的当前实例。
服务器是后台基础设施,用于对代码进行所有类型分析。是连续的 这就是为什么hh_client报告错误接近瞬间。
Hack文件类型检查
typechecker只检查Hack文件; 那就是开头的文件<?hh。所以如果你的代码库是全部的<?php,那么typechecker将不会对你有太多的用处,只会报告No errors!。
自动加载
Typechecker假设项目中的所有可用代码都可以在项目的任何地方使用。没有检查您的require和include语句是否准确和正确。如果不是,那么你将会在运行时被咬死。
当然,如果你的代码是一个文件,这一点是愚蠢的。但一旦你开始拥有多个文件自动加载的项目变得非常有用。如果您不自动加载,则Typechecker仍然会正确键入错误,但无法确定您忘记了包含一些必需代码的文件才能实际运行。
<?hh
namespace Hack\UserDocumentation\TypeChecker\Running\Examples\Autoloading;
class A {
private B $b;
public function __construct(B $b) {
$this->b = $b;
}
public function foo(): int {
return $this->b->getSomeInt();
}
}
function callFoo(): void {
$a = new A(new B());
var_dump($a->foo());
}
function myAutoloader(string $class): void {
// Remove all the namespace stuff and just get the 'B'
include __DIR__ . '/' . substr($class, -1) . '.inc.php';
}
spl_autoload_register(
'Hack\UserDocumentation\TypeChecker\Running\Examples\Autoloading\myAutoloader'
);
callFoo();
/*
<?hh
namespace Hack\UserDocumentation\TypeChecker\Intro\Examples\Autoloading;
class B {
public function getSomeInt(): int {
return 5;
}
}
*/
Output
int(5)
假设我们忘了在这里要求访问类的代码B
。没有自动加载代码,如果你运行hh_client,
你会得到No errors!
。太好了吧?嗯,不是真的 类型检查器做了正确的事情,但是你会在运行时死机。
Fatal error: Class undefined: Hack\UserDocumentation\TypeChecker\Intro\Examples\Autoloading\B
通过自动加载包含的文件B,您可能会意外忘记requires,但您的代码仍将正确运行。
INT(5)