Docsの目次

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: 型検査」を実行してください。ホバーや補完で型が見えていても、プログラム全体の型検査が成功したとは限りません。

Nagi 0.1のドキュメントこのページのソース