xray16 1.6.3 → 1.6.4
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 +12 -15
- package/package.json +1 -1
- package/plugins/inline_constants/plugin.d.ts +12 -5
- package/plugins/inline_constants/plugin.js +20 -6
- package/plugins/inline_constants/transformation/ast.d.ts +25 -16
- package/plugins/inline_constants/transformation/ast.js +58 -24
- package/plugins/inline_constants/transformation/constants.d.ts +62 -4
- package/plugins/inline_constants/transformation/constants.js +35 -4
- package/plugins/inline_constants/transformation/errors.d.ts +6 -0
- package/plugins/inline_constants/transformation/errors.js +6 -2
- package/plugins/inline_constants/transformation/evaluation.d.ts +58 -28
- package/plugins/inline_constants/transformation/evaluation.js +130 -33
- package/plugins/inline_constants/transformation/index.d.ts +1 -0
- package/plugins/inline_constants/transformation/index.js +1 -0
- package/plugins/inline_constants/transformation/transformers.d.ts +24 -10
- package/plugins/inline_constants/transformation/transformers.js +225 -17
- package/plugins/inline_constants/transformation/validation.d.ts +2 -1
- package/plugins/inline_constants/transformation/validation.js +3 -2
- package/plugins/inline_constants/transformation/virtual.d.ts +74 -0
- package/plugins/inline_constants/transformation/virtual.js +340 -0
- package/xray16.d.ts +877 -366
package/README.md
CHANGED
|
@@ -115,17 +115,17 @@ This avoids temporary result locals for patterns like `return condition ? first
|
|
|
115
115
|
|
|
116
116
|
### inline_constants
|
|
117
117
|
|
|
118
|
-
Plugin
|
|
118
|
+
Plugin that inlines compile-time constants from declarations tagged with `@inline` or `@virtual`.\
|
|
119
119
|
Supported targets are enums, module-level `as const` object literals and module-level scalar constants.\
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
Values may be literals or expressions that can be folded at build time: arithmetic, string concatenation,
|
|
121
|
+
template literals and references to other constant declarations.\
|
|
122
122
|
Tagged declarations act as an explicit whitelist and produce build errors when they cannot be inlined.
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
124
|
+
- `@inline` replaces accesses with literal values but still emits the original declaration, so iteration,
|
|
125
|
+
reverse mapping and whole-object usages keep working. Import bindings that are no longer used at runtime
|
|
126
|
+
are stripped; if the target module is proven pure, its `require` is dropped too.
|
|
127
|
+
- `@virtual` includes `@inline` behavior and also removes the declaration from emitted output. Every value
|
|
128
|
+
reference must be computable at build time. Object spreads of virtual objects are expanded to table literals.
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
131
|
/**
|
|
@@ -137,19 +137,16 @@ export const medkits = {
|
|
|
137
137
|
} as const;
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
|
-
* @
|
|
140
|
+
* @virtual
|
|
141
141
|
*/
|
|
142
142
|
export const TIMEOUT: number = 60 * 1000;
|
|
143
143
|
|
|
144
|
-
/**
|
|
145
|
-
* @inline
|
|
146
|
-
*/
|
|
147
|
-
export const PI_DEGREE: number = math.pi / 180;
|
|
148
|
-
|
|
149
144
|
// Build time: `medkits.medkit_army` access is emitted as plain "medkit_army" string literal.
|
|
150
|
-
// Build time: `TIMEOUT` reference is emitted as 60000
|
|
145
|
+
// Build time: `TIMEOUT` reference is emitted as 60000 and the declaration is erased from output.
|
|
151
146
|
```
|
|
152
147
|
|
|
148
|
+
See [src/plugins/inline_constants/README.md](src/plugins/inline_constants/README.md) for full documentation.
|
|
149
|
+
|
|
153
150
|
### inject_tracy_zones
|
|
154
151
|
|
|
155
152
|
Plugin designed to work specifically with [tracy profiler](https://github.com/wolfpld/tracy).\
|
package/package.json
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { type Plugin } from "typescript-to-lua";
|
|
2
2
|
/**
|
|
3
|
-
* Plugin that inlines compile-time
|
|
3
|
+
* Plugin that inlines compile-time constants from declarations tagged with `@inline` or `@virtual`.
|
|
4
4
|
*
|
|
5
5
|
* Supported targets are enums, module-level `as const` object literals and module-level scalar constants.
|
|
6
|
-
* Values may be literals or expressions
|
|
6
|
+
* Values may be literals or expressions that can be folded at build time: arithmetic, string concatenation,
|
|
7
7
|
* template literals and references to other constant declarations (enum members, const scalars,
|
|
8
8
|
* `as const` object properties, whitelisted constants like 'math.pi').
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
*
|
|
10
|
+
* `@inline` replaces member accesses with literal values while still emitting the original declaration,
|
|
11
|
+
* so iteration, reverse mapping and whole-object usages keep working. Import bindings with no remaining
|
|
12
|
+
* runtime usages are stripped; requires of provably pure modules are dropped with them.
|
|
13
|
+
*
|
|
14
|
+
* `@virtual` includes `@inline` behavior and also erases the declaration from emitted output. Every
|
|
15
|
+
* value reference must be computable at build time. Object spreads are expanded to table literals.
|
|
16
|
+
* Modules containing `@virtual` declarations are validated to be side-effect free.
|
|
17
|
+
*
|
|
18
|
+
* Tagged declarations act as an explicit whitelist and produce build errors when they cannot be inlined.
|
|
12
19
|
*/
|
|
13
20
|
declare const plugin: Plugin;
|
|
14
21
|
export default plugin;
|
|
@@ -3,22 +3,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const ts = require("typescript");
|
|
4
4
|
const transformation_1 = require("./transformation");
|
|
5
5
|
/**
|
|
6
|
-
* Plugin that inlines compile-time
|
|
6
|
+
* Plugin that inlines compile-time constants from declarations tagged with `@inline` or `@virtual`.
|
|
7
7
|
*
|
|
8
8
|
* Supported targets are enums, module-level `as const` object literals and module-level scalar constants.
|
|
9
|
-
* Values may be literals or expressions
|
|
9
|
+
* Values may be literals or expressions that can be folded at build time: arithmetic, string concatenation,
|
|
10
10
|
* template literals and references to other constant declarations (enum members, const scalars,
|
|
11
11
|
* `as const` object properties, whitelisted constants like 'math.pi').
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
*
|
|
13
|
+
* `@inline` replaces member accesses with literal values while still emitting the original declaration,
|
|
14
|
+
* so iteration, reverse mapping and whole-object usages keep working. Import bindings with no remaining
|
|
15
|
+
* runtime usages are stripped; requires of provably pure modules are dropped with them.
|
|
16
|
+
*
|
|
17
|
+
* `@virtual` includes `@inline` behavior and also erases the declaration from emitted output. Every
|
|
18
|
+
* value reference must be computable at build time. Object spreads are expanded to table literals.
|
|
19
|
+
* Modules containing `@virtual` declarations are validated to be side-effect free.
|
|
20
|
+
*
|
|
21
|
+
* Tagged declarations act as an explicit whitelist and produce build errors when they cannot be inlined.
|
|
15
22
|
*/
|
|
16
23
|
const plugin = {
|
|
17
24
|
beforeTransform(program) {
|
|
18
25
|
// Force binder to assign node parents before any 'getJSDocTags' call,
|
|
19
26
|
// otherwise empty results are computed for parent-less nodes and cached on them forever.
|
|
20
27
|
program.getTypeChecker();
|
|
21
|
-
const diagnostics = (0, transformation_1.validateTopLevelTags)(program);
|
|
28
|
+
const diagnostics = [...(0, transformation_1.validateTopLevelTags)(program), ...(0, transformation_1.collectVirtualDiagnostics)(program)];
|
|
22
29
|
if (diagnostics.length > 0) {
|
|
23
30
|
return diagnostics;
|
|
24
31
|
}
|
|
@@ -27,15 +34,22 @@ const plugin = {
|
|
|
27
34
|
[ts.SyntaxKind.PropertyAccessExpression]: transformation_1.transformAccessExpression,
|
|
28
35
|
[ts.SyntaxKind.ElementAccessExpression]: transformation_1.transformAccessExpression,
|
|
29
36
|
[ts.SyntaxKind.Identifier]: transformation_1.transformIdentifierExpression,
|
|
37
|
+
[ts.SyntaxKind.ImportDeclaration]: transformation_1.transformImportDeclaration,
|
|
30
38
|
[ts.SyntaxKind.VariableStatement]: (statement, context) => {
|
|
31
39
|
if ((0, transformation_1.hasInlineTag)(statement)) {
|
|
32
40
|
(0, transformation_1.validateVariableStatement)(statement, context);
|
|
41
|
+
if ((0, transformation_1.hasVirtualTag)(statement)) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
33
44
|
}
|
|
34
45
|
return context.superTransformStatements(statement);
|
|
35
46
|
},
|
|
36
47
|
[ts.SyntaxKind.EnumDeclaration]: (declaration, context) => {
|
|
37
48
|
if ((0, transformation_1.hasInlineTag)(declaration)) {
|
|
38
49
|
(0, transformation_1.validateEnumDeclaration)(declaration, context);
|
|
50
|
+
if ((0, transformation_1.hasVirtualTag)(declaration)) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
39
53
|
}
|
|
40
54
|
return context.superTransformStatements(declaration);
|
|
41
55
|
},
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import * as ts from "typescript";
|
|
2
2
|
/**
|
|
3
|
-
* Check whether node is
|
|
3
|
+
* Check whether a node is whitelisted for inlining.
|
|
4
|
+
* Both `@inline` and `@virtual` enable inlining; `@virtual` adds erasure rules elsewhere.
|
|
4
5
|
*
|
|
5
6
|
* @param node - Node to check tags for.
|
|
6
|
-
* @returns Whether the node
|
|
7
|
+
* @returns Whether the node is whitelisted for inlining.
|
|
7
8
|
*/
|
|
8
9
|
export declare function hasInlineTag(node: ts.Node): boolean;
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Check whether a node has the `@virtual` JSDoc tag.
|
|
12
|
+
*
|
|
13
|
+
* @param node - Node to check tags for.
|
|
14
|
+
* @returns Whether the node has `@virtual` JSDoc tag.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hasVirtualTag(node: ts.Node): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Find the variable statement that contains the provided declaration node.
|
|
11
19
|
*
|
|
12
20
|
* @param node - Declaration node to walk up from.
|
|
13
21
|
* @returns Containing variable statement or null.
|
|
14
22
|
*/
|
|
15
23
|
export declare function getContainingVariableStatement(node: ts.Node): ts.VariableStatement | null;
|
|
16
24
|
/**
|
|
17
|
-
* Unwrap initializer expression from as
|
|
25
|
+
* Unwrap an initializer expression from `as`, `satisfies`, and parenthesized wrappers.
|
|
18
26
|
*
|
|
19
27
|
* @param expression - Initializer expression to unwrap.
|
|
20
28
|
* @returns Unwrapped expression or null.
|
|
@@ -24,18 +32,18 @@ export declare function unwrapInitializer(expression?: ts.Expression): ts.Expres
|
|
|
24
32
|
* Check whether variable statement is a module-level `const` declaration.
|
|
25
33
|
*
|
|
26
34
|
* @param statement - Variable statement to check.
|
|
27
|
-
* @returns Whether statement is module-level const.
|
|
35
|
+
* @returns Whether the statement is a module-level const.
|
|
28
36
|
*/
|
|
29
37
|
export declare function isModuleLevelConst(statement: ts.VariableStatement): boolean;
|
|
30
38
|
/**
|
|
31
|
-
* Check whether expression is wrapped
|
|
39
|
+
* Check whether an expression is wrapped in an `as const` assertion, possibly through parens/satisfies wrappers.
|
|
32
40
|
*
|
|
33
41
|
* @param expression - Expression to check.
|
|
34
|
-
* @returns Whether expression has `as const` assertion.
|
|
42
|
+
* @returns Whether the expression has an `as const` assertion.
|
|
35
43
|
*/
|
|
36
44
|
export declare function hasAsConstAssertion(expression?: ts.Expression): boolean;
|
|
37
45
|
/**
|
|
38
|
-
* Check whether property is declared inside an `as const` object literal assigned to a module-level const.
|
|
46
|
+
* Check whether a property is declared inside an `as const` object literal assigned to a module-level const.
|
|
39
47
|
* Such properties are readonly and cannot be legally reassigned, so their values are stable at runtime.
|
|
40
48
|
*
|
|
41
49
|
* @param declaration - Property declaration to check.
|
|
@@ -43,18 +51,19 @@ export declare function hasAsConstAssertion(expression?: ts.Expression): boolean
|
|
|
43
51
|
*/
|
|
44
52
|
export declare function isReadonlyModuleConstProperty(declaration: ts.PropertyAssignment | ts.ShorthandPropertyAssignment): boolean;
|
|
45
53
|
/**
|
|
46
|
-
* Check whether identifier
|
|
54
|
+
* Check whether an identifier is used in a value position where it can be replaced with a literal.
|
|
47
55
|
*
|
|
48
56
|
* @param node - Identifier node to check.
|
|
49
|
-
* @returns Whether identifier is a
|
|
57
|
+
* @returns Whether the identifier is a replaceable value usage.
|
|
50
58
|
*/
|
|
51
59
|
export declare function isValueUsagePosition(node: ts.Identifier): boolean;
|
|
52
60
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
61
|
+
* Get global access path for a runtime-constant engine member declaration.
|
|
62
|
+
* Qualifying declarations are `static readonly` class members declared inside ambient `declare module "xray16"` -
|
|
63
|
+
* such values are registered once by the engine and never change at runtime.
|
|
64
|
+
* The path uses the declared class name, so import aliases do not affect emitted references.
|
|
55
65
|
*
|
|
56
|
-
* @param
|
|
57
|
-
* @
|
|
58
|
-
* @returns Resolved member symbol or null.
|
|
66
|
+
* @param declaration - Declaration to check.
|
|
67
|
+
* @returns Global access path like ['stalker_ids', 'action_dying'], or null when not a constant engine member.
|
|
59
68
|
*/
|
|
60
|
-
export declare function
|
|
69
|
+
export declare function getEngineConstantPath(declaration: ts.Declaration): Array<string> | null;
|
|
@@ -1,26 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.hasInlineTag = hasInlineTag;
|
|
4
|
+
exports.hasVirtualTag = hasVirtualTag;
|
|
4
5
|
exports.getContainingVariableStatement = getContainingVariableStatement;
|
|
5
6
|
exports.unwrapInitializer = unwrapInitializer;
|
|
6
7
|
exports.isModuleLevelConst = isModuleLevelConst;
|
|
7
8
|
exports.hasAsConstAssertion = hasAsConstAssertion;
|
|
8
9
|
exports.isReadonlyModuleConstProperty = isReadonlyModuleConstProperty;
|
|
9
10
|
exports.isValueUsagePosition = isValueUsagePosition;
|
|
10
|
-
exports.
|
|
11
|
+
exports.getEngineConstantPath = getEngineConstantPath;
|
|
11
12
|
const ts = require("typescript");
|
|
12
13
|
const constants_1 = require("./constants");
|
|
13
14
|
/**
|
|
14
|
-
* Check whether node
|
|
15
|
+
* Check whether a node has the provided JSDoc tag.
|
|
15
16
|
*
|
|
16
17
|
* @param node - Node to check tags for.
|
|
17
|
-
* @
|
|
18
|
+
* @param tag - Tag name to look for.
|
|
19
|
+
* @returns Whether the node has the JSDoc tag.
|
|
20
|
+
*/
|
|
21
|
+
function hasJsDocTag(node, tag) {
|
|
22
|
+
return ts.getJSDocTags(node).some((it) => it.tagName.text === tag);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check whether a node is whitelisted for inlining.
|
|
26
|
+
* Both `@inline` and `@virtual` enable inlining; `@virtual` adds erasure rules elsewhere.
|
|
27
|
+
*
|
|
28
|
+
* @param node - Node to check tags for.
|
|
29
|
+
* @returns Whether the node is whitelisted for inlining.
|
|
18
30
|
*/
|
|
19
31
|
function hasInlineTag(node) {
|
|
20
|
-
return
|
|
32
|
+
return hasJsDocTag(node, constants_1.INLINE_TAG) || hasJsDocTag(node, constants_1.VIRTUAL_TAG);
|
|
21
33
|
}
|
|
22
34
|
/**
|
|
23
|
-
*
|
|
35
|
+
* Check whether a node has the `@virtual` JSDoc tag.
|
|
36
|
+
*
|
|
37
|
+
* @param node - Node to check tags for.
|
|
38
|
+
* @returns Whether the node has `@virtual` JSDoc tag.
|
|
39
|
+
*/
|
|
40
|
+
function hasVirtualTag(node) {
|
|
41
|
+
return hasJsDocTag(node, constants_1.VIRTUAL_TAG);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Find the variable statement that contains the provided declaration node.
|
|
24
45
|
*
|
|
25
46
|
* @param node - Declaration node to walk up from.
|
|
26
47
|
* @returns Containing variable statement or null.
|
|
@@ -36,7 +57,7 @@ function getContainingVariableStatement(node) {
|
|
|
36
57
|
return null;
|
|
37
58
|
}
|
|
38
59
|
/**
|
|
39
|
-
* Unwrap initializer expression from as
|
|
60
|
+
* Unwrap an initializer expression from `as`, `satisfies`, and parenthesized wrappers.
|
|
40
61
|
*
|
|
41
62
|
* @param expression - Initializer expression to unwrap.
|
|
42
63
|
* @returns Unwrapped expression or null.
|
|
@@ -56,16 +77,16 @@ function unwrapInitializer(expression) {
|
|
|
56
77
|
* Check whether variable statement is a module-level `const` declaration.
|
|
57
78
|
*
|
|
58
79
|
* @param statement - Variable statement to check.
|
|
59
|
-
* @returns Whether statement is module-level const.
|
|
80
|
+
* @returns Whether the statement is a module-level const.
|
|
60
81
|
*/
|
|
61
82
|
function isModuleLevelConst(statement) {
|
|
62
83
|
return ts.isSourceFile(statement.parent) && (statement.declarationList.flags & ts.NodeFlags.Const) !== 0;
|
|
63
84
|
}
|
|
64
85
|
/**
|
|
65
|
-
* Check whether expression is wrapped
|
|
86
|
+
* Check whether an expression is wrapped in an `as const` assertion, possibly through parens/satisfies wrappers.
|
|
66
87
|
*
|
|
67
88
|
* @param expression - Expression to check.
|
|
68
|
-
* @returns Whether expression has `as const` assertion.
|
|
89
|
+
* @returns Whether the expression has an `as const` assertion.
|
|
69
90
|
*/
|
|
70
91
|
function hasAsConstAssertion(expression) {
|
|
71
92
|
let current = expression;
|
|
@@ -85,7 +106,7 @@ function hasAsConstAssertion(expression) {
|
|
|
85
106
|
return false;
|
|
86
107
|
}
|
|
87
108
|
/**
|
|
88
|
-
* Check whether property is declared inside an `as const` object literal assigned to a module-level const.
|
|
109
|
+
* Check whether a property is declared inside an `as const` object literal assigned to a module-level const.
|
|
89
110
|
* Such properties are readonly and cannot be legally reassigned, so their values are stable at runtime.
|
|
90
111
|
*
|
|
91
112
|
* @param declaration - Property declaration to check.
|
|
@@ -116,10 +137,10 @@ function isReadonlyModuleConstProperty(declaration) {
|
|
|
116
137
|
return statement !== null && isModuleLevelConst(statement);
|
|
117
138
|
}
|
|
118
139
|
/**
|
|
119
|
-
* Check whether identifier
|
|
140
|
+
* Check whether an identifier is used in a value position where it can be replaced with a literal.
|
|
120
141
|
*
|
|
121
142
|
* @param node - Identifier node to check.
|
|
122
|
-
* @returns Whether identifier is a
|
|
143
|
+
* @returns Whether the identifier is a replaceable value usage.
|
|
123
144
|
*/
|
|
124
145
|
function isValueUsagePosition(node) {
|
|
125
146
|
const parent = node.parent;
|
|
@@ -165,21 +186,34 @@ function isValueUsagePosition(node) {
|
|
|
165
186
|
return true;
|
|
166
187
|
}
|
|
167
188
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
189
|
+
* Get global access path for a runtime-constant engine member declaration.
|
|
190
|
+
* Qualifying declarations are `static readonly` class members declared inside ambient `declare module "xray16"` -
|
|
191
|
+
* such values are registered once by the engine and never change at runtime.
|
|
192
|
+
* The path uses the declared class name, so import aliases do not affect emitted references.
|
|
170
193
|
*
|
|
171
|
-
* @param
|
|
172
|
-
* @
|
|
173
|
-
* @returns Resolved member symbol or null.
|
|
194
|
+
* @param declaration - Declaration to check.
|
|
195
|
+
* @returns Global access path like ['stalker_ids', 'action_dying'], or null when not a constant engine member.
|
|
174
196
|
*/
|
|
175
|
-
function
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
197
|
+
function getEngineConstantPath(declaration) {
|
|
198
|
+
if (!ts.isPropertyDeclaration(declaration) || !ts.isIdentifier(declaration.name)) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
const modifiers = ts.getModifiers(declaration) ?? [];
|
|
202
|
+
const isStaticReadonly = modifiers.some((it) => it.kind === ts.SyntaxKind.StaticKeyword) &&
|
|
203
|
+
modifiers.some((it) => it.kind === ts.SyntaxKind.ReadonlyKeyword);
|
|
204
|
+
if (!isStaticReadonly) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
const classDeclaration = declaration.parent;
|
|
208
|
+
if (!ts.isClassDeclaration(classDeclaration) || classDeclaration.name === undefined) {
|
|
209
|
+
return null;
|
|
179
210
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
211
|
+
let current = classDeclaration.parent;
|
|
212
|
+
while (current !== undefined && !ts.isSourceFile(current)) {
|
|
213
|
+
if (ts.isModuleDeclaration(current) && ts.isStringLiteral(current.name) && current.name.text === "xray16") {
|
|
214
|
+
return [classDeclaration.name.text, declaration.name.text];
|
|
215
|
+
}
|
|
216
|
+
current = current.parent;
|
|
183
217
|
}
|
|
184
218
|
return null;
|
|
185
219
|
}
|
|
@@ -3,12 +3,70 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare const INLINE_TAG: string;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* JSDoc tag marking declarations for compile-time inlining and erasure from emitted output.
|
|
7
|
+
* Includes `@inline` behavior and requires every value reference to be erasable.
|
|
8
|
+
*/
|
|
9
|
+
export declare const VIRTUAL_TAG: string;
|
|
10
|
+
/**
|
|
11
|
+
* Value types that can be inlined as Lua literals.
|
|
7
12
|
*/
|
|
8
13
|
export type TInlineValue = string | number | boolean;
|
|
9
14
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
15
|
+
* Reference to a runtime-constant engine value like 'stalker_ids.action_dying'.
|
|
16
|
+
* Emitted as a global access expression instead of a baked literal, so values stay correct
|
|
17
|
+
* even when engine builds diverge from the literal types declared in typings.
|
|
18
|
+
*/
|
|
19
|
+
export interface IEngineReference {
|
|
20
|
+
kind: "engine-ref";
|
|
21
|
+
path: Array<string>;
|
|
22
|
+
isNumeric: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Binary numeric expression mixing engine references with other folded values.
|
|
26
|
+
*/
|
|
27
|
+
export interface IFoldedBinary {
|
|
28
|
+
kind: "binary";
|
|
29
|
+
operator: TFoldedBinaryOperator;
|
|
30
|
+
left: TFoldedValue;
|
|
31
|
+
right: TFoldedValue;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Numeric negation of a folded expression.
|
|
35
|
+
*/
|
|
36
|
+
export interface IFoldedNegation {
|
|
37
|
+
kind: "negate";
|
|
38
|
+
operand: TFoldedValue;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Operators allowed in folded expression trees - restricted to those where emitted Lua matches
|
|
42
|
+
* tstl lowering exactly. '%', bitwise operators and string concatenation are rejected for trees.
|
|
43
|
+
*/
|
|
44
|
+
export type TFoldedBinaryOperator = "+" | "-" | "*" | "/" | "**";
|
|
45
|
+
/**
|
|
46
|
+
* Expression parts of folded values that cannot be computed to plain literals at build time.
|
|
47
|
+
*/
|
|
48
|
+
export type TFoldedExpression = IEngineReference | IFoldedBinary | IFoldedNegation;
|
|
49
|
+
/**
|
|
50
|
+
* Result of build-time folding - either a plain literal or an expression tree with engine references.
|
|
51
|
+
*/
|
|
52
|
+
export type TFoldedValue = TInlineValue | TFoldedExpression;
|
|
53
|
+
/**
|
|
54
|
+
* Check whether folded value is an expression tree rather than a plain literal.
|
|
55
|
+
*
|
|
56
|
+
* @param value - Folded value to check.
|
|
57
|
+
* @returns Whether value is an expression tree.
|
|
58
|
+
*/
|
|
59
|
+
export declare function isFoldedExpression(value: TFoldedValue): value is TFoldedExpression;
|
|
60
|
+
/**
|
|
61
|
+
* Check whether folded value is numeric - a number literal or a numeric expression tree.
|
|
62
|
+
*
|
|
63
|
+
* @param value - Folded value to check.
|
|
64
|
+
* @returns Whether value is numeric.
|
|
65
|
+
*/
|
|
66
|
+
export declare function isNumericFoldedValue(value: TFoldedValue): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Numeric namespace constants with identical IEEE 754 double values in the build environment and LuaJIT runtime.
|
|
69
|
+
* Covers both TS 'Math' and Lua 'math' namespaces. Function calls are intentionally not supported because
|
|
70
|
+
* libm implementations may differ between build machine and game runtime.
|
|
13
71
|
*/
|
|
14
72
|
export declare const FOLDABLE_NAMESPACE_CONSTANTS: Record<string, Record<string, number>>;
|
|
@@ -1,14 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FOLDABLE_NAMESPACE_CONSTANTS = exports.INLINE_TAG = void 0;
|
|
3
|
+
exports.FOLDABLE_NAMESPACE_CONSTANTS = exports.VIRTUAL_TAG = exports.INLINE_TAG = void 0;
|
|
4
|
+
exports.isFoldedExpression = isFoldedExpression;
|
|
5
|
+
exports.isNumericFoldedValue = isNumericFoldedValue;
|
|
4
6
|
/**
|
|
5
7
|
* JSDoc tag marking declarations as whitelisted for compile-time inlining.
|
|
6
8
|
*/
|
|
7
9
|
exports.INLINE_TAG = "inline";
|
|
8
10
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
11
|
+
* JSDoc tag marking declarations for compile-time inlining and erasure from emitted output.
|
|
12
|
+
* Includes `@inline` behavior and requires every value reference to be erasable.
|
|
13
|
+
*/
|
|
14
|
+
exports.VIRTUAL_TAG = "virtual";
|
|
15
|
+
/**
|
|
16
|
+
* Check whether folded value is an expression tree rather than a plain literal.
|
|
17
|
+
*
|
|
18
|
+
* @param value - Folded value to check.
|
|
19
|
+
* @returns Whether value is an expression tree.
|
|
20
|
+
*/
|
|
21
|
+
function isFoldedExpression(value) {
|
|
22
|
+
return typeof value === "object";
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check whether folded value is numeric - a number literal or a numeric expression tree.
|
|
26
|
+
*
|
|
27
|
+
* @param value - Folded value to check.
|
|
28
|
+
* @returns Whether value is numeric.
|
|
29
|
+
*/
|
|
30
|
+
function isNumericFoldedValue(value) {
|
|
31
|
+
if (typeof value === "number") {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (typeof value === "object") {
|
|
35
|
+
return value.kind === "engine-ref" ? value.isNumeric : true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Numeric namespace constants with identical IEEE 754 double values in the build environment and LuaJIT runtime.
|
|
41
|
+
* Covers both TS 'Math' and Lua 'math' namespaces. Function calls are intentionally not supported because
|
|
42
|
+
* libm implementations may differ between build machine and game runtime.
|
|
12
43
|
*/
|
|
13
44
|
exports.FOLDABLE_NAMESPACE_CONSTANTS = {
|
|
14
45
|
Math: {
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export declare const createUnsupportedDeclarationError: ((node: import("typescript").Node, ...args: any[]) => import("typescript").Diagnostic) & {
|
|
2
2
|
code: number;
|
|
3
3
|
};
|
|
4
|
+
export declare const createVirtualValueReferenceError: ((node: import("typescript").Node, name: string) => import("typescript").Diagnostic) & {
|
|
5
|
+
code: number;
|
|
6
|
+
};
|
|
7
|
+
export declare const createImpureVirtualModuleError: ((node: import("typescript").Node, ...args: any[]) => import("typescript").Diagnostic) & {
|
|
8
|
+
code: number;
|
|
9
|
+
};
|
|
4
10
|
export declare const createNotModuleLevelError: ((node: import("typescript").Node, ...args: any[]) => import("typescript").Diagnostic) & {
|
|
5
11
|
code: number;
|
|
6
12
|
};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
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;
|
|
3
|
+
exports.createNotConstantEnumMemberError = exports.createForeignPropertyError = exports.createNotLiteralPropertyError = exports.createNotLiteralConstantError = exports.createNotAsConstObjectError = exports.createNotConstError = exports.createNotModuleLevelError = exports.createImpureVirtualModuleError = exports.createVirtualValueReferenceError = exports.createUnsupportedDeclarationError = void 0;
|
|
4
4
|
const diagnostics_1 = require("../../utils/diagnostics");
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
|
-
exports.createUnsupportedDeclarationError = (0, diagnostics_1.createErrorDiagnosticFactory)(`'@${constants_1.INLINE_TAG}'
|
|
6
|
+
exports.createUnsupportedDeclarationError = (0, diagnostics_1.createErrorDiagnosticFactory)(`'@${constants_1.INLINE_TAG}' and '@${constants_1.VIRTUAL_TAG}' are supported only for enums and module-level 'const' declarations.`);
|
|
7
|
+
exports.createVirtualValueReferenceError = (0, diagnostics_1.createErrorDiagnosticFactory)((name) => `'@${constants_1.VIRTUAL_TAG}' declaration '${name}' is referenced as a value and cannot be erased, ` +
|
|
8
|
+
`demote it to '@${constants_1.INLINE_TAG}' or make the reference computable on build time.`);
|
|
9
|
+
exports.createImpureVirtualModuleError = (0, diagnostics_1.createErrorDiagnosticFactory)(`Modules with '@${constants_1.VIRTUAL_TAG}' declarations may contain only type-only imports, ` +
|
|
10
|
+
`'@${constants_1.INLINE_TAG}'/'@${constants_1.VIRTUAL_TAG}' constants, constant enums, type aliases and interfaces.`);
|
|
7
11
|
exports.createNotModuleLevelError = (0, diagnostics_1.createErrorDiagnosticFactory)(`'@${constants_1.INLINE_TAG}' declarations must be module-level statements.`);
|
|
8
12
|
exports.createNotConstError = (0, diagnostics_1.createErrorDiagnosticFactory)(`'@${constants_1.INLINE_TAG}' declarations must use 'const' keyword.`);
|
|
9
13
|
exports.createNotAsConstObjectError = (0, diagnostics_1.createErrorDiagnosticFactory)((name) => `'@${constants_1.INLINE_TAG}' object '${name}' must use 'as const' assertion.`);
|