* Build the list of class-level decorator scopes, sorted by position. Each * scope runs from its decorator up to the next class decorator (of any kind), * which lets a method decorator find its enclosing class regardless of how * many classes share a file.
(safe: string)
| 427 | * many classes share a file. |
| 428 | */ |
| 429 | function buildClassScopes(safe: string): ClassScope[] { |
| 430 | const defs: Array<{ kind: ClassKind; name: string; prefixOf: (a: string) => string }> = [ |
| 431 | { kind: 'controller', name: 'Controller', prefixOf: parseControllerPrefix }, |
| 432 | { kind: 'resolver', name: 'Resolver', prefixOf: () => '' }, |
| 433 | { kind: 'gateway', name: 'WebSocketGateway', prefixOf: parseGatewayNamespace }, |
| 434 | { kind: 'other', name: 'Injectable', prefixOf: () => '' }, |
| 435 | { kind: 'other', name: 'Module', prefixOf: () => '' }, |
| 436 | { kind: 'other', name: 'Catch', prefixOf: () => '' }, |
| 437 | ]; |
| 438 | |
| 439 | const raw: Array<{ kind: ClassKind; prefix: string; index: number }> = []; |
| 440 | for (const def of defs) { |
| 441 | for (const hit of findDecorators(safe, [def.name])) { |
| 442 | raw.push({ kind: def.kind, prefix: def.prefixOf(hit.args), index: hit.index }); |
| 443 | } |
| 444 | } |
| 445 | raw.sort((a, b) => a.index - b.index); |
| 446 | |
| 447 | return raw.map((r, i) => ({ |
| 448 | kind: r.kind, |
| 449 | prefix: r.prefix, |
| 450 | start: r.index, |
| 451 | end: i + 1 < raw.length ? raw[i + 1]!.index : safe.length, |
| 452 | })); |
| 453 | } |
| 454 | |
| 455 | function scopeFor(scopes: ClassScope[], index: number): ClassScope | null { |
| 456 | for (const s of scopes) { |
no test coverage detected