@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 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.
@@ -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
- if (sn.node.init.type === "Literal") {
8222
- return typeFromLiteral(sn.node.init);
8228
+ let node = sn.node.init;
8229
+ if (node.type === "Literal") {
8230
+ return typeFromLiteral(node);
8223
8231
  }
8224
- const [value] = getNodeValue(sn.node.init);
8225
- if (value) {
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
- : (left.type | right.type) == (TypeTag.Number | TypeTag.Char)
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
- ? ((left.type | right.type) &
8779
- (TypeTag.Object |
8780
- TypeTag.Module |
8781
- TypeTag.Function |
8782
- TypeTag.Class)) ===
8783
- TypeTag.Object
8784
- ? undefined
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 replace(optimizeCall(istate, call, node), node.test);
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 replace(optimizeCall(istate, node.argument, node), node.argument);
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 replace(optimizeCall(istate, node, null), node);
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 = replace(optimizeCall(istate, call, decl), decl.init);
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 replace(optimizeCall(istate, node.expression, node), node.expression);
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 replace(optimizeCall(istate, call, node.expression), node.expression.right);
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 && 1673220499844 < 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.0",
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,2 @@
1
+ import { ExactOrUnion } from "./types";
2
+ export declare function couldBe(a: ExactOrUnion, b: ExactOrUnion): boolean;
@@ -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,2 @@
1
+ import { ExactOrUnion } from "./types";
2
+ export declare function subtypeOf(a: ExactOrUnion, b: ExactOrUnion): boolean;
@@ -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 {};
@@ -0,0 +1,3 @@
1
+ import { ExactOrUnion, TypeTag } from "./types";
2
+ export declare function unionInto(to: ExactOrUnion, from: ExactOrUnion): boolean;
3
+ export declare function clearValuesUnder(v: ExactOrUnion, tag: TypeTag, clearTag?: boolean): void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@markw65/monkeyc-optimizer",
3
3
  "type": "module",
4
- "version": "1.1.0",
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/*.d.ts"
38
+ "build/src/**/*.d.ts"
39
39
  ],
40
40
  "author": "markw65",
41
41
  "license": "MIT",