@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,85 @@
1
+ /**
2
+ * Type conversion orchestrator
3
+ */
4
+
5
+ import * as ts from "typescript";
6
+ import {
7
+ IrType,
8
+ IrFunctionType,
9
+ IrObjectType,
10
+ IrDictionaryType,
11
+ } from "../types.js";
12
+ import { convertPrimitiveKeyword } from "./primitives.js";
13
+ import { convertTypeReference } from "./references.js";
14
+ import { convertArrayType } from "./arrays.js";
15
+ import { convertFunctionType } from "./functions.js";
16
+ import { convertObjectType } from "./objects.js";
17
+ import {
18
+ convertUnionType,
19
+ convertIntersectionType,
20
+ } from "./unions-intersections.js";
21
+ import { convertLiteralType } from "./literals.js";
22
+
23
+ /**
24
+ * Convert TypeScript type node to IR type
25
+ */
26
+ export const convertType = (
27
+ typeNode: ts.TypeNode,
28
+ checker: ts.TypeChecker
29
+ ): IrType => {
30
+ // Type references (including primitive type names)
31
+ if (ts.isTypeReferenceNode(typeNode)) {
32
+ return convertTypeReference(typeNode, checker, convertType);
33
+ }
34
+
35
+ // Primitive keywords
36
+ const primitiveType = convertPrimitiveKeyword(typeNode.kind);
37
+ if (primitiveType) {
38
+ return primitiveType;
39
+ }
40
+
41
+ // Array types
42
+ if (ts.isArrayTypeNode(typeNode)) {
43
+ return convertArrayType(typeNode, checker, convertType);
44
+ }
45
+
46
+ // Function types
47
+ if (ts.isFunctionTypeNode(typeNode)) {
48
+ return convertFunctionType(typeNode, checker, convertType);
49
+ }
50
+
51
+ // Object/interface types
52
+ if (ts.isTypeLiteralNode(typeNode)) {
53
+ return convertObjectType(typeNode, checker, convertType);
54
+ }
55
+
56
+ // Union types
57
+ if (ts.isUnionTypeNode(typeNode)) {
58
+ return convertUnionType(typeNode, checker, convertType);
59
+ }
60
+
61
+ // Intersection types
62
+ if (ts.isIntersectionTypeNode(typeNode)) {
63
+ return convertIntersectionType(typeNode, checker, convertType);
64
+ }
65
+
66
+ // Literal types
67
+ if (ts.isLiteralTypeNode(typeNode)) {
68
+ return convertLiteralType(typeNode);
69
+ }
70
+
71
+ // Parenthesized types
72
+ if (ts.isParenthesizedTypeNode(typeNode)) {
73
+ return convertType(typeNode.type, checker);
74
+ }
75
+
76
+ // Default to any type for unsupported types
77
+ return { kind: "anyType" };
78
+ };
79
+
80
+ // Re-export specialized converters for backward compatibility
81
+ export { convertFunctionType } from "./functions.js";
82
+ export { convertObjectType } from "./objects.js";
83
+
84
+ // Export types
85
+ export type { IrFunctionType, IrObjectType, IrDictionaryType };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Binding pattern converter - TypeScript patterns to IR patterns
3
+ */
4
+
5
+ import * as ts from "typescript";
6
+ import { IrPattern, IrObjectPatternProperty } from "../types.js";
7
+
8
+ /**
9
+ * Convert TypeScript binding name to IR pattern
10
+ */
11
+ export const convertBindingName = (name: ts.BindingName): IrPattern => {
12
+ if (ts.isIdentifier(name)) {
13
+ return {
14
+ kind: "identifierPattern",
15
+ name: name.text,
16
+ };
17
+ }
18
+
19
+ if (ts.isArrayBindingPattern(name)) {
20
+ return {
21
+ kind: "arrayPattern",
22
+ elements: name.elements.map((elem) => {
23
+ if (ts.isOmittedExpression(elem)) {
24
+ return undefined; // Hole in array pattern
25
+ }
26
+ if (ts.isBindingElement(elem)) {
27
+ return convertBindingName(elem.name);
28
+ }
29
+ return undefined;
30
+ }),
31
+ };
32
+ }
33
+
34
+ if (ts.isObjectBindingPattern(name)) {
35
+ const properties: IrObjectPatternProperty[] = [];
36
+
37
+ name.elements.forEach((elem) => {
38
+ if (elem.dotDotDotToken) {
39
+ // Rest property
40
+ properties.push({
41
+ kind: "rest",
42
+ pattern: convertBindingName(elem.name),
43
+ });
44
+ } else {
45
+ const key = elem.propertyName
46
+ ? ts.isIdentifier(elem.propertyName)
47
+ ? elem.propertyName.text
48
+ : elem.propertyName.getText()
49
+ : ts.isIdentifier(elem.name)
50
+ ? elem.name.text
51
+ : "[computed]";
52
+
53
+ properties.push({
54
+ kind: "property",
55
+ key,
56
+ value: convertBindingName(elem.name),
57
+ shorthand: !elem.propertyName,
58
+ });
59
+ }
60
+ });
61
+
62
+ return {
63
+ kind: "objectPattern",
64
+ properties,
65
+ };
66
+ }
67
+
68
+ // Default to identifier pattern (should not reach here normally)
69
+ return {
70
+ kind: "identifierPattern",
71
+ name: "_unknown",
72
+ };
73
+ };
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Primitive type conversion
3
+ */
4
+
5
+ import * as ts from "typescript";
6
+ import { IrType } from "../types.js";
7
+
8
+ /**
9
+ * Convert TypeScript primitive keyword to IR type
10
+ */
11
+ export const convertPrimitiveKeyword = (kind: ts.SyntaxKind): IrType | null => {
12
+ switch (kind) {
13
+ case ts.SyntaxKind.StringKeyword:
14
+ return { kind: "primitiveType", name: "string" };
15
+ case ts.SyntaxKind.NumberKeyword:
16
+ return { kind: "primitiveType", name: "number" };
17
+ case ts.SyntaxKind.BooleanKeyword:
18
+ return { kind: "primitiveType", name: "boolean" };
19
+ case ts.SyntaxKind.NullKeyword:
20
+ return { kind: "primitiveType", name: "null" };
21
+ case ts.SyntaxKind.UndefinedKeyword:
22
+ return { kind: "primitiveType", name: "undefined" };
23
+ case ts.SyntaxKind.VoidKeyword:
24
+ return { kind: "voidType" };
25
+ case ts.SyntaxKind.AnyKeyword:
26
+ return { kind: "anyType" };
27
+ case ts.SyntaxKind.UnknownKeyword:
28
+ return { kind: "unknownType" };
29
+ case ts.SyntaxKind.NeverKeyword:
30
+ return { kind: "neverType" };
31
+ default:
32
+ return null;
33
+ }
34
+ };
35
+
36
+ /**
37
+ * Check if a type name is a primitive type
38
+ */
39
+ export const isPrimitiveTypeName = (
40
+ typeName: string
41
+ ): typeName is "string" | "number" | "boolean" | "null" | "undefined" => {
42
+ return ["string", "number", "boolean", "null", "undefined"].includes(
43
+ typeName
44
+ );
45
+ };
46
+
47
+ /**
48
+ * Get primitive type IR representation for a type name
49
+ */
50
+ export const getPrimitiveType = (
51
+ typeName: "string" | "number" | "boolean" | "null" | "undefined"
52
+ ): IrType => {
53
+ return {
54
+ kind: "primitiveType",
55
+ name: typeName,
56
+ };
57
+ };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Reference type conversion
3
+ */
4
+
5
+ import * as ts from "typescript";
6
+ import { IrType, IrDictionaryType } from "../types.js";
7
+ import { isPrimitiveTypeName, getPrimitiveType } from "./primitives.js";
8
+ import { getParameterModifierRegistry } from "../../types/parameter-modifiers.js";
9
+
10
+ /**
11
+ * Convert TypeScript type reference to IR type
12
+ * Handles both primitive type names and user-defined types
13
+ */
14
+ export const convertTypeReference = (
15
+ node: ts.TypeReferenceNode,
16
+ checker: ts.TypeChecker,
17
+ convertType: (node: ts.TypeNode, checker: ts.TypeChecker) => IrType
18
+ ): IrType => {
19
+ const typeName = ts.isIdentifier(node.typeName)
20
+ ? node.typeName.text
21
+ : node.typeName.getText();
22
+
23
+ // Check for primitive type names
24
+ if (isPrimitiveTypeName(typeName)) {
25
+ return getPrimitiveType(typeName);
26
+ }
27
+
28
+ // Check for Record<K, V> utility type → convert to IrDictionaryType
29
+ if (typeName === "Record" && node.typeArguments?.length === 2) {
30
+ const keyType = convertType(node.typeArguments[0]!, checker);
31
+ const valueType = convertType(node.typeArguments[1]!, checker);
32
+
33
+ return {
34
+ kind: "dictionaryType",
35
+ keyType,
36
+ valueType,
37
+ } as IrDictionaryType;
38
+ }
39
+
40
+ // Check if this is a parameter modifier type (ref/out/In) from @tsonic/types
41
+ const registry = getParameterModifierRegistry();
42
+ const modifierKind = registry.getParameterModifierKind(typeName);
43
+
44
+ if (modifierKind && node.typeArguments && node.typeArguments.length > 0) {
45
+ // This is ref<T>, out<T>, or In<T> from @tsonic/types
46
+ // Convert it to a special IR type that preserves the modifier
47
+ const wrappedType = convertType(node.typeArguments[0]!, checker);
48
+
49
+ return {
50
+ kind: "referenceType",
51
+ name: typeName,
52
+ typeArguments: [wrappedType],
53
+ // Add metadata to indicate this is a parameter modifier
54
+ parameterModifier: modifierKind,
55
+ } as IrType & { parameterModifier?: "ref" | "out" | "in" };
56
+ }
57
+
58
+ // Reference type (user-defined or library)
59
+ return {
60
+ kind: "referenceType",
61
+ name: typeName,
62
+ typeArguments: node.typeArguments?.map((t) => convertType(t, checker)),
63
+ };
64
+ };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Union and intersection type conversion
3
+ */
4
+
5
+ import * as ts from "typescript";
6
+ import { IrType } from "../types.js";
7
+
8
+ /**
9
+ * Convert TypeScript union type to IR union type
10
+ */
11
+ export const convertUnionType = (
12
+ node: ts.UnionTypeNode,
13
+ checker: ts.TypeChecker,
14
+ convertType: (node: ts.TypeNode, checker: ts.TypeChecker) => IrType
15
+ ): IrType => {
16
+ return {
17
+ kind: "unionType",
18
+ types: node.types.map((t) => convertType(t, checker)),
19
+ };
20
+ };
21
+
22
+ /**
23
+ * Convert TypeScript intersection type to IR intersection type
24
+ */
25
+ export const convertIntersectionType = (
26
+ node: ts.IntersectionTypeNode,
27
+ checker: ts.TypeChecker,
28
+ convertType: (node: ts.TypeNode, checker: ts.TypeChecker) => IrType
29
+ ): IrType => {
30
+ return {
31
+ kind: "intersectionType",
32
+ types: node.types.map((t) => convertType(t, checker)),
33
+ };
34
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Type converter - TypeScript types to IR types
3
+ * Main dispatcher - re-exports from type-converter/ subdirectory
4
+ */
5
+
6
+ export {
7
+ convertType,
8
+ convertFunctionType,
9
+ convertObjectType,
10
+ convertBindingName,
11
+ inferType,
12
+ convertTsTypeToIr,
13
+ } from "./type-converter/index.js";
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Expression types for IR
3
+ */
4
+
5
+ import { IrType } from "./ir-types.js";
6
+ import {
7
+ IrParameter,
8
+ IrPattern,
9
+ IrBinaryOperator,
10
+ IrAssignmentOperator,
11
+ } from "./helpers.js";
12
+ import { IrBlockStatement } from "./statements.js";
13
+
14
+ export type IrExpression =
15
+ | IrLiteralExpression
16
+ | IrIdentifierExpression
17
+ | IrArrayExpression
18
+ | IrObjectExpression
19
+ | IrFunctionExpression
20
+ | IrArrowFunctionExpression
21
+ | IrMemberExpression
22
+ | IrCallExpression
23
+ | IrNewExpression
24
+ | IrThisExpression
25
+ | IrUpdateExpression
26
+ | IrUnaryExpression
27
+ | IrBinaryExpression
28
+ | IrLogicalExpression
29
+ | IrConditionalExpression
30
+ | IrAssignmentExpression
31
+ | IrTemplateLiteralExpression
32
+ | IrSpreadExpression
33
+ | IrAwaitExpression
34
+ | IrYieldExpression;
35
+
36
+ export type IrLiteralExpression = {
37
+ readonly kind: "literal";
38
+ readonly value: string | number | boolean | null | undefined;
39
+ readonly raw?: string;
40
+ readonly inferredType?: IrType;
41
+ };
42
+
43
+ export type IrIdentifierExpression = {
44
+ readonly kind: "identifier";
45
+ readonly name: string;
46
+ readonly inferredType?: IrType;
47
+ // Resolved binding for globals (console, Math, etc.)
48
+ readonly resolvedClrType?: string; // e.g., "Tsonic.Runtime.console"
49
+ readonly resolvedAssembly?: string; // e.g., "Tsonic.Runtime"
50
+ readonly csharpName?: string; // Optional: renamed identifier in C# (from binding)
51
+ // For imported symbols from local modules
52
+ readonly importedFrom?: {
53
+ readonly containerName: string; // e.g., "Math"
54
+ readonly exportName: string; // e.g., "add" (may differ from local name if aliased)
55
+ readonly namespace: string; // e.g., "MultiFileCheck.utils"
56
+ };
57
+ };
58
+
59
+ export type IrArrayExpression = {
60
+ readonly kind: "array";
61
+ readonly elements: readonly (IrExpression | IrSpreadExpression | undefined)[]; // undefined for holes
62
+ readonly inferredType?: IrType;
63
+ };
64
+
65
+ export type IrObjectExpression = {
66
+ readonly kind: "object";
67
+ readonly properties: readonly IrObjectProperty[];
68
+ readonly inferredType?: IrType;
69
+ /** Contextual type for object literals in typed positions (return, assignment, etc.) */
70
+ readonly contextualType?: IrType;
71
+ };
72
+
73
+ export type IrObjectProperty =
74
+ | {
75
+ readonly kind: "property";
76
+ readonly key: string | IrExpression;
77
+ readonly value: IrExpression;
78
+ readonly shorthand: boolean;
79
+ }
80
+ | { readonly kind: "spread"; readonly expression: IrExpression };
81
+
82
+ export type IrFunctionExpression = {
83
+ readonly kind: "functionExpression";
84
+ readonly name?: string;
85
+ readonly parameters: readonly IrParameter[];
86
+ readonly returnType?: IrType;
87
+ readonly body: IrBlockStatement;
88
+ readonly isAsync: boolean;
89
+ readonly isGenerator: boolean;
90
+ readonly inferredType?: IrType;
91
+ };
92
+
93
+ export type IrArrowFunctionExpression = {
94
+ readonly kind: "arrowFunction";
95
+ readonly parameters: readonly IrParameter[];
96
+ readonly returnType?: IrType;
97
+ readonly body: IrBlockStatement | IrExpression;
98
+ readonly isAsync: boolean;
99
+ readonly inferredType?: IrType;
100
+ };
101
+
102
+ export type IrMemberExpression = {
103
+ readonly kind: "memberAccess";
104
+ readonly object: IrExpression;
105
+ readonly property: IrExpression | string;
106
+ readonly isComputed: boolean; // true for obj[prop], false for obj.prop
107
+ readonly isOptional: boolean; // true for obj?.prop
108
+ readonly inferredType?: IrType;
109
+ // Hierarchical member binding (from bindings manifest)
110
+ // When a member access like systemLinq.enumerable.selectMany is resolved,
111
+ // this contains the full CLR binding info
112
+ readonly memberBinding?: {
113
+ readonly assembly: string; // e.g., "System.Linq"
114
+ readonly type: string; // Full CLR type e.g., "System.Linq.Enumerable"
115
+ readonly member: string; // CLR member name e.g., "SelectMany"
116
+ };
117
+ };
118
+
119
+ export type IrCallExpression = {
120
+ readonly kind: "call";
121
+ readonly callee: IrExpression;
122
+ readonly arguments: readonly (IrExpression | IrSpreadExpression)[];
123
+ readonly isOptional: boolean; // true for func?.()
124
+ readonly inferredType?: IrType;
125
+ readonly typeArguments?: readonly IrType[]; // Explicit or inferred type arguments
126
+ readonly requiresSpecialization?: boolean; // Flag for conditional/unsupported patterns
127
+ readonly argumentPassing?: readonly ("value" | "ref" | "out" | "in")[]; // Passing mode for each argument
128
+ };
129
+
130
+ export type IrNewExpression = {
131
+ readonly kind: "new";
132
+ readonly callee: IrExpression;
133
+ readonly arguments: readonly (IrExpression | IrSpreadExpression)[];
134
+ readonly inferredType?: IrType;
135
+ readonly typeArguments?: readonly IrType[]; // Explicit or inferred type arguments
136
+ readonly requiresSpecialization?: boolean; // Flag for conditional/unsupported patterns
137
+ };
138
+
139
+ export type IrThisExpression = {
140
+ readonly kind: "this";
141
+ readonly inferredType?: IrType;
142
+ };
143
+
144
+ export type IrUpdateExpression = {
145
+ readonly kind: "update";
146
+ readonly operator: "++" | "--";
147
+ readonly prefix: boolean;
148
+ readonly expression: IrExpression;
149
+ readonly inferredType?: IrType;
150
+ };
151
+
152
+ export type IrUnaryExpression = {
153
+ readonly kind: "unary";
154
+ readonly operator: "+" | "-" | "!" | "~" | "typeof" | "void" | "delete";
155
+ readonly expression: IrExpression;
156
+ readonly inferredType?: IrType;
157
+ };
158
+
159
+ export type IrBinaryExpression = {
160
+ readonly kind: "binary";
161
+ readonly operator: IrBinaryOperator;
162
+ readonly left: IrExpression;
163
+ readonly right: IrExpression;
164
+ readonly inferredType?: IrType;
165
+ };
166
+
167
+ export type IrLogicalExpression = {
168
+ readonly kind: "logical";
169
+ readonly operator: "&&" | "||" | "??";
170
+ readonly left: IrExpression;
171
+ readonly right: IrExpression;
172
+ readonly inferredType?: IrType;
173
+ };
174
+
175
+ export type IrConditionalExpression = {
176
+ readonly kind: "conditional";
177
+ readonly condition: IrExpression;
178
+ readonly whenTrue: IrExpression;
179
+ readonly whenFalse: IrExpression;
180
+ readonly inferredType?: IrType;
181
+ };
182
+
183
+ export type IrAssignmentExpression = {
184
+ readonly kind: "assignment";
185
+ readonly operator: IrAssignmentOperator;
186
+ readonly left: IrExpression | IrPattern;
187
+ readonly right: IrExpression;
188
+ readonly inferredType?: IrType;
189
+ };
190
+
191
+ export type IrTemplateLiteralExpression = {
192
+ readonly kind: "templateLiteral";
193
+ readonly quasis: readonly string[];
194
+ readonly expressions: readonly IrExpression[];
195
+ readonly inferredType?: IrType;
196
+ };
197
+
198
+ export type IrSpreadExpression = {
199
+ readonly kind: "spread";
200
+ readonly expression: IrExpression;
201
+ readonly inferredType?: IrType;
202
+ };
203
+
204
+ export type IrAwaitExpression = {
205
+ readonly kind: "await";
206
+ readonly expression: IrExpression;
207
+ readonly inferredType?: IrType;
208
+ };
209
+
210
+ export type IrYieldExpression = {
211
+ readonly kind: "yield";
212
+ readonly expression?: IrExpression; // Optional for bare `yield`
213
+ readonly delegate: boolean; // true for `yield*`, false for `yield`
214
+ readonly inferredType?: IrType;
215
+ };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Type guard helper functions
3
+ */
4
+
5
+ import { IrStatement } from "./statements.js";
6
+ import { IrExpression } from "./expressions.js";
7
+
8
+ export const isStatement = (
9
+ node: IrStatement | IrExpression
10
+ ): node is IrStatement => {
11
+ const statementKinds: string[] = [
12
+ "variableDeclaration",
13
+ "functionDeclaration",
14
+ "classDeclaration",
15
+ "interfaceDeclaration",
16
+ "enumDeclaration",
17
+ "typeAliasDeclaration",
18
+ "expressionStatement",
19
+ "returnStatement",
20
+ "ifStatement",
21
+ "whileStatement",
22
+ "forStatement",
23
+ "forOfStatement",
24
+ "switchStatement",
25
+ "throwStatement",
26
+ "tryStatement",
27
+ "blockStatement",
28
+ "breakStatement",
29
+ "continueStatement",
30
+ "emptyStatement",
31
+ ];
32
+ return statementKinds.includes(node.kind);
33
+ };
34
+
35
+ export const isExpression = (
36
+ node: IrStatement | IrExpression
37
+ ): node is IrExpression => {
38
+ return !isStatement(node);
39
+ };