Chapter 12

Go To Definition

takl
takl
2020.12.22に更新

AST ができたので、 Go To Definition が実装できるようになりました。というわけで Go To Definintion を実装しましょう。

capabilities に definitionProvider: true を追加します。すると VSCode のコンテキストメニューに Go To Definition が追加されます。

oreore.js
requestTable["initialize"] = (msg) => {
    const tokenTypes = msg.params.capabilities.textDocument.semanticTokens.tokenTypes;
    for (const i in tokenTypes) {
        tokenTypeToIndex[tokenTypes[i]] = i;
    }

    const capabilities = {
        textDocumentSync: 1,
        definitionProvider: true, // <---- ここ
        semanticTokensProvider: {
            legend: {
                tokenTypes,
                tokenModifiers: []
            },
            range: false,
            full: true
        }
    };

    sendMessage({ jsonrpc: "2.0", id: msg.id, result: { capabilities } });
}

Go To Definition が選ばれると textDocument/definition メッセージとともにカーソル位置が知らされます。AST を検索して definition メンバを見れば定義の位置がわかります。その位置を Language Client に送り返せば定義にジャンプできます。

oreore.js
requestTable["textDocument/definition"] = (msg) => {
    const uri = msg.params.textDocument.uri;
    const position = msg.params.position;

    const ast = findAstOfPosition(uri, position);
    if (!ast || ast.kind !== "variable" || !ast.definition || !ast.definition.token) {
        sendMessage({ jsonrpc: "2.0", id: msg.id, result: null });
    } else {
        sendMessage({ jsonrpc: "2.0", id: msg.id, result: ast.definition.token.location });
    }
}

findAstOfPosition の実装は少々長いですので、こちらから見てください。長いだけで大したことはしていません。

* ここまでのソースコード *