xray16 1.6.1 → 1.6.3

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/README.md CHANGED
@@ -62,6 +62,7 @@ Plugins can be included in [tstl tsconfig](https://typescripttolua.github.io/doc
62
62
  { "name": "xray16/plugins/inject_filename" },
63
63
  { "name": "xray16/plugins/from_cast_utils" },
64
64
  { "name": "xray16/plugins/optimize_return_ternary" },
65
+ { "name": "xray16/plugins/inline_constants/plugin" },
65
66
  { "name": "xray16/plugins/inject_tracy_zones" }
66
67
  ]
67
68
  }
@@ -112,6 +113,43 @@ All the calls are completely gets stripped and removed from runtime.
112
113
  Plugin rewrites returned ternary expressions into direct `if` / `else` branch returns when it is safe.\
113
114
  This avoids temporary result locals for patterns like `return condition ? first : second` while preserving general ternary semantics.
114
115
 
116
+ ### inline_constants
117
+
118
+ Plugin inlining compile-time constant values of `@inline` JSDoc tagged declarations.\
119
+ Supported targets are enums, module-level `as const` object literals and module-level scalar constants.\
120
+ Member accesses are replaced with literal values in place, while original tables are still emitted,
121
+ so iteration / reverse mapping / whole-object usages keep working.\
122
+ Tagged declarations act as an explicit whitelist and produce build errors when they cannot be inlined.
123
+
124
+ Values may be literals or expressions foldable on build time - arithmetic, string concatenation,
125
+ template literals and references to other constant declarations (enum members, module-level const scalars,
126
+ `as const` object properties, whitelisted namespace constants like `math.pi`).\
127
+ Runtime-dependent expressions (function calls, mutable object properties, values producing NaN / Infinity)
128
+ are rejected with build errors.
129
+
130
+ ```typescript
131
+ /**
132
+ * @inline
133
+ */
134
+ export const medkits = {
135
+ medkit: "medkit",
136
+ medkit_army: "medkit_army",
137
+ } as const;
138
+
139
+ /**
140
+ * @inline
141
+ */
142
+ export const TIMEOUT: number = 60 * 1000;
143
+
144
+ /**
145
+ * @inline
146
+ */
147
+ export const PI_DEGREE: number = math.pi / 180;
148
+
149
+ // Build time: `medkits.medkit_army` access is emitted as plain "medkit_army" string literal.
150
+ // Build time: `TIMEOUT` reference is emitted as 60000, `PI_DEGREE` as 0.017453292519943295.
151
+ ```
152
+
115
153
  ### inject_tracy_zones
116
154
 
117
155
  Plugin designed to work specifically with [tracy profiler](https://github.com/wolfpld/tracy).\
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xray16",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "author": "Neloreck",
5
5
  "repository": "https://github.com/xray-forge/xray-16-types",
6
6
  "homepage": "https://xray-forge.github.io/xray-16-types/index.html",
@@ -11,10 +11,11 @@
11
11
  "prepublish": "npm run build",
12
12
  "prepack": "npm run build",
13
13
  "build": "npm run build:plugins && npm run build:types",
14
- "build:plugins": "tsc -p ./src/tsconfig.json",
14
+ "build:plugins": "tsc -p ./src/tsconfig.build.json",
15
15
  "build:types": "rollup -c rollup.dts.config.mjs",
16
16
  "build:docs": "typedoc",
17
- "typecheck": "tsc --noEmit",
17
+ "test": "jest",
18
+ "typecheck": "tsc --noEmit && tsc --noEmit -p ./src/tsconfig.json",
18
19
  "typedoc": "typedoc",
19
20
  "format": "prettier --write \"**/*.(js|ts|tsx|md)\" && eslint . --fix",
20
21
  "lint": "eslint ."
@@ -24,6 +25,7 @@
24
25
  },
