@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.
Files changed (145) hide show
  1. package/package.json +53 -0
  2. package/src/dependency-graph.ts +18 -0
  3. package/src/dotnet-metadata.ts +121 -0
  4. package/src/graph/builder.ts +81 -0
  5. package/src/graph/circular.ts +58 -0
  6. package/src/graph/extraction/exports.ts +55 -0
  7. package/src/graph/extraction/imports.ts +81 -0
  8. package/src/graph/extraction/index.ts +7 -0
  9. package/src/graph/extraction/orchestrator.ts +99 -0
  10. package/src/graph/extraction.ts +10 -0
  11. package/src/graph/helpers.ts +51 -0
  12. package/src/graph/index.ts +17 -0
  13. package/src/graph/types.ts +13 -0
  14. package/src/index.ts +80 -0
  15. package/src/ir/binding-resolution.test.ts +585 -0
  16. package/src/ir/builder/exports.ts +78 -0
  17. package/src/ir/builder/helpers.ts +27 -0
  18. package/src/ir/builder/imports.ts +153 -0
  19. package/src/ir/builder/index.ts +10 -0
  20. package/src/ir/builder/orchestrator.ts +178 -0
  21. package/src/ir/builder/statements.ts +55 -0
  22. package/src/ir/builder/types.ts +8 -0
  23. package/src/ir/builder/validation.ts +129 -0
  24. package/src/ir/builder.test.ts +581 -0
  25. package/src/ir/builder.ts +14 -0
  26. package/src/ir/converters/expressions/access.ts +99 -0
  27. package/src/ir/converters/expressions/calls.ts +137 -0
  28. package/src/ir/converters/expressions/collections.ts +84 -0
  29. package/src/ir/converters/expressions/functions.ts +62 -0
  30. package/src/ir/converters/expressions/helpers.ts +264 -0
  31. package/src/ir/converters/expressions/index.ts +43 -0
  32. package/src/ir/converters/expressions/literals.ts +22 -0
  33. package/src/ir/converters/expressions/operators.ts +147 -0
  34. package/src/ir/converters/expressions/other.ts +60 -0
  35. package/src/ir/converters/statements/control/blocks.ts +22 -0
  36. package/src/ir/converters/statements/control/conditionals.ts +67 -0
  37. package/src/ir/converters/statements/control/exceptions.ts +43 -0
  38. package/src/ir/converters/statements/control/index.ts +17 -0
  39. package/src/ir/converters/statements/control/loops.ts +99 -0
  40. package/src/ir/converters/statements/control.ts +17 -0
  41. package/src/ir/converters/statements/declarations/classes/constructors.ts +120 -0
  42. package/src/ir/converters/statements/declarations/classes/index.ts +12 -0
  43. package/src/ir/converters/statements/declarations/classes/methods.ts +61 -0
  44. package/src/ir/converters/statements/declarations/classes/orchestrator.ts +166 -0
  45. package/src/ir/converters/statements/declarations/classes/override-detection.ts +116 -0
  46. package/src/ir/converters/statements/declarations/classes/properties.ts +63 -0
  47. package/src/ir/converters/statements/declarations/classes.ts +6 -0
  48. package/src/ir/converters/statements/declarations/enums.ts +29 -0
  49. package/src/ir/converters/statements/declarations/functions.ts +39 -0
  50. package/src/ir/converters/statements/declarations/index.ts +14 -0
  51. package/src/ir/converters/statements/declarations/interfaces.ts +131 -0
  52. package/src/ir/converters/statements/declarations/registry.ts +45 -0
  53. package/src/ir/converters/statements/declarations/type-aliases.ts +25 -0
  54. package/src/ir/converters/statements/declarations/variables.ts +60 -0
  55. package/src/ir/converters/statements/declarations.ts +16 -0
  56. package/src/ir/converters/statements/helpers.ts +174 -0
  57. package/src/ir/converters/statements/index.ts +40 -0
  58. package/src/ir/expression-converter.ts +207 -0
  59. package/src/ir/generic-validator.ts +100 -0
  60. package/src/ir/hierarchical-bindings-e2e.test.ts +163 -0
  61. package/src/ir/index.ts +6 -0
  62. package/src/ir/statement-converter.ts +128 -0
  63. package/src/ir/type-converter/arrays.ts +20 -0
  64. package/src/ir/type-converter/converter.ts +10 -0
  65. package/src/ir/type-converter/functions.ts +22 -0
  66. package/src/ir/type-converter/index.ts +11 -0
  67. package/src/ir/type-converter/inference.ts +122 -0
  68. package/src/ir/type-converter/literals.ts +40 -0
  69. package/src/ir/type-converter/objects.ts +107 -0
  70. package/src/ir/type-converter/orchestrator.ts +85 -0
  71. package/src/ir/type-converter/patterns.ts +73 -0
  72. package/src/ir/type-converter/primitives.ts +57 -0
  73. package/src/ir/type-converter/references.ts +64 -0
  74. package/src/ir/type-converter/unions-intersections.ts +34 -0
  75. package/src/ir/type-converter.ts +13 -0
  76. package/src/ir/types/expressions.ts +215 -0
  77. package/src/ir/types/guards.ts +39 -0
  78. package/src/ir/types/helpers.ts +135 -0
  79. package/src/ir/types/index.ts +108 -0
  80. package/src/ir/types/ir-types.ts +96 -0
  81. package/src/ir/types/module.ts +57 -0
  82. package/src/ir/types/statements.ts +238 -0
  83. package/src/ir/types.ts +97 -0
  84. package/src/metadata/bindings-loader.test.ts +144 -0
  85. package/src/metadata/bindings-loader.ts +357 -0
  86. package/src/metadata/index.ts +15 -0
  87. package/src/metadata/library-loader.ts +153 -0
  88. package/src/metadata/loader.test.ts +156 -0
  89. package/src/metadata/loader.ts +382 -0
  90. package/src/program/bindings.test.ts +512 -0
  91. package/src/program/bindings.ts +253 -0
  92. package/src/program/config.ts +30 -0
  93. package/src/program/creation.ts +249 -0
  94. package/src/program/dependency-graph.ts +245 -0
  95. package/src/program/diagnostics.ts +103 -0
  96. package/src/program/index.ts +19 -0
  97. package/src/program/metadata.ts +68 -0
  98. package/src/program/queries.ts +18 -0
  99. package/src/program/types.ts +38 -0
  100. package/src/program.ts +13 -0
  101. package/src/resolver/dotnet-import-resolver.ts +226 -0
  102. package/src/resolver/import-resolution.ts +177 -0
  103. package/src/resolver/index.ts +18 -0
  104. package/src/resolver/namespace.test.ts +86 -0
  105. package/src/resolver/namespace.ts +42 -0
  106. package/src/resolver/naming.ts +38 -0
  107. package/src/resolver/path-resolution.ts +22 -0
  108. package/src/resolver/types.ts +15 -0
  109. package/src/resolver.test.ts +155 -0
  110. package/src/resolver.ts +14 -0
  111. package/src/symbol-table/builder.ts +114 -0
  112. package/src/symbol-table/creation.ts +42 -0
  113. package/src/symbol-table/helpers.ts +18 -0
  114. package/src/symbol-table/index.ts +13 -0
  115. package/src/symbol-table/queries.ts +42 -0
  116. package/src/symbol-table/types.ts +28 -0
  117. package/src/symbol-table.ts +14 -0
  118. package/src/types/bindings.ts +172 -0
  119. package/src/types/diagnostic.test.ts +164 -0
  120. package/src/types/diagnostic.ts +153 -0
  121. package/src/types/explicit-views.test.ts +113 -0
  122. package/src/types/explicit-views.ts +218 -0
  123. package/src/types/metadata.ts +229 -0
  124. package/src/types/module.ts +99 -0
  125. package/src/types/nested-types.test.ts +194 -0
  126. package/src/types/nested-types.ts +215 -0
  127. package/src/types/parameter-modifiers.ts +173 -0
  128. package/src/types/ref-parameters.test.ts +192 -0
  129. package/src/types/ref-parameters.ts +268 -0
  130. package/src/types/result.test.ts +157 -0
  131. package/src/types/result.ts +48 -0
  132. package/src/types/support-types.test.ts +81 -0
  133. package/src/types/support-types.ts +288 -0
  134. package/src/types/test-harness.ts +180 -0
  135. package/src/validation/exports.ts +98 -0
  136. package/src/validation/features.ts +89 -0
  137. package/src/validation/generics.ts +40 -0
  138. package/src/validation/helpers.ts +31 -0
  139. package/src/validation/imports.ts +97 -0
  140. package/src/validation/index.ts +11 -0
  141. package/src/validation/orchestrator.ts +51 -0
  142. package/src/validation/static-safety.ts +267 -0
  143. package/src/validator.test.ts +468 -0
  144. package/src/validator.ts +15 -0
  145. 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
+ };