@markw65/monkeyc-optimizer 1.1.0 → 1.1.2
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 +13 -0
- package/build/optimizer.cjs +74 -24
- package/build/src/type-flow/could-be.d.ts +2 -0
- package/build/src/type-flow/interp-binary.d.ts +4 -0
- package/build/src/type-flow/interp-call.d.ts +4 -0
- package/build/src/type-flow/interp.d.ts +23 -0
- package/build/src/type-flow/intersection-type.d.ts +4 -0
- package/build/src/type-flow/optimize.d.ts +6 -0
- package/build/src/type-flow/sub-type.d.ts +2 -0
- package/build/src/type-flow/types.d.ts +202 -0
- package/build/src/type-flow/union-type.d.ts +3 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -574,3 +574,16 @@ Bug Fixes
|
|
|
574
574
|
- Bug fixes
|
|
575
575
|
- Fixes a bug that could ignore side effects from Method.invoke
|
|
576
576
|
- Fixes a crash in the inliner, when trying to inline a function with multiple returns
|
|
577
|
+
|
|
578
|
+
### 1.1.1
|
|
579
|
+
|
|
580
|
+
- Fix the package spec to include the new .d.ts files
|
|
581
|
+
|
|
582
|
+
### 1.1.2
|
|
583
|
+
|
|
584
|
+
- Fix a couple of edge cases when constant folding == and !=
|
|
585
|
+
- Optimize `<boolean> && false`, and `<boolean> || true`, when `<boolean>` has no side effects
|
|
586
|
+
- Better optimization of inlined function bodies
|
|
587
|
+
- Analyze constants with casts to help with constant propagation
|
|
588
|
+
- Ignore widening casts (eg a cast that is given a `Number` and converts it to `Number or String`)
|
|
589
|
+
- More accurate deletion of unused constants. Sometimes a constant that was unused after the optimization phase ended, was still considered used because of references that were eventually deleted.
|
package/build/optimizer.cjs
CHANGED
|
@@ -8104,6 +8104,13 @@ function hasValue(v) {
|
|
|
8104
8104
|
return (isExact(v) &&
|
|
8105
8105
|
((v.type & SingleTonTypeTagsConst) !== 0 || v.value !== undefined));
|
|
8106
8106
|
}
|
|
8107
|
+
function hasNoData(v, t) {
|
|
8108
|
+
if (v.value == null)
|
|
8109
|
+
return true;
|
|
8110
|
+
return ((hasUnionData(v.type)
|
|
8111
|
+
? v.value.mask & t
|
|
8112
|
+
: v.type & t & ~SingleTonTypeTagsConst) == 0);
|
|
8113
|
+
}
|
|
8107
8114
|
function lookupByFullName(state, fullName) {
|
|
8108
8115
|
return fullName.split(".").reduce((results, part) => {
|
|
8109
8116
|
return results
|
|
@@ -8218,11 +8225,15 @@ function typeFromTypeStateNode(state, sn, classVsObj) {
|
|
|
8218
8225
|
}
|
|
8219
8226
|
case "VariableDeclarator":
|
|
8220
8227
|
if (sn.node.kind === "const" && sn.node.init) {
|
|
8221
|
-
|
|
8222
|
-
|
|
8228
|
+
let node = sn.node.init;
|
|
8229
|
+
if (node.type === "Literal") {
|
|
8230
|
+
return typeFromLiteral(node);
|
|
8223
8231
|
}
|
|
8224
|
-
|
|
8225
|
-
|
|
8232
|
+
while (node.type === "BinaryExpression" && node.operator === "as") {
|
|
8233
|
+
node = node.left;
|
|
8234
|
+
}
|
|
8235
|
+
if (node.type === "Literal" ||
|
|
8236
|
+
(node.type === "UnaryExpression" && node.operator === ":")) {
|
|
8226
8237
|
return evaluateExpr(state, sn.node.init).value;
|
|
8227
8238
|
}
|
|
8228
8239
|
}
|
|
@@ -8763,9 +8774,10 @@ function equalsCheck(left, right) {
|
|
|
8763
8774
|
// otherwise if its a Char or Symbol, compare for equality
|
|
8764
8775
|
// otherwise its unknown (we don't track object identity).
|
|
8765
8776
|
// Note that each type can only have a single bit set. This is important!
|
|
8777
|
+
const lrBits = left.type | right.type;
|
|
8766
8778
|
return left.type & TypeTag.Numeric && right.type & TypeTag.Numeric
|
|
8767
8779
|
? left.value == right.value
|
|
8768
|
-
:
|
|
8780
|
+
: lrBits == (TypeTag.Number | TypeTag.Char)
|
|
8769
8781
|
? // Char vs Number is true iff the number is the char-code of the char
|
|
8770
8782
|
left.type === TypeTag.Char
|
|
8771
8783
|
? left.value.charCodeAt(0) === right.value
|
|
@@ -8775,14 +8787,13 @@ function equalsCheck(left, right) {
|
|
|
8775
8787
|
: right.type == TypeTag.Number && left.type & TypeTag.Boolean
|
|
8776
8788
|
? right.value == (left.value ? 1 : 0)
|
|
8777
8789
|
: left.type !== right.type
|
|
8778
|
-
?
|
|
8779
|
-
(TypeTag.Object |
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
: false
|
|
8790
|
+
? lrBits & TypeTag.Null
|
|
8791
|
+
? lrBits & (TypeTag.Object | TypeTag.Array | TypeTag.Dictionary)
|
|
8792
|
+
? undefined
|
|
8793
|
+
: false
|
|
8794
|
+
: lrBits & (TypeTag.Module | TypeTag.Function | TypeTag.Class)
|
|
8795
|
+
? false
|
|
8796
|
+
: undefined
|
|
8786
8797
|
: left.type === TypeTag.Char || left.type === TypeTag.Symbol
|
|
8787
8798
|
? left.value === right.value
|
|
8788
8799
|
: isSingleton(left)
|
|
@@ -9259,6 +9270,17 @@ function evaluateNode(istate, node) {
|
|
|
9259
9270
|
const right = popIstate(istate, node.right);
|
|
9260
9271
|
const left = popIstate(istate, node.left);
|
|
9261
9272
|
if (node.operator === "as") {
|
|
9273
|
+
if ((left.value.type & (ValueTypeTagsConst | SingleTonTypeTagsConst)) ==
|
|
9274
|
+
left.value.type &&
|
|
9275
|
+
(right.value.type & left.value.type) === left.value.type &&
|
|
9276
|
+
hasNoData(right.value, left.value.type)) {
|
|
9277
|
+
push({
|
|
9278
|
+
value: left.value,
|
|
9279
|
+
embeddedEffects: left.embeddedEffects,
|
|
9280
|
+
node,
|
|
9281
|
+
});
|
|
9282
|
+
return;
|
|
9283
|
+
}
|
|
9262
9284
|
if (hasValue(right.value) && right.value.type === TypeTag.Enum) {
|
|
9263
9285
|
if ((left.value.type & (TypeTag.Numeric | TypeTag.String)) ==
|
|
9264
9286
|
left.value.type) {
|
|
@@ -10143,8 +10165,10 @@ function beforeEvaluate(istate, node) {
|
|
|
10143
10165
|
break;
|
|
10144
10166
|
if (node.operator === "==" || node.operator === "!=") {
|
|
10145
10167
|
const [{ value: left }, { value: right }] = istate.stack.slice(-2);
|
|
10146
|
-
if ((left.type === TypeTag.Null && !(right.type & TypeTag.Null)) ||
|
|
10147
|
-
(right.type === TypeTag.Null && !(left.type & TypeTag.Null)))
|
|
10168
|
+
if (((left.type === TypeTag.Null && !(right.type & TypeTag.Null)) ||
|
|
10169
|
+
(right.type === TypeTag.Null && !(left.type & TypeTag.Null))) &&
|
|
10170
|
+
(left.type | right.type) &
|
|
10171
|
+
(TypeTag.Object | TypeTag.Array | TypeTag.Dictionary)) {
|
|
10148
10172
|
(0,external_api_cjs_namespaceObject.diagnostic)(istate.state, node.loc, `This comparison seems redundant because ${(0,external_api_cjs_namespaceObject.formatAst)(left.type === TypeTag.Null ? node.right : node.left)} should never be null`, level);
|
|
10149
10173
|
}
|
|
10150
10174
|
}
|
|
@@ -10186,6 +10210,14 @@ function beforeEvaluate(istate, node) {
|
|
|
10186
10210
|
popIstate(istate, node.right);
|
|
10187
10211
|
return node.left;
|
|
10188
10212
|
}
|
|
10213
|
+
if (right.value.type === (isAnd ? TypeTag.False : TypeTag.True) &&
|
|
10214
|
+
!left.embeddedEffects &&
|
|
10215
|
+
(left.value.type & TypeTag.Boolean) === left.value.type) {
|
|
10216
|
+
popIstate(istate, node.right);
|
|
10217
|
+
popIstate(istate, node.left);
|
|
10218
|
+
istate.stack.push(right);
|
|
10219
|
+
return node.right;
|
|
10220
|
+
}
|
|
10189
10221
|
if (isAnd ? !mustBeTrue(left.value) : !mustBeFalse(left.value)) {
|
|
10190
10222
|
break;
|
|
10191
10223
|
}
|
|
@@ -11102,6 +11134,17 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
11102
11134
|
}
|
|
11103
11135
|
return result;
|
|
11104
11136
|
};
|
|
11137
|
+
let again = false;
|
|
11138
|
+
const optimizeCallHelper = (istate, call, node) => {
|
|
11139
|
+
const result = optimizeCall(istate, call, node);
|
|
11140
|
+
if (result) {
|
|
11141
|
+
if (isExpression(result)) {
|
|
11142
|
+
istate.stack[istate.stack.length - 1].node = result;
|
|
11143
|
+
}
|
|
11144
|
+
again = true;
|
|
11145
|
+
}
|
|
11146
|
+
return result;
|
|
11147
|
+
};
|
|
11105
11148
|
const topLocals = () => state.localsStack[state.localsStack.length - 1];
|
|
11106
11149
|
/*
|
|
11107
11150
|
* Might this function be called from somewhere, including
|
|
@@ -11384,6 +11427,12 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
11384
11427
|
throw new Error("Stack was not empty");
|
|
11385
11428
|
}
|
|
11386
11429
|
istate = gistate;
|
|
11430
|
+
if (again) {
|
|
11431
|
+
again = false;
|
|
11432
|
+
const top = state.stack.pop();
|
|
11433
|
+
state.traverse(node);
|
|
11434
|
+
state.stack.push(top);
|
|
11435
|
+
}
|
|
11387
11436
|
break;
|
|
11388
11437
|
case "BlockStatement":
|
|
11389
11438
|
if (node.body.length === 1 && node.body[0].type === "BlockStatement") {
|
|
@@ -11398,13 +11447,13 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
11398
11447
|
case "IfStatement": {
|
|
11399
11448
|
const call = inlinableSubExpression(node.test);
|
|
11400
11449
|
if (call) {
|
|
11401
|
-
return
|
|
11450
|
+
return optimizeCallHelper(istate, call, node);
|
|
11402
11451
|
}
|
|
11403
11452
|
break;
|
|
11404
11453
|
}
|
|
11405
11454
|
case "ReturnStatement":
|
|
11406
11455
|
if (node.argument && node.argument.type === "CallExpression") {
|
|
11407
|
-
return
|
|
11456
|
+
return optimizeCallHelper(istate, node.argument, node);
|
|
11408
11457
|
}
|
|
11409
11458
|
break;
|
|
11410
11459
|
case "Identifier":
|
|
@@ -11433,7 +11482,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
11433
11482
|
}
|
|
11434
11483
|
break;
|
|
11435
11484
|
case "CallExpression": {
|
|
11436
|
-
return
|
|
11485
|
+
return optimizeCallHelper(istate, node, null);
|
|
11437
11486
|
}
|
|
11438
11487
|
case "VariableDeclaration": {
|
|
11439
11488
|
const locals = topLocals();
|
|
@@ -11450,7 +11499,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
11450
11499
|
continue;
|
|
11451
11500
|
const call = inlinableSubExpression(decl.init);
|
|
11452
11501
|
if (call) {
|
|
11453
|
-
const inlined =
|
|
11502
|
+
const inlined = optimizeCallHelper(istate, call, decl);
|
|
11454
11503
|
if (!inlined)
|
|
11455
11504
|
continue;
|
|
11456
11505
|
if (Array.isArray(inlined) || inlined.type != "BlockStatement") {
|
|
@@ -11482,7 +11531,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
11482
11531
|
}
|
|
11483
11532
|
case "ExpressionStatement":
|
|
11484
11533
|
if (node.expression.type === "CallExpression") {
|
|
11485
|
-
return
|
|
11534
|
+
return optimizeCallHelper(istate, node.expression, node);
|
|
11486
11535
|
}
|
|
11487
11536
|
else if (node.expression.type === "AssignmentExpression") {
|
|
11488
11537
|
const call = inlinableSubExpression(node.expression.right);
|
|
@@ -11498,7 +11547,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
11498
11547
|
ok = !!result;
|
|
11499
11548
|
}
|
|
11500
11549
|
if (ok) {
|
|
11501
|
-
return
|
|
11550
|
+
return optimizeCallHelper(istate, call, node.expression);
|
|
11502
11551
|
}
|
|
11503
11552
|
}
|
|
11504
11553
|
}
|
|
@@ -11544,6 +11593,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
11544
11593
|
Object.values(fnMap).forEach((f) => {
|
|
11545
11594
|
(0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
|
|
11546
11595
|
});
|
|
11596
|
+
state.usedByName = {};
|
|
11547
11597
|
state.calledFunctions = {};
|
|
11548
11598
|
state.exposed = state.nextExposed;
|
|
11549
11599
|
state.nextExposed = {};
|
|
@@ -11703,7 +11753,7 @@ function optimizeCall(istate, node, context) {
|
|
|
11703
11753
|
node.arguments.every((n) => getNodeValue(n)[0] !== null)) {
|
|
11704
11754
|
const ret = evaluateFunction(istate, callee, node.arguments);
|
|
11705
11755
|
if (ret) {
|
|
11706
|
-
return ret;
|
|
11756
|
+
return withLoc(ret, node, node);
|
|
11707
11757
|
}
|
|
11708
11758
|
}
|
|
11709
11759
|
if (shouldInline(state, callees[0], node, context)) {
|
|
@@ -12233,7 +12283,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
|
|
|
12233
12283
|
// the oldest optimized file, we don't need to regenerate
|
|
12234
12284
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
12235
12285
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
12236
|
-
if (source_time < opt_time &&
|
|
12286
|
+
if (source_time < opt_time && 1673307671092 < opt_time) {
|
|
12237
12287
|
return { hasTests, diagnostics: prevDiagnostics };
|
|
12238
12288
|
}
|
|
12239
12289
|
}
|
|
@@ -12260,7 +12310,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
|
|
|
12260
12310
|
return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
|
|
12261
12311
|
hasTests,
|
|
12262
12312
|
diagnostics,
|
|
12263
|
-
optimizerVersion: "1.1.
|
|
12313
|
+
optimizerVersion: "1.1.2",
|
|
12264
12314
|
...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
|
|
12265
12315
|
}))
|
|
12266
12316
|
.then(() => ({ hasTests, diagnostics }));
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
|
+
import { ExactOrUnion } from "./types";
|
|
3
|
+
export declare function evaluateBinaryTypes(op: mctree.BinaryOperator | "instanceof", left: ExactOrUnion, right: ExactOrUnion): ExactOrUnion;
|
|
4
|
+
export declare function evaluateLogicalTypes(op: mctree.LogicalOperator, left: ExactOrUnion, right: ExactOrUnion): ExactOrUnion;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ProgramStateAnalysis } from "../optimizer-types";
|
|
2
|
+
import { ExactOrUnion } from "./types";
|
|
3
|
+
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
4
|
+
export declare function evaluateCall(state: ProgramStateAnalysis, node: mctree.CallExpression, callee: ExactOrUnion, _args: ExactOrUnion[]): ExactOrUnion;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
|
+
import { FunctionStateNode, ProgramStateAnalysis } from "../optimizer-types";
|
|
3
|
+
import { ExactOrUnion } from "./types";
|
|
4
|
+
export declare type TypeMap = Map<mctree.Node, ExactOrUnion>;
|
|
5
|
+
export declare type InterpStackElem = {
|
|
6
|
+
value: ExactOrUnion;
|
|
7
|
+
embeddedEffects: boolean;
|
|
8
|
+
node: mctree.Expression | mctree.TypeSpecList | mctree.InstanceOfCase;
|
|
9
|
+
};
|
|
10
|
+
export declare type InterpState = {
|
|
11
|
+
state: ProgramStateAnalysis;
|
|
12
|
+
stack: InterpStackElem[];
|
|
13
|
+
typeMap?: TypeMap;
|
|
14
|
+
func?: FunctionStateNode;
|
|
15
|
+
pre?: (node: mctree.Node) => mctree.Node | false | null | void;
|
|
16
|
+
post?: (node: mctree.Node) => mctree.Node | false | null | void;
|
|
17
|
+
};
|
|
18
|
+
export declare function popIstate(istate: InterpState, node: mctree.Node): InterpStackElem;
|
|
19
|
+
export declare function evaluateExpr(state: ProgramStateAnalysis, expr: mctree.Expression, typeMap?: TypeMap): InterpStackElem;
|
|
20
|
+
export declare function evaluate(istate: InterpState, node: mctree.Expression): InterpStackElem;
|
|
21
|
+
export declare function evaluate(istate: InterpState, node: mctree.Node): InterpStackElem | undefined;
|
|
22
|
+
export declare function evaluateNode(istate: InterpState, node: mctree.Node): void;
|
|
23
|
+
export declare function roundToFloat(value: number): number;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ExactOrUnion } from "./types";
|
|
2
|
+
export declare function expandTypedef(t: ExactOrUnion): ExactOrUnion;
|
|
3
|
+
export declare function intersection(a: ExactOrUnion, b: ExactOrUnion): ExactOrUnion;
|
|
4
|
+
export declare function restrictByEquality(a: ExactOrUnion, b: ExactOrUnion): ExactOrUnion;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
|
+
import { FunctionStateNode, ProgramStateAnalysis } from "../optimizer-types";
|
|
3
|
+
import { InterpState } from "./interp";
|
|
4
|
+
export declare function optimizeFunction(state: ProgramStateAnalysis, func: FunctionStateNode): void;
|
|
5
|
+
export declare function beforeEvaluate(istate: InterpState, node: mctree.Node): mctree.Node | null | false;
|
|
6
|
+
export declare function afterEvaluate(istate: InterpState, node: mctree.Node): mctree.Node | null | false;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
|
+
import { ClassStateNode, EnumStateNode, FunctionStateNode, ModuleStateNode, ProgramStateAnalysis, ProgramStateStack, StateNodeDecl, TypedefStateNode } from "../optimizer-types";
|
|
3
|
+
/**
|
|
4
|
+
* TypeBit gives the position of the 1 bit in TypeTag
|
|
5
|
+
*/
|
|
6
|
+
export declare enum TypeBit {
|
|
7
|
+
Null = 0,
|
|
8
|
+
False = 1,
|
|
9
|
+
True = 2,
|
|
10
|
+
Number = 3,
|
|
11
|
+
Long = 4,
|
|
12
|
+
Float = 5,
|
|
13
|
+
Double = 6,
|
|
14
|
+
Char = 7,
|
|
15
|
+
String = 8,
|
|
16
|
+
Array = 9,
|
|
17
|
+
Dictionary = 10,
|
|
18
|
+
Module = 11,
|
|
19
|
+
Function = 12,
|
|
20
|
+
Class = 13,
|
|
21
|
+
Object = 14,
|
|
22
|
+
Enum = 15,
|
|
23
|
+
Symbol = 16,
|
|
24
|
+
Typedef = 17
|
|
25
|
+
}
|
|
26
|
+
export declare enum TypeTag {
|
|
27
|
+
Never = 0,
|
|
28
|
+
Null = 1,
|
|
29
|
+
False = 2,
|
|
30
|
+
True = 4,
|
|
31
|
+
Boolean = 6,
|
|
32
|
+
Number = 8,
|
|
33
|
+
Long = 16,
|
|
34
|
+
Float = 32,
|
|
35
|
+
Double = 64,
|
|
36
|
+
Numeric = 120,
|
|
37
|
+
Char = 128,
|
|
38
|
+
String = 256,
|
|
39
|
+
Array = 512,
|
|
40
|
+
Dictionary = 1024,
|
|
41
|
+
Module = 2048,
|
|
42
|
+
Function = 4096,
|
|
43
|
+
Class = 8192,
|
|
44
|
+
Object = 16384,
|
|
45
|
+
Enum = 32768,
|
|
46
|
+
Symbol = 65536,
|
|
47
|
+
Typedef = 131072,
|
|
48
|
+
Any = 262143
|
|
49
|
+
}
|
|
50
|
+
export declare const SingleTonTypeTagsConst: number;
|
|
51
|
+
export declare const UnionDataTypeTagsConst: number;
|
|
52
|
+
export declare const ValueTypeTagsConst: number;
|
|
53
|
+
export declare const ObjectLikeTagsConst: number;
|
|
54
|
+
declare type ExactTypeTags = TypeTag.Null | TypeTag.False | TypeTag.True | TypeTag.Number | TypeTag.Long | TypeTag.Float | TypeTag.Double | TypeTag.Char | TypeTag.String | TypeTag.Array | TypeTag.Dictionary | TypeTag.Module | TypeTag.Function | TypeTag.Class | TypeTag.Object | TypeTag.Enum | TypeTag.Symbol | TypeTag.Typedef;
|
|
55
|
+
export declare type EnumeratedTypeTags = ExactTypeTags | TypeTag.Never | TypeTag.Any;
|
|
56
|
+
export declare type UnionTypeTags = number;
|
|
57
|
+
interface AbstractValue {
|
|
58
|
+
type: UnionTypeTags;
|
|
59
|
+
value?: unknown;
|
|
60
|
+
}
|
|
61
|
+
export declare type ExactTypes = NullType | FalseType | TrueType | NumberType | LongType | FloatType | DoubleType | CharType | StringType | ArrayType | DictionaryType | ModuleType | FunctionType | ClassType | ObjectType | EnumType | SymbolType | TypedefType;
|
|
62
|
+
declare type WithValue<T> = T extends ExactTypes ? T extends SingletonType ? T : T & {
|
|
63
|
+
value: NonNullable<T["value"]>;
|
|
64
|
+
} : never;
|
|
65
|
+
export declare type ValueTypes = WithValue<ExactTypes>;
|
|
66
|
+
export declare type ExtendedTypes = ExactTypes | NeverType | AnyType;
|
|
67
|
+
export interface NeverType extends AbstractValue {
|
|
68
|
+
type: 0;
|
|
69
|
+
value?: undefined;
|
|
70
|
+
}
|
|
71
|
+
export interface NullType extends AbstractValue {
|
|
72
|
+
type: TypeTag.Null;
|
|
73
|
+
value?: undefined;
|
|
74
|
+
}
|
|
75
|
+
export interface FalseType extends AbstractValue {
|
|
76
|
+
type: TypeTag.False;
|
|
77
|
+
value?: undefined;
|
|
78
|
+
}
|
|
79
|
+
export interface TrueType extends AbstractValue {
|
|
80
|
+
type: TypeTag.True;
|
|
81
|
+
value?: undefined;
|
|
82
|
+
}
|
|
83
|
+
export interface NumberType extends AbstractValue {
|
|
84
|
+
type: TypeTag.Number;
|
|
85
|
+
value?: number | undefined;
|
|
86
|
+
}
|
|
87
|
+
export interface LongType extends AbstractValue {
|
|
88
|
+
type: TypeTag.Long;
|
|
89
|
+
value?: bigint | undefined;
|
|
90
|
+
}
|
|
91
|
+
export interface FloatType extends AbstractValue {
|
|
92
|
+
type: TypeTag.Float;
|
|
93
|
+
value?: number | undefined;
|
|
94
|
+
}
|
|
95
|
+
export interface DoubleType extends AbstractValue {
|
|
96
|
+
type: TypeTag.Double;
|
|
97
|
+
value?: number | undefined;
|
|
98
|
+
}
|
|
99
|
+
export interface CharType extends AbstractValue {
|
|
100
|
+
type: TypeTag.Char;
|
|
101
|
+
value?: string | undefined;
|
|
102
|
+
}
|
|
103
|
+
export interface StringType extends AbstractValue {
|
|
104
|
+
type: TypeTag.String;
|
|
105
|
+
value?: string | undefined;
|
|
106
|
+
}
|
|
107
|
+
export interface ArrayType extends AbstractValue {
|
|
108
|
+
type: TypeTag.Array;
|
|
109
|
+
value?: ExactOrUnion | undefined;
|
|
110
|
+
}
|
|
111
|
+
export interface DictionaryType extends AbstractValue {
|
|
112
|
+
type: TypeTag.Dictionary;
|
|
113
|
+
value?: {
|
|
114
|
+
key: ExactOrUnion;
|
|
115
|
+
value: ExactOrUnion;
|
|
116
|
+
} | undefined;
|
|
117
|
+
}
|
|
118
|
+
export interface ModuleType extends AbstractValue {
|
|
119
|
+
type: TypeTag.Module;
|
|
120
|
+
value?: ModuleStateNode | ModuleStateNode[] | undefined;
|
|
121
|
+
}
|
|
122
|
+
export interface FunctionType extends AbstractValue {
|
|
123
|
+
type: TypeTag.Function;
|
|
124
|
+
value?: FunctionStateNode | FunctionStateNode[] | undefined;
|
|
125
|
+
}
|
|
126
|
+
export interface ClassType extends AbstractValue {
|
|
127
|
+
type: TypeTag.Class;
|
|
128
|
+
value?: ClassStateNode | ClassStateNode[] | undefined;
|
|
129
|
+
}
|
|
130
|
+
export interface TypedefType extends AbstractValue {
|
|
131
|
+
type: TypeTag.Typedef;
|
|
132
|
+
value?: TypedefStateNode | TypedefStateNode[] | undefined;
|
|
133
|
+
}
|
|
134
|
+
export interface ObjectType extends AbstractValue {
|
|
135
|
+
type: TypeTag.Object;
|
|
136
|
+
value?: {
|
|
137
|
+
klass: ClassType;
|
|
138
|
+
obj?: Record<string, ExactOrUnion>;
|
|
139
|
+
} | undefined;
|
|
140
|
+
}
|
|
141
|
+
export interface EnumType extends AbstractValue {
|
|
142
|
+
type: TypeTag.Enum;
|
|
143
|
+
value?: {
|
|
144
|
+
enum: EnumStateNode;
|
|
145
|
+
value?: ExactOrUnion | undefined;
|
|
146
|
+
} | undefined;
|
|
147
|
+
}
|
|
148
|
+
export interface SymbolType extends AbstractValue {
|
|
149
|
+
type: TypeTag.Symbol;
|
|
150
|
+
value?: string | undefined;
|
|
151
|
+
}
|
|
152
|
+
export interface AnyType extends AbstractValue {
|
|
153
|
+
type: -1;
|
|
154
|
+
value?: undefined;
|
|
155
|
+
}
|
|
156
|
+
export declare type SingletonType = NullType | FalseType | TrueType;
|
|
157
|
+
export declare type UnionData = {
|
|
158
|
+
mask: TypeTag;
|
|
159
|
+
[TypeTag.Array]?: NonNullable<ArrayType["value"]>;
|
|
160
|
+
[TypeTag.Dictionary]?: NonNullable<DictionaryType["value"]>;
|
|
161
|
+
[TypeTag.Module]?: NonNullable<ModuleType["value"]>;
|
|
162
|
+
[TypeTag.Function]?: NonNullable<FunctionType["value"]>;
|
|
163
|
+
[TypeTag.Class]?: NonNullable<ClassType["value"]>;
|
|
164
|
+
[TypeTag.Object]?: NonNullable<ObjectType["value"]>;
|
|
165
|
+
[TypeTag.Enum]?: NonNullable<EnumType["value"]>;
|
|
166
|
+
};
|
|
167
|
+
export declare type UnionDataKey = Exclude<keyof UnionData, "mask">;
|
|
168
|
+
export interface UnionType extends AbstractValue {
|
|
169
|
+
value?: UnionData | undefined;
|
|
170
|
+
}
|
|
171
|
+
export declare type ExactOrUnion = UnionType | ExactTypes;
|
|
172
|
+
export declare type SingleValue = NonNullable<ValueTypes["value"]>;
|
|
173
|
+
declare type TagValue<TAG> = Extract<ValueTypes, {
|
|
174
|
+
type: TAG;
|
|
175
|
+
}>["value"];
|
|
176
|
+
export declare type ArrayValueType = TagValue<TypeTag.Array>;
|
|
177
|
+
export declare type DictionaryValueType = TagValue<TypeTag.Dictionary>;
|
|
178
|
+
export declare type ObjectValueType = TagValue<TypeTag.Object>;
|
|
179
|
+
export declare type EnumValueType = TagValue<TypeTag.Enum>;
|
|
180
|
+
export declare type TypedefValueType = TagValue<TypeTag.Typedef>;
|
|
181
|
+
export declare type StateDeclValueType = TagValue<TypeTag.Module> | TagValue<TypeTag.Function> | TagValue<TypeTag.Class>;
|
|
182
|
+
export declare function isExact(v: AbstractValue): v is ExactTypes;
|
|
183
|
+
export declare function isUnion(v: AbstractValue): v is UnionType;
|
|
184
|
+
export declare function isSingleton(v: AbstractValue): v is SingletonType;
|
|
185
|
+
export declare function hasValue(v: AbstractValue): v is WithValue<ExactTypes>;
|
|
186
|
+
export declare function hasNoData(v: AbstractValue, t: TypeTag): boolean;
|
|
187
|
+
export declare function cloneType<T extends ExactOrUnion>(t: T): T;
|
|
188
|
+
export declare function typeFromTypeStateNode(state: ProgramStateAnalysis, sn: StateNodeDecl, classVsObj?: boolean): ExactOrUnion;
|
|
189
|
+
export declare function typeFromTypeStateNodes(state: ProgramStateAnalysis, sns: StateNodeDecl[], classVsObj?: boolean): ExactOrUnion;
|
|
190
|
+
export declare function typeFromTypespec(state: ProgramStateAnalysis, ts: mctree.TypeSpecList, stack?: ProgramStateStack | undefined): ExactOrUnion;
|
|
191
|
+
export declare function typeFromLiteral(literal: mctree.Literal): ExactTypes;
|
|
192
|
+
export declare function mcExprFromType(type: ValueTypes): mctree.Expression | null;
|
|
193
|
+
export declare function castType(type: ExactOrUnion, target: UnionTypeTags): ExactOrUnion;
|
|
194
|
+
export declare const TruthyTypes: number;
|
|
195
|
+
export declare function mustBeTrue(arg: ExactOrUnion): boolean;
|
|
196
|
+
export declare function mustBeFalse(arg: ExactOrUnion): boolean;
|
|
197
|
+
export declare function display(type: ExactOrUnion): string;
|
|
198
|
+
export declare function hasUnionData(tag: TypeTag): boolean;
|
|
199
|
+
export declare function getObjectValue(t: ExactOrUnion): ObjectType["value"] | null;
|
|
200
|
+
export declare function forEachUnionComponent(v: ExactOrUnion, bits: TypeTag, fn: (tag: UnionDataKey, value: SingleValue | null | undefined) => boolean | void): void;
|
|
201
|
+
export declare function getUnionComponent(v: ExactOrUnion, tag: TypeTag): SingleValue | null;
|
|
202
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markw65/monkeyc-optimizer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"description": "Source to source optimizer for Garmin Monkey C code",
|
|
6
6
|
"main": "build/optimizer.cjs",
|
|
7
7
|
"types": "build/src/optimizer.d.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"build/util.cjs",
|
|
36
36
|
"build/sdk-util.cjs",
|
|
37
37
|
"build/api.cjs",
|
|
38
|
-
"build/src
|
|
38
|
+
"build/src/**/*.d.ts"
|
|
39
39
|
],
|
|
40
40
|
"author": "markw65",
|
|
41
41
|
"license": "MIT",
|