Dwarf Navigator
Dwarf DSL の model('Auth'), repository('Order'), presenter('Item') 等から対応するクラスへの定義ジャンプ、ホバー情報、オートコンプリートを提供する VSCode 拡張機能です。
機能
1. 定義へのジャンプ (Go to Definition)
DSL クラスへのジャンプ
model('Auth'), repository('Order'), qbuilder('Order'), presenter('Item'), usecase('CreateOrder') の上で F12 キーを押すか、Cmd+クリック (Mac) / Ctrl+クリック (Windows) すると、対応するクラスファイルにジャンプします。
# この 'Auth' の上で F12 を押すと...
model('Auth')->check(...);
# → app/lib/App/Model/Auth.pm の package 宣言にジャンプ
repository('Order')->find(...);
# → app/lib/App/Repository/Order.pm にジャンプ
presenter('Item')->format(...);
# → app/lib/App/Presenter/Item.pm にジャンプ
| DSL 関数 |
クラスプレフィックス |
model() / m() |
App::Model:: |
repository() |
App::Repository:: |
qbuilder() |
App::QueryBuilder:: |
presenter() |
App::Presenter:: |
usecase() |
App::Usecase:: |
メソッド定義へのジャンプ
model('Auth')->check の check の上で F12 を押すと、App::Model::Auth 内の check メソッド定義にジャンプします。他の DSL 関数でも同様に動作します。
# この check の上で F12 を押すと...
model('Auth')->check(...);
# → app/lib/App/Model/Auth.pm の sub check 定義にジャンプ
repository('Order')->find(...);
# → app/lib/App/Repository/Order.pm の sub find 定義にジャンプ
これにより、Perl Navigator が間違った check メソッドに飛んでしまう問題を解決し、正しいクラスのメソッドにジャンプできます。
self によるメソッド定義へのジャンプ
self->method_name の method_name の上で F12 を押すと、同じファイル内の method_name メソッド定義にジャンプします。見つからない場合は親クラス(use parent, use base, extends)を再帰的に辿って検索します。
# この validate の上で F12 を押すと...
sub create {
my $args = args { ... }, @_;
self->validate($args); # ← 同じファイル内の validate にジャンプ
}
# → 同じファイルの sub validate 定義にジャンプ
# → 見つからなければ親クラスの定義にジャンプ
self は Dwarf DSL の関数で、そのモジュール自身を指します。Dwarf::Accessor で定義されたアクセサ名もメソッド定義として認識されます。
DSL キーワードの定義ジャンプ
redirect, session, db などの Dwarf DSL キーワードの上で F12 を押すと、Dwarf::Module::DSL の定義元にジャンプします。shift->c->redirect(@_) のようなデリゲートパターンの場合は、実際の定義元(例: Dwarf::Request::redirect)まで辿ります。
redirect('/'); # ← F12 で実際の redirect 実装にジャンプ
session->param('login'); # ← session で F12 → Dwarf::Session の定義へ
Validator Constraint の定義ジャンプ
validate() 内の大文字キーワード(UINT, DEFAULT, CHOICE 等)の上で F12 を押すと、App::Validator::Constraint::Default または Dwarf::Validator::Constraint::Default 内の rule/filter/alias 定義にジャンプします。
validate(
id => [UINT], # ← F12 で rule UINT => sub { ... } にジャンプ
name => [DEFAULT], # ← F12 で filter DEFAULT => sub { ... } にジャンプ
);
2. 型情報の表示 (Hover)
DSL クラスの型情報
model('Auth'), repository('Order') 等の上にマウスカーソルを置くと、型情報が表示されます。
model('Auth') # ← ホバーすると "App::Model::Auth" と表示
repository('Order') # ← ホバーすると "App::Repository::Order" と表示
メソッドの型情報と引数情報
model('Auth')->check の check の上にマウスカーソルを置くと、メソッドの完全修飾名と引数情報が表示されます。他の DSL 関数でも同様に動作します。
model('Auth')->check # ← ホバーすると以下が表示される:
# App::Model::Auth::check(function: Int?, permission: Int?)
#
# Method check on App::Model::Auth
#
# Parameters:
# - function: Int (optional)
# - permission: Int (optional)
引数定義は args { ... } ブロックから自動的に抽出されます:
- 引数名と型情報
- 必須/オプショナルの区別(
? サフィックス)
Int, Str, Bool, ArrayRef[Int] などの型
- ハッシュリファレンス形式の複雑な定義(
{ isa => 'HashRef', rules => ... })にも対応
self によるメソッド呼び出しの型情報
self->method_name の method_name の上にマウスカーソルを置くと、メソッドの完全修飾名と引数情報が表示されます。
# App::Model::Auth.pm の中で
self->validate # ← ホバーすると以下が表示される:
# App::Model::Auth::validate(user_id: Int, token: Str)
#
# Method validate on App::Model::Auth (self)
#
# Parameters:
# - user_id: Int (required)
# - token: Str (required)
self の場合も、同じファイル内の args { ... } ブロックから引数情報を自動的に抽出します。
3. サポートされる引数定義パターン
拡張機能は以下の args 定義パターンを認識します:
シンプルな型定義
my $args = args {
id => 'Int',
name => 'Str',
is_active => 'Bool?', # オプショナル
}, @_;
複雑な型定義(Data::Validator の全属性に対応)
my $args = args {
items => 'ArrayRef[Int]',
service => { isa => 'HashRef', rules => $App::Type::SESSION_SERVICE },
options => { isa => 'ArrayRef', rules => { ... } },
json => { isa => 'Str', xor => 'decoded', optional => 1 },
decoded => { isa => 'ArrayRef', xor => 'json', optional => 1 },
count => { isa => 'Int', default => 10 },
}, @_;
対応している Data::Validator 属性:
isa - 型指定
does - ロール指定
optional - オプショナルフラグ
default - デフォルト値(自動的に optional として扱われる)
xor - 排他的OR(他のパラメータとの相互排他)
rules - ネストされたバリデーションルール
coerce - 型強制
documentation - ドキュメント文字列
ホバー時には以下のように表示されます:
id: Int (required)
name: Str (required)
is_active: Bool (optional)
items: ArrayRef[Int] (required)
service: HashRef (rules: $App::Type::SESSION_SERVICE) (required)
json: Str (xor: decoded) (optional)
decoded: ArrayRef (xor: json) (optional)
count: Int (default: 10) (optional)
4. オートコンプリート
クラス名の補完
model(', repository(', presenter(' 等と入力すると、利用可能なクラスの一覧が補完候補として表示されます。
model('A # ← ここで候補が表示される
# - Auth
# - AppProxy
# など
repository('O # ← Repository クラスの候補が表示される
# - Order
# - Order::Attribute
# など
既存のクラス名の編集にも対応: model('Auth') の Auth 部分にカーソルを置いて編集すると、入力に応じて補完候補が更新されます。
メソッド名の補完
model('Auth')-> と入力すると、そのクラスで利用可能なメソッドの一覧が補完候補として表示されます。他の DSL 関数でも同様に動作します。
model('Auth')-> # ← ここで候補が表示される
# - check
# - validate
# - create
# など
メソッドの補完候補には以下の情報が含まれます:
- メソッド名
- 完全修飾名(
App::Model::Auth::check)
- 引数情報(
args { ... } ブロックから自動抽出)
- 引数スニペット(引数が定義されている場合、自動的に挿入)
# check を選択すると...
model('Auth')->check(function => $1, permission => $2)
# ↑ 引数名が自動的に挿入され、Tab キーで次の引数に移動可能
DSL キーワード経由のメソッド補完
db->, req->, session-> などの DSL キーワードの後に -> を入力すると、対応するクラスのメソッド一覧が補完候補として表示されます。self-> の場合は現在のクラスのメソッド(プライベートメソッド含む)が表示され、親クラスから継承されたメソッドも含まれます。
db-> # ← App::DB のメソッド一覧が表示される(プラグインメソッドも含む)
req-> # ← Dwarf::Request のメソッド一覧が表示される
self-> # ← 現在のクラスと親クラスのメソッド一覧が表示される
プラグインメソッドのサポート: Teng などのフレームワークでプラグイン機構を使ってメソッドを追加している場合も、自動的に検出して補完候補に含めます。例えば、App::DB が Teng::Plugin::FindOrCreate を読み込んでいる場合、db-> と入力すると find_or_create メソッドも補完候補に表示されます。
DSL キーワード補完
Dwarf DSL のキーワード(model, self, app, db, conf, session, redirect, render, args 等)のオートコンプリートに対応しています。各キーワードにはスニペットが付属し、入力を補助します。
5. プラグインメソッドのサポート
Teng などのフレームワークでプラグイン機構(__PACKAGE__->load_plugin('PluginName'))を使ってメソッドを追加している場合、プラグインで定義されたメソッドの定義ジャンプ、ホバー情報、オートコンプリートをサポートします。
プラグインメソッドの定義ジャンプ
db->find_or_create の find_or_create の上で F12 を押すと、プラグインで定義されたメソッドの実装にジャンプします。
# App::DB.pm で以下のようにプラグインを読み込んでいる場合
package App::DB;
use parent 'Teng';
__PACKAGE__->load_plugin('FindOrCreate');
# Controller などで
db->find_or_create('users', { name => 'test' });
# ↑ find_or_create で F12 を押すと...
# → Teng::Plugin::FindOrCreate の sub find_or_create 定義にジャンプ
プラグインメソッドのホバー情報
プラグインで定義されたメソッドにマウスカーソルを置くと、メソッドの引数情報が表示されます。
db->find_or_create # ← ホバーすると以下が表示される:
# App::DB::find_or_create
#
# Method find_or_create on App::DB (plugin method)
#
# Parameters:
# - table: 検索/作成対象のテーブル名
# - args: HashRef - 検索条件およびINSERTデータ
プラグインメソッドの補完
db-> と入力すると、プラグインで追加されたメソッドも補完候補に表示されます。
db-> # ← ここで候補が表示される
# - search (通常のメソッド)
# - single (通常のメソッド)
# - find_or_create (プラグインメソッド)
# - count (プラグインメソッド)
# など
補完候補にはメソッドの出所(通常のメソッドか、プラグインメソッドか)も表示されます。
サポートされるプラグインパターン
- 直接のプラグイン:
App::DB::Plugin::Custom
- 親クラスのプラグイン:
Teng::Plugin::FindOrCreate(親クラスが Teng の場合)
- 複数の親クラスに対応(
use parent qw(Class1 Class2))
- プラグインの再帰的な検索(親クラスのプラグインも自動検出)
現在サポートされている Teng プラグイン:
Teng::Plugin::FindOrCreate - find_or_create メソッド
Teng::Plugin::Count - count メソッド
Teng::Plugin::BulkInsert - bulk_insert メソッド
- その他の Teng プラグイン全般
サポートされるパターン
DSL クラス取得
model('Auth') / m('Auth') → App::Model::Auth
repository('Order') → App::Repository::Order
qbuilder('Order') → App::QueryBuilder::Order
presenter('Item') → App::Presenter::Item
usecase('CreateOrder') → App::Usecase::CreateOrder
- ネストされたクラス名:
model('Order::Attribute')
メソッド呼び出し
model('Auth')->check
repository('Order')->find(...)
model('Member')->find(...)->update(...)
- 複数行にまたがるメソッドチェーンもサポート
self によるメソッド呼び出し
self->method_name
self->validate(...)
- 同じファイル内のメソッド定義にジャンプ(見つからなければ親クラスを辿る)
- 引数情報の表示にも対応
SQLBuilder
new_query->select(...), new_query->from(...), new_query->where(...) 等
new_named_query->select(...), new_named_query->add_where(...) 等
- 定義ジャンプ、ホバー、メソッド補完に対応
DSL キーワード
redirect('/'), session->param(...), db->search(...) 等
- 定義ジャンプ、型解決付きメソッド補完に対応
Validator Constraint
UINT, DEFAULT, CHOICE, NOT_NULL 等の大文字キーワード
rule/filter/alias 定義への定義ジャンプに対応
Error プラグインメソッド
e->INVALID_SESSION, error->PAYMENT_ERROR 等
- ホバーでエラーコードとメッセージを表示(例:
e->INVALID_SESSION [1003])
- F12 で Controller Base クラスの定義行にジャンプ(複数候補時は Peek UI)
ApiBase / WebBase / CliBase の Error プラグイン定義を動的にパース
App::Constant 定数
ORDER_STATUS_MAKING, GENDER_MEN, PAYMENT_TYPES_CREDIT_CARD 等
- ホバーで定数値を表示(例:
App::Constant::ORDER_STATUS_MAKING = 3)
- F12 で
App::Constant.pm の定義行にジャンプ
設定
.vscode/settings.json で設定をカスタマイズできます:
{
"dwarfNavigator.appPrefix": "App",
"dwarfNavigator.libBasePath": "app/lib"
}
| 設定 |
デフォルト |
説明 |
dwarfNavigator.appPrefix |
"App" |
アプリケーション名前空間プレフィックス。model('Auth') → {appPrefix}::Model::Auth に解決される |
dwarfNavigator.libBasePath |
"app/lib" |
ワークスペースルートからの相対ライブラリパス |
dwarfNavigator.ctags.enabled |
true |
ctags による定義ジャンプを有効にする |
dwarfNavigator.ctags.path |
"ctags" |
ctags コマンドのパス |
dwarfNavigator.ctags.tagFile |
".vstags" |
タグファイルのパス(ワークスペースルートからの相対パス) |
dwarfNavigator.ctags.autoGenerate |
true |
activate 時・保存時にタグを自動生成する |
dwarfNavigator.ctags.completion |
true |
ctags によるオートコンプリートを有効にする |
dwarfNavigator.ctags.extraArgs |
"" |
ctags に渡す追加引数 |
動作要件
- VSCode 1.60.0 以上
- Perl ファイル (
.pm, .pl)
- Universal Ctags(ctags 機能を使う場合)
既知の制限
トラブルシューティング
拡張機能が動作しない
- VSCode を再起動してください
- "Reload Window" を実行してください (Cmd+Shift+P → "Reload Window")
- VSCode の Developer Tools (Help → Toggle Developer Tools) を開いて、エラーがないか確認してください
ファイルが見つからない
設定を確認してください:
dwarfNavigator.libBasePath がプロジェクトの lib ディレクトリを正しく指しているか
- ファイルパスが正しいか (
app/lib/App/Model/Auth.pm)
バージョン履歴
0.9.4 (2026-02-09)
0.9.3 (2026-02-04)
0.9.2 (2026-02-02)
- NEW: Perl 変数の定義ジャンプに対応
$scalar, @array, %hash の my / our / local 宣言元にジャンプ
$hash{key} → my %hash / my $hash の宣言にジャンプ
$array[0] → my @array / my $array の宣言にジャンプ
- カーソル位置から上方向に最も近い宣言を定義元として解決
0.9.1 (2026-02-02)
- NEW:
Dwarf::Accessor で宣言されたアクセサメソッドの補完・ホバー・定義ジャンプに対応
use Dwarf::Accessor qw/name1 name2/; 形式(全て rw)に対応
use Dwarf::Accessor { ro => [qw/name1/], rw => [qw/name2/] }; 形式に対応
- 複数行にまたがる宣言に対応
- 補完候補に
(ro) / (rw) ラベルを表示、Property アイコンで区別
- ホバーで
read-only / read-write アクセサ情報を表示
- 親クラスから継承されたアクセサも認識
0.9.0 (2026-02-02)
- NEW: ctags ベースの定義ジャンプ・ホバー・補完(フォールバック)
- 既存の DSL パターンにマッチしない関数・クラスに対して ctags で定義ジャンプ
Dwarf::Util::Xslate::format_yen() や encode_base64() 等の任意関数に F12 で定義ジャンプ
LWP::UserAgent->new() 等の任意クラスメソッドにもジャンプ可能
- 複数候補がある場合は Peek UI で一覧表示
- ctags シンボルのホバー情報表示(定義元ファイル・行番号)
- ctags シンボルのオートコンプリート(2文字以上入力で候補表示)
- NEW: ctags の自動生成
- 拡張機能 activate 時に
app/lib と app/local/lib/perl5 に対して ctags を自動実行
- Perl ファイル保存時にインクリメンタル更新(
ctags -a)
- NEW: ctags 関連設定の追加
ctags.enabled: ctags 定義ジャンプの有効/無効
ctags.path: ctags コマンドのパス指定
ctags.tagFile: タグファイルのパス(デフォルト: .vstags)
ctags.autoGenerate: 自動生成の有効/無効
ctags.completion: ctags 補完の有効/無効
ctags.extraArgs: ctags への追加引数
0.8.5 (2026-01-30)
- NEW:
dwarfNavigator.appPrefix 設定の追加
- アプリケーション名前空間プレフィックス(デフォルト:
"App")を設定で変更可能に
model(), repository(), qbuilder(), presenter(), usecase() のクラス解決に反映
App::Constant, App::Validator::Constraint::Default, App::Controller::*Base 等のハードコードを全て動的に解決
- DSL キーワードの
returnType(App::DB 等)も appPrefix に追従
dwarfNavigator.modelPrefix 設定は廃止(appPrefix に統合)
0.8.4 (2026-01-30)
- NEW:
ret による返り値型のホバー表示
return ret VALUE, 'Type' で宣言された返り値型をホバーのシグネチャに → Type として表示
- Returns: セクションで型名を表示
- DSL メソッド、DSL キーワードメソッド、self メソッドの全パターンに対応
0.8.3 (2026-01-29)
- NEW: Error プラグインメソッドのサポート
e->INVALID_SESSION 等のエラーメソッドにホバーでエラーコード・メッセージを表示
- F12 で
ApiBase / WebBase / CliBase の load_plugins('Error' => {...}) 定義行にジャンプ
- 複数の Base クラスに同名エラーがある場合は Peek UI で候補一覧表示(ApiBase 優先)
0.8.2 (2026-01-29)
- NEW: App::Constant 定数のサポート
ORDER_STATUS_MAKING 等の大文字スネークケース定数をホバーで値表示
- F12 で
App::Constant.pm の定義行に定義ジャンプ
App::Constant.pm を動的にパースして 150+ の定数に対応
0.8.1 (2026-01-29)
- NEW: SQLBuilder DSL キーワードの追加
new_query → Dwarf::SQLBuilder::Query のインスタンスとして型解決
new_named_query → Dwarf::SQLBuilder::NamedQuery のインスタンスとして型解決
new_query->select, new_query->where 等のメソッド補完・ホバー・定義ジャンプに対応
0.8.0 (2026-01-29)
- NEW: プラグインメソッドのサポート
- Teng などのプラグイン機構(
__PACKAGE__->load_plugin('PluginName'))で追加されたメソッドの定義ジャンプに対応
- プラグインメソッドのホバー情報表示(引数情報も含む)
- プラグインメソッドのオートコンプリート(
db-> で find_or_create などが候補に表示)
- 親クラスのプラグインも自動検出(
App::DB → Teng::Plugin::FindOrCreate など)
- 複数の親クラスに対応(
use parent qw(Class1 Class2))
- プラグインの再帰的な検索をサポート
- FIX: プラグイン解決ロジックの改善
- ベースクラスのプラグインだけでなく、親クラスのプラグインも検索するように修正
App::DB::Plugin::FindOrCreate だけでなく Teng::Plugin::FindOrCreate も検索
0.7.0 (2026-01-29)
- NEW: 複数の DSL 関数に対応
repository(), qbuilder(), presenter(), usecase() の定義ジャンプ、ホバー、補完をサポート
- NEW: DSL キーワードの定義ジャンプ
redirect, session, db 等から Dwarf::Module::DSL の定義元にジャンプ
shift->c->redirect(@_) のようなデリゲートパターンは実際の定義元まで辿る
- NEW: Validator Constraint の定義ジャンプ
UINT, DEFAULT 等の大文字キーワードから rule/filter/alias 定義にジャンプ
- NEW: DSL キーワード経由のメソッド補完
db->, req->, session-> 等で型解決付きメソッド一覧を表示
- NEW: DSL キーワードのオートコンプリート
- Dwarf DSL の全キーワードをスニペット付きで補完
- NEW: 継承メソッドの解決
self-> で親クラス(use parent, use base, extends)を再帰的に辿って定義ジャンプ・補完
- 補完候補に継承元クラス情報を表示
- NEW:
Dwarf::Accessor で定義されたアクセサ名をメソッド定義として認識
- NEW:
app/local/lib/perl5 をクラスファイルの検索パスに追加
0.6.0 (2026-01-28)
- NEW: 強化されたオートコンプリート機能
- 既存のモデル名編集時に補完候補を表示(
model('Auth') の Auth 部分を編集可能)
- メソッド名の補完機能(
model('Auth')-> で利用可能なメソッド一覧を表示)
- メソッド補完時に引数情報とスニペットを自動挿入
- 部分一致による補完候補のフィルタリング
-> をトリガー文字に追加
0.5.0 (2026-01-28)
- NEW:
self->method サポート
- 同じファイル内のメソッド定義へのジャンプ機能
- ホバー時に現在のクラスのメソッド情報と引数を表示
- Dwarf DSL の
self 関数(モジュール自身を指す)に対応
- FIX: 引数定義内の
isa 属性が誤ってパラメータとして認識されるバグを修正
0.4.0 (2026-01-28)
- NEW: Data::Validator の全属性に完全対応
isa, does, optional, default, xor, rules, coerce, documentation をサポート
- ハッシュリファレンス形式の複雑な引数定義を完全に解析
xor による排他的OR関係の表示
default 値の表示
0.3.0 (2026-01-28)
- NEW: メソッド引数情報の表示
args { ... } ブロックから引数定義を自動解析
- ホバー時に引数名、型、必須/オプショナルを表示
Int?, ArrayRef[Int] などの複雑な型にも対応
0.2.0 (2026-01-28)
- NEW: メソッド呼び出しの定義ジャンプ機能
model('Auth')->check の check から App::Model::Auth::check へジャンプ
- NEW: メソッド呼び出し時のホバーで型情報表示
- Perl Navigator との競合を解決
0.1.0 (2026-01-28)
- 初回リリース
- Go to Definition 機能
- Hover で型情報表示
- オートコンプリート機能