-
Notifications
You must be signed in to change notification settings - Fork 1
自動生成する変数名が既存の名前と衝突しないようにする #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| return name | ||
| } | ||
| i += 1 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2から始めて衝突しなくなるまでインクリメントし続ける。
| .callDecodeField(json: expr) | ||
|
|
||
| let varName = nameProvider.provide(base: TSKeyword.escaped(label)) | ||
| names[label] = varName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
用意された名前は後で参照する時のために辞書に入れておく
| ) throws -> TSObjectExpr { | ||
| return TSObjectExpr(try caseElement.associatedValues.map { (value) in | ||
| let label = value.codableLabel | ||
| let varName = try names[label].unwrap(name: "var name") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
用意した名前を辞書から引く。
エスケープ済みの名前を格納してるので利用側のエスケープ処理が不要になっている。
| ) | ||
| ) | ||
| block.append(j) | ||
| nameProvider.register(name: "j") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enumについては e や j という変数も使用するが、
これとも衝突しないように利用済みの名前を追記しておく
| guard let decl = try converter.decodeSignature() else { return nil } | ||
|
|
||
| var nameProvider = NameProvider() | ||
| nameProvider.register(signature: decl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数の仮引数名を登録しておく。
これは関数の実装部全体で有効なのでこのnameProviderをこの先で引き継ぐが、
ローカルスコープ同士の間では名前の衝突は起きない。
そこはうまく局所的な生成関数に nameProvider をコピー渡しすることで、隣のスコープ同士が影響しないようにしつつ、関数仮引数という上流のスコープの影響は引き継がせる。
トランスパイルするSwiftの型が
var entityのようなプロパティを持っていると、コード生成するときにJSの関数の引数の
entityと、プロパティに対応して生成されるローカル変数の
const entityが衝突して、TypeScriptとしてコンパイル不可能になってしまう。
このパッチはこの問題を回避する。
ローカル変数を生成するときに既存の名前として使用済みかどうかを調べて、
使用済みであれば代わりに連番をつけた名前を使用する。