Binder

Last updated 2 months ago

ほとんどのJavaScriptトランスパイラはTypeScriptよりもシンプルです。コード解析の方法がほとんどないためです。典型的なJavaScriptのトランスパイラは、次のようなフローしかありません:

SourceCode ~~Scanner~~> Tokens ~~Parser~~> AST ~~Emitter~~> JavaScript

上記のアーキテクチャーはTypeScriptのJS生成の単純化された理解と同じですが、TypeScriptの主な特徴はSemanticシステムです。型チェック(checkerによって実行される)を助けるために、binder(binder.ts)は、ソースコードの様々な部分を正しい型システムに接続するために使用されます。そして、checkerにより使用されます。binderの主な役目はSymbolの作成です。

Symbol

シンボルは、AST内の宣言ノードを、同じエンティティに寄与する他の宣言に接続します。Symbolは、セマンティックシステムの基本的な建設部材です。Symbolコンストラクタは core.tsで定義されています(そしてbinderは実際にobjectAllocator.getSymbolConstructorを使ってそれを手に入れます)。以下はSymbolコンストラクタです:

function Symbol(flags: SymbolFlags, name: string) {
this.flags = flags;
this.name = name;
this.declarations = undefined;
}

SymbolFlagsはフラグ列挙型であり、Symbolの更なる分類を識別するために本当に使用されます(例えば変数スコープフラグFunctionScopedVariableBlockScopedVariableなど)

Checkerによる使用法

binderは実際にchecker型で内部的に使用され、checkerprogramによって使用されます。単純化したコールスタックは次のようになります。

program.getTypeChecker ->
ts.createTypeChecker (in checker)->
initializeTypeChecker (in checker) ->
for each SourceFile `ts.bindSourceFile` (in binder)
// followed by
for each SourceFile `ts.mergeSymbolTable` (in checker)

binderの作業単位はSourceFileです。binder.tschecker.tsによって駆動されます。