圧倒亭グランパのブログ

30年後の自分にもわかるように書くブログ

Crystalのcli紹介 "tool implementations"

この記事は、 Crystal Advent Calendar 2017 の16日目の記事です。

crystalのcliには便利なサブコマンドやオプションがあります。コーディングを支えるものだったり、build時の細かな設定だったりします。知っていると得をする、だけど知らない人も多いかもしれない。そんなサブコマンドやオプションを紹介します。

  

今回は、 $ crystal tool implementations を紹介します。

tool implementations

まずはcliのhelpを見てみましょう。

$ crystal tool --help
Usage: crystal tool [tool] [switches] [program file] [--] [arguments]

Tool:
    context                  show context for given location
    expand                   show macro expansion for given location
    format                   format project, directories and/or files
    hierarchy                show type hierarchy
    implementations          show implementations for given call in location
    types                    show type of main variables
    --help, -h               show this help

implementations があります。

show implementations for given call in location

カーソル上にあるメソッドが定義されている位置を出力してくれるコマンドです。implementationsのhelpも見てみましょう。

$ crystal tool implementations --help
Usage: crystal tool implementations [options] [programfile] [--] [arguments]

Options:
    -D FLAG, --define FLAG           Define a compile-time flag
    -c LOC, --cursor LOC             Cursor location with LOC as path/to/file.cr:line:column
    -f text|json, --format text|json Output format text (default) or json
    --error-trace                    Show full error trace
    -h, --help                       Show this message
    --no-color                       Disable colored output
    --prelude                        Use given file as prelude
    -s, --stats                      Enable statistics output
    -p, --progress                   Enable progress output
    -t, --time                       Enable execution time output

よく使うのは-cオプションです。カーソルの位置をファイルパス:行数:列数と指定することで、その位置にあるメソッドを対象とし、その定義が書かれている位置を表示してくれます。

例を見てみましょう。下記のファイルを用意します。

src/implementations.cr

module Implementations
  class MyClass
    getter iv

    def initialize(@iv : String)
    end

    def my_method
      "my_method"
    end
  end
end

c = Implementations::MyClass.new("hoge")
p c.my_method
p c.iv

コマンドを打ってみます。15:5p c.my_methodmy_method部分です。

$ crystal tool implementations -c src/implementations.cr:15:5 src/implementations.cr
1 implementation found
/path/to/repository_root/src/implementations.cr:8:5

8:5def my_methodの位置になります。

次に、macro部分に向けてコマンドを打ってみましょう。

$ crystal tool implementations -c src/implementations.cr:16:5 src/implementations.cr
1 implementation found
/path/to/repository_root/src/implementations.cr:3:5
 ~> macro getter: expanded macro: macro_4438952128:117:13

macroであることが出力されました。macroの位置は3:5なので、その行列数をtool expandに持っていきましょう。

$ crystal tool expand -c src/implementations.cr:3:5 src/implementations.cr
1 expansion found
expansion 1:
   getter(iv)

~> def iv
     @iv
   end

macroが展開されました。

implementationsは、もちろん組み込みのメソッドに対しても有効です。下記のコードを付け足します。

p "string".gsub(/s/, "S")

gsubに向けてコマンドを打ってみます。

$ crystal tool implementations -c src/implementations.cr:18:12 src/implementations.cr
1 implementation found
/usr/local/Cellar/crystal-lang/0.23.1_3/src/string.cr:2066:3

しっかりと位置を教えてくれました。

implementationsはエディタ支援に位置します。自分はVSCodeを使っていますが、VSCodeのCrystalのプラグインでは実際にimplementationsが使われていました(implementations--format jsonオプションを使用し、jsonをparseして情報を得ていた)。

こんなコマンドもあるんだなと知っていただければ幸いです。