@travetto/transformer 8.0.0-alpha.9 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -34
- package/__index__.ts +16 -10
- package/package.json +14 -14
- package/src/importer.ts +40 -39
- package/src/manager.ts +9 -7
- package/src/register.ts +10 -4
- package/src/resolver/builder.ts +127 -66
- package/src/resolver/cache.ts +1 -0
- package/src/resolver/coerce.ts +12 -10
- package/src/resolver/service.ts +26 -19
- package/src/resolver/types.ts +17 -4
- package/src/state.ts +49 -36
- package/src/types/shared.ts +3 -3
- package/src/types/visitor.ts +13 -3
- package/src/util/core.ts +21 -16
- package/src/util/declaration.ts +69 -11
- package/src/util/decorator.ts +2 -2
- package/src/util/doc.ts +12 -11
- package/src/util/import.ts +2 -2
- package/src/util/literal.ts +11 -10
- package/src/util/log.ts +23 -5
- package/src/util/system.ts +2 -4
- package/src/visitor.ts +48 -48
package/README.md
CHANGED
|
@@ -15,15 +15,15 @@ yarn add @travetto/transformer
|
|
|
15
15
|
|
|
16
16
|
This module provides support for enhanced AST transformations, and declarative transformer registration, with common patterns to support all the transformers used throughout the framework. Transformations are located by `support/transformer.<name>.ts` as the filename.
|
|
17
17
|
|
|
18
|
-
The module is primarily aimed at extremely advanced usages for things that cannot be detected at runtime.
|
|
18
|
+
The module is primarily aimed at extremely advanced usages for things that cannot be detected at runtime. The [Registry](https://github.com/travetto/travetto/tree/main/module/registry#readme "Patterns and utilities for handling registration of metadata and functionality for run-time use") module already has knowledge of all `class`es and `field`s, and is able to listen to changes there. Many of the modules build upon work by some of the foundational transformers defined in [Manifest](https://github.com/travetto/travetto/tree/main/module/manifest#readme "Support for project indexing, manifesting, along with file watching"), [Registry](https://github.com/travetto/travetto/tree/main/module/registry#readme "Patterns and utilities for handling registration of metadata and functionality for run-time use"), [Schema](https://github.com/travetto/travetto/tree/main/module/schema#readme "Data type registry for runtime validation, reflection and binding.") and [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support."). These all center around defining a registry of classes, and associated type information.
|
|
19
19
|
|
|
20
20
|
Because working with the [Typescript](https://typescriptlang.org) API can be delicate (and open to breaking changes), creating new transformers should be done cautiously.
|
|
21
21
|
|
|
22
22
|
## Monorepos and Idempotency
|
|
23
|
-
Within the framework, any build or compile step will target the entire workspace, and for mono-repo projects, will include all modules.
|
|
23
|
+
Within the framework, any build or compile step will target the entire workspace, and for mono-repo projects, will include all modules. The optimization this provides is great, but comes with a strict requirement that all compilation processes need to be idempotent. This means that compiling a module directly, versus as a dependency should always produce the same output. This produces a requirement that all transformers are opt-in by the source code, and which transformers are needed in a file should be code-evident. This also means that no transformers are optional, as that could produce different output depending on the dependency graph for a given module.
|
|
24
24
|
|
|
25
25
|
## Custom Transformer
|
|
26
|
-
Below is an example of a transformer that upper cases all `class`, `method` and `param` declarations.
|
|
26
|
+
Below is an example of a transformer that upper cases all `class`, `method` and `param` declarations. This will break any code that depends upon it as we are redefining all the identifiers at compile time.
|
|
27
27
|
|
|
28
28
|
**Code: Sample Transformer - Upper case all declarations**
|
|
29
29
|
```typescript
|
|
@@ -32,7 +32,6 @@ import type ts from 'typescript';
|
|
|
32
32
|
import { TransformerHandler, type TransformerState } from '@travetto/transformer';
|
|
33
33
|
|
|
34
34
|
export class MakeUpper {
|
|
35
|
-
|
|
36
35
|
static isValid(state: TransformerState): boolean {
|
|
37
36
|
return state.importName !== '@travetto/transformer/doc/upper.ts';
|
|
38
37
|
}
|
|
@@ -44,39 +43,45 @@ export class MakeUpper {
|
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
static handleProperty(state: TransformerState, node: ts.PropertyDeclaration): ts.PropertyDeclaration {
|
|
47
|
-
return !this.isValid(state)
|
|
48
|
-
node
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
return !this.isValid(state)
|
|
47
|
+
? node
|
|
48
|
+
: state.factory.updatePropertyDeclaration(
|
|
49
|
+
node,
|
|
50
|
+
node.modifiers,
|
|
51
|
+
node.name.getText().toUpperCase(),
|
|
52
|
+
undefined,
|
|
53
|
+
node.type,
|
|
54
|
+
node.initializer ?? state.createIdentifier('undefined')
|
|
55
|
+
);
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
static handleClass(state: TransformerState, node: ts.ClassDeclaration): ts.ClassDeclaration {
|
|
58
|
-
return !this.isValid(state)
|
|
59
|
-
node
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
return !this.isValid(state)
|
|
60
|
+
? node
|
|
61
|
+
: state.factory.updateClassDeclaration(
|
|
62
|
+
node,
|
|
63
|
+
node.modifiers,
|
|
64
|
+
state.createIdentifier(node.name!.getText().toUpperCase()),
|
|
65
|
+
node.typeParameters,
|
|
66
|
+
node.heritageClauses,
|
|
67
|
+
node.members
|
|
68
|
+
);
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
static handleMethod(state: TransformerState, node: ts.MethodDeclaration): ts.MethodDeclaration {
|
|
69
|
-
return !this.isValid(state)
|
|
70
|
-
node
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
return !this.isValid(state)
|
|
73
|
+
? node
|
|
74
|
+
: state.factory.updateMethodDeclaration(
|
|
75
|
+
node,
|
|
76
|
+
node.modifiers,
|
|
77
|
+
undefined,
|
|
78
|
+
state.createIdentifier(node.name.getText().toUpperCase()),
|
|
79
|
+
undefined,
|
|
80
|
+
node.typeParameters,
|
|
81
|
+
node.parameters,
|
|
82
|
+
node.type,
|
|
83
|
+
node.body
|
|
84
|
+
);
|
|
80
85
|
}
|
|
81
86
|
}
|
|
82
87
|
```
|
|
@@ -91,7 +96,7 @@ export class Test {
|
|
|
91
96
|
dob: Date;
|
|
92
97
|
|
|
93
98
|
computeAge(): void {
|
|
94
|
-
this
|
|
99
|
+
this.age = Date.now() - this.dob.getTime();
|
|
95
100
|
}
|
|
96
101
|
}
|
|
97
102
|
```
|
|
@@ -101,12 +106,12 @@ export class Test {
|
|
|
101
106
|
import * as Δfunction from "@travetto/runtime/src/function.js";
|
|
102
107
|
const Δm_1 = ["@travetto/transformer", "doc/upper.ts"];
|
|
103
108
|
export class TEST {
|
|
104
|
-
static { Δfunction.registerFunction(TEST, Δm_1, { hash:
|
|
109
|
+
static { Δfunction.registerFunction(TEST, Δm_1, { hash: 2002713074, lines: [1, 9] }, { COMPUTEAGE: { hash: 731903366, lines: [6, 8, 7] } }, false); }
|
|
105
110
|
NAME;
|
|
106
111
|
AGE;
|
|
107
112
|
DOB;
|
|
108
113
|
COMPUTEAGE() {
|
|
109
|
-
this
|
|
114
|
+
this.AGE = Date.now() - this.DOB.getTime();
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
117
|
```
|
package/__index__.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
export * from './src/
|
|
2
|
-
export * from './src/visitor.ts';
|
|
1
|
+
export * from './src/manager.ts';
|
|
3
2
|
export * from './src/register.ts';
|
|
4
|
-
export
|
|
3
|
+
export type {
|
|
4
|
+
AnyType,
|
|
5
|
+
CompositionType,
|
|
6
|
+
ForeignType,
|
|
7
|
+
LiteralType,
|
|
8
|
+
ManagedType,
|
|
9
|
+
PointerType,
|
|
10
|
+
ShapeType,
|
|
11
|
+
TemplateType,
|
|
12
|
+
TupleType,
|
|
13
|
+
UnknownType
|
|
14
|
+
} from './src/resolver/types.ts';
|
|
15
|
+
export * from './src/state.ts';
|
|
5
16
|
export * from './src/types/shared.ts';
|
|
6
|
-
export * from './src/
|
|
7
|
-
|
|
17
|
+
export * from './src/types/visitor.ts';
|
|
8
18
|
export * from './src/util/core.ts';
|
|
9
19
|
export * from './src/util/declaration.ts';
|
|
10
20
|
export * from './src/util/decorator.ts';
|
|
@@ -12,8 +22,4 @@ export * from './src/util/doc.ts';
|
|
|
12
22
|
export * from './src/util/literal.ts';
|
|
13
23
|
export * from './src/util/log.ts';
|
|
14
24
|
export * from './src/util/system.ts';
|
|
15
|
-
|
|
16
|
-
export type {
|
|
17
|
-
AnyType, ForeignType, ManagedType, PointerType, LiteralType, ShapeType,
|
|
18
|
-
CompositionType, TupleType, UnknownType, TemplateType
|
|
19
|
-
} from './src/resolver/types.ts';
|
|
25
|
+
export * from './src/visitor.ts';
|
package/package.json
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/transformer",
|
|
3
|
-
"version": "8.0.
|
|
4
|
-
"type": "module",
|
|
3
|
+
"version": "8.0.1",
|
|
5
4
|
"description": "Functionality for AST transformations, with transformer registration, and general utils",
|
|
6
5
|
"keywords": [
|
|
7
|
-
"typescript",
|
|
8
6
|
"ast-transformations",
|
|
9
|
-
"travetto"
|
|
7
|
+
"travetto",
|
|
8
|
+
"typescript"
|
|
10
9
|
],
|
|
11
10
|
"homepage": "https://travetto.io",
|
|
12
11
|
"license": "MIT",
|
|
13
12
|
"author": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
13
|
+
"name": "Travetto Framework",
|
|
14
|
+
"email": "travetto.framework@gmail.com"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"url": "git+https://github.com/travetto/travetto.git",
|
|
18
|
+
"directory": "module/transformer"
|
|
16
19
|
},
|
|
17
20
|
"files": [
|
|
18
21
|
"__index__.ts",
|
|
19
22
|
"src",
|
|
20
23
|
"support"
|
|
21
24
|
],
|
|
25
|
+
"type": "module",
|
|
22
26
|
"main": "__index__.ts",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"directory": "module/transformer"
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
26
29
|
},
|
|
27
30
|
"dependencies": {
|
|
28
|
-
"@travetto/manifest": "^8.0.
|
|
31
|
+
"@travetto/manifest": "^8.0.1",
|
|
29
32
|
"tslib": "^2.8.1",
|
|
30
|
-
"typescript": "^6.0.
|
|
33
|
+
"typescript": "^6.0.3"
|
|
31
34
|
},
|
|
32
35
|
"travetto": {
|
|
33
36
|
"displayName": "Transformation",
|
|
34
37
|
"roles": [
|
|
35
38
|
"compile"
|
|
36
39
|
]
|
|
37
|
-
},
|
|
38
|
-
"publishConfig": {
|
|
39
|
-
"access": "public"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/importer.ts
CHANGED
|
@@ -2,12 +2,12 @@ import ts from 'typescript';
|
|
|
2
2
|
|
|
3
3
|
import { ManifestModuleUtil, PackageUtil, path } from '@travetto/manifest';
|
|
4
4
|
|
|
5
|
-
import type { AnyType,
|
|
6
|
-
import { ImportUtil } from './util/import.ts';
|
|
7
|
-
import { CoreUtil } from './util/core.ts';
|
|
5
|
+
import type { AnyType, ManagedType, MappedType, TransformResolver } from './resolver/types.ts';
|
|
8
6
|
import type { Import } from './types/shared.ts';
|
|
9
|
-
import {
|
|
7
|
+
import { CoreUtil } from './util/core.ts';
|
|
10
8
|
import { DeclarationUtil } from './util/declaration.ts';
|
|
9
|
+
import { ImportUtil } from './util/import.ts';
|
|
10
|
+
import { LiteralUtil } from './util/literal.ts';
|
|
11
11
|
|
|
12
12
|
const D_OR_D_TS_EXT_REGEX = /[.]d([.]ts)?$/;
|
|
13
13
|
|
|
@@ -15,7 +15,6 @@ const D_OR_D_TS_EXT_REGEX = /[.]d([.]ts)?$/;
|
|
|
15
15
|
* Manages imports within a ts.SourceFile
|
|
16
16
|
*/
|
|
17
17
|
export class ImportManager {
|
|
18
|
-
|
|
19
18
|
#newImports = new Map<string, Import>();
|
|
20
19
|
#imports: Map<string, Import>;
|
|
21
20
|
#idx: Record<string, number> = {};
|
|
@@ -51,19 +50,13 @@ export class ImportManager {
|
|
|
51
50
|
const type = this.#resolver.getType(element.name);
|
|
52
51
|
const objFlags = DeclarationUtil.getObjectFlags(type);
|
|
53
52
|
const typeFlags = type.getFlags();
|
|
54
|
-
// eslint-disable-next-line no-bitwise
|
|
55
53
|
if (!(objFlags & (ts.SymbolFlags.Type | ts.SymbolFlags.Interface)) || !(typeFlags & ts.TypeFlags.Any)) {
|
|
56
54
|
newBindings.push(element);
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
}
|
|
60
58
|
if (newBindings.length !== bindings.elements.length) {
|
|
61
|
-
return this.factory.updateImportClause(
|
|
62
|
-
clause,
|
|
63
|
-
clause.isTypeOnly,
|
|
64
|
-
clause.name,
|
|
65
|
-
this.factory.createNamedImports(newBindings)
|
|
66
|
-
);
|
|
59
|
+
return this.factory.updateImportClause(clause, clause.isTypeOnly, clause.name, this.factory.createNamedImports(newBindings));
|
|
67
60
|
} else {
|
|
68
61
|
return clause;
|
|
69
62
|
}
|
|
@@ -82,9 +75,7 @@ export class ImportManager {
|
|
|
82
75
|
}
|
|
83
76
|
}
|
|
84
77
|
|
|
85
|
-
return fileOrImport ?
|
|
86
|
-
(fileOrImport.startsWith('.') || this.#resolver.isKnownFile(fileOrImport)) :
|
|
87
|
-
false;
|
|
78
|
+
return fileOrImport ? fileOrImport.startsWith('.') || this.#resolver.isKnownFile(fileOrImport) : false;
|
|
88
79
|
}
|
|
89
80
|
|
|
90
81
|
/**
|
|
@@ -96,10 +87,8 @@ export class ImportManager {
|
|
|
96
87
|
|
|
97
88
|
const type = ManifestModuleUtil.getFileType(specText);
|
|
98
89
|
if (type === 'js' || type === 'ts') {
|
|
99
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
100
90
|
return LiteralUtil.fromLiteral(this.factory, ManifestModuleUtil.withOutputExtension(specText)) as unknown as T;
|
|
101
91
|
} else {
|
|
102
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
103
92
|
return LiteralUtil.fromLiteral(this.factory, `${specText}${ManifestModuleUtil.OUTPUT_EXT}`) as unknown as T;
|
|
104
93
|
}
|
|
105
94
|
}
|
|
@@ -115,7 +104,7 @@ export class ImportManager {
|
|
|
115
104
|
return this.factory.createIdentifier(name);
|
|
116
105
|
} else {
|
|
117
106
|
const key = path.basename(file, path.extname(file)).replace(/\W+/g, '_');
|
|
118
|
-
const suffix = this.#idx[key] = (this.#idx[key] ?? -1) + 1;
|
|
107
|
+
const suffix = (this.#idx[key] = (this.#idx[key] ?? -1) + 1);
|
|
119
108
|
return this.factory.createIdentifier(`Δ${key}${suffix ? suffix : ''}`);
|
|
120
109
|
}
|
|
121
110
|
});
|
|
@@ -140,7 +129,8 @@ export class ImportManager {
|
|
|
140
129
|
const identifier = this.getIdentifier(file, name);
|
|
141
130
|
const uniqueName = identifier.text;
|
|
142
131
|
|
|
143
|
-
if (this.#imports.has(uniqueName)) {
|
|
132
|
+
if (this.#imports.has(uniqueName)) {
|
|
133
|
+
// Already imported, be cool
|
|
144
134
|
return this.#imports.get(uniqueName)!;
|
|
145
135
|
}
|
|
146
136
|
|
|
@@ -161,10 +151,16 @@ export class ImportManager {
|
|
|
161
151
|
}
|
|
162
152
|
switch (type.key) {
|
|
163
153
|
case 'managed':
|
|
164
|
-
case 'literal':
|
|
154
|
+
case 'literal':
|
|
155
|
+
this.importFromResolved(...(type.typeArguments || []));
|
|
156
|
+
break;
|
|
165
157
|
case 'composition':
|
|
166
|
-
case 'tuple':
|
|
167
|
-
|
|
158
|
+
case 'tuple':
|
|
159
|
+
this.importFromResolved(...(type.subTypes || []));
|
|
160
|
+
break;
|
|
161
|
+
case 'shape':
|
|
162
|
+
this.importFromResolved(...Object.values(type.fieldTypes));
|
|
163
|
+
break;
|
|
168
164
|
}
|
|
169
165
|
}
|
|
170
166
|
}
|
|
@@ -191,7 +187,8 @@ export class ImportManager {
|
|
|
191
187
|
...importStmts,
|
|
192
188
|
...file.statements.filter((node: ts.Statement & { remove?: boolean }) => !node.remove) // Exclude culled imports
|
|
193
189
|
]);
|
|
194
|
-
} catch (error) {
|
|
190
|
+
} catch (error) {
|
|
191
|
+
// Missing import
|
|
195
192
|
if (!(error instanceof Error)) {
|
|
196
193
|
throw error;
|
|
197
194
|
}
|
|
@@ -207,24 +204,28 @@ export class ImportManager {
|
|
|
207
204
|
for (const statement of source.statements) {
|
|
208
205
|
if (ts.isExportDeclaration(statement)) {
|
|
209
206
|
if (!statement.isTypeOnly) {
|
|
210
|
-
toAdd.push(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
207
|
+
toAdd.push(
|
|
208
|
+
this.factory.updateExportDeclaration(
|
|
209
|
+
statement,
|
|
210
|
+
statement.modifiers,
|
|
211
|
+
statement.isTypeOnly,
|
|
212
|
+
statement.exportClause,
|
|
213
|
+
this.normalizeModuleSpecifier(statement.moduleSpecifier),
|
|
214
|
+
statement.attributes
|
|
215
|
+
)
|
|
216
|
+
);
|
|
218
217
|
}
|
|
219
218
|
} else if (ts.isImportDeclaration(statement)) {
|
|
220
219
|
if (statement.importClause?.phaseModifier !== ts.SyntaxKind.TypeKeyword) {
|
|
221
|
-
toAdd.push(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
220
|
+
toAdd.push(
|
|
221
|
+
this.factory.updateImportDeclaration(
|
|
222
|
+
statement,
|
|
223
|
+
statement.modifiers,
|
|
224
|
+
this.#rewriteImportClause(statement.moduleSpecifier, statement.importClause)!,
|
|
225
|
+
this.normalizeModuleSpecifier(statement.moduleSpecifier)!,
|
|
226
|
+
statement.attributes
|
|
227
|
+
)
|
|
228
|
+
);
|
|
228
229
|
}
|
|
229
230
|
} else {
|
|
230
231
|
toAdd.push(statement);
|
|
@@ -255,4 +256,4 @@ export class ImportManager {
|
|
|
255
256
|
return factory.createPropertyAccessExpression(identifier, targetName);
|
|
256
257
|
}
|
|
257
258
|
}
|
|
258
|
-
}
|
|
259
|
+
}
|
package/src/manager.ts
CHANGED
|
@@ -2,16 +2,15 @@ import type ts from 'typescript';
|
|
|
2
2
|
|
|
3
3
|
import type { ManifestIndex } from '@travetto/manifest';
|
|
4
4
|
|
|
5
|
+
import { getAllTransformers } from './register.ts';
|
|
6
|
+
import { TransformerState } from './state.ts';
|
|
5
7
|
import type { NodeTransformer } from './types/visitor.ts';
|
|
6
8
|
import { VisitorFactory } from './visitor.ts';
|
|
7
|
-
import { TransformerState } from './state.ts';
|
|
8
|
-
import { getAllTransformers } from './register.ts';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Manages the typescript transformers
|
|
12
12
|
*/
|
|
13
13
|
export class TransformerManager {
|
|
14
|
-
|
|
15
14
|
/**
|
|
16
15
|
* Create transformer manager
|
|
17
16
|
* @param transformerFiles
|
|
@@ -23,16 +22,19 @@ export class TransformerManager {
|
|
|
23
22
|
|
|
24
23
|
const transformers: NodeTransformer<TransformerState>[] = [];
|
|
25
24
|
|
|
26
|
-
for (const file of transformerFiles) {
|
|
25
|
+
for (const file of transformerFiles) {
|
|
26
|
+
// Exclude based on blacklist
|
|
27
27
|
const entry = manifestIndex.getEntry(file)!;
|
|
28
28
|
transformers.push(...getAllTransformers(await import(entry.import), entry.module));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
for (const transformer of transformers) {
|
|
32
32
|
process.send?.({
|
|
33
|
-
type: 'log',
|
|
33
|
+
type: 'log',
|
|
34
|
+
payload: {
|
|
34
35
|
level: 'debug',
|
|
35
|
-
message: `Loaded Transformer: ${transformer.key}#${transformer.type}`,
|
|
36
|
+
message: `Loaded Transformer: ${transformer.key}#${transformer.type}`,
|
|
37
|
+
scope: 'transformers'
|
|
36
38
|
}
|
|
37
39
|
});
|
|
38
40
|
}
|
|
@@ -72,4 +74,4 @@ export class TransformerManager {
|
|
|
72
74
|
get(): ts.CustomTransformers | undefined {
|
|
73
75
|
return this.#cached!;
|
|
74
76
|
}
|
|
75
|
-
}
|
|
77
|
+
}
|
package/src/register.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type NodeTransformer, type
|
|
1
|
+
import { ModuleNameSymbol, type NodeTransformer, type Transformer, type TransformerType, type TransformPhase } from './types/visitor.ts';
|
|
2
2
|
|
|
3
3
|
const HandlersSymbol = Symbol();
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@ export function getAllTransformers(inputs: Record<string, { [HandlersSymbol]?: N
|
|
|
18
18
|
if (isTransformer(value)) {
|
|
19
19
|
value[ModuleNameSymbol] = module;
|
|
20
20
|
}
|
|
21
|
-
return
|
|
21
|
+
return value[HandlersSymbol] ?? [];
|
|
22
22
|
})
|
|
23
23
|
.map(handler => ({
|
|
24
24
|
...handler,
|
|
@@ -28,6 +28,12 @@ export function getAllTransformers(inputs: Record<string, { [HandlersSymbol]?: N
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// Store handlers in class
|
|
31
|
-
export function TransformerHandler(
|
|
31
|
+
export function TransformerHandler(
|
|
32
|
+
cls: TransformerWithHandlers,
|
|
33
|
+
fn: Function,
|
|
34
|
+
phase: TransformPhase,
|
|
35
|
+
type: TransformerType,
|
|
36
|
+
target?: string[]
|
|
37
|
+
): void {
|
|
32
38
|
(cls[HandlersSymbol] ??= []).push({ key: fn.name, [phase]: fn.bind(cls), type, target });
|
|
33
|
-
}
|
|
39
|
+
}
|