@tsonic/frontend 0.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/package.json +53 -0
- package/src/dependency-graph.ts +18 -0
- package/src/dotnet-metadata.ts +121 -0
- package/src/graph/builder.ts +81 -0
- package/src/graph/circular.ts +58 -0
- package/src/graph/extraction/exports.ts +55 -0
- package/src/graph/extraction/imports.ts +81 -0
- package/src/graph/extraction/index.ts +7 -0
- package/src/graph/extraction/orchestrator.ts +99 -0
- package/src/graph/extraction.ts +10 -0
- package/src/graph/helpers.ts +51 -0
- package/src/graph/index.ts +17 -0
- package/src/graph/types.ts +13 -0
- package/src/index.ts +80 -0
- package/src/ir/binding-resolution.test.ts +585 -0
- package/src/ir/builder/exports.ts +78 -0
- package/src/ir/builder/helpers.ts +27 -0
- package/src/ir/builder/imports.ts +153 -0
- package/src/ir/builder/index.ts +10 -0
- package/src/ir/builder/orchestrator.ts +178 -0
- package/src/ir/builder/statements.ts +55 -0
- package/src/ir/builder/types.ts +8 -0
- package/src/ir/builder/validation.ts +129 -0
- package/src/ir/builder.test.ts +581 -0
- package/src/ir/builder.ts +14 -0
- package/src/ir/converters/expressions/access.ts +99 -0
- package/src/ir/converters/expressions/calls.ts +137 -0
- package/src/ir/converters/expressions/collections.ts +84 -0
- package/src/ir/converters/expressions/functions.ts +62 -0
- package/src/ir/converters/expressions/helpers.ts +264 -0
- package/src/ir/converters/expressions/index.ts +43 -0
- package/src/ir/converters/expressions/literals.ts +22 -0
- package/src/ir/converters/expressions/operators.ts +147 -0
- package/src/ir/converters/expressions/other.ts +60 -0
- package/src/ir/converters/statements/control/blocks.ts +22 -0
- package/src/ir/converters/statements/control/conditionals.ts +67 -0
- package/src/ir/converters/statements/control/exceptions.ts +43 -0
- package/src/ir/converters/statements/control/index.ts +17 -0
- package/src/ir/converters/statements/control/loops.ts +99 -0
- package/src/ir/converters/statements/control.ts +17 -0
- package/src/ir/converters/statements/declarations/classes/constructors.ts +120 -0
- package/src/ir/converters/statements/declarations/classes/index.ts +12 -0
- package/src/ir/converters/statements/declarations/classes/methods.ts +61 -0
- package/src/ir/converters/statements/declarations/classes/orchestrator.ts +166 -0
- package/src/ir/converters/statements/declarations/classes/override-detection.ts +116 -0
- package/src/ir/converters/statements/declarations/classes/properties.ts +63 -0
- package/src/ir/converters/statements/declarations/classes.ts +6 -0
- package/src/ir/converters/statements/declarations/enums.ts +29 -0
- package/src/ir/converters/statements/declarations/functions.ts +39 -0
- package/src/ir/converters/statements/declarations/index.ts +14 -0
- package/src/ir/converters/statements/declarations/interfaces.ts +131 -0
- package/src/ir/converters/statements/declarations/registry.ts +45 -0
- package/src/ir/converters/statements/declarations/type-aliases.ts +25 -0
- package/src/ir/converters/statements/declarations/variables.ts +60 -0
- package/src/ir/converters/statements/declarations.ts +16 -0
- package/src/ir/converters/statements/helpers.ts +174 -0
- package/src/ir/converters/statements/index.ts +40 -0
- package/src/ir/expression-converter.ts +207 -0
- package/src/ir/generic-validator.ts +100 -0
- package/src/ir/hierarchical-bindings-e2e.test.ts +163 -0
- package/src/ir/index.ts +6 -0
- package/src/ir/statement-converter.ts +128 -0
- package/src/ir/type-converter/arrays.ts +20 -0
- package/src/ir/type-converter/converter.ts +10 -0
- package/src/ir/type-converter/functions.ts +22 -0
- package/src/ir/type-converter/index.ts +11 -0
- package/src/ir/type-converter/inference.ts +122 -0
- package/src/ir/type-converter/literals.ts +40 -0
- package/src/ir/type-converter/objects.ts +107 -0
- package/src/ir/type-converter/orchestrator.ts +85 -0
- package/src/ir/type-converter/patterns.ts +73 -0
- package/src/ir/type-converter/primitives.ts +57 -0
- package/src/ir/type-converter/references.ts +64 -0
- package/src/ir/type-converter/unions-intersections.ts +34 -0
- package/src/ir/type-converter.ts +13 -0
- package/src/ir/types/expressions.ts +215 -0
- package/src/ir/types/guards.ts +39 -0
- package/src/ir/types/helpers.ts +135 -0
- package/src/ir/types/index.ts +108 -0
- package/src/ir/types/ir-types.ts +96 -0
- package/src/ir/types/module.ts +57 -0
- package/src/ir/types/statements.ts +238 -0
- package/src/ir/types.ts +97 -0
- package/src/metadata/bindings-loader.test.ts +144 -0
- package/src/metadata/bindings-loader.ts +357 -0
- package/src/metadata/index.ts +15 -0
- package/src/metadata/library-loader.ts +153 -0
- package/src/metadata/loader.test.ts +156 -0
- package/src/metadata/loader.ts +382 -0
- package/src/program/bindings.test.ts +512 -0
- package/src/program/bindings.ts +253 -0
- package/src/program/config.ts +30 -0
- package/src/program/creation.ts +249 -0
- package/src/program/dependency-graph.ts +245 -0
- package/src/program/diagnostics.ts +103 -0
- package/src/program/index.ts +19 -0
- package/src/program/metadata.ts +68 -0
- package/src/program/queries.ts +18 -0
- package/src/program/types.ts +38 -0
- package/src/program.ts +13 -0
- package/src/resolver/dotnet-import-resolver.ts +226 -0
- package/src/resolver/import-resolution.ts +177 -0
- package/src/resolver/index.ts +18 -0
- package/src/resolver/namespace.test.ts +86 -0
- package/src/resolver/namespace.ts +42 -0
- package/src/resolver/naming.ts +38 -0
- package/src/resolver/path-resolution.ts +22 -0
- package/src/resolver/types.ts +15 -0
- package/src/resolver.test.ts +155 -0
- package/src/resolver.ts +14 -0
- package/src/symbol-table/builder.ts +114 -0
- package/src/symbol-table/creation.ts +42 -0
- package/src/symbol-table/helpers.ts +18 -0
- package/src/symbol-table/index.ts +13 -0
- package/src/symbol-table/queries.ts +42 -0
- package/src/symbol-table/types.ts +28 -0
- package/src/symbol-table.ts +14 -0
- package/src/types/bindings.ts +172 -0
- package/src/types/diagnostic.test.ts +164 -0
- package/src/types/diagnostic.ts +153 -0
- package/src/types/explicit-views.test.ts +113 -0
- package/src/types/explicit-views.ts +218 -0
- package/src/types/metadata.ts +229 -0
- package/src/types/module.ts +99 -0
- package/src/types/nested-types.test.ts +194 -0
- package/src/types/nested-types.ts +215 -0
- package/src/types/parameter-modifiers.ts +173 -0
- package/src/types/ref-parameters.test.ts +192 -0
- package/src/types/ref-parameters.ts +268 -0
- package/src/types/result.test.ts +157 -0
- package/src/types/result.ts +48 -0
- package/src/types/support-types.test.ts +81 -0
- package/src/types/support-types.ts +288 -0
- package/src/types/test-harness.ts +180 -0
- package/src/validation/exports.ts +98 -0
- package/src/validation/features.ts +89 -0
- package/src/validation/generics.ts +40 -0
- package/src/validation/helpers.ts +31 -0
- package/src/validation/imports.ts +97 -0
- package/src/validation/index.ts +11 -0
- package/src/validation/orchestrator.ts +51 -0
- package/src/validation/static-safety.ts +267 -0
- package/src/validator.test.ts +468 -0
- package/src/validator.ts +15 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for .NET metadata.json files generated by tsbindgen.
|
|
3
|
+
*
|
|
4
|
+
* These types represent the CLR type system metadata in a TypeScript-friendly format.
|
|
5
|
+
* All property names use camelCase (JavaScript convention).
|
|
6
|
+
*
|
|
7
|
+
* @see spec/metadata.md for complete schema documentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Root metadata file structure.
|
|
12
|
+
* Represents a single namespace with all its types.
|
|
13
|
+
*/
|
|
14
|
+
export type MetadataFile = {
|
|
15
|
+
readonly namespace: string;
|
|
16
|
+
readonly contributingAssemblies: string[];
|
|
17
|
+
readonly types: TypeMetadata[];
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Type kind enumeration.
|
|
22
|
+
* Represents the fundamental kind of CLR type.
|
|
23
|
+
*/
|
|
24
|
+
export type TypeKind = "Class" | "Interface" | "Struct" | "Enum" | "Delegate";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Accessibility level enumeration.
|
|
28
|
+
* Represents CLR accessibility modifiers.
|
|
29
|
+
*/
|
|
30
|
+
export type Accessibility =
|
|
31
|
+
| "Public"
|
|
32
|
+
| "Internal"
|
|
33
|
+
| "Protected"
|
|
34
|
+
| "ProtectedInternal"
|
|
35
|
+
| "PrivateProtected"
|
|
36
|
+
| "Private";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Emit scope enumeration.
|
|
40
|
+
* Determines where a member should be emitted in TypeScript declarations.
|
|
41
|
+
*/
|
|
42
|
+
export type EmitScope =
|
|
43
|
+
| "ClassSurface" // Emit on main class
|
|
44
|
+
| "ViewOnly" // Emit only in explicit interface views
|
|
45
|
+
| "Omitted"; // Don't emit (not accessible from TypeScript)
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Provenance enumeration.
|
|
49
|
+
* Tracks the origin of a member in the type hierarchy.
|
|
50
|
+
*/
|
|
51
|
+
export type Provenance =
|
|
52
|
+
| "Original" // Declared on this type
|
|
53
|
+
| "Declared" // Explicitly declared (alias of Original)
|
|
54
|
+
| "InlineFromInterface" // Implicit interface implementation
|
|
55
|
+
| "InlineFromBase" // Inherited from base class
|
|
56
|
+
| "SynthesizedViewOnly" // Generated for view-only access
|
|
57
|
+
| "ExplicitView"; // Explicit interface implementation
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Complete metadata for a CLR type.
|
|
61
|
+
*/
|
|
62
|
+
export type TypeMetadata = {
|
|
63
|
+
readonly clrName: string;
|
|
64
|
+
readonly tsEmitName: string;
|
|
65
|
+
readonly kind: TypeKind;
|
|
66
|
+
readonly accessibility: Accessibility;
|
|
67
|
+
readonly isAbstract: boolean;
|
|
68
|
+
readonly isSealed: boolean;
|
|
69
|
+
readonly isStatic: boolean;
|
|
70
|
+
readonly arity: number;
|
|
71
|
+
readonly baseType?: string | null;
|
|
72
|
+
readonly interfaces?: string[];
|
|
73
|
+
readonly isValueType?: boolean;
|
|
74
|
+
readonly methods: MethodMetadata[];
|
|
75
|
+
readonly properties: PropertyMetadata[];
|
|
76
|
+
readonly fields: FieldMetadata[];
|
|
77
|
+
readonly events: EventMetadata[];
|
|
78
|
+
readonly constructors: ConstructorMetadata[];
|
|
79
|
+
readonly intentionalOmissions?: IntentionalOmissions;
|
|
80
|
+
readonly explicitViews?: ExplicitView[];
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Method metadata.
|
|
85
|
+
*/
|
|
86
|
+
export type MethodMetadata = {
|
|
87
|
+
readonly name: string;
|
|
88
|
+
readonly clrName: string;
|
|
89
|
+
readonly tsEmitName: string;
|
|
90
|
+
readonly accessibility: Accessibility;
|
|
91
|
+
readonly isStatic: boolean;
|
|
92
|
+
readonly isAbstract: boolean;
|
|
93
|
+
readonly isVirtual: boolean;
|
|
94
|
+
readonly isFinal: boolean;
|
|
95
|
+
readonly arity: number;
|
|
96
|
+
readonly parameters: ParameterMetadata[];
|
|
97
|
+
readonly returnType: string;
|
|
98
|
+
readonly emitScope: EmitScope;
|
|
99
|
+
readonly provenance: Provenance;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Property metadata.
|
|
104
|
+
*/
|
|
105
|
+
export type PropertyMetadata = {
|
|
106
|
+
readonly name: string;
|
|
107
|
+
readonly clrName: string;
|
|
108
|
+
readonly tsEmitName: string;
|
|
109
|
+
readonly accessibility: Accessibility;
|
|
110
|
+
readonly isStatic: boolean;
|
|
111
|
+
readonly type: string;
|
|
112
|
+
readonly hasGetter: boolean;
|
|
113
|
+
readonly hasSetter: boolean;
|
|
114
|
+
readonly emitScope: EmitScope;
|
|
115
|
+
readonly provenance: Provenance;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Field metadata.
|
|
120
|
+
*/
|
|
121
|
+
export type FieldMetadata = {
|
|
122
|
+
readonly name: string;
|
|
123
|
+
readonly clrName: string;
|
|
124
|
+
readonly tsEmitName: string;
|
|
125
|
+
readonly accessibility: Accessibility;
|
|
126
|
+
readonly isStatic: boolean;
|
|
127
|
+
readonly isReadonly: boolean;
|
|
128
|
+
readonly type: string;
|
|
129
|
+
readonly emitScope: EmitScope;
|
|
130
|
+
readonly provenance: Provenance;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Event metadata.
|
|
135
|
+
*/
|
|
136
|
+
export type EventMetadata = {
|
|
137
|
+
readonly name: string;
|
|
138
|
+
readonly clrName: string;
|
|
139
|
+
readonly tsEmitName: string;
|
|
140
|
+
readonly accessibility: Accessibility;
|
|
141
|
+
readonly isStatic: boolean;
|
|
142
|
+
readonly type: string;
|
|
143
|
+
readonly emitScope: EmitScope;
|
|
144
|
+
readonly provenance: Provenance;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Constructor metadata.
|
|
149
|
+
*/
|
|
150
|
+
export type ConstructorMetadata = {
|
|
151
|
+
readonly accessibility: Accessibility;
|
|
152
|
+
readonly parameters: ParameterMetadata[];
|
|
153
|
+
readonly emitScope: EmitScope;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Parameter metadata.
|
|
158
|
+
*/
|
|
159
|
+
export type ParameterMetadata = {
|
|
160
|
+
readonly name: string;
|
|
161
|
+
readonly type: string;
|
|
162
|
+
readonly isRef: boolean;
|
|
163
|
+
readonly isOut: boolean;
|
|
164
|
+
readonly isIn?: boolean;
|
|
165
|
+
readonly isParams: boolean;
|
|
166
|
+
readonly defaultValue?: any | null;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Intentional omissions from TypeScript declarations.
|
|
171
|
+
* Tracks members that are deliberately not emitted.
|
|
172
|
+
*/
|
|
173
|
+
export type IntentionalOmissions = {
|
|
174
|
+
readonly methods?: OmittedMethod[];
|
|
175
|
+
readonly properties?: OmittedProperty[];
|
|
176
|
+
readonly fields?: OmittedField[];
|
|
177
|
+
readonly events?: OmittedEvent[];
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Omitted method information.
|
|
182
|
+
*/
|
|
183
|
+
export type OmittedMethod = {
|
|
184
|
+
readonly name: string;
|
|
185
|
+
readonly reason: string;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Omitted property information.
|
|
190
|
+
*/
|
|
191
|
+
export type OmittedProperty = {
|
|
192
|
+
readonly name: string;
|
|
193
|
+
readonly reason: string;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Omitted field information.
|
|
198
|
+
*/
|
|
199
|
+
export type OmittedField = {
|
|
200
|
+
readonly name: string;
|
|
201
|
+
readonly reason: string;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Omitted event information.
|
|
206
|
+
*/
|
|
207
|
+
export type OmittedEvent = {
|
|
208
|
+
readonly name: string;
|
|
209
|
+
readonly reason: string;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Explicit interface view metadata.
|
|
214
|
+
* Represents an As_IInterface property for explicit interface implementations.
|
|
215
|
+
*/
|
|
216
|
+
export type ExplicitView = {
|
|
217
|
+
readonly interfaceName: string;
|
|
218
|
+
readonly tsPropertyName: string;
|
|
219
|
+
readonly members: ExplicitViewMember[];
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Member within an explicit interface view.
|
|
224
|
+
*/
|
|
225
|
+
export type ExplicitViewMember = {
|
|
226
|
+
readonly kind: "Method" | "Property" | "Event";
|
|
227
|
+
readonly name: string;
|
|
228
|
+
readonly clrName: string;
|
|
229
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module representation types for Tsonic compiler
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type ImportKind = "local" | "dotnet" | "node_module";
|
|
6
|
+
|
|
7
|
+
export type Import = {
|
|
8
|
+
readonly kind: ImportKind;
|
|
9
|
+
readonly specifier: string; // Original import specifier
|
|
10
|
+
readonly resolvedPath?: string; // Resolved file path for local imports
|
|
11
|
+
readonly namespace?: string; // .NET namespace for dotnet imports
|
|
12
|
+
readonly importedNames: readonly ImportedName[];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type ImportedName = {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly alias?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type Export =
|
|
21
|
+
| {
|
|
22
|
+
readonly kind: "named";
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly localName: string;
|
|
25
|
+
}
|
|
26
|
+
| { readonly kind: "default"; readonly localName: string }
|
|
27
|
+
| {
|
|
28
|
+
readonly kind: "namespace";
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly localName: string;
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
readonly kind: "reexport";
|
|
34
|
+
readonly fromModule: string;
|
|
35
|
+
readonly exports: readonly ImportedName[];
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type ModuleInfo = {
|
|
39
|
+
readonly filePath: string;
|
|
40
|
+
readonly sourceText: string;
|
|
41
|
+
readonly imports: readonly Import[];
|
|
42
|
+
readonly exports: readonly Export[];
|
|
43
|
+
readonly hasTopLevelCode: boolean;
|
|
44
|
+
readonly namespace?: string; // Will be computed from directory structure
|
|
45
|
+
readonly className?: string; // Will be computed from file name
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type ModuleGraph = {
|
|
49
|
+
readonly modules: ReadonlyMap<string, ModuleInfo>;
|
|
50
|
+
readonly dependencies: ReadonlyMap<string, readonly string[]>;
|
|
51
|
+
readonly dependents: ReadonlyMap<string, readonly string[]>;
|
|
52
|
+
readonly entryPoints: readonly string[];
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const createModuleInfo = (
|
|
56
|
+
filePath: string,
|
|
57
|
+
sourceText: string,
|
|
58
|
+
imports: readonly Import[] = [],
|
|
59
|
+
exports: readonly Export[] = [],
|
|
60
|
+
hasTopLevelCode: boolean = false,
|
|
61
|
+
namespace?: string,
|
|
62
|
+
className?: string
|
|
63
|
+
): ModuleInfo => ({
|
|
64
|
+
filePath,
|
|
65
|
+
sourceText,
|
|
66
|
+
imports,
|
|
67
|
+
exports,
|
|
68
|
+
hasTopLevelCode,
|
|
69
|
+
namespace,
|
|
70
|
+
className,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
export const createModuleGraph = (
|
|
74
|
+
modules: ReadonlyMap<string, ModuleInfo> = new Map(),
|
|
75
|
+
dependencies: ReadonlyMap<string, readonly string[]> = new Map(),
|
|
76
|
+
dependents: ReadonlyMap<string, readonly string[]> = new Map(),
|
|
77
|
+
entryPoints: readonly string[] = []
|
|
78
|
+
): ModuleGraph => ({
|
|
79
|
+
modules,
|
|
80
|
+
dependencies,
|
|
81
|
+
dependents,
|
|
82
|
+
entryPoints,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
export const addModule = (
|
|
86
|
+
graph: ModuleGraph,
|
|
87
|
+
module: ModuleInfo
|
|
88
|
+
): ModuleGraph => {
|
|
89
|
+
const newModules = new Map(graph.modules);
|
|
90
|
+
newModules.set(module.filePath, module);
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
...graph,
|
|
94
|
+
modules: newModules,
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const isLocalImport = (importSpec: string): boolean =>
|
|
99
|
+
importSpec.startsWith(".") || importSpec.startsWith("/");
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for nested types handling
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it } from "mocha";
|
|
6
|
+
import { strict as assert } from "assert";
|
|
7
|
+
import {
|
|
8
|
+
parseNestedTypeName,
|
|
9
|
+
isNestedType,
|
|
10
|
+
tsCSharpNestedTypeName,
|
|
11
|
+
clrToTsNestedTypeName,
|
|
12
|
+
tsToCLRNestedTypeName,
|
|
13
|
+
getNestedTypeLevels,
|
|
14
|
+
getOutermostType,
|
|
15
|
+
getInnermostType,
|
|
16
|
+
isNestedInside,
|
|
17
|
+
getParentType,
|
|
18
|
+
} from "./nested-types.js";
|
|
19
|
+
|
|
20
|
+
describe("Nested Types", () => {
|
|
21
|
+
describe("isNestedType", () => {
|
|
22
|
+
it("should detect nested type with $ separator", () => {
|
|
23
|
+
assert.ok(isNestedType("List_1$Enumerator"));
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should return false for non-nested type", () => {
|
|
27
|
+
assert.ok(!isNestedType("List_1"));
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe("parseNestedTypeName", () => {
|
|
32
|
+
it("should parse simple nested type", () => {
|
|
33
|
+
const info = parseNestedTypeName("List_1$Enumerator");
|
|
34
|
+
|
|
35
|
+
assert.ok(info);
|
|
36
|
+
assert.equal(info?.outerType, "List_1");
|
|
37
|
+
assert.equal(info?.nestedType, "Enumerator");
|
|
38
|
+
assert.equal(info?.depth, 1);
|
|
39
|
+
assert.deepEqual(info?.fullPath, ["List_1", "Enumerator"]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("should parse multiple nesting levels", () => {
|
|
43
|
+
const info = parseNestedTypeName("A$B$C");
|
|
44
|
+
|
|
45
|
+
assert.ok(info);
|
|
46
|
+
assert.equal(info?.outerType, "A");
|
|
47
|
+
assert.equal(info?.nestedType, "C");
|
|
48
|
+
assert.equal(info?.depth, 2);
|
|
49
|
+
assert.deepEqual(info?.fullPath, ["A", "B", "C"]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("should return undefined for non-nested type", () => {
|
|
53
|
+
const info = parseNestedTypeName("SimpleType");
|
|
54
|
+
|
|
55
|
+
assert.equal(info, undefined);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe("tsCSharpNestedTypeName", () => {
|
|
60
|
+
it("should convert $ to . separator", () => {
|
|
61
|
+
const result = tsCSharpNestedTypeName("List_1$Enumerator");
|
|
62
|
+
|
|
63
|
+
assert.equal(result, "List_1.Enumerator");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("should handle multiple levels", () => {
|
|
67
|
+
const result = tsCSharpNestedTypeName("A$B$C");
|
|
68
|
+
|
|
69
|
+
assert.equal(result, "A.B.C");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should leave non-nested types unchanged", () => {
|
|
73
|
+
const result = tsCSharpNestedTypeName("SimpleType");
|
|
74
|
+
|
|
75
|
+
assert.equal(result, "SimpleType");
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("clrToTsNestedTypeName", () => {
|
|
80
|
+
it("should convert CLR name to TypeScript", () => {
|
|
81
|
+
const result = clrToTsNestedTypeName("List`1+Enumerator");
|
|
82
|
+
|
|
83
|
+
assert.equal(result, "List_1$Enumerator");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should handle multiple levels", () => {
|
|
87
|
+
const result = clrToTsNestedTypeName("A+B+C");
|
|
88
|
+
|
|
89
|
+
assert.equal(result, "A$B$C");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("should handle generic nested types", () => {
|
|
93
|
+
const result = clrToTsNestedTypeName("Dictionary`2+KeyCollection`1");
|
|
94
|
+
|
|
95
|
+
assert.equal(result, "Dictionary_2$KeyCollection_1");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe("tsToCLRNestedTypeName", () => {
|
|
100
|
+
it("should convert TypeScript name to CLR", () => {
|
|
101
|
+
const result = tsToCLRNestedTypeName("List_1$Enumerator");
|
|
102
|
+
|
|
103
|
+
assert.equal(result, "List`1+Enumerator");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("should handle multiple levels", () => {
|
|
107
|
+
const result = tsToCLRNestedTypeName("A$B$C");
|
|
108
|
+
|
|
109
|
+
assert.equal(result, "A+B+C");
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe("getNestedTypeLevels", () => {
|
|
114
|
+
it("should return all nesting levels", () => {
|
|
115
|
+
const levels = getNestedTypeLevels("A$B$C");
|
|
116
|
+
|
|
117
|
+
assert.deepEqual(levels, ["A", "A$B", "A$B$C"]);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("should return single level for non-nested type", () => {
|
|
121
|
+
const levels = getNestedTypeLevels("SimpleType");
|
|
122
|
+
|
|
123
|
+
assert.deepEqual(levels, ["SimpleType"]);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe("getOutermostType", () => {
|
|
128
|
+
it("should return outermost type", () => {
|
|
129
|
+
const outermost = getOutermostType("List_1$Enumerator");
|
|
130
|
+
|
|
131
|
+
assert.equal(outermost, "List_1");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("should return same type for non-nested", () => {
|
|
135
|
+
const outermost = getOutermostType("SimpleType");
|
|
136
|
+
|
|
137
|
+
assert.equal(outermost, "SimpleType");
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe("getInnermostType", () => {
|
|
142
|
+
it("should return innermost type", () => {
|
|
143
|
+
const innermost = getInnermostType("A$B$C");
|
|
144
|
+
|
|
145
|
+
assert.equal(innermost, "C");
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("should return same type for non-nested", () => {
|
|
149
|
+
const innermost = getInnermostType("SimpleType");
|
|
150
|
+
|
|
151
|
+
assert.equal(innermost, "SimpleType");
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe("isNestedInside", () => {
|
|
156
|
+
it("should detect type nested inside another", () => {
|
|
157
|
+
const result = isNestedInside("List_1$Enumerator", "List_1");
|
|
158
|
+
|
|
159
|
+
assert.ok(result);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("should return false for unrelated types", () => {
|
|
163
|
+
const result = isNestedInside("Dictionary_2$KeyCollection", "List_1");
|
|
164
|
+
|
|
165
|
+
assert.ok(!result);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("should return false for non-nested type", () => {
|
|
169
|
+
const result = isNestedInside("SimpleType", "List_1");
|
|
170
|
+
|
|
171
|
+
assert.ok(!result);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe("getParentType", () => {
|
|
176
|
+
it("should return parent type", () => {
|
|
177
|
+
const parent = getParentType("A$B$C");
|
|
178
|
+
|
|
179
|
+
assert.equal(parent, "A$B");
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("should return parent for single nesting", () => {
|
|
183
|
+
const parent = getParentType("List_1$Enumerator");
|
|
184
|
+
|
|
185
|
+
assert.equal(parent, "List_1");
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("should return undefined for non-nested type", () => {
|
|
189
|
+
const parent = getParentType("SimpleType");
|
|
190
|
+
|
|
191
|
+
assert.equal(parent, undefined);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|