この記事はモバイルファクトリー Advent Calendar 2020 14日目の記事です。
はじめまして、20卒エンジニアのthe96です。 今回は業務中に使っているPerlのVSCodeの拡張機能のメソッド呼び出しの際の定義元ジャンプが正しく動作するように修正した話をします。
やったこと
従来のVSCode Perlではメソッド呼び出し(Hoge::Fuga->func()
)のときに定義元ジャンプを行った場合、別パッケージの同名関数の定義元に移動してしまうことがあります。
ソースコードを読む際に正しい定義元に移動しないと不便なので、この拡張機能に手を入れて改善しました。
この不具合について説明するために、同名の関数hello
が定義された二つのパッケージA
とB
を用意しました。
修正前の定義元ジャンプ機能では、関数呼び出し(A::hello
)のときはA#hello
の定義に移動できていますが、メソッド呼び出し(A->hello
)のときに定義元ジャンプをするとB#hello
の定義に移動してしまっています。
修正後の定義元ジャンプ機能では、メソッド呼び出しでも期待通りA#hello
へ移動できています。
原因
メソッド呼び出しされている関数で定義元ジャンプをする際、その関数の前の文字列を参照し、パッケージ名であればそれを含めて検索してくれます。
しかし、->
がパッケージ名をつなぐ区切り文字として認識されていなかったのが原因でした。
https://github.com/vscode-perl/vscode-perl/blob/master/src/utils.ts#L15
export function getPackageBefore(document: vscode.TextDocument, range: vscode.Range): string { let separatorRange = getRangeBefore(range, 2); let separator = document.getText(separatorRange); let pkg = ""; while (separator === "::") { const newRange = document.getWordRangeAtPosition(getPointBefore(separatorRange, 1)); if (newRange) { range = newRange; pkg = document.getText(range) + separator + pkg; separatorRange = getRangeBefore(range, 2); separator = document.getText(separatorRange); } else { // break loop separator = ""; } } return pkg.replace(/::$/, ""); }
区切り文字に->
を加えた結果、予想通りパッケージ名を考慮して正しい定義元へとジャンプしてくれるようになりました!
これで、業務中のコードリーディングが捗りそうです:tada:
改良後の拡張機能
初めてのOSSへのP-Rです https://github.com/vscode-perl/vscode-perl/pull/41
しばらく更新されていなかったので、VSCodeのマーケットプレイスにも公開しておきました。 上記が元リポジトリに反映されるまで、よろしければご利用ください。 https://marketplace.visualstudio.com/items?itemName=the96.vscode-perl
明日の記事は yokoi0803 さんです!