(classText: string, name: string)
| 219 | } |
| 220 | |
| 221 | function syncFacadeSourceCtor(classText: string, name: string): string { |
| 222 | const n = escapeRe(name) |
| 223 | const re = new RegExp( |
| 224 | `((?:[A-Za-z_$][\\w$]*\\.)?)(?:Opaque|OpaqueType|OpaqueShape)<\\s*(?:${n}|_${n})(?:\\.Type)?\\s*(?:,\\s*(?:${n}|_${n})\\.Encoded(?:\\s*,\\s*(?:${n}|_${n})\\.Make)?)?\\s*>`, |
| 225 | "g" |
| 226 | ) |
| 227 | const rewritten = classText.replace(re, `$1Opaque<_${name}>`) |
| 228 | // The body moves onto the private `_X`, but the public facade `X` is declared |
| 229 | // AFTER it. Member-access self-references (`X.fields`, `X.someStatic`) would be |
| 230 | // use-before-declaration, so point them at `_X` (structurally equivalent, declared |
| 231 | // first). Keep namespace TYPE members (`X.Encoded`/`Make`/`Type`/services) on `X`. |
| 232 | // NOTE: only the `X.` (member-access) form is rewritten — a bare `\bX\b` rewrite |
| 233 | // would also corrupt `TaggedStruct("X")` tag strings. Bare value self-refs |
| 234 | // (`S.decodeTo(X, ...)`) in a static body are rare; such models stay standard. |
| 235 | const selfValueRef = new RegExp( |
| 236 | `\\b${n}\\.(?!(?:Encoded|Make|Type|DecodingServices|EncodingServices)\\b)`, |
| 237 | "g" |
| 238 | ) |
| 239 | return rewritten.replace(selfValueRef, `_${name}.`) |
| 240 | } |
| 241 | |
| 242 | function facadeClassLine(name: string, prefix: string): string { |
| 243 | return `export class ${name} extends ${prefix}OpaqueFacade<${name}, ${name}.Encoded, ${name}.Make, ${name}.DecodingServices, ${name}.EncodingServices>()(_${name}) {}` |
no test coverage detected
searching dependent graphs…