Conversation
| let base = self.path.absoluteURL.standardized.pathComponents | ||
| let full = path.absoluteURL.standardized.pathComponents | ||
|
|
||
| guard full.starts(with: base) else { |
There was a problem hiding this comment.
もしパスの冒頭部分がエイリアスに一致していたら、以下で置き換える
|
|
||
| public var entries: [Entry] | ||
|
|
||
| public func mapToAlias(path: URL) -> (path: URL, updated: Bool) { |
There was a problem hiding this comment.
パスに対して登録エントリを順番に試してマッチしたら変換したものを返す
| } | ||
| } | ||
|
|
||
| public var entries: [Entry] |
There was a problem hiding this comment.
一般的にはエイリアス名を実パスに置き換える辞書として表現されるが、
ここではその順方向の解決はしない
また、逆変換にしても foo -> /foo, bar -> /foo/bar みたいな重複のある定義の場合に、
処理結果を安定させるため配列にしている
|
|
||
| var file = file | ||
| let (newPath, updated) = pathAliasTable.mapToAlias( | ||
| path: from.deletingLastPathComponent().appendingPathComponent(file) |
There was a problem hiding this comment.
1次生成されたimport文を、もう一回このファイルを起点にフルパスに戻して、それをエイリアスの逆変換にかけてみる
There was a problem hiding this comment.
Nodeとかのエイリアスって、パスの冒頭が一致しておらずともエイリアスから../で親を辿って解決させる方法があるため、常にエイリアスから変換可能だと思うんですよね。
例えば@が/srcにマップされている場合、
/src/foo/A.tsにある以下の記述は、
import B from "./B.ts"は
import B from "@/foo/B.ts"と変換でき、これは直感的ですが
/gen/bar/A.tsにある以下の記述は、
import B from "./B.ts"は
import B from "@/../gen/foo/B.ts"と変換できます。
現在の構造はエイリアスが複数存在できてそのうちのどれか1つが変換できるかも、というインターフェースをしていますが、実際はすべて変換に成功するはずです。
エイリアスごとの優先度の概念は本来存在しえないため、複数のエイリアスを登録できるPathAliasTableは不自然な構造に感じます。
実用的な部分だけ考えると../を禁止してしまっても問題なさそうですが、TypeScriptASTに関してはなるべくTSの仕様に忠実であるべきだと思ったので、違う形のほうが良いと思いました。
buildAutoImportDeclsに関しては今のPathAliasTable.Entry相当の構造体を1つだけ受け取る形式の方が良いかも?
| public var alias: String | ||
| public var path: URL | ||
|
|
||
| public func mapToAlias(path: URL) -> (path: URL, updated: Bool) { |
There was a problem hiding this comment.
気持ち的な話ですがこの程度の内容なら単にURL?を返すだけの方がシンプルに感じました。
何も起きなかった場合に引数のpathがそのまま返ってくる保証はなくて、利用側に少し混乱を与えそうです
There was a problem hiding this comment.
何も起きなかった場合に引数のpathがそのまま返ってくる保証はなく
確かに optional だとそれが表現できますね。
更新されていようがいまいが、処理した値をそのまま使えるのが便利かと思ったんですが、
結果的に利用側でそういう書き方をしてないし、利用側でやることか。
見直します。
import B from "@/../gen/foo/B.ts"確かに論理的にはこれが可能なのはそうですね。
やりたいことが 実際の用途も逆引きですしね。
外向きの特殊な参照ディレクトリが2つ以上ある場合もあるのでN個なインターフェースにはしたいです。 やりたいことがパスプレフィックスの置き換えに過ぎないので、
|
|
確かに名前で解決しそうな話ではありますね。 |
| } | ||
|
|
||
| public var path: URL | ||
| public var replacement: String |
There was a problem hiding this comment.
変換元は解決された実際のパスを見ています。
変換先は @src のような特殊な表記を考慮して単なる文字列です。
|
@sidepelican 単にパスの先頭部分を特定の文字列に置き換えるということで PathPrefixReplacement という型を導入し、インターフェースをそれに寄せました。 |
sidepelican
left a comment
There was a problem hiding this comment.
機能と命名がうまく対応して良くなったと思います
|
確認ありがとうございました |
インポート文を生成するときに、設定があればエイリアスを使った表記を出力できるようにします。
背景
tsconfig.jsonのpathsの設定や、vitejs のresolve.aliasのように、特定のパスのプレフィックスを特定のシンボルに置き換えることがあります。
そのようなビルド環境のプロジェクトにおいては、
自動生成するコードのimport文で、
特定のファイルについてはこのエイリアスを使った表記で出力したいことがあります。
特に、Swift Build Pluginを使用する都合などにより、
自動生成するコードがnpmパッケージから離れた場所に出力される場合、
npmパッケージ側からはこれをシンボリックリンクを辿って参照させれば良くとも、
生成コード側からnpmパッケージ側を参照させる方向の対応は、
エイリアス機能を使わないと困難です。
利用側
最終的にはこのパッチを以下のようにCodableToTypeScriptにおいてAPIとして提供する想定です。
omochi/CodableToTypeScript#131