Prettierにコントリビュートした(2)
またPrettierにPRを投げたらマージされました。
解決したIssue
https://github.com/prettier/prettier/issues/6111
ある型の配列の型を定義したときに、余分なカッコが含まれていると必要なカッコまでフォーマットするときに省いてしまって意味が変わってしまうというバグです。
下のようなコードがあるとします。2つの型でカッコの数は違いますが、意味は同じです。
type T1 = (keyof G)[];
type T2 = ((keyof G))[];
このコードをPrettierでフォーマットすると、次のようになります。
type T1 = (keyof G)[];
type T2 = keyof G[];
余分なカッコを除去する際に必要なカッコまで除去してしまい、T2の意味が、「Gのkeyofの配列」から「G型の配列のkeyof」に変わっています。
出したPR
https://github.com/prettier/prettier/pull/6131
前回に引き続き今回も僕のした実装上の変更は1ファイルのみで、他はテストとチェンジログです。
ESTreeをDocに変換するときの処理は主にprinter-estree.jsというファイル内に書かれていますが、ノードに対してカッコが必要かどうかを判断する処理はneeds-parens.jsというファイルに分かれています。
今までカッコで囲まれたノードがあったときに、そのノードの子がカッコで囲まれたノードだったらneeds-parensはfalseを返していました(つまりカッコを除去する)。今回の変更では、子ノードがカッコで囲まれていても、自分の親が配列だったらカッコを維持するように修正しました。
感想
PrettierにPRを投げるのはこれで2つめですが、実は僕はPrettierのアルゴリズムをちゃんと理解しているわけではありません。論文(?)の方にも目を通しておかないとですね。
あとESTreeの形もあんまり把握できていないのでそのあたりも。