25
26
  "devDependencies": {
26
27
  "@eslint/js": "^9.39.4",
28
+ "@types/jest": "^29.5.14",
27
29
  "@types/node": "22.10.2",
28
30
  "@typescript-eslint/eslint-plugin": "^8.62.0",
29
31
  "@typescript-eslint/parser": "^8.62.0",
@@ -34,9 +36,11 @@
34
36
  "eslint-plugin-jest": "^29.15.2",
35
37
  "eslint-plugin-jsdoc": "^63.0.7",
36
38
  "globals": "^17.7.0",
39
+ "jest": "^29.7.0",
37
40
  "prettier": "^3.4.2",
38
41
  "rollup": "^4.62.2",
39
42
  "rollup-plugin-dts": "^6.4.1",
43
+ "ts-jest": "^29.4.11",
40
44
  "typedoc": "^0.27.5",
41
45
  "typescript": "5.7.2",
42
46
  "typescript-eslint": "^8.62.0",
@@ -0,0 +1,14 @@
1
+ import { type Plugin } from "typescript-to-lua";
2
+ /**
3
+ * Plugin that inlines compile-time constant values of `@inline` JSDoc tagged declarations.
4
+ *
5
+ * Supported targets are enums, module-level `as const` object literals and module-level scalar constants.
6
+ * Values may be literals or expressions foldable on build time - arithmetic, string concatenation,
7
+ * template literals and references to other constant declarations (enum members, const scalars,
8
+ * `as const` object properties, whitelisted constants like 'math.pi').
9
+ * Tagged declarations act as an explicit whitelist - member accesses are replaced with literal values in place,
10
+ * while original tables are still emitted, so iteration / reverse mapping / whole-object usages keep working.
11
+ * Tagged declarations that cannot be inlined produce build errors instead of silently emitting property lookups.
12
+ */
13
+ declare const plugin: Plugin;
14
+ export default plugin;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ts = require("typescript");
4
+ const transformation_1 = require("./transformation");
5
+ /**
6
+ * Plugin that inlines compile-time constant values of `@inline` JSDoc tagged declarations.
7
+ *
8
+ * Supported targets are enums, module-level `as const` object literals and module-level scalar constants.
9
+ * Values may be literals or expressions foldable on build time - arithmetic, string concatenation,
10
+ * template literals and references to other constant declarations (enum members, const scalars,
11
+ * `as const` object properties, whitelisted constants like 'math.pi').
12
+ * Tagged declarations act as an explicit whitelist - member accesses are replaced with literal values in place,
13
+ * while original tables are still emitted, so iteration / reverse mapping / whole-object usages keep working.
14
+ * Tagged declarations that cannot be inlined produce build errors instead of silently emitting property lookups.
15
+ */
16
+ const plugin = {
17
+ beforeTransform(program) {
18
+ // Force binder to assign node parents before any 'getJSDocTags' call,
19
+ // otherwise empty results are computed for parent-less nodes and cached on them forever.
20
+ program.getTypeChecker();
21
+ const diagnostics = (0, transformation_1.validateTopLevelTags)(program);
22
+ if (diagnostics.length > 0) {
23
+ return diagnostics;
24
+ }
25
+ },
26
+ visitors: {
27
+ [ts.SyntaxKind.PropertyAccessExpression]: transformation_1.transformAccessExpression,
28
+ [ts.SyntaxKind.ElementAccessExpression]: transformation_1.transformAccessExpression,
29
+ [ts.SyntaxKind.Identifier]: transformation_1.transformIdentifierExpression,
30
+ [ts.SyntaxKind.VariableStatement]: (statement, context) => {
31
+ if ((0, transformation_1.hasInlineTag)(statement)) {
32
+ (0, transformation_1.validateVariableStatement)(statement, context);
33
+ }
34
+ return context.superTransformStatements(statement);
35
+ },
36
+ [ts.SyntaxKind.EnumDeclaration]: (declaration, context) => {
37
+ if ((0, transformation_1.hasInlineTag)(declaration)) {
38
+ (0, transformation_1.validateEnumDeclaration)(declaration, context);
39
+ }
40
+ return context.superTransformStatements(declaration);
41
+ },
42
+ },
43
+ };
44
+ exports.default = plugin;
@@ -0,0 +1,60 @@
1
+ import * as ts from "typescript";
2
+ /**
3
+ * Check whether node is annotated with `@inline` JSDoc tag.
4
+ *
5
+ * @param node - Node to check tags for.
6
+ * @returns Whether the node has `@inline` JSDoc tag.
7
+ */
8
+ export declare function hasInlineTag(node: ts.Node): boolean;
9
+ /**
10
+ * Find variable statement containing provided declaration node, if any.
11
+ *
12
+ * @param node - Declaration node to walk up from.
13
+ * @returns Containing variable statement or null.
14
+ */
15
+ export declare function getContainingVariableStatement(node: ts.Node): ts.VariableStatement | null;
16
+ /**
17
+ * Unwrap initializer expression from as/satisfies/parenthesized wrappers.
18
+ *
19
+ * @param expression - Initializer expression to unwrap.
20
+ * @returns Unwrapped expression or null.
21
+ */
22
+ export declare function unwrapInitializer(expression?: ts.Expression): ts.Expression | null;
23
+ /**
24
+ * Check whether variable statement is a module-level `const` declaration.
25
+ *
26
+ * @param statement - Variable statement to check.
27
+ * @returns Whether statement is module-level const.
28
+ */
29
+ export declare function isModuleLevelConst(statement: ts.VariableStatement): boolean;
30
+ /**
31
+ * Check whether expression is wrapped with `as const` assertion, possibly through parens/satisfies wrappers.
32
+ *
33
+ * @param expression - Expression to check.
34
+ * @returns Whether expression has `as const` assertion.
35
+ */
36
+ export declare function hasAsConstAssertion(expression?: ts.Expression): boolean;
37
+ /**
38
+ * Check whether property is declared inside an `as const` object literal assigned to a module-level const.
39
+ * Such properties are readonly and cannot be legally reassigned, so their values are stable at runtime.
40
+ *
41
+ * @param declaration - Property declaration to check.
42
+ * @returns Whether property value is safe to fold.
43
+ */
44
+ export declare function isReadonlyModuleConstProperty(declaration: ts.PropertyAssignment | ts.ShorthandPropertyAssignment): boolean;
45
+ /**
46
+ * Check whether identifier node is used in a value position where it can be replaced with a literal.
47
+ *
48
+ * @param node - Identifier node to check.
49
+ * @returns Whether identifier is a replace-able value usage.
50
+ */
51
+ export declare function isValueUsagePosition(node: ts.Identifier): boolean;
52
+ /**
53
+ * Resolve member symbol for property/element access expression.
54
+ * Element access with literal key is resolved through object type when direct symbol resolution fails.
55
+ *
56
+ * @param checker - Program type checker.
57
+ * @param node - Access expression to resolve symbol for.
58
+ * @returns Resolved member symbol or null.
59
+ */
60
+ export declare function resolveMemberSymbol(checker: ts.TypeChecker, node: ts.PropertyAccessExpression | ts.ElementAccessExpression): ts.Symbol | null;
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasInlineTag = hasInlineTag;
4
+ exports.getContainingVariableStatement = getContainingVariableStatement;
5
+ exports.unwrapInitializer = unwrapInitializer;
6
+ exports.isModuleLevelConst = isModuleLevelConst;
7
+ exports.hasAsConstAssertion = hasAsConstAssertion;
8
+ exports.isReadonlyModuleConstProperty = isReadonlyModuleConstProperty;
9
+ exports.isValueUsagePosition = isValueUsagePosition;
10
+ exports.resolveMemberSymbol = resolveMemberSymbol;
11
+ const ts = require("typescript");
12
+ const constants_1 = require("./constants");
13
+ /**
14
+ * Check whether node is annotated with `@inline` JSDoc tag.
15
+ *
16
+ * @param node - Node to check tags for.
17
+ * @returns Whether the node has `@inline` JSDoc tag.
18
+ */
19
+ function hasInlineTag(node) {
20
+ return ts.getJSDocTags(node).some((it) => it.tagName.text === constants_1.INLINE_TAG);
21
+ }
22
+ /**
23
+ * Find variable statement containing provided declaration node, if any.
24
+ *
25
+ * @param node - Declaration node to walk up from.
26
+ * @returns Containing variable statement or null.
27
+ */
28
+ function getContainingVariableStatement(node) {
29
+ let current = node;
30
+ while (current !== undefined && !ts.isSourceFile(current)) {
31
+ if (ts.isVariableStatement(current)) {
32
+ return current;
33
+ }
34
+ current = current.parent;
35
+ }
36
+ return null;
37
+ }
38
+ /**
39
+ * Unwrap initializer expression from as/satisfies/parenthesized wrappers.
40
+ *
41
+ * @param expression - Initializer expression to unwrap.
42
+ * @returns Unwrapped expression or null.
43
+ */
44
+ function unwrapInitializer(expression) {
45
+ let current = expression ?? null;
46
+ while (current !== null &&
47
+ (ts.isAsExpression(current) ||
48
+ ts.isSatisfiesExpression(current) ||
49
+ ts.isParenthesizedExpression(current) ||
50
+ ts.isTypeAssertionExpression(current))) {
51
+ current = current.expression;
52
+ }
53
+ return current;
54
+ }
55
+ /**
56
+ * Check whether variable statement is a module-level `const` declaration.
57
+ *
58
+ * @param statement - Variable statement to check.
59
+ * @returns Whether statement is module-level const.
60
+ */
61
+ function isModuleLevelConst(statement) {
62
+ return ts.isSourceFile(statement.parent) && (statement.declarationList.flags & ts.NodeFlags.Const) !== 0;
63
+ }
64
+ /**
65
+ * Check whether expression is wrapped with `as const` assertion, possibly through parens/satisfies wrappers.
66
+ *
67
+ * @param expression - Expression to check.
68
+ * @returns Whether expression has `as const` assertion.
69
+ */
70
+ function hasAsConstAssertion(expression) {
71
+ let current = expression;
72
+ while (current !== undefined) {
73
+ if (ts.isAsExpression(current) &&
74
+ ts.isTypeReferenceNode(current.type) &&
75
+ current.type.typeName.getText() === "const") {
76
+ return true;
77
+ }
78
+ if (ts.isAsExpression(current) || ts.isParenthesizedExpression(current) || ts.isSatisfiesExpression(current)) {
79
+ current = current.expression;
80
+ }
81
+ else {
82
+ return false;
83
+ }
84
+ }
85
+ return false;
86
+ }
87
+ /**
88
+ * Check whether property is declared inside an `as const` object literal assigned to a module-level const.
89
+ * Such properties are readonly and cannot be legally reassigned, so their values are stable at runtime.
90
+ *
91
+ * @param declaration - Property declaration to check.
92
+ * @returns Whether property value is safe to fold.
93
+ */
94
+ function isReadonlyModuleConstProperty(declaration) {
95
+ let sawAsConst = false;
96
+ let current = declaration.parent;
97
+ while (current !== undefined && !ts.isVariableDeclaration(current)) {
98
+ if (ts.isAsExpression(current) &&
99
+ ts.isTypeReferenceNode(current.type) &&
100
+ current.type.typeName.getText() === "const") {
101
+ sawAsConst = true;
102
+ }
103
+ if (!ts.isObjectLiteralExpression(current) &&
104
+ !ts.isPropertyAssignment(current) &&
105
+ !ts.isAsExpression(current) &&
106
+ !ts.isParenthesizedExpression(current) &&
107
+ !ts.isSatisfiesExpression(current)) {
108
+ return false;
109
+ }
110
+ current = current.parent;
111
+ }
112
+ if (current === undefined || !sawAsConst) {
113
+ return false;
114
+ }
115
+ const statement = getContainingVariableStatement(current);
116
+ return statement !== null && isModuleLevelConst(statement);
117
+ }
118
+ /**
119
+ * Check whether identifier node is used in a value position where it can be replaced with a literal.
120
+ *
121
+ * @param node - Identifier node to check.
122
+ * @returns Whether identifier is a replace-able value usage.
123
+ */
124
+ function isValueUsagePosition(node) {
125
+ const parent = node.parent;
126
+ if (parent === undefined || ts.isPartOfTypeNode(node)) {
127
+ return false;
128
+ }
129
+ if (ts.isPropertyAccessExpression(parent)) {
130
+ return parent.expression === node;
131
+ }
132
+ if (ts.isPropertyAssignment(parent) ||
133
+ ts.isBindingElement(parent) ||
134
+ ts.isParameter(parent) ||
135
+ ts.isEnumMember(parent) ||
136
+ ts.isPropertyDeclaration(parent) ||
137
+ ts.isVariableDeclaration(parent)) {
138
+ return parent.initializer === node;
139
+ }
140
+ if (ts.isShorthandPropertyAssignment(parent) ||
141
+ ts.isImportSpecifier(parent) ||
142
+ ts.isImportClause(parent) ||
143
+ ts.isNamespaceImport(parent) ||
144
+ ts.isExportSpecifier(parent) ||
145
+ ts.isNamespaceExport(parent) ||
146
+ ts.isImportEqualsDeclaration(parent) ||
147
+ ts.isQualifiedName(parent) ||
148
+ ts.isLabeledStatement(parent) ||
149
+ ts.isBreakOrContinueStatement(parent)) {
150
+ return false;
151
+ }
152
+ if (ts.isFunctionDeclaration(parent) ||
153
+ ts.isFunctionExpression(parent) ||
154
+ ts.isClassDeclaration(parent) ||
155
+ ts.isClassExpression(parent) ||
156
+ ts.isMethodDeclaration(parent) ||
157
+ ts.isGetAccessorDeclaration(parent) ||
158
+ ts.isSetAccessorDeclaration(parent) ||
159
+ ts.isModuleDeclaration(parent) ||
160
+ ts.isEnumDeclaration(parent) ||
161
+ ts.isInterfaceDeclaration(parent) ||
162
+ ts.isTypeAliasDeclaration(parent)) {
163
+ return parent.name !== node;
164
+ }
165
+ return true;
166
+ }
167
+ /**
168
+ * Resolve member symbol for property/element access expression.
169
+ * Element access with literal key is resolved through object type when direct symbol resolution fails.
170
+ *
171
+ * @param checker - Program type checker.
172
+ * @param node - Access expression to resolve symbol for.
173
+ * @returns Resolved member symbol or null.
174
+ */
175
+ function resolveMemberSymbol(checker, node) {
176
+ const symbol = checker.getSymbolAtLocation(node);
177
+ if (symbol !== undefined) {
178
+ return symbol;
179
+ }
180
+ if (ts.isElementAccessExpression(node) &&
181
+ (ts.isStringLiteralLike(node.argumentExpression) || ts.isNumericLiteral(node.argumentExpression))) {
182
+ return checker.getTypeAtLocation(node.expression).getProperty(node.argumentExpression.text) ?? null;
183
+ }
184
+ return null;
185
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * JSDoc tag marking declarations as whitelisted for compile-time inlining.
3
+ */
4
+ export declare const INLINE_TAG: string;
5
+ /**
6
+ * Value types that can be inlined as lua literals.
7
+ */
8
+ export type TInlineValue = string | number | boolean;
9
+ /**
10
+ * Numeric namespace constants that are identical IEEE 754 doubles in build environment and LuaJIT runtime.
11
+ * Covers both TS 'Math' and lua 'math' namespaces, function calls are intentionally not supported
12
+ * since libm implementations may differ between build machine and game runtime.
13
+ */
14
+ export declare const FOLDABLE_NAMESPACE_CONSTANTS: Record<string, Record<string, number>>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FOLDABLE_NAMESPACE_CONSTANTS = exports.INLINE_TAG = void 0;
4
+ /**
5
+ * JSDoc tag marking declarations as whitelisted for compile-time inlining.
6
+ */
7
+ exports.INLINE_TAG = "inline";
8
+ /**
9
+ * Numeric namespace constants that are identical IEEE 754 doubles in build environment and LuaJIT runtime.
10
+ * Covers both TS 'Math' and lua 'math' namespaces, function calls are intentionally not supported
11
+ * since libm implementations may differ between build machine and game runtime.
12
+ */
13
+ exports.FOLDABLE_NAMESPACE_CONSTANTS = {
14
+ Math: {
15
+ E: Math.E,
16
+ LN10: Math.LN10,
17
+ LN2: Math.LN2,
18
+ LOG10E: Math.LOG10E,
19
+ LOG2E: Math.LOG2E,
20
+ PI: Math.PI,
21
+ SQRT1_2: Math.SQRT1_2,
22
+ SQRT2: Math.SQRT2,
23
+ },
24
+ math: {
25
+ pi: Math.PI,
26
+ },
27
+ };
@@ -0,0 +1,24 @@
1
+ export declare const createUnsupportedDeclarationError: ((node: import("typescript").Node, ...args: any[]) => import("typescript").Diagnostic) & {
2
+ code: number;
3
+ };
4
+ export declare const createNotModuleLevelError: ((node: import("typescript").Node, ...args: any[]) => import("typescript").Diagnostic) & {
5
+ code: number;
6
+ };
7
+ export declare const createNotConstError: ((node: import("typescript").Node, ...args: any[]) => import("typescript").Diagnostic) & {
8
+ code: number;
9
+ };
10
+ export declare const createNotAsConstObjectError: ((node: import("typescript").Node, name: string) => import("typescript").Diagnostic) & {
11
+ code: number;
12
+ };
13
+ export declare const createNotLiteralConstantError: ((node: import("typescript").Node, name: string) => import("typescript").Diagnostic) & {
14
+ code: number;
15
+ };
16
+ export declare const createNotLiteralPropertyError: ((node: import("typescript").Node, object: string, property: string) => import("typescript").Diagnostic) & {
17
+ code: number;
18
+ };
19
+ export declare const createForeignPropertyError: ((node: import("typescript").Node, object: string, property: string) => import("typescript").Diagnostic) & {
20
+ code: number;
21
+ };
22
+ export declare const createNotConstantEnumMemberError: ((node: import("typescript").Node, name: string) => import("typescript").Diagnostic) & {
23
+ code: number;
24
+ };
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNotConstantEnumMemberError = exports.createForeignPropertyError = exports.createNotLiteralPropertyError = exports.createNotLiteralConstantError = exports.createNotAsConstObjectError = exports.createNotConstError = exports.createNotModuleLevelError = exports.createUnsupportedDeclarationError = void 0;
4
+ const diagnostics_1 = require("../../utils/diagnostics");
5
+ const constants_1 = require("./constants");
6
+ exports.createUnsupportedDeclarationError = (0, diagnostics_1.createErrorDiagnosticFactory)(`'@${constants_1.INLINE_TAG}' is supported only for enums and module-level 'const' declarations.`);
7
+ exports.createNotModuleLevelError = (0, diagnostics_1.createErrorDiagnosticFactory)(`'@${constants_1.INLINE_TAG}' declarations must be module-level statements.`);
8
+ exports.createNotConstError = (0, diagnostics_1.createErrorDiagnosticFactory)(`'@${constants_1.INLINE_TAG}' declarations must use 'const' keyword.`);
9
+ exports.createNotAsConstObjectError = (0, diagnostics_1.createErrorDiagnosticFactory)((name) => `'@${constants_1.INLINE_TAG}' object '${name}' must use 'as const' assertion.`);
10
+ exports.createNotLiteralConstantError = (0, diagnostics_1.createErrorDiagnosticFactory)((name) => `'@${constants_1.INLINE_TAG}' constant '${name}' must have a compile-time constant value, ` +
11
+ "use a literal or an expression computable on build time.");
12
+ exports.createNotLiteralPropertyError = (0, diagnostics_1.createErrorDiagnosticFactory)((object, property) => `'@${constants_1.INLINE_TAG}' object '${object}' property '${property}' must have a compile-time constant value, ` +
13
+ "use a literal or an expression computable on build time.");
14
+ exports.createForeignPropertyError = (0, diagnostics_1.createErrorDiagnosticFactory)((object, property) => `'@${constants_1.INLINE_TAG}' object '${object}' property '${property}' is declared outside of '@${constants_1.INLINE_TAG}' statements, ` +
15
+ `mark the source declaration with '@${constants_1.INLINE_TAG}' too.`);
16
+ exports.createNotConstantEnumMemberError = (0, diagnostics_1.createErrorDiagnosticFactory)((name) => `'@${constants_1.INLINE_TAG}' enum member '${name}' must have a compile-time constant value.`);
@@ -0,0 +1,79 @@
1
+ import * as ts from "typescript";
2
+ import { type TInlineValue } from "./constants";
3
+ /**
4
+ * Get literal value of symbol declared type, if it is a unit type.
5
+ * Uses declared type instead of flow-narrowed type so mutable narrowed values are never inlined.
6
+ *
7
+ * @param checker - Program type checker.
8
+ * @param symbol - Symbol to get declared literal value for.
9
+ * @returns Literal value or null.
10
+ */
11
+ export declare function getDeclaredLiteralValue(checker: ts.TypeChecker, symbol: ts.Symbol): TInlineValue | null;
12
+ /**
13
+ * Convert folded value to string for concatenation contexts.
14
+ * Non-integer numbers are rejected - JS 'String()' and LuaJIT 'tostring' format them differently
15
+ * (17 significant digits vs '%.14g'), so folding would change runtime-visible output.
16
+ *
17
+ * @param value - Folded value to convert.
18
+ * @returns String representation or null.
19
+ */
20
+ export declare function toFoldedString(value: TInlineValue | null): string | null;
21
+ /**
22
+ * Guard folded numeric results against NaN / Infinity that cannot be emitted as lua literals.
23
+ *
24
+ * @param value - Folded numeric value.
25
+ * @returns Finite number or null.
26
+ */
27
+ export declare function toFiniteNumber(value: number): number | null;
28
+ /**
29
+ * Fold binary expression of constant operands with JS semantics.
30
+ * JS semantics are the correct target since tstl preserves them at runtime (e.g. '%' on negative operands).
31
+ *
32
+ * @param operator - Binary operator kind.
33
+ * @param left - Folded left operand.
34
+ * @param right - Folded right operand.
35
+ * @returns Folded value or null.
36
+ */
37
+ export declare function foldBinaryExpression(operator: ts.SyntaxKind, left: TInlineValue, right: TInlineValue): TInlineValue | null;
38
+ /**
39
+ * Evaluate expression to a compile-time constant value when possible.
40
+ * Supports literals, unary/binary arithmetic, string concatenation, template literals,
41
+ * references to enum members / module-level const scalars / `as const` object properties
42
+ * and whitelisted namespace constants like 'math.pi'.
43
+ *
44
+ * @param checker - Program type checker.
45
+ * @param expression - Expression to evaluate.
46
+ * @param seen - Set of declarations on current resolution path, guards from circular references.
47
+ * @returns Folded constant value or null.
48
+ */
49
+ export declare function evaluateConstantExpression(checker: ts.TypeChecker, expression: ts.Expression, seen: Set<ts.Declaration>): TInlineValue | null;
50
+ /**
51
+ * Resolve referenced symbol to a compile-time constant value when the reference is safe to fold.
52
+ * Safe references are enum members, module-level const scalars and readonly `as const` object properties -
53
+ * values that cannot legally change at runtime. Tags are not required on referenced declarations.
54
+ *
55
+ * @param checker - Program type checker.
56
+ * @param symbol - Referenced symbol to resolve.
57
+ * @param seen - Set of declarations on current resolution path.
58
+ * @returns Folded constant value or null.
59
+ */
60
+ export declare function resolveConstantSymbol(checker: ts.TypeChecker, symbol: ts.Symbol, seen: Set<ts.Declaration>): TInlineValue | null;
61
+ /**
62
+ * Get constant value of a declaration - declared unit type first, initializer folding as fallback.
63
+ * Safety and tagging requirements are checked by callers.
64
+ *
65
+ * @param checker - Program type checker.
66
+ * @param symbol - Symbol to get value for.
67
+ * @param seen - Set of declarations on current resolution path.
68
+ * @returns Constant value or null.
69
+ */
70
+ export declare function getComputedDeclarationValue(checker: ts.TypeChecker, symbol: ts.Symbol, seen: Set<ts.Declaration>): TInlineValue | null;
71
+ /**
72
+ * Get inline-able literal value for a symbol resolved from an access expression or identifier.
73
+ * Only symbols declared inside `@inline` tagged enums / variable statements produce values.
74
+ *
75
+ * @param checker - Program type checker.
76
+ * @param symbol - Symbol to resolve inline value for.
77
+ * @returns Literal value or null.
78
+ */
79
+ export declare function tryGetInlineValue(checker: ts.TypeChecker, symbol: ts.Symbol): TInlineValue | null;