@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,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator expression converters (binary, unary, update, assignment)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import {
|
|
7
|
+
IrExpression,
|
|
8
|
+
IrUnaryExpression,
|
|
9
|
+
IrUpdateExpression,
|
|
10
|
+
IrBinaryOperator,
|
|
11
|
+
IrAssignmentOperator,
|
|
12
|
+
} from "../../types.js";
|
|
13
|
+
import {
|
|
14
|
+
getInferredType,
|
|
15
|
+
convertBinaryOperator,
|
|
16
|
+
isAssignmentOperator,
|
|
17
|
+
} from "./helpers.js";
|
|
18
|
+
import { convertExpression } from "../../expression-converter.js";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Convert binary expression (including logical and assignment)
|
|
22
|
+
*/
|
|
23
|
+
export const convertBinaryExpression = (
|
|
24
|
+
node: ts.BinaryExpression,
|
|
25
|
+
checker: ts.TypeChecker
|
|
26
|
+
): IrExpression => {
|
|
27
|
+
const operator = convertBinaryOperator(node.operatorToken);
|
|
28
|
+
const inferredType = getInferredType(node, checker);
|
|
29
|
+
|
|
30
|
+
// Handle assignment separately
|
|
31
|
+
if (isAssignmentOperator(node.operatorToken)) {
|
|
32
|
+
return {
|
|
33
|
+
kind: "assignment",
|
|
34
|
+
operator: operator as IrAssignmentOperator,
|
|
35
|
+
left: ts.isIdentifier(node.left)
|
|
36
|
+
? { kind: "identifier", name: node.left.text }
|
|
37
|
+
: convertExpression(node.left, checker),
|
|
38
|
+
right: convertExpression(node.right, checker),
|
|
39
|
+
inferredType,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Handle logical operators
|
|
44
|
+
if (operator === "&&" || operator === "||" || operator === "??") {
|
|
45
|
+
return {
|
|
46
|
+
kind: "logical",
|
|
47
|
+
operator,
|
|
48
|
+
left: convertExpression(node.left, checker),
|
|
49
|
+
right: convertExpression(node.right, checker),
|
|
50
|
+
inferredType,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Regular binary expression
|
|
55
|
+
return {
|
|
56
|
+
kind: "binary",
|
|
57
|
+
operator: operator as IrBinaryOperator,
|
|
58
|
+
left: convertExpression(node.left, checker),
|
|
59
|
+
right: convertExpression(node.right, checker),
|
|
60
|
+
inferredType,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Convert prefix unary expression
|
|
66
|
+
*/
|
|
67
|
+
export const convertUnaryExpression = (
|
|
68
|
+
node: ts.PrefixUnaryExpression,
|
|
69
|
+
checker: ts.TypeChecker
|
|
70
|
+
): IrUnaryExpression | IrUpdateExpression => {
|
|
71
|
+
const inferredType = getInferredType(node, checker);
|
|
72
|
+
|
|
73
|
+
// Check if it's an increment/decrement (++ or --)
|
|
74
|
+
if (
|
|
75
|
+
node.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
76
|
+
node.operator === ts.SyntaxKind.MinusMinusToken
|
|
77
|
+
) {
|
|
78
|
+
return {
|
|
79
|
+
kind: "update",
|
|
80
|
+
operator: node.operator === ts.SyntaxKind.PlusPlusToken ? "++" : "--",
|
|
81
|
+
prefix: true,
|
|
82
|
+
expression: convertExpression(node.operand, checker),
|
|
83
|
+
inferredType,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Handle regular unary operators
|
|
88
|
+
let operator: IrUnaryExpression["operator"] = "+";
|
|
89
|
+
|
|
90
|
+
switch (node.operator) {
|
|
91
|
+
case ts.SyntaxKind.PlusToken:
|
|
92
|
+
operator = "+";
|
|
93
|
+
break;
|
|
94
|
+
case ts.SyntaxKind.MinusToken:
|
|
95
|
+
operator = "-";
|
|
96
|
+
break;
|
|
97
|
+
case ts.SyntaxKind.ExclamationToken:
|
|
98
|
+
operator = "!";
|
|
99
|
+
break;
|
|
100
|
+
case ts.SyntaxKind.TildeToken:
|
|
101
|
+
operator = "~";
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
kind: "unary",
|
|
107
|
+
operator,
|
|
108
|
+
expression: convertExpression(node.operand, checker),
|
|
109
|
+
inferredType,
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Convert postfix unary expression (++ or --)
|
|
115
|
+
*/
|
|
116
|
+
export const convertUpdateExpression = (
|
|
117
|
+
node: ts.PostfixUnaryExpression | ts.PrefixUnaryExpression,
|
|
118
|
+
checker: ts.TypeChecker
|
|
119
|
+
): IrUpdateExpression => {
|
|
120
|
+
const inferredType = getInferredType(node, checker);
|
|
121
|
+
|
|
122
|
+
if (ts.isPrefixUnaryExpression(node)) {
|
|
123
|
+
// Check if it's an increment or decrement
|
|
124
|
+
if (
|
|
125
|
+
node.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
126
|
+
node.operator === ts.SyntaxKind.MinusMinusToken
|
|
127
|
+
) {
|
|
128
|
+
return {
|
|
129
|
+
kind: "update",
|
|
130
|
+
operator: node.operator === ts.SyntaxKind.PlusPlusToken ? "++" : "--",
|
|
131
|
+
prefix: true,
|
|
132
|
+
expression: convertExpression(node.operand, checker),
|
|
133
|
+
inferredType,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Handle postfix unary expression
|
|
139
|
+
const postfix = node as ts.PostfixUnaryExpression;
|
|
140
|
+
return {
|
|
141
|
+
kind: "update",
|
|
142
|
+
operator: postfix.operator === ts.SyntaxKind.PlusPlusToken ? "++" : "--",
|
|
143
|
+
prefix: false,
|
|
144
|
+
expression: convertExpression(postfix.operand, checker),
|
|
145
|
+
inferredType,
|
|
146
|
+
};
|
|
147
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Miscellaneous expression converters (conditional, template literals)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import {
|
|
7
|
+
IrConditionalExpression,
|
|
8
|
+
IrTemplateLiteralExpression,
|
|
9
|
+
IrExpression,
|
|
10
|
+
} from "../../types.js";
|
|
11
|
+
import { getInferredType } from "./helpers.js";
|
|
12
|
+
import { convertExpression } from "../../expression-converter.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Convert conditional (ternary) expression
|
|
16
|
+
*/
|
|
17
|
+
export const convertConditionalExpression = (
|
|
18
|
+
node: ts.ConditionalExpression,
|
|
19
|
+
checker: ts.TypeChecker
|
|
20
|
+
): IrConditionalExpression => {
|
|
21
|
+
return {
|
|
22
|
+
kind: "conditional",
|
|
23
|
+
condition: convertExpression(node.condition, checker),
|
|
24
|
+
whenTrue: convertExpression(node.whenTrue, checker),
|
|
25
|
+
whenFalse: convertExpression(node.whenFalse, checker),
|
|
26
|
+
inferredType: getInferredType(node, checker),
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Convert template literal expression
|
|
32
|
+
*/
|
|
33
|
+
export const convertTemplateLiteral = (
|
|
34
|
+
node: ts.TemplateExpression | ts.NoSubstitutionTemplateLiteral,
|
|
35
|
+
checker: ts.TypeChecker
|
|
36
|
+
): IrTemplateLiteralExpression => {
|
|
37
|
+
if (ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
38
|
+
return {
|
|
39
|
+
kind: "templateLiteral",
|
|
40
|
+
quasis: [node.text],
|
|
41
|
+
expressions: [],
|
|
42
|
+
inferredType: getInferredType(node, checker),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const quasis: string[] = [node.head.text];
|
|
47
|
+
const expressions: IrExpression[] = [];
|
|
48
|
+
|
|
49
|
+
node.templateSpans.forEach((span) => {
|
|
50
|
+
expressions.push(convertExpression(span.expression, checker));
|
|
51
|
+
quasis.push(span.literal.text);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
kind: "templateLiteral",
|
|
56
|
+
quasis,
|
|
57
|
+
expressions,
|
|
58
|
+
inferredType: getInferredType(node, checker),
|
|
59
|
+
};
|
|
60
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block statement converter
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import { IrStatement, IrBlockStatement } from "../../../types.js";
|
|
7
|
+
import { convertStatement } from "../../../statement-converter.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Convert block statement
|
|
11
|
+
*/
|
|
12
|
+
export const convertBlockStatement = (
|
|
13
|
+
node: ts.Block,
|
|
14
|
+
checker: ts.TypeChecker
|
|
15
|
+
): IrBlockStatement => {
|
|
16
|
+
return {
|
|
17
|
+
kind: "blockStatement",
|
|
18
|
+
statements: node.statements
|
|
19
|
+
.map((s) => convertStatement(s, checker))
|
|
20
|
+
.filter((s): s is IrStatement => s !== null),
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conditional statement converters (if, switch)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import {
|
|
7
|
+
IrStatement,
|
|
8
|
+
IrIfStatement,
|
|
9
|
+
IrSwitchStatement,
|
|
10
|
+
IrSwitchCase,
|
|
11
|
+
} from "../../../types.js";
|
|
12
|
+
import { convertExpression } from "../../../expression-converter.js";
|
|
13
|
+
import { convertStatement } from "../../../statement-converter.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Convert if statement
|
|
17
|
+
*/
|
|
18
|
+
export const convertIfStatement = (
|
|
19
|
+
node: ts.IfStatement,
|
|
20
|
+
checker: ts.TypeChecker
|
|
21
|
+
): IrIfStatement => {
|
|
22
|
+
const thenStmt = convertStatement(node.thenStatement, checker);
|
|
23
|
+
const elseStmt = node.elseStatement
|
|
24
|
+
? convertStatement(node.elseStatement, checker)
|
|
25
|
+
: undefined;
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
kind: "ifStatement",
|
|
29
|
+
condition: convertExpression(node.expression, checker),
|
|
30
|
+
thenStatement: thenStmt ?? { kind: "emptyStatement" },
|
|
31
|
+
elseStatement: elseStmt ?? undefined,
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Convert switch statement
|
|
37
|
+
*/
|
|
38
|
+
export const convertSwitchStatement = (
|
|
39
|
+
node: ts.SwitchStatement,
|
|
40
|
+
checker: ts.TypeChecker
|
|
41
|
+
): IrSwitchStatement => {
|
|
42
|
+
return {
|
|
43
|
+
kind: "switchStatement",
|
|
44
|
+
expression: convertExpression(node.expression, checker),
|
|
45
|
+
cases: node.caseBlock.clauses.map((clause) =>
|
|
46
|
+
convertSwitchCase(clause, checker)
|
|
47
|
+
),
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Convert switch case
|
|
53
|
+
*/
|
|
54
|
+
export const convertSwitchCase = (
|
|
55
|
+
node: ts.CaseOrDefaultClause,
|
|
56
|
+
checker: ts.TypeChecker
|
|
57
|
+
): IrSwitchCase => {
|
|
58
|
+
return {
|
|
59
|
+
kind: "switchCase",
|
|
60
|
+
test: ts.isCaseClause(node)
|
|
61
|
+
? convertExpression(node.expression, checker)
|
|
62
|
+
: undefined,
|
|
63
|
+
statements: node.statements
|
|
64
|
+
.map((s) => convertStatement(s, checker))
|
|
65
|
+
.filter((s): s is IrStatement => s !== null),
|
|
66
|
+
};
|
|
67
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exception handling converters (try, catch)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import { IrTryStatement, IrCatchClause } from "../../../types.js";
|
|
7
|
+
import { convertBindingName } from "../../../type-converter.js";
|
|
8
|
+
import { convertBlockStatement } from "./blocks.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Convert try statement
|
|
12
|
+
*/
|
|
13
|
+
export const convertTryStatement = (
|
|
14
|
+
node: ts.TryStatement,
|
|
15
|
+
checker: ts.TypeChecker
|
|
16
|
+
): IrTryStatement => {
|
|
17
|
+
return {
|
|
18
|
+
kind: "tryStatement",
|
|
19
|
+
tryBlock: convertBlockStatement(node.tryBlock, checker),
|
|
20
|
+
catchClause: node.catchClause
|
|
21
|
+
? convertCatchClause(node.catchClause, checker)
|
|
22
|
+
: undefined,
|
|
23
|
+
finallyBlock: node.finallyBlock
|
|
24
|
+
? convertBlockStatement(node.finallyBlock, checker)
|
|
25
|
+
: undefined,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Convert catch clause
|
|
31
|
+
*/
|
|
32
|
+
export const convertCatchClause = (
|
|
33
|
+
node: ts.CatchClause,
|
|
34
|
+
checker: ts.TypeChecker
|
|
35
|
+
): IrCatchClause => {
|
|
36
|
+
return {
|
|
37
|
+
kind: "catchClause",
|
|
38
|
+
parameter: node.variableDeclaration
|
|
39
|
+
? convertBindingName(node.variableDeclaration.name)
|
|
40
|
+
: undefined,
|
|
41
|
+
body: convertBlockStatement(node.block, checker),
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control flow statement converters - Public API
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
convertIfStatement,
|
|
7
|
+
convertSwitchStatement,
|
|
8
|
+
convertSwitchCase,
|
|
9
|
+
} from "./conditionals.js";
|
|
10
|
+
export {
|
|
11
|
+
convertWhileStatement,
|
|
12
|
+
convertForStatement,
|
|
13
|
+
convertForOfStatement,
|
|
14
|
+
convertForInStatement,
|
|
15
|
+
} from "./loops.js";
|
|
16
|
+
export { convertTryStatement, convertCatchClause } from "./exceptions.js";
|
|
17
|
+
export { convertBlockStatement } from "./blocks.js";
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop statement converters (while, for, for-of, for-in)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import {
|
|
7
|
+
IrWhileStatement,
|
|
8
|
+
IrForStatement,
|
|
9
|
+
IrForOfStatement,
|
|
10
|
+
} from "../../../types.js";
|
|
11
|
+
import { convertExpression } from "../../../expression-converter.js";
|
|
12
|
+
import { convertBindingName } from "../../../type-converter.js";
|
|
13
|
+
import { convertStatement } from "../../../statement-converter.js";
|
|
14
|
+
import { convertVariableDeclarationList } from "../helpers.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Convert while statement
|
|
18
|
+
*/
|
|
19
|
+
export const convertWhileStatement = (
|
|
20
|
+
node: ts.WhileStatement,
|
|
21
|
+
checker: ts.TypeChecker
|
|
22
|
+
): IrWhileStatement => {
|
|
23
|
+
const body = convertStatement(node.statement, checker);
|
|
24
|
+
return {
|
|
25
|
+
kind: "whileStatement",
|
|
26
|
+
condition: convertExpression(node.expression, checker),
|
|
27
|
+
body: body ?? { kind: "emptyStatement" },
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Convert for statement
|
|
33
|
+
*/
|
|
34
|
+
export const convertForStatement = (
|
|
35
|
+
node: ts.ForStatement,
|
|
36
|
+
checker: ts.TypeChecker
|
|
37
|
+
): IrForStatement => {
|
|
38
|
+
const body = convertStatement(node.statement, checker);
|
|
39
|
+
return {
|
|
40
|
+
kind: "forStatement",
|
|
41
|
+
initializer: node.initializer
|
|
42
|
+
? ts.isVariableDeclarationList(node.initializer)
|
|
43
|
+
? convertVariableDeclarationList(node.initializer, checker)
|
|
44
|
+
: convertExpression(node.initializer, checker)
|
|
45
|
+
: undefined,
|
|
46
|
+
condition: node.condition
|
|
47
|
+
? convertExpression(node.condition, checker)
|
|
48
|
+
: undefined,
|
|
49
|
+
update: node.incrementor
|
|
50
|
+
? convertExpression(node.incrementor, checker)
|
|
51
|
+
: undefined,
|
|
52
|
+
body: body ?? { kind: "emptyStatement" },
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Convert for-of statement
|
|
58
|
+
*/
|
|
59
|
+
export const convertForOfStatement = (
|
|
60
|
+
node: ts.ForOfStatement,
|
|
61
|
+
checker: ts.TypeChecker
|
|
62
|
+
): IrForOfStatement => {
|
|
63
|
+
const firstDecl = ts.isVariableDeclarationList(node.initializer)
|
|
64
|
+
? node.initializer.declarations[0]
|
|
65
|
+
: undefined;
|
|
66
|
+
|
|
67
|
+
const variable = ts.isVariableDeclarationList(node.initializer)
|
|
68
|
+
? convertBindingName(firstDecl?.name ?? ts.factory.createIdentifier("_"))
|
|
69
|
+
: convertBindingName(node.initializer as ts.BindingName);
|
|
70
|
+
|
|
71
|
+
const body = convertStatement(node.statement, checker);
|
|
72
|
+
return {
|
|
73
|
+
kind: "forOfStatement",
|
|
74
|
+
variable,
|
|
75
|
+
expression: convertExpression(node.expression, checker),
|
|
76
|
+
body: body ?? { kind: "emptyStatement" },
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Convert for-in statement
|
|
82
|
+
*/
|
|
83
|
+
export const convertForInStatement = (
|
|
84
|
+
node: ts.ForInStatement,
|
|
85
|
+
checker: ts.TypeChecker
|
|
86
|
+
): IrForStatement => {
|
|
87
|
+
// Note: for...in needs special handling in C# - variable extraction will be handled in emitter
|
|
88
|
+
// We'll need to extract the variable info in the emitter phase
|
|
89
|
+
|
|
90
|
+
const body = convertStatement(node.statement, checker);
|
|
91
|
+
// Note: for...in needs special handling in C#
|
|
92
|
+
return {
|
|
93
|
+
kind: "forStatement",
|
|
94
|
+
initializer: undefined,
|
|
95
|
+
condition: undefined,
|
|
96
|
+
update: undefined,
|
|
97
|
+
body: body ?? { kind: "emptyStatement" },
|
|
98
|
+
};
|
|
99
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control flow statement converters (if, while, for, switch, try, block)
|
|
3
|
+
* Main dispatcher - re-exports from control/ subdirectory
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
convertIfStatement,
|
|
8
|
+
convertSwitchStatement,
|
|
9
|
+
convertSwitchCase,
|
|
10
|
+
convertWhileStatement,
|
|
11
|
+
convertForStatement,
|
|
12
|
+
convertForOfStatement,
|
|
13
|
+
convertForInStatement,
|
|
14
|
+
convertTryStatement,
|
|
15
|
+
convertCatchClause,
|
|
16
|
+
convertBlockStatement,
|
|
17
|
+
} from "./control/index.js";
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constructor conversion with parameter properties
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import { IrClassMember, IrStatement } from "../../../../types.js";
|
|
7
|
+
import { convertType } from "../../../../type-converter.js";
|
|
8
|
+
import { convertBlockStatement } from "../../control.js";
|
|
9
|
+
import {
|
|
10
|
+
hasReadonlyModifier,
|
|
11
|
+
getAccessibility,
|
|
12
|
+
convertParameters,
|
|
13
|
+
} from "../../helpers.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Convert constructor declaration to IR
|
|
17
|
+
*/
|
|
18
|
+
export const convertConstructor = (
|
|
19
|
+
node: ts.ConstructorDeclaration,
|
|
20
|
+
checker: ts.TypeChecker,
|
|
21
|
+
constructorParams?: ts.NodeArray<ts.ParameterDeclaration>
|
|
22
|
+
): IrClassMember => {
|
|
23
|
+
// Build constructor body with parameter property assignments
|
|
24
|
+
const statements: IrStatement[] = [];
|
|
25
|
+
|
|
26
|
+
// Add assignments for parameter properties (parameters with explicit modifiers)
|
|
27
|
+
if (constructorParams) {
|
|
28
|
+
for (const param of constructorParams) {
|
|
29
|
+
// Check if parameter has an EXPLICIT accessibility modifier
|
|
30
|
+
const modifiers = ts.getModifiers(param);
|
|
31
|
+
const hasAccessibilityModifier = modifiers?.some(
|
|
32
|
+
(m) =>
|
|
33
|
+
m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
34
|
+
m.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
35
|
+
m.kind === ts.SyntaxKind.ProtectedKeyword
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if (hasAccessibilityModifier && ts.isIdentifier(param.name)) {
|
|
39
|
+
// Create: this.name = name;
|
|
40
|
+
statements.push({
|
|
41
|
+
kind: "expressionStatement",
|
|
42
|
+
expression: {
|
|
43
|
+
kind: "assignment",
|
|
44
|
+
operator: "=",
|
|
45
|
+
left: {
|
|
46
|
+
kind: "memberAccess",
|
|
47
|
+
object: { kind: "this" },
|
|
48
|
+
property: param.name.text,
|
|
49
|
+
isComputed: false,
|
|
50
|
+
isOptional: false,
|
|
51
|
+
},
|
|
52
|
+
right: {
|
|
53
|
+
kind: "identifier",
|
|
54
|
+
name: param.name.text,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Add existing constructor body statements
|
|
63
|
+
if (node.body) {
|
|
64
|
+
const existingBody = convertBlockStatement(node.body, checker);
|
|
65
|
+
statements.push(...existingBody.statements);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
kind: "constructorDeclaration",
|
|
70
|
+
parameters: convertParameters(node.parameters, checker),
|
|
71
|
+
body: { kind: "blockStatement", statements },
|
|
72
|
+
accessibility: getAccessibility(node),
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Extract parameter properties from constructor
|
|
78
|
+
*/
|
|
79
|
+
export const extractParameterProperties = (
|
|
80
|
+
constructor: ts.ConstructorDeclaration | undefined,
|
|
81
|
+
checker: ts.TypeChecker
|
|
82
|
+
): IrClassMember[] => {
|
|
83
|
+
if (!constructor) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const parameterProperties: IrClassMember[] = [];
|
|
88
|
+
|
|
89
|
+
for (const param of constructor.parameters) {
|
|
90
|
+
// Check if parameter has an EXPLICIT accessibility modifier
|
|
91
|
+
// (public/private/protected makes it a parameter property)
|
|
92
|
+
const modifiers = ts.getModifiers(param);
|
|
93
|
+
const hasAccessibilityModifier = modifiers?.some(
|
|
94
|
+
(m) =>
|
|
95
|
+
m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
96
|
+
m.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
97
|
+
m.kind === ts.SyntaxKind.ProtectedKeyword
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (!hasAccessibilityModifier) {
|
|
101
|
+
continue; // Not a parameter property
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Create a field declaration for this parameter property
|
|
105
|
+
if (ts.isIdentifier(param.name)) {
|
|
106
|
+
const accessibility = getAccessibility(param);
|
|
107
|
+
parameterProperties.push({
|
|
108
|
+
kind: "propertyDeclaration",
|
|
109
|
+
name: param.name.text,
|
|
110
|
+
type: param.type ? convertType(param.type, checker) : undefined,
|
|
111
|
+
initializer: undefined, // Will be assigned in constructor
|
|
112
|
+
isStatic: false,
|
|
113
|
+
isReadonly: hasReadonlyModifier(param),
|
|
114
|
+
accessibility,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return parameterProperties;
|
|
120
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Class conversion - Public API
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { convertClassDeclaration } from "./orchestrator.js";
|
|
6
|
+
export { detectOverride, type OverrideInfo } from "./override-detection.js";
|
|
7
|
+
export { convertProperty } from "./properties.js";
|
|
8
|
+
export { convertMethod } from "./methods.js";
|
|
9
|
+
export {
|
|
10
|
+
convertConstructor,
|
|
11
|
+
extractParameterProperties,
|
|
12
|
+
} from "./constructors.js";
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Method member conversion
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as ts from "typescript";
|
|
6
|
+
import { IrClassMember } from "../../../../types.js";
|
|
7
|
+
import { convertType } from "../../../../type-converter.js";
|
|
8
|
+
import { convertBlockStatement } from "../../control.js";
|
|
9
|
+
import {
|
|
10
|
+
hasStaticModifier,
|
|
11
|
+
getAccessibility,
|
|
12
|
+
convertTypeParameters,
|
|
13
|
+
convertParameters,
|
|
14
|
+
} from "../../helpers.js";
|
|
15
|
+
import { detectOverride } from "./override-detection.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Convert method declaration to IR
|
|
19
|
+
*/
|
|
20
|
+
export const convertMethod = (
|
|
21
|
+
node: ts.MethodDeclaration,
|
|
22
|
+
checker: ts.TypeChecker,
|
|
23
|
+
superClass: ts.ExpressionWithTypeArguments | undefined
|
|
24
|
+
): IrClassMember => {
|
|
25
|
+
const memberName = ts.isIdentifier(node.name) ? node.name.text : "[computed]";
|
|
26
|
+
|
|
27
|
+
// Extract parameter types for method signature
|
|
28
|
+
const parameterTypes = node.parameters.map((param) => {
|
|
29
|
+
if (param.type) {
|
|
30
|
+
// Get type string representation
|
|
31
|
+
const type = checker.getTypeAtLocation(param.type);
|
|
32
|
+
return checker.typeToString(type);
|
|
33
|
+
}
|
|
34
|
+
return "any";
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const overrideInfo = detectOverride(
|
|
38
|
+
memberName,
|
|
39
|
+
"method",
|
|
40
|
+
superClass,
|
|
41
|
+
checker,
|
|
42
|
+
parameterTypes
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
kind: "methodDeclaration",
|
|
47
|
+
name: memberName,
|
|
48
|
+
typeParameters: convertTypeParameters(node.typeParameters, checker),
|
|
49
|
+
parameters: convertParameters(node.parameters, checker),
|
|
50
|
+
returnType: node.type ? convertType(node.type, checker) : undefined,
|
|
51
|
+
body: node.body ? convertBlockStatement(node.body, checker) : undefined,
|
|
52
|
+
isStatic: hasStaticModifier(node),
|
|
53
|
+
isAsync: !!node.modifiers?.some(
|
|
54
|
+
(m) => m.kind === ts.SyntaxKind.AsyncKeyword
|
|
55
|
+
),
|
|
56
|
+
isGenerator: !!node.asteriskToken,
|
|
57
|
+
accessibility: getAccessibility(node),
|
|
58
|
+
isOverride: overrideInfo.isOverride ? true : undefined,
|
|
59
|
+
isShadow: overrideInfo.isShadow ? true : undefined,
|
|
60
|
+
};
|
|
61
|
+
};
|