Typechecker運行

2018-10-28 11:34 更新

運行Typechecker很簡單。對于大多數(shù)用戶和大多數(shù)用途,它是一個單行命令,稱為hh_client。

hh_client

hh_client對于所有意圖和目的,是類型檢查器。假設(shè)您已正確安裝所有內(nèi)容,并且已將.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

我們來檢查調(diào)用的錯誤消息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行告訴您發(fā)現(xiàn)實際錯誤的位置。在我們的情況下,調(diào)用a("5")是什么導(dǎo)致錯誤。

注意:這Typing[4110]是服務(wù)器的狀態(tài)碼。這個代碼可以用于這樣的東西HH_FIXME

這一This is an int行讓你知道typechecker預(yù)期你要做什么。基本上說你的電話a()應(yīng)該提供一個int。

該It is incompatible with a string行讓你知道你做了什么導(dǎo)致typechecker錯誤。在這種情況下,你通過了string以a()代替int。

hh_server

運行時hh_client,它會檢查Typechecker服務(wù)器hh_server是否正在運行。如果沒有,服務(wù)器將被轉(zhuǎn)移。否則,將使用服務(wù)器的當(dāng)前實例。

服務(wù)器是后臺基礎(chǔ)設(shè)施,用于對代碼進(jìn)行所有類型分析。是連續(xù)的 這就是為什么hh_client報告錯誤接近瞬間。

Hack文件類型檢查

typechecker只檢查Hack文件; 那就是開頭的文件<?hh。所以如果你的代碼庫是全部的<?php,那么typechecker將不會對你有太多的用處,只會報告No errors!。

自動加載

Typechecker假設(shè)項目中的所有可用代碼都可以在項目的任何地方使用。沒有檢查您的require和include語句是否準(zhǔn)確和正確。如果不是,那么你將會在運行時被咬死。

當(dāng)然,如果你的代碼是一個文件,這一點是愚蠢的。但一旦你開始擁有多個文件自動加載的項目變得非常有用。如果您不自動加載,則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)

假設(shè)我們忘了在這里要求訪問類的代碼B。沒有自動加載代碼,如果你運行hh_client,你會得到No errors!。太好了吧?嗯,不是真的 類型檢查器做了正確的事情,但是你會在運行時死機(jī)。

Fatal error: Class undefined: Hack\UserDocumentation\TypeChecker\Intro\Examples\Autoloading\B

通過自動加載包含的文件B,您可能會意外忘記requires,但您的代碼仍將正確運行。

INT(5)


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號