@goodie-ts/transformer 0.1.0
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/LICENSE +21 -0
- package/dist/codegen.d.ts +13 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +294 -0
- package/dist/codegen.js.map +1 -0
- package/dist/graph-builder.d.ts +14 -0
- package/dist/graph-builder.d.ts.map +1 -0
- package/dist/graph-builder.js +264 -0
- package/dist/graph-builder.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/ir.d.ts +102 -0
- package/dist/ir.d.ts.map +1 -0
- package/dist/ir.js +2 -0
- package/dist/ir.js.map +1 -0
- package/dist/options.d.ts +31 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +2 -0
- package/dist/options.js.map +1 -0
- package/dist/resolver.d.ts +14 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +299 -0
- package/dist/resolver.js.map +1 -0
- package/dist/scanner.d.ts +87 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +386 -0
- package/dist/scanner.js.map +1 -0
- package/dist/transform.d.ts +13 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/transform.js +65 -0
- package/dist/transform.js.map +1 -0
- package/dist/transformer-errors.d.ts +42 -0
- package/dist/transformer-errors.d.ts.map +1 -0
- package/dist/transformer-errors.js +81 -0
- package/dist/transformer-errors.js.map +1 -0
- package/package.json +37 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type { CodegenOptions } from './codegen.js';
|
|
2
|
+
export { generateCode } from './codegen.js';
|
|
3
|
+
export type { GraphResult } from './graph-builder.js';
|
|
4
|
+
export { buildGraph } from './graph-builder.js';
|
|
5
|
+
export type { ClassTokenRef, InjectionTokenRef, IRBeanDefinition, IRDependency, IRFieldInjection, IRModule, IRProvides, SourceLocation, TokenRef, } from './ir.js';
|
|
6
|
+
export type { TransformerPlugin, TransformOptions, TransformResult, } from './options.js';
|
|
7
|
+
export type { ResolveResult } from './resolver.js';
|
|
8
|
+
export { resolve } from './resolver.js';
|
|
9
|
+
export type { ScannedBean, ScannedConstructorParam, ScannedFieldInjection, ScannedModule, ScannedModuleImport, ScannedProvides, ScannedTypeArgument, ScanResult, } from './scanner.js';
|
|
10
|
+
export { scan } from './scanner.js';
|
|
11
|
+
export { transform, transformInMemory } from './transform.js';
|
|
12
|
+
export { AmbiguousProviderError, CircularDependencyError, GenericTypeResolutionError, InvalidDecoratorUsageError, MissingProviderError, TransformerError, UnresolvableTypeError, } from './transformer-errors.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,cAAc,EACd,QAAQ,GACT,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,YAAY,EACV,WAAW,EACX,uBAAuB,EACvB,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,UAAU,GACX,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE9D,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// @goodie-ts/transformer — Phase 2: Compile-time DI transformer
|
|
2
|
+
// Code Generator
|
|
3
|
+
export { generateCode } from './codegen.js';
|
|
4
|
+
// Graph Builder
|
|
5
|
+
export { buildGraph } from './graph-builder.js';
|
|
6
|
+
// Resolver
|
|
7
|
+
export { resolve } from './resolver.js';
|
|
8
|
+
// Scanner
|
|
9
|
+
export { scan } from './scanner.js';
|
|
10
|
+
// Pipeline
|
|
11
|
+
export { transform, transformInMemory } from './transform.js';
|
|
12
|
+
// Errors
|
|
13
|
+
export { AmbiguousProviderError, CircularDependencyError, GenericTypeResolutionError, InvalidDecoratorUsageError, MissingProviderError, TransformerError, UnresolvableTypeError, } from './transformer-errors.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAGhE,iBAAiB;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,gBAAgB;AAChB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAoBhD,WAAW;AACX,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAYxC,UAAU;AACV,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,WAAW;AACX,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,SAAS;AACT,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC"}
|
package/dist/ir.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { Scope } from '@goodie-ts/core';
|
|
2
|
+
/** Source location for error messages pointing back to user code. */
|
|
3
|
+
export interface SourceLocation {
|
|
4
|
+
filePath: string;
|
|
5
|
+
line: number;
|
|
6
|
+
column: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Reference to a bean token — either a class constructor or an InjectionToken.
|
|
10
|
+
*
|
|
11
|
+
* `kind: 'class'` → the token is the class constructor itself.
|
|
12
|
+
* `kind: 'injection-token'` → an auto-generated InjectionToken (e.g. from @Provides method name).
|
|
13
|
+
*/
|
|
14
|
+
export type TokenRef = ClassTokenRef | InjectionTokenRef;
|
|
15
|
+
export interface ClassTokenRef {
|
|
16
|
+
kind: 'class';
|
|
17
|
+
/** The class name as it appears in user code. */
|
|
18
|
+
className: string;
|
|
19
|
+
/** Absolute path to the file that exports this class. */
|
|
20
|
+
importPath: string;
|
|
21
|
+
}
|
|
22
|
+
export interface InjectionTokenRef {
|
|
23
|
+
kind: 'injection-token';
|
|
24
|
+
/** The token description / variable name (e.g. 'dbUrl'). */
|
|
25
|
+
tokenName: string;
|
|
26
|
+
/**
|
|
27
|
+
* If the token comes from a user-declared InjectionToken variable, its import path.
|
|
28
|
+
* Undefined for auto-generated method-name tokens.
|
|
29
|
+
*/
|
|
30
|
+
importPath: string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* The original return type annotation for codegen (e.g. 'Repository<User>').
|
|
33
|
+
* Used to emit typed InjectionToken<T> declarations instead of <unknown>.
|
|
34
|
+
*/
|
|
35
|
+
typeAnnotation?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Map of type name → absolute import path for types referenced in typeAnnotation.
|
|
38
|
+
* Used to emit correct type-only imports in generated code.
|
|
39
|
+
*/
|
|
40
|
+
typeImports?: Map<string, string>;
|
|
41
|
+
}
|
|
42
|
+
/** A single dependency of a bean in the IR. */
|
|
43
|
+
export interface IRDependency {
|
|
44
|
+
tokenRef: TokenRef;
|
|
45
|
+
optional: boolean;
|
|
46
|
+
sourceLocation: SourceLocation;
|
|
47
|
+
}
|
|
48
|
+
/** A field injection discovered from @Inject / @Optional on an accessor. */
|
|
49
|
+
export interface IRFieldInjection {
|
|
50
|
+
fieldName: string;
|
|
51
|
+
tokenRef: TokenRef;
|
|
52
|
+
optional: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** A @Provides method discovered inside a @Module class. */
|
|
55
|
+
export interface IRProvides {
|
|
56
|
+
methodName: string;
|
|
57
|
+
/** Token for the bean this method produces. */
|
|
58
|
+
tokenRef: TokenRef;
|
|
59
|
+
scope: Scope;
|
|
60
|
+
eager: boolean;
|
|
61
|
+
/** Dependencies of the method parameters. */
|
|
62
|
+
dependencies: IRDependency[];
|
|
63
|
+
sourceLocation: SourceLocation;
|
|
64
|
+
}
|
|
65
|
+
/** A @Module class with its @Provides methods. */
|
|
66
|
+
export interface IRModule {
|
|
67
|
+
/** The module class itself. */
|
|
68
|
+
classTokenRef: ClassTokenRef;
|
|
69
|
+
/** Imported module class refs (from @Module({ imports: [...] })). */
|
|
70
|
+
imports: ClassTokenRef[];
|
|
71
|
+
/** @Provides methods defined on this module. */
|
|
72
|
+
provides: IRProvides[];
|
|
73
|
+
sourceLocation: SourceLocation;
|
|
74
|
+
}
|
|
75
|
+
/** Full intermediate representation of a single bean. */
|
|
76
|
+
export interface IRBeanDefinition {
|
|
77
|
+
tokenRef: TokenRef;
|
|
78
|
+
scope: Scope;
|
|
79
|
+
eager: boolean;
|
|
80
|
+
/** Qualifier name from @Named(). */
|
|
81
|
+
name: string | undefined;
|
|
82
|
+
/** Constructor parameter dependencies (in order). */
|
|
83
|
+
constructorDeps: IRDependency[];
|
|
84
|
+
/** Accessor field injections (in declaration order). */
|
|
85
|
+
fieldDeps: IRFieldInjection[];
|
|
86
|
+
/**
|
|
87
|
+
* How this bean is created:
|
|
88
|
+
* - 'constructor': `new Class(dep0, dep1)`
|
|
89
|
+
* - 'provides': `module.method(dep0)` — from a @Provides method
|
|
90
|
+
*/
|
|
91
|
+
factoryKind: 'constructor' | 'provides';
|
|
92
|
+
/** For 'provides' beans: the module class and method name. */
|
|
93
|
+
providesSource: {
|
|
94
|
+
moduleTokenRef: ClassTokenRef;
|
|
95
|
+
methodName: string;
|
|
96
|
+
} | undefined;
|
|
97
|
+
metadata: Record<string, unknown>;
|
|
98
|
+
/** All ancestor class tokens (direct parent first, root last). */
|
|
99
|
+
baseTokenRefs?: ClassTokenRef[];
|
|
100
|
+
sourceLocation: SourceLocation;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=ir.d.ts.map
|
package/dist/ir.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,iBAAiB,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,iBAAiB,CAAC;IACxB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,4DAA4D;AAC5D,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,6CAA6C;IAC7C,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,kDAAkD;AAClD,MAAM,WAAW,QAAQ;IACvB,+BAA+B;IAC/B,aAAa,EAAE,aAAa,CAAC;IAC7B,qEAAqE;IACrE,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,gDAAgD;IAChD,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,oCAAoC;IACpC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,qDAAqD;IACrD,eAAe,EAAE,YAAY,EAAE,CAAC;IAChC,wDAAwD;IACxD,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B;;;;OAIG;IACH,WAAW,EAAE,aAAa,GAAG,UAAU,CAAC;IACxC,8DAA8D;IAC9D,cAAc,EACV;QAAE,cAAc,EAAE,aAAa,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACrD,SAAS,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,kEAAkE;IAClE,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;CAChC"}
|
package/dist/ir.js
ADDED
package/dist/ir.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.js","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IRBeanDefinition } from './ir.js';
|
|
2
|
+
/** Options for the compile-time transform pipeline. */
|
|
3
|
+
export interface TransformOptions {
|
|
4
|
+
/** Path to the tsconfig.json used to create the ts-morph Project. */
|
|
5
|
+
tsConfigFilePath: string;
|
|
6
|
+
/** Absolute path for the generated output file. */
|
|
7
|
+
outputPath: string;
|
|
8
|
+
/**
|
|
9
|
+
* Source file globs to scan (relative to tsconfig root).
|
|
10
|
+
* Defaults to all .ts files in the project.
|
|
11
|
+
*/
|
|
12
|
+
include?: string[];
|
|
13
|
+
}
|
|
14
|
+
/** Result returned by the transform pipeline. */
|
|
15
|
+
export interface TransformResult {
|
|
16
|
+
/** The generated source code. */
|
|
17
|
+
code: string;
|
|
18
|
+
/** Absolute path where the file was written. */
|
|
19
|
+
outputPath: string;
|
|
20
|
+
/** All discovered bean definitions in topological order. */
|
|
21
|
+
beans: IRBeanDefinition[];
|
|
22
|
+
/** Non-fatal warnings encountered during transformation. */
|
|
23
|
+
warnings: string[];
|
|
24
|
+
}
|
|
25
|
+
/** Stub for future plugin support (Phase 3+). */
|
|
26
|
+
export interface TransformerPlugin {
|
|
27
|
+
name: string;
|
|
28
|
+
beforeScan?(): void;
|
|
29
|
+
afterScan?(beans: IRBeanDefinition[]): IRBeanDefinition[];
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,IAAI,IAAI,CAAC;IACpB,SAAS,CAAC,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAAC;CAC3D"}
|
package/dist/options.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IRBeanDefinition, IRModule } from './ir.js';
|
|
2
|
+
import type { ScanResult } from './scanner.js';
|
|
3
|
+
/** Result of the resolver stage. */
|
|
4
|
+
export interface ResolveResult {
|
|
5
|
+
beans: IRBeanDefinition[];
|
|
6
|
+
modules: IRModule[];
|
|
7
|
+
warnings: string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve scanned AST information into typed IR.
|
|
11
|
+
* Converts raw type names and source files into TokenRefs.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolve(scanResult: ScanResult): ResolveResult;
|
|
14
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAGhB,QAAQ,EAIT,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAMV,UAAU,EACX,MAAM,cAAc,CAAC;AAGtB,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAkBD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAgB7D"}
|
package/dist/resolver.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { UnresolvableTypeError } from './transformer-errors.js';
|
|
2
|
+
/** Primitive types that cannot be used as constructor tokens. */
|
|
3
|
+
const PRIMITIVE_TYPES = new Set([
|
|
4
|
+
'string',
|
|
5
|
+
'number',
|
|
6
|
+
'boolean',
|
|
7
|
+
'symbol',
|
|
8
|
+
'bigint',
|
|
9
|
+
'undefined',
|
|
10
|
+
'null',
|
|
11
|
+
'void',
|
|
12
|
+
'never',
|
|
13
|
+
'any',
|
|
14
|
+
'unknown',
|
|
15
|
+
'object',
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Resolve scanned AST information into typed IR.
|
|
19
|
+
* Converts raw type names and source files into TokenRefs.
|
|
20
|
+
*/
|
|
21
|
+
export function resolve(scanResult) {
|
|
22
|
+
const warnings = [...scanResult.warnings];
|
|
23
|
+
const beans = [];
|
|
24
|
+
const modules = [];
|
|
25
|
+
// Resolve regular beans
|
|
26
|
+
for (const scanned of scanResult.beans) {
|
|
27
|
+
beans.push(resolveBean(scanned, warnings));
|
|
28
|
+
}
|
|
29
|
+
// Resolve modules
|
|
30
|
+
for (const scannedModule of scanResult.modules) {
|
|
31
|
+
modules.push(resolveModule(scannedModule, warnings));
|
|
32
|
+
}
|
|
33
|
+
return { beans, modules, warnings };
|
|
34
|
+
}
|
|
35
|
+
function resolveBean(scanned, _warnings) {
|
|
36
|
+
const constructorDeps = resolveConstructorParams(scanned.constructorParams, scanned.classTokenRef.className);
|
|
37
|
+
const fieldDeps = resolveFieldInjections(scanned.fieldInjections, scanned.classTokenRef.className);
|
|
38
|
+
const baseTokenRefs = scanned.baseClasses
|
|
39
|
+
.filter((bc) => bc.sourceFile !== undefined)
|
|
40
|
+
.map((bc) => ({
|
|
41
|
+
kind: 'class',
|
|
42
|
+
className: bc.className,
|
|
43
|
+
importPath: bc.sourceFile.getFilePath(),
|
|
44
|
+
}));
|
|
45
|
+
const metadata = {};
|
|
46
|
+
if (scanned.preDestroyMethods.length > 0) {
|
|
47
|
+
metadata.preDestroyMethods = scanned.preDestroyMethods;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
tokenRef: scanned.classTokenRef,
|
|
51
|
+
scope: scanned.scope,
|
|
52
|
+
eager: scanned.eager,
|
|
53
|
+
name: scanned.name,
|
|
54
|
+
constructorDeps,
|
|
55
|
+
fieldDeps,
|
|
56
|
+
factoryKind: 'constructor',
|
|
57
|
+
providesSource: undefined,
|
|
58
|
+
metadata,
|
|
59
|
+
baseTokenRefs: baseTokenRefs.length > 0 ? baseTokenRefs : undefined,
|
|
60
|
+
sourceLocation: scanned.sourceLocation,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function resolveModule(scannedModule, _warnings) {
|
|
64
|
+
const imports = scannedModule.imports.map((imp) => ({
|
|
65
|
+
kind: 'class',
|
|
66
|
+
className: imp.className,
|
|
67
|
+
importPath: imp.sourceFile?.getFilePath() ?? '',
|
|
68
|
+
}));
|
|
69
|
+
// Two-pass provides resolution:
|
|
70
|
+
// Pass 1: resolve return types to get each method's tokenRef + return type name
|
|
71
|
+
const providesWithTokens = scannedModule.provides.map((p) => ({
|
|
72
|
+
scanned: p,
|
|
73
|
+
tokenRef: resolveProvidesReturnType(p.returnTypeName, p.returnTypeSourceFile, p.returnTypeArguments, p.returnResolvedBaseTypeName, p.methodName, p.sourceLocation),
|
|
74
|
+
}));
|
|
75
|
+
// Build a map of return type name → provides entries for primitive param resolution
|
|
76
|
+
const providesByReturnType = new Map();
|
|
77
|
+
for (const entry of providesWithTokens) {
|
|
78
|
+
const returnTypeName = entry.scanned.returnTypeName;
|
|
79
|
+
if (returnTypeName && isPrimitiveType(returnTypeName)) {
|
|
80
|
+
const existing = providesByReturnType.get(returnTypeName) ?? [];
|
|
81
|
+
existing.push({
|
|
82
|
+
methodName: entry.scanned.methodName,
|
|
83
|
+
tokenRef: entry.tokenRef,
|
|
84
|
+
});
|
|
85
|
+
providesByReturnType.set(returnTypeName, existing);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Pass 2: resolve params, wiring primitive params to matching provides
|
|
89
|
+
const provides = providesWithTokens.map(({ scanned: p, tokenRef }) => {
|
|
90
|
+
const dependencies = resolveProvidesParams(p.params, `${scannedModule.classTokenRef.className}.${p.methodName}`, providesByReturnType);
|
|
91
|
+
return {
|
|
92
|
+
methodName: p.methodName,
|
|
93
|
+
tokenRef,
|
|
94
|
+
scope: 'singleton',
|
|
95
|
+
eager: false,
|
|
96
|
+
dependencies,
|
|
97
|
+
sourceLocation: p.sourceLocation,
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
classTokenRef: scannedModule.classTokenRef,
|
|
102
|
+
imports,
|
|
103
|
+
provides,
|
|
104
|
+
sourceLocation: scannedModule.sourceLocation,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Resolve @Provides method parameters, with special handling for primitives.
|
|
109
|
+
* Primitive-typed params are matched to other @Provides methods that return that type.
|
|
110
|
+
*/
|
|
111
|
+
function resolveProvidesParams(params, ownerName, providesByReturnType) {
|
|
112
|
+
return params.map((param) => {
|
|
113
|
+
if (!param.typeName) {
|
|
114
|
+
throw new UnresolvableTypeError(`parameter "${param.paramName}" of ${ownerName}`, param.sourceLocation);
|
|
115
|
+
}
|
|
116
|
+
// Primitive param → look up matching @Provides by return type
|
|
117
|
+
if (isPrimitiveType(param.typeName)) {
|
|
118
|
+
const candidates = providesByReturnType.get(param.typeName);
|
|
119
|
+
if (!candidates || candidates.length === 0) {
|
|
120
|
+
throw new UnresolvableTypeError(`${param.typeName} (parameter "${param.paramName}" of ${ownerName})`, param.sourceLocation);
|
|
121
|
+
}
|
|
122
|
+
if (candidates.length === 1) {
|
|
123
|
+
return {
|
|
124
|
+
tokenRef: candidates[0].tokenRef,
|
|
125
|
+
optional: false,
|
|
126
|
+
sourceLocation: param.sourceLocation,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// Multiple providers of same type → disambiguate by param name matching method name
|
|
130
|
+
const match = candidates.find((c) => c.methodName === param.paramName);
|
|
131
|
+
if (match) {
|
|
132
|
+
return {
|
|
133
|
+
tokenRef: match.tokenRef,
|
|
134
|
+
optional: false,
|
|
135
|
+
sourceLocation: param.sourceLocation,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
throw new UnresolvableTypeError(`${param.typeName} (parameter "${param.paramName}" of ${ownerName}) — multiple providers exist, use parameter name matching a @Provides method name to disambiguate`, param.sourceLocation);
|
|
139
|
+
}
|
|
140
|
+
// Non-primitive → standard resolution
|
|
141
|
+
return resolveConstructorParam(param, ownerName);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Resolve the return type of a @Provides method to a TokenRef.
|
|
146
|
+
* - Generic class types → InjectionTokenRef with canonical key
|
|
147
|
+
* - Non-generic class types → ClassTokenRef
|
|
148
|
+
* - Primitives/interfaces → InjectionTokenRef with method name
|
|
149
|
+
*/
|
|
150
|
+
function resolveProvidesReturnType(typeName, typeSourceFile, typeArguments, resolvedBaseTypeName, methodName, _sourceLocation) {
|
|
151
|
+
if (!typeName || isPrimitiveType(typeName)) {
|
|
152
|
+
// Auto-generate InjectionToken from method name
|
|
153
|
+
return {
|
|
154
|
+
kind: 'injection-token',
|
|
155
|
+
tokenName: methodName,
|
|
156
|
+
importPath: undefined,
|
|
157
|
+
typeAnnotation: typeName,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
// Generic return type → InjectionTokenRef with canonical name
|
|
161
|
+
if (typeArguments.length > 0 && resolvedBaseTypeName && typeSourceFile) {
|
|
162
|
+
const canonicalName = canonicalizeGenericType(resolvedBaseTypeName, typeArguments);
|
|
163
|
+
const typeImports = collectTypeImports(resolvedBaseTypeName, typeSourceFile, typeArguments);
|
|
164
|
+
return {
|
|
165
|
+
kind: 'injection-token',
|
|
166
|
+
tokenName: canonicalName,
|
|
167
|
+
importPath: typeSourceFile.getFilePath(),
|
|
168
|
+
typeAnnotation: canonicalName,
|
|
169
|
+
typeImports,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// If there's a source file for the type, it's a class
|
|
173
|
+
if (typeSourceFile) {
|
|
174
|
+
return {
|
|
175
|
+
kind: 'class',
|
|
176
|
+
className: resolvedBaseTypeName ?? typeName,
|
|
177
|
+
importPath: typeSourceFile.getFilePath(),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// Interface or unresolvable type → use method name as token
|
|
181
|
+
return {
|
|
182
|
+
kind: 'injection-token',
|
|
183
|
+
tokenName: methodName,
|
|
184
|
+
importPath: undefined,
|
|
185
|
+
typeAnnotation: typeName,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function resolveConstructorParams(params, ownerName) {
|
|
189
|
+
return params.map((param) => resolveConstructorParam(param, ownerName));
|
|
190
|
+
}
|
|
191
|
+
function resolveConstructorParam(param, ownerName) {
|
|
192
|
+
if (!param.typeName) {
|
|
193
|
+
throw new UnresolvableTypeError(`parameter "${param.paramName}" of ${ownerName}`, param.sourceLocation);
|
|
194
|
+
}
|
|
195
|
+
if (isPrimitiveType(param.typeName)) {
|
|
196
|
+
throw new UnresolvableTypeError(`${param.typeName} (parameter "${param.paramName}" of ${ownerName})`, param.sourceLocation);
|
|
197
|
+
}
|
|
198
|
+
const tokenRef = resolveTypeToTokenRef(param.typeName, param.typeSourceFile, param.typeArguments, param.resolvedBaseTypeName, param.sourceLocation);
|
|
199
|
+
return {
|
|
200
|
+
tokenRef,
|
|
201
|
+
optional: false,
|
|
202
|
+
sourceLocation: param.sourceLocation,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function resolveFieldInjections(fields, ownerName) {
|
|
206
|
+
return fields.map((field) => resolveFieldInjection(field, ownerName));
|
|
207
|
+
}
|
|
208
|
+
function resolveFieldInjection(field, ownerName) {
|
|
209
|
+
let tokenRef;
|
|
210
|
+
if (field.qualifier) {
|
|
211
|
+
// @Inject('name') → we'll match against @Named beans later in graph-builder
|
|
212
|
+
// For now, store as an injection-token with the qualifier as name
|
|
213
|
+
tokenRef = {
|
|
214
|
+
kind: 'injection-token',
|
|
215
|
+
tokenName: field.qualifier,
|
|
216
|
+
importPath: undefined,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
else if (field.typeName && !isPrimitiveType(field.typeName)) {
|
|
220
|
+
tokenRef = resolveTypeToTokenRef(field.typeName, field.typeSourceFile, field.typeArguments, field.resolvedBaseTypeName, field.sourceLocation);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
throw new UnresolvableTypeError(`field "${field.fieldName}" of ${ownerName}`, field.sourceLocation);
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
fieldName: field.fieldName,
|
|
227
|
+
tokenRef,
|
|
228
|
+
optional: field.optional,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function resolveTypeToTokenRef(typeName, typeSourceFile, typeArguments, resolvedBaseTypeName, _sourceLocation) {
|
|
232
|
+
// Generic type → always InjectionTokenRef with canonical key
|
|
233
|
+
if (typeArguments.length > 0 && resolvedBaseTypeName && typeSourceFile) {
|
|
234
|
+
const canonicalName = canonicalizeGenericType(resolvedBaseTypeName, typeArguments);
|
|
235
|
+
const typeImports = collectTypeImports(resolvedBaseTypeName, typeSourceFile, typeArguments);
|
|
236
|
+
return {
|
|
237
|
+
kind: 'injection-token',
|
|
238
|
+
tokenName: canonicalName,
|
|
239
|
+
importPath: typeSourceFile.getFilePath(),
|
|
240
|
+
typeAnnotation: canonicalName,
|
|
241
|
+
typeImports,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
if (typeSourceFile) {
|
|
245
|
+
return {
|
|
246
|
+
kind: 'class',
|
|
247
|
+
className: resolvedBaseTypeName ?? typeName,
|
|
248
|
+
importPath: typeSourceFile.getFilePath(),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
// No source file means we can't find the class declaration — treat as interface
|
|
252
|
+
return {
|
|
253
|
+
kind: 'injection-token',
|
|
254
|
+
tokenName: typeName,
|
|
255
|
+
importPath: undefined,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
// ── Generic type canonicalization ──
|
|
259
|
+
/**
|
|
260
|
+
* Build a canonical type name from a base name and type arguments.
|
|
261
|
+
* E.g. canonicalizeGenericType('Repository', [{typeName: 'User', ...}]) → 'Repository<User>'
|
|
262
|
+
*/
|
|
263
|
+
function canonicalizeGenericType(baseName, typeArguments) {
|
|
264
|
+
if (typeArguments.length === 0)
|
|
265
|
+
return baseName;
|
|
266
|
+
const args = typeArguments.map(canonicalizeTypeArgument).join(', ');
|
|
267
|
+
return `${baseName}<${args}>`;
|
|
268
|
+
}
|
|
269
|
+
/** Recursively canonicalize a type argument. */
|
|
270
|
+
function canonicalizeTypeArgument(arg) {
|
|
271
|
+
if (arg.typeArguments.length === 0)
|
|
272
|
+
return arg.typeName;
|
|
273
|
+
const nested = arg.typeArguments.map(canonicalizeTypeArgument).join(', ');
|
|
274
|
+
return `${arg.typeName}<${nested}>`;
|
|
275
|
+
}
|
|
276
|
+
function isPrimitiveType(typeName) {
|
|
277
|
+
return PRIMITIVE_TYPES.has(typeName);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Collect type name → import path mappings from type arguments.
|
|
281
|
+
* Walks the argument tree recursively.
|
|
282
|
+
*/
|
|
283
|
+
function collectTypeImports(baseTypeName, baseSourceFile, typeArguments) {
|
|
284
|
+
const imports = new Map();
|
|
285
|
+
if (baseTypeName && baseSourceFile) {
|
|
286
|
+
imports.set(baseTypeName, baseSourceFile.getFilePath());
|
|
287
|
+
}
|
|
288
|
+
function walk(args) {
|
|
289
|
+
for (const arg of args) {
|
|
290
|
+
if (arg.typeSourceFile) {
|
|
291
|
+
imports.set(arg.typeName, arg.typeSourceFile.getFilePath());
|
|
292
|
+
}
|
|
293
|
+
walk(arg.typeArguments);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
walk(typeArguments);
|
|
297
|
+
return imports;
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Scope } from '@goodie-ts/core';
|
|
2
|
+
import { type ClassDeclaration, type Project, type SourceFile } from 'ts-morph';
|
|
3
|
+
import type { ClassTokenRef, SourceLocation } from './ir.js';
|
|
4
|
+
/** A class decorated with @Injectable or @Singleton (but not @Module). */
|
|
5
|
+
export interface ScannedBean {
|
|
6
|
+
classDeclaration: ClassDeclaration;
|
|
7
|
+
classTokenRef: ClassTokenRef;
|
|
8
|
+
scope: Scope;
|
|
9
|
+
eager: boolean;
|
|
10
|
+
name: string | undefined;
|
|
11
|
+
constructorParams: ScannedConstructorParam[];
|
|
12
|
+
fieldInjections: ScannedFieldInjection[];
|
|
13
|
+
/** Method names decorated with @PreDestroy(). */
|
|
14
|
+
preDestroyMethods: string[];
|
|
15
|
+
/** All ancestor classes (direct parent first, root last). */
|
|
16
|
+
baseClasses: Array<{
|
|
17
|
+
className: string;
|
|
18
|
+
sourceFile: SourceFile | undefined;
|
|
19
|
+
}>;
|
|
20
|
+
sourceLocation: SourceLocation;
|
|
21
|
+
}
|
|
22
|
+
/** A resolved type argument for generic types (recursive for nested generics). */
|
|
23
|
+
export interface ScannedTypeArgument {
|
|
24
|
+
typeName: string;
|
|
25
|
+
typeSourceFile: SourceFile | undefined;
|
|
26
|
+
typeArguments: ScannedTypeArgument[];
|
|
27
|
+
}
|
|
28
|
+
/** A constructor parameter discovered via AST analysis. */
|
|
29
|
+
export interface ScannedConstructorParam {
|
|
30
|
+
paramName: string;
|
|
31
|
+
typeName: string | undefined;
|
|
32
|
+
typeSourceFile: SourceFile | undefined;
|
|
33
|
+
/** Type arguments if this is a generic type (e.g. Repository<User>). */
|
|
34
|
+
typeArguments: ScannedTypeArgument[];
|
|
35
|
+
/** The resolved base type name (e.g. 'Repository' for Repository<User>). */
|
|
36
|
+
resolvedBaseTypeName: string | undefined;
|
|
37
|
+
sourceLocation: SourceLocation;
|
|
38
|
+
}
|
|
39
|
+
/** A field injection discovered from @Inject / @Optional on an accessor. */
|
|
40
|
+
export interface ScannedFieldInjection {
|
|
41
|
+
fieldName: string;
|
|
42
|
+
/** The qualifier argument from @Inject(qualifier). */
|
|
43
|
+
qualifier: string | undefined;
|
|
44
|
+
/** Whether @Optional() is present on this field. */
|
|
45
|
+
optional: boolean;
|
|
46
|
+
/** The type annotation of the accessor field. */
|
|
47
|
+
typeName: string | undefined;
|
|
48
|
+
typeSourceFile: SourceFile | undefined;
|
|
49
|
+
/** Type arguments if this is a generic type. */
|
|
50
|
+
typeArguments: ScannedTypeArgument[];
|
|
51
|
+
/** The resolved base type name (e.g. 'Repository' for Repository<User>). */
|
|
52
|
+
resolvedBaseTypeName: string | undefined;
|
|
53
|
+
sourceLocation: SourceLocation;
|
|
54
|
+
}
|
|
55
|
+
/** A @Module class with its @Provides methods. */
|
|
56
|
+
export interface ScannedModule {
|
|
57
|
+
classDeclaration: ClassDeclaration;
|
|
58
|
+
classTokenRef: ClassTokenRef;
|
|
59
|
+
imports: ScannedModuleImport[];
|
|
60
|
+
provides: ScannedProvides[];
|
|
61
|
+
sourceLocation: SourceLocation;
|
|
62
|
+
}
|
|
63
|
+
export interface ScannedModuleImport {
|
|
64
|
+
className: string;
|
|
65
|
+
sourceFile: SourceFile | undefined;
|
|
66
|
+
}
|
|
67
|
+
/** A @Provides method inside a @Module. */
|
|
68
|
+
export interface ScannedProvides {
|
|
69
|
+
methodName: string;
|
|
70
|
+
returnTypeName: string | undefined;
|
|
71
|
+
returnTypeSourceFile: SourceFile | undefined;
|
|
72
|
+
/** Type arguments of the return type if generic. */
|
|
73
|
+
returnTypeArguments: ScannedTypeArgument[];
|
|
74
|
+
/** The resolved base type name of the return type. */
|
|
75
|
+
returnResolvedBaseTypeName: string | undefined;
|
|
76
|
+
params: ScannedConstructorParam[];
|
|
77
|
+
sourceLocation: SourceLocation;
|
|
78
|
+
}
|
|
79
|
+
/** Result of scanning source files. */
|
|
80
|
+
export interface ScanResult {
|
|
81
|
+
beans: ScannedBean[];
|
|
82
|
+
modules: ScannedModule[];
|
|
83
|
+
warnings: string[];
|
|
84
|
+
}
|
|
85
|
+
/** Scan a ts-morph Project for decorated classes. */
|
|
86
|
+
export declare function scan(project: Project): ScanResult;
|
|
87
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
|