アーキテクチャ
このドキュメントでは、 Biomeの内部機能の一部と、それらがプロジェクト内でどのように利用されているかについて説明します。
パーサーとCST
Section titled パーサーとCSTパーサーのアーキテクチャは rowan の内部フォークによって更新されています。 これは Green and Red tree パターンを実装したライブラリです。
CST (Concrete Syntax Tree) は、 トリビアを含むプログラム内のすべての情報を追跡するAST (Abstract Syntax Tree) によく似たデータ構造です。
トリビア は、プログラムを実行するために不可欠な情報を含んでいます:
- スペース
- タブ
- コメント
トリビアは各ノードに関連付けられ、それぞれのノードは前方トリビアと後方トリビアを持ちます。 コードを左から右へ読む場合、前方トリビアはキーワード前に、後方トリビアはキーワード後に現れるものです。
前方トリビアと後方トリビアは、それぞれ以下のように分類されます:
- 前方トリビア: トークン/キーワードまでのすべてのトリビア(改行を含む)
- 後方トリビア: 次の改行までのすべてのトリビア(その改行自体は含まない)
次のJavaScriptのスニペットでは、// comment 1
はトークン ;
に対する後方トリビアで、// comment 2
はキーワード const
に対する前方トリビアです。
下部は、Biomeによって表現されたCSTの簡略版です:
const a = "foo"; // comment 1// comment 2const b = "bar";
0: JS_MODULE@0..55 ... 1: SEMICOLON@15..27 ";" [] [Whitespace(" "), Comments("// comment 1")] 1: JS_VARIABLE_STATEMENT@27..55 ... 1: CONST_KW@27..45 "const" [Newline("\n"), Comments("// comment 2"), Newline("\n")] [Whitespace(" ")] 3: EOF@55..55 "" [] []
設計上、CSTは直接アクセスできないようになっていますが、言語の文法から自動生成されたAPIによって、開発者はRed treeからその情報を取得できます。
頑健かつ回復可能なパーサー
Section titled 頑健かつ回復可能なパーサーCSTを構築するためには、パーサーはエラーに対して頑健かつ回復可能である必要があります:
- 頑健性: 言語の構文エラーに遭遇した後でも解析を再開できるパーサー
- 回復可能性: エラーが発生した箇所を理解でき、正しい情報を生成することで解析を再開できるパーサー
パーサーの回復可能性は科学的なルールに基づかず、厳格なルールは存在しません。 これは、解析対象やエラー発生箇所によって予測された方法で、パーサーが自己回復できる可能性があることを示します。
パーサーは誤った構文を処理することからコンシューマーを保護するため、 Bogus
ノードも使用します。
このノードは、構文エラーに起因する破損したコードを装飾するのに利用されます。
以下の例では、 while
の括弧が抜けていますが、パーサーは上手く回復し、適切なCSTでコードを表現できています。
ループの条件や括弧が欠落しているとしてマークされ、そしてコードブロックは正しく解析されます:
while {}
JsModule { interpreter_token: missing (optional), directives: JsDirectiveList [], items: JsModuleItemList [ JsWhileStatement { while_token: WHILE_KW@0..6 "while" [] [Whitespace(" ")], l_paren_token: missing (required), test: missing (required), r_paren_token: missing (required), body: JsBlockStatement { l_curly_token: L_CURLY@6..7 "{" [] [], statements: JsStatementList [], r_curly_token: R_CURLY@7..8 "}" [] [], }, }, ], eof_token: EOF@8..8 "" [] [],}
これは、解析中に発生したエラーです:
main.tsx:1:7 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ expected `(` but instead found `{`
> 1 │ while {} │ ^
ℹ Remove {
次のスニペットは同様ではありません。
パーサーは回復フェーズ中に構文を適切に理解することができず、Bogus
ノードに頼って一部の構文をエラーとしてマークする必要があります。
JsBogusStatement
に注目してください:
function}
JsModule { interpreter_token: missing (optional), directives: JsDirectiveList [], items: JsModuleItemList [ TsDeclareFunctionDeclaration { async_token: missing (optional), function_token: FUNCTION_KW@0..8 "function" [] [], id: missing (required), type_parameters: missing (optional), parameters: missing (required), return_type_annotation: missing (optional), semicolon_token: missing (optional), }, JsBogusStatement { items: [ R_CURLY@8..9 "}" [] [], ], }, ], eof_token: EOF@9..9 "" [] [],}
これは、解析フェーズ中に発生したエラーです:
main.tsx:1:9 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ expected a name for the function in a function declaration, but found none
> 1 │ function} │ ^
フォーマッタ (WIP)
Section titled フォーマッタ (WIP)リンタ (WIP)
Section titled リンタ (WIP)デーモン (WIP)
Section titled デーモン (WIP)Biomeは、タスク実行のためにサーバークライアントアーキテクチャを使用しています。
daemon は、エディターやCLIからのリクエストを処理するためにBiomeをバッググラウンドで起動し、長時間実行されるサーバーです。