VS Codeで型と補完を使う
目次 · 準備と最初の実行 · 拡張のインストールと設定
Nagi拡張0.1.9と最新版のnagicを用意し、NagiリポジトリをVS Codeで開きます。このページでは、動くコードを使って型ホバー・フィールド補完・定義への移動を試します。HighとLowの両方で使えます。
字下げを補助する
拡張0.1.9では、def main():などの後の改行、else・caseの位置、複数行の括弧の位置合わせを補助します。
else:やcase ...:の最後のコロンを入力すると、対応するifやmatchに揃います。既定は4スペースで、エディターの字下げ設定にも従います。コンパイラを使わずに動くため、新しい未保存ファイルでも使えます。詳しい動作と設定は入力時のインデントを参照してください。
サンプルを開く
examples/tutorial/editor_types.nagiを開いてください。内容は次の完全なコードです。
class Count:
value: i64
def parse_count(text: str) -> Result[Count, Error]:
number = try parse_i64(text)
return ok(Count(value=number))
def show(count: Count):
print(count.value)
def main():
result = parse_count("42")
match result:
case Ok(count):
show(count)
case Err(problem):
print(error_message(problem))
右上の実行ボタン、またはコマンドパレットの「Nagi: 実行」で動かすと42を表示します。実行はファイルを保存してから行います。
変数の型を確認する
次の名前にマウスを置いてください。型注釈を省略した変数も、コンパイラが求めた型を確認できます。
| 名前と場所 | 表示する型 | 理由 |
|---|---|---|
parse_countのtext |
text: str |
引数の型注釈 |
number |
number: i64 |
parse_i64の成功値をtryで取り出す |
showのcount |
count: Count |
引数の型注釈 |
mainのresult |
result: Result[Count, Error] |
parse_countの戻り値 |
Ok側のcount |
count: Count |
Resultの成功値 |
Err側のproblem |
problem: Error |
Resultの失敗値 |
caseの名前はそのcaseの中だけで使えます。matchのあとにcountを書いても、Ok側の型情報を表示することはありません。if・while・for・scopeの中で新しく作った変数も、ブロックを出ると使えません。型注釈のない整数は通常i64、小数はf64です。詳しくは型と推論を参照してください。
フィールドを補完する
showのprint(count.value)からvalueを消し、print(count.)にします。ドットのあとで候補が出なければCtrl+Spaceを押してください。value: i64を選ぶと、元のcount.valueに戻ります。count.vaまで書いてから補完することもできます。
classを返す関数のmake().、入れ子のcontainer.item.、Copy classの配列のitems[0].も、その式の型に対応するフィールドを候補にします。候補を選んだときに挿入するのはフィールド名だけです。
resultの型はResult[Count, Error]なので、result.にはCountのフィールドを出しません。上の例のようにmatchで中のCountを取り出します。tryを使う関数では、count = try parse_count("42")と変数に受けるか、(try parse_count("42")).valueと括弧で囲みます。awaitの結果のフィールドも(await fetch()).fieldと書きます。
関数を呼ぶ・定義を探す
関数名を書きかけるかCtrl+Spaceを押すと、プロジェクト内の関数・classと組み込み関数の候補が出ます。関数を選ぶと引数の入力欄が入り、Tabで次の欄へ移動します。classの生成ではCount(value=...)のように名前付き引数が入ります。(や,の入力時には、引数ヒントで順番と型を確認できます。
parse_countやCountにカーソルを置いてF12を押すと定義へ移動します。importの文字列ではそのファイルを開きます。一度保存したファイルなら、未保存の編集や開いているimport先の変更も使います。
変数名でもF12を使えます。上のサンプルで、次の移動を試してください。
| カーソルを置く名前 | 移動先 |
|---|---|
parse_i64(text)のtext |
parse_countの引数text: str |
Count(value=number)のnumber |
number = try parse_i64(text) |
print(count.value)のcount |
showの引数count: Count |
match resultのresult |
result = parse_count("42") |
show(count)のcount |
case Ok(count) |
error_message(problem)のproblem |
case Err(problem) |
再代入した名前は最初の定義へ戻ります。forで外側と同じ名前を使うと、ループ内ではforの名前へ、ループ後では元の定義へ戻ります。if・while・scope・caseの中で新しく作った名前は、そのブロック内だけが対象です。move後の使用や初期化の型エラーがあっても、束縛先を特定できる名前には移動できます。classのフィールド名や組み込み関数へのF12は未対応です。
編集中の情報が出ないとき
一度保存した.nagiと.lowは、未保存の編集をメモリ上で解析します。開いているimport先や手書きLowの編集も反映します。エディターの問い合わせでソースを保存したり、ビルドしたりはしません。プロジェクトの情報を使うには、新しいファイルとnagi.tomlを保存してください。
拡張0.1.9では、新規の未保存ファイルやコンパイラなし、未信頼のワークスペースでも、キーワード・型の補完と組み込み関数の補完・ホバー・引数ヒントを使えます。解析できないimportやファイル内の同じ名前の関数や変数がある場合は、衝突しうる組み込み関数の情報を控えます。ローカル型・フィールド候補・F12にはコンパイラとワークスペースの信頼が必要です。
| 状態 | 表示する情報・確認すること |
|---|---|
value.のフィールド名だけを書きかけている |
受け手の型が分かればフィールド候補を出す |
| 別の場所に閉じていない括弧などがある | 保存済みの関数・classの宣言を「保存済み」と示す。ローカル型・フィールド候補・F12は止める |
| 未定義の型・変数、move後の値、スコープ外の名前 | 推測した型は出さない。Problemsでエラーを確認する |
| ローカル型・フィールド補完・ローカル変数へのF12が使えない | コンパイラと拡張を両方更新する |
| 補助ファイルの関数が見つからない | nagi.tomlのentryからimportされているか確認する |
| プロジェクトの宣言・ローカル型・F12が使えない | ワークスペースの信頼、nagi.compilerPath、Outputの「Nagi」を確認する |
未保存の編集では、古いProblemsの診断を消します。診断を更新するには保存するか「Nagi: 型検査」を実行してください。ホバーや補完で型が見えていても、プログラム全体の型検査が成功したとは限りません。