たにしきんぐダム

プログラミングやったりゲームしてます

2019年12月と2020年1月のOSS活動記

  • レビュー結構やってました
  • 英会話とか仕事がちょっと忙しかった
  • metals結構わかってきた。

scalameta/metals #1174 Sort auto-completed exhaustive match'es by declaration order

sealed abstract class Test
case object Foo extends Test
case object Bar extends Test
case object Baz extends Test

// ...

def test(t: Test) = t match
//                    ^ ここで補完すると

// 補完後
def test(t: Test) = t match {
  case Foo => // move cursor to here
  case Baz =>
  case Bar =>
}

となる機能が元からあったのだけれど、このcaseの順序は不定(Scalaのreflection APIが返す順序をそのまま使っている)のたのをそれぞれsubclassの定義順序で返すようにする。地味に便利

  • 割と簡単なタスクだったけれどいろいろ学べたので良い入門タスクだった。
    • このプロジェクトのテストの書き方
    • presentation compiler threadのlife cycle
    • symbol search の cache 戦略 など

tanishiking/scalaunfmt #62 Introduce github actions

自分のScalaプロジェクトのCIをgithub actionsに移行しました。完。

scalameta/metals #1213 Fix scaladoc for methods in Completions

後続のPR出すためにmetalsのコード読んでたらscaladocがミスってるやつあったので修正

scalameta/metals #1250 Support scaladoc auto completion on type /**

/** までタイプした時点で、隣接するメソッド定義やクラス定義に対応するscaladocを自動生成する機能

def foo(x: Int, y: Int)(implicit ctx: Context): Int = ???

/**
  * | <- move cursor to here
  *
  * @param x
  * @param y
  * @param ctx
  * @return
  */
def foo(x: Int, y: Int)(implicit ctx: Context): Int = ???

typescript使っててめちゃ便利だなと思ってた機能、実装するときはtypescriptとvscodeの実装を読んでそれを参考にした。

(tsserverはlsp実装してないのでそこらへんの読み替えは必要(ほかはしてる?少なくともこの補完では textDocument/completion 使わずに全部commandでやりとりしている))

方針としては

  • /** をうったら textDocument/completion が発火するようにする
  • 編集中のファイルをcompilation unitに追加、追加前に /** に対応する */ をカーソルの直後に追加した状態でcompilation unitに追加することで、/** 以下のコードがコメントアウトされないようにしてるのが可愛いポイント
  • unitから取得したASTをtraverse、記入中の /** 以下で一番近いメソッド/クラス定義を補完対象とする。
  • scalacのsymbol APIを使って対応するメソッドをすべて取得して completion result をいい感じに生成して返す。

細かい部分の気遣いもよくやってる

  • clientSnippet対応してないクライアントでもインデントがちゃんと揃うように
  • return type が Unit なら @return は追加しない。
  • def foo[T: Ordering](t: T) とかの場合、parse時に (implicit evidence$0: Ordering[T]) みたいなparamが暗黙的に追加されるのを取り除く
    • 本来は evidence$0 には SYNTHETIC flag がついてるはずなのだけれど、parse phase -> typer phase の段階でsynthetic flagが消滅するっぽいことをscalacのコードを読んで調べる。
    • コメントにworkaroundですよって書いておく。scalac側にissue立てようと思ってるけどそんなに直すモチベーションは少ない...

scalameta/sbt-scalafmt #78 Implement error method with an additinal error message and cause

  • sbt-scalafmtが一部条件でエラーメッセージを握りつぶしていて、バグ修正しようにもなんのヒントもない状態だったので、エラーメッセージを握りつぶさないようにする。
  • sbt-scalafmt 2.3.1 リリースした後 sonatype から jar 取得できるようになるまでに2日くらいかかったんだけどなんか障害でもあった?

scalameta/scalafmt #1656 Enable to download and run snapshot version from dynamic

  • レビューしてたら、 2.2.2-SNAPSHOT みたいなscalafmtをローカル環境で実行できないことに気づいたので修正
  • 雑なregexでscalafmtのバージョンパースしてるけど意外とうまくいってる