@markw65/monkeyc-optimizer 1.0.44 → 1.1.0
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 +46 -0
- package/build/api.cjs +867 -4976
- package/build/optimizer.cjs +3637 -833
- package/build/sdk-util.cjs +80 -2
- package/build/src/api.d.ts +6 -3
- package/build/src/ast.d.ts +27 -0
- package/build/src/control-flow.d.ts +1 -1
- package/build/src/data-flow.d.ts +45 -0
- package/build/src/function-info.d.ts +2 -0
- package/build/src/inliner.d.ts +1 -2
- package/build/src/jungles.d.ts +2 -1
- package/build/src/manifest.d.ts +1 -0
- package/build/src/mc-rewrite.d.ts +1 -2
- package/build/src/optimizer-types.d.ts +23 -5
- package/build/src/pre.d.ts +1 -1
- package/build/src/projects.d.ts +2 -1
- package/build/src/type-flow.d.ts +3 -0
- package/build/src/util.d.ts +6 -1
- package/build/src/worker-pool.d.ts +1 -1
- package/build/src/worker-task.d.ts +49 -18
- package/build/src/worker-thread.d.ts +1 -0
- package/build/util.cjs +58 -2
- package/package.json +9 -3
package/build/sdk-util.cjs
CHANGED
|
@@ -237,8 +237,6 @@ function mayThrow(node) {
|
|
|
237
237
|
switch (node.type) {
|
|
238
238
|
case "BinaryExpression":
|
|
239
239
|
case "CallExpression":
|
|
240
|
-
case "ConditionalExpression":
|
|
241
|
-
case "LogicalExpression":
|
|
242
240
|
case "NewExpression":
|
|
243
241
|
case "ThrowStatement":
|
|
244
242
|
case "UnaryExpression":
|
|
@@ -325,6 +323,86 @@ function getNodeValue(node) {
|
|
|
325
323
|
}
|
|
326
324
|
throw new Error(`Literal has unknown type '${type}'`);
|
|
327
325
|
}
|
|
326
|
+
function wrap(node, loc) {
|
|
327
|
+
if (loc) {
|
|
328
|
+
node.loc = loc;
|
|
329
|
+
node.start = loc.start.offset;
|
|
330
|
+
node.end = loc.end.offset;
|
|
331
|
+
}
|
|
332
|
+
return node;
|
|
333
|
+
}
|
|
334
|
+
function locRange(start, end) {
|
|
335
|
+
return {
|
|
336
|
+
source: start.source || end.source,
|
|
337
|
+
start: start.start,
|
|
338
|
+
end: end.end,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function adjustLoc(loc, start = 1, end = -1) {
|
|
342
|
+
return {
|
|
343
|
+
source: loc.source,
|
|
344
|
+
start: {
|
|
345
|
+
offset: loc.start.offset + start,
|
|
346
|
+
line: loc.start.line,
|
|
347
|
+
column: loc.start.column + start,
|
|
348
|
+
},
|
|
349
|
+
end: {
|
|
350
|
+
offset: loc.end.offset + end,
|
|
351
|
+
line: loc.end.line,
|
|
352
|
+
column: loc.end.column + end,
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
function makeIdentifier(name, loc) {
|
|
357
|
+
return wrap({ type: "Identifier", name }, loc);
|
|
358
|
+
}
|
|
359
|
+
function makeMemberExpression(object, property) {
|
|
360
|
+
return wrap({
|
|
361
|
+
type: "MemberExpression",
|
|
362
|
+
object,
|
|
363
|
+
property,
|
|
364
|
+
computed: false,
|
|
365
|
+
}, object.loc && locRange(object.loc, property.loc));
|
|
366
|
+
}
|
|
367
|
+
function makeScopedName(dotted, l) {
|
|
368
|
+
const loc = l && adjustLoc(l, 0, l.start.offset - l.end.offset);
|
|
369
|
+
const result = dotted.split(/\s*\.\s*/).reduce(({ cur, offset }, next) => {
|
|
370
|
+
const id = makeIdentifier(next, loc && adjustLoc(loc, offset, offset + next.length));
|
|
371
|
+
if (!cur) {
|
|
372
|
+
cur = id;
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
cur = makeMemberExpression(cur, id);
|
|
376
|
+
}
|
|
377
|
+
offset += next.length + 1;
|
|
378
|
+
return { cur, offset };
|
|
379
|
+
}, { cur: null, offset: 0 }).cur;
|
|
380
|
+
if (!result)
|
|
381
|
+
throw new Error("Failed to make a ScopedName");
|
|
382
|
+
return result;
|
|
383
|
+
}
|
|
384
|
+
function getLiteralNode(node) {
|
|
385
|
+
if (node == null)
|
|
386
|
+
return null;
|
|
387
|
+
if (node.type == "Literal")
|
|
388
|
+
return node;
|
|
389
|
+
if (node.type == "BinaryExpression" && node.operator == "as") {
|
|
390
|
+
return getLiteralNode(node.left) && node;
|
|
391
|
+
}
|
|
392
|
+
if (node.type == "UnaryExpression") {
|
|
393
|
+
if (node.argument.type != "Literal")
|
|
394
|
+
return null;
|
|
395
|
+
switch (node.operator) {
|
|
396
|
+
case "-": {
|
|
397
|
+
const [arg, type] = getNodeValue(node.argument);
|
|
398
|
+
if (type === "Number" || type === "Long") {
|
|
399
|
+
return { ...arg, value: -arg.value, raw: `-${arg.raw}` };
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
328
406
|
|
|
329
407
|
;// CONCATENATED MODULE: ./src/xml-util.ts
|
|
330
408
|
|
package/build/src/api.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
2
|
import { hasProperty, traverseAst } from "./ast";
|
|
3
3
|
import { JungleResourceMap } from "./jungles";
|
|
4
|
-
import { FunctionInfo, FunctionStateNode, LookupDefinition, ModuleStateNode, ProgramState, ProgramStateLive, ProgramStateNode, ProgramStateStack, StateNode, StateNodeDecl } from "./optimizer-types";
|
|
4
|
+
import { ClassStateNode, FunctionInfo, FunctionStateNode, LookupDefinition, ModuleStateNode, ProgramState, ProgramStateAnalysis, ProgramStateLive, ProgramStateNode, ProgramStateStack, StateNode, StateNodeDecl, VariableStateNode } from "./optimizer-types";
|
|
5
5
|
import { visit_resources } from "./resources";
|
|
6
6
|
import { xmlUtil } from "./sdk-util";
|
|
7
7
|
export { visitorNode, visitReferences } from "./visitor";
|
|
@@ -22,5 +22,8 @@ export declare function findUsingForNode(state: ProgramStateLive, stack: Program
|
|
|
22
22
|
results: StateNodeDecl[];
|
|
23
23
|
};
|
|
24
24
|
}[] | null;
|
|
25
|
-
export declare function getApiFunctionInfo(func: FunctionStateNode): FunctionInfo;
|
|
26
|
-
export declare function markInvokeClassMethod(func: FunctionStateNode): void;
|
|
25
|
+
export declare function getApiFunctionInfo(state: ProgramState, func: FunctionStateNode): FunctionInfo | false;
|
|
26
|
+
export declare function markInvokeClassMethod(state: ProgramStateAnalysis, func: FunctionStateNode): void;
|
|
27
|
+
export declare function isLocal(v: VariableStateNode): boolean;
|
|
28
|
+
export declare function diagnostic(state: ProgramState, loc: mctree.Node["loc"], message: string | null, type?: NonNullable<ProgramStateAnalysis["diagnostics"]>[string][number]["type"]): void;
|
|
29
|
+
export declare function getSuperClasses(klass: ClassStateNode): Set<ClassStateNode> | null;
|
package/build/src/ast.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
|
+
import type { xmlUtil } from "./sdk-util";
|
|
2
3
|
export declare function traverseAst(node: mctree.Node, pre?: null | ((node: mctree.Node) => void | null | false | (keyof mctree.NodeAll)[]), post?: (node: mctree.Node) => void | null | false | mctree.Node | mctree.Node[]): false | void | null | mctree.Node | mctree.Node[];
|
|
3
4
|
export declare function isStatement(node: mctree.Node): node is mctree.Statement;
|
|
4
5
|
export declare function isExpression(node: mctree.Node): node is mctree.Expression;
|
|
@@ -29,4 +30,30 @@ interface NullLiteral extends mctree.Literal {
|
|
|
29
30
|
declare type LiteralValues = [NumberLiteral, "Number" | "Float" | "Double"] | [LongLiteral, "Long"] | [StringLiteral, "String"] | [CharLiteral, "Char"] | [BooleanLiteral, "Boolean"] | [NullLiteral, "Null"];
|
|
30
31
|
export declare function getNodeValue(node: mctree.Literal): LiteralValues;
|
|
31
32
|
export declare function getNodeValue(node: mctree.Node): LiteralValues | [null, null];
|
|
33
|
+
export declare function wrap<T extends mctree.Node>(node: T, loc?: mctree.SourceLocation | null): T;
|
|
34
|
+
export declare function locRange(start: mctree.SourceLocation, end: mctree.SourceLocation): {
|
|
35
|
+
source: string | null | undefined;
|
|
36
|
+
start: mctree.Position;
|
|
37
|
+
end: mctree.Position;
|
|
38
|
+
};
|
|
39
|
+
export declare function adjustLoc(loc: xmlUtil.SourceLocation, start?: number, end?: number): {
|
|
40
|
+
readonly source: string | null | undefined;
|
|
41
|
+
readonly start: {
|
|
42
|
+
readonly offset: number;
|
|
43
|
+
readonly line: number;
|
|
44
|
+
readonly column: number;
|
|
45
|
+
};
|
|
46
|
+
readonly end: {
|
|
47
|
+
readonly offset: number;
|
|
48
|
+
readonly line: number;
|
|
49
|
+
readonly column: number;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
export declare function makeIdentifier(name: string, loc?: mctree.SourceLocation | null | undefined): {
|
|
53
|
+
type: "Identifier";
|
|
54
|
+
name: string;
|
|
55
|
+
};
|
|
56
|
+
export declare function makeMemberExpression(object: mctree.ScopedName, property: mctree.Identifier): mctree.DottedName;
|
|
57
|
+
export declare function makeScopedName(dotted: string, l?: mctree.SourceLocation): mctree.ScopedName;
|
|
58
|
+
export declare function getLiteralNode(node: mctree.Node | null | undefined): null | mctree.Literal | mctree.AsExpression;
|
|
32
59
|
export {};
|
|
@@ -13,7 +13,7 @@ export declare type Block<T extends EventConstraint<T>> = {
|
|
|
13
13
|
exsucc?: Block<T>;
|
|
14
14
|
events?: T[];
|
|
15
15
|
};
|
|
16
|
-
export declare function buildReducedGraph<T extends EventConstraint<T>>(state: ProgramStateAnalysis, func: FunctionStateNode, notice: (node: mctree.Node, stmt: mctree.Node, mayThrow: boolean) => T | null): Block<T>;
|
|
16
|
+
export declare function buildReducedGraph<T extends EventConstraint<T>>(state: ProgramStateAnalysis, func: FunctionStateNode, notice: (node: mctree.Node, stmt: mctree.Node, mayThrow: boolean | 1) => T | null): Block<T>;
|
|
17
17
|
export declare function postOrderTraverse<T extends EventConstraint<T>>(head: Block<T>, visitor: (block: Block<T>) => void): void;
|
|
18
18
|
export declare function preOrderTraverse<T extends EventConstraint<T>>(head: Block<T>, visitor: (block: Block<T>) => void): void;
|
|
19
19
|
export declare function getPostOrder<T extends EventConstraint<T>>(head: Block<T>): Block<T>[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
|
+
import { BaseEvent, Block } from "./control-flow";
|
|
3
|
+
import { FunctionStateNode, ProgramStateAnalysis, StateNodeDecl } from "./optimizer-types";
|
|
4
|
+
export declare type RefNode = mctree.Identifier | mctree.MemberExpression | mctree.Literal;
|
|
5
|
+
export declare type EventDecl = StateNodeDecl | StateNodeDecl[] | mctree.Literal;
|
|
6
|
+
export interface RefEvent extends BaseEvent {
|
|
7
|
+
type: "ref";
|
|
8
|
+
node: RefNode;
|
|
9
|
+
decl: EventDecl;
|
|
10
|
+
}
|
|
11
|
+
export interface DefEvent extends BaseEvent {
|
|
12
|
+
type: "def";
|
|
13
|
+
node: mctree.AssignmentExpression | mctree.UpdateExpression | mctree.VariableDeclarator;
|
|
14
|
+
decl: EventDecl;
|
|
15
|
+
}
|
|
16
|
+
export interface ModEvent extends BaseEvent {
|
|
17
|
+
type: "mod";
|
|
18
|
+
node: mctree.Node;
|
|
19
|
+
decl?: EventDecl | undefined | null;
|
|
20
|
+
before?: boolean;
|
|
21
|
+
id?: RefNode;
|
|
22
|
+
callees?: FunctionStateNode[] | null;
|
|
23
|
+
}
|
|
24
|
+
export interface ExnEvent extends BaseEvent {
|
|
25
|
+
type: "exn";
|
|
26
|
+
node: mctree.Node;
|
|
27
|
+
}
|
|
28
|
+
export declare type Event = RefEvent | DefEvent | ModEvent | ExnEvent;
|
|
29
|
+
export interface DataFlowBlock extends Block<Event> {
|
|
30
|
+
order?: number;
|
|
31
|
+
}
|
|
32
|
+
export declare function declFullName(decl: EventDecl): string | undefined;
|
|
33
|
+
export declare function declName(decl: EventDecl): string | undefined;
|
|
34
|
+
export declare function unhandledType(node: never): never;
|
|
35
|
+
export declare function buildDataFlowGraph(state: ProgramStateAnalysis, func: FunctionStateNode, wantsLiteral: (literal: mctree.Literal) => boolean, trackInsertionPoints: boolean, wantsAllRefs: boolean): {
|
|
36
|
+
identifiers: Set<string>;
|
|
37
|
+
graph: Block<RefEvent | DefEvent | ModEvent | ExnEvent>;
|
|
38
|
+
};
|
|
39
|
+
export declare class DataflowQueue {
|
|
40
|
+
private enqueued;
|
|
41
|
+
private queue;
|
|
42
|
+
enqueue(block: DataFlowBlock): void;
|
|
43
|
+
dequeue(): DataFlowBlock;
|
|
44
|
+
empty(): boolean;
|
|
45
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
1
2
|
import { VariableStateNode, FunctionStateNode, LookupDefinition, ProgramStateAnalysis } from "./optimizer-types";
|
|
2
3
|
export declare function cloneSet<T>(ae: Set<T>): Set<T>;
|
|
3
4
|
export declare function mergeSet<T>(a: Set<T>, b: Set<T>): void;
|
|
@@ -10,3 +11,4 @@ export declare function recordCalledFuncs(func: FunctionStateNode, callees: Func
|
|
|
10
11
|
export declare function functionMayModify(state: ProgramStateAnalysis, func: FunctionStateNode, decl: VariableStateNode): boolean;
|
|
11
12
|
export declare function findCallees(lookupDefs: LookupDefinition[]): FunctionStateNode[] | null;
|
|
12
13
|
export declare function findCalleesForNew(lookupDefs: LookupDefinition[]): FunctionStateNode[];
|
|
14
|
+
export declare function findCalleesByNode(state: ProgramStateAnalysis, callee: mctree.Expression): FunctionStateNode[] | null;
|
package/build/src/inliner.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
|
-
import { FunctionStateNode,
|
|
2
|
+
import { FunctionStateNode, ProgramStateAnalysis } from "./optimizer-types";
|
|
3
3
|
export declare function inlinableSubExpression(expr: mctree.Expression): mctree.SimpleCallExpression | null;
|
|
4
4
|
export declare function shouldInline(state: ProgramStateAnalysis, func: FunctionStateNode, call: mctree.CallExpression, context: InlineContext | null): boolean;
|
|
5
5
|
declare type InlineBody = mctree.BlockStatement | mctree.ExpressionStatement["expression"];
|
|
6
6
|
export declare function unused(state: ProgramStateAnalysis, expression: mctree.ExpressionStatement["expression"]): mctree.Statement[];
|
|
7
7
|
export declare function unused(state: ProgramStateAnalysis, expression: mctree.ExpressionStatement["expression"], top: true): mctree.Statement[] | null;
|
|
8
|
-
export declare function diagnostic(state: ProgramState, loc: mctree.Node["loc"], message: string | null, type?: NonNullable<ProgramStateAnalysis["diagnostics"]>[string][number]["type"]): void;
|
|
9
8
|
export declare type InlineContext = mctree.ReturnStatement | mctree.IfStatement | mctree.AssignmentExpression | mctree.ExpressionStatement | mctree.VariableDeclarator;
|
|
10
9
|
export declare function inlineFunction(state: ProgramStateAnalysis, func: FunctionStateNode, call: mctree.CallExpression, context: InlineContext | null): InlineBody | null;
|
|
11
10
|
export declare function applyTypeIfNeeded(node: mctree.Node): mctree.Node;
|
package/build/src/jungles.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ManifestXML } from "./manifest";
|
|
2
2
|
import { BuildConfig } from "./optimizer-types.js";
|
|
3
|
-
import { xmlUtil } from "./sdk-util";
|
|
3
|
+
import { DeviceInfo, xmlUtil } from "./sdk-util";
|
|
4
4
|
export declare type JungleBuildDependencies = Record<string, xmlUtil.Document | true>;
|
|
5
5
|
export declare type JungleError = Error & {
|
|
6
6
|
buildDependencies?: JungleBuildDependencies;
|
|
@@ -49,6 +49,7 @@ declare type JungleInfoBase = {
|
|
|
49
49
|
annotations?: string[];
|
|
50
50
|
resources: JungleResourceMap;
|
|
51
51
|
buildDependencies: JungleBuildDependencies;
|
|
52
|
+
devices: DeviceInfo;
|
|
52
53
|
};
|
|
53
54
|
export declare type JungleResourceMap = Record<string, xmlUtil.Document>;
|
|
54
55
|
export declare type ResolvedJungle = JungleInfoBase & {
|
package/build/src/manifest.d.ts
CHANGED
|
@@ -7,4 +7,5 @@ export declare function manifestBarrels(manifest: ManifestXML): string[];
|
|
|
7
7
|
export declare function manifestDropBarrels(manifest: ManifestXML): void;
|
|
8
8
|
export declare function manifestBarrelName(manifestName: string, manifest: ManifestXML): string;
|
|
9
9
|
export declare function manifestAnnotations(manifest: ManifestXML): string[] | undefined;
|
|
10
|
+
export declare function manifestLanguages(manifest: ManifestXML): string[] | undefined;
|
|
10
11
|
export declare function checkManifest(manifest: ManifestXML, products: string[]): Promise<boolean>;
|
|
@@ -4,10 +4,9 @@ import { BuildConfig, FilesToOptimizeMap, LookupDefinition, ProgramStateAnalysis
|
|
|
4
4
|
import { xmlUtil } from "./sdk-util";
|
|
5
5
|
export declare function getFileSources(fnMap: FilesToOptimizeMap): Promise<void>;
|
|
6
6
|
export declare function getFileASTs(fnMap: FilesToOptimizeMap): Promise<boolean>;
|
|
7
|
-
export declare function analyze(fnMap: FilesToOptimizeMap, resourcesMap: Record<string, JungleResourceMap>, manifestXML: xmlUtil.Document, config: BuildConfig): Promise<ProgramStateAnalysis>;
|
|
7
|
+
export declare function analyze(fnMap: FilesToOptimizeMap, resourcesMap: Record<string, JungleResourceMap>, manifestXML: xmlUtil.Document | undefined, config: BuildConfig): Promise<ProgramStateAnalysis>;
|
|
8
8
|
export declare function reportMissingSymbols(state: ProgramStateAnalysis, config?: BuildConfig): void;
|
|
9
9
|
export declare function getLiteralFromDecls(lookupDefns: LookupDefinition[]): mctree.Literal | mctree.AsExpression | null;
|
|
10
|
-
export declare function getLiteralNode(node: mctree.Node | null | undefined): null | mctree.Literal | mctree.AsExpression;
|
|
11
10
|
export declare function optimizeMonkeyC(fnMap: FilesToOptimizeMap, resourcesMap: Record<string, JungleResourceMap>, manifestXML: xmlUtil.Document, config: BuildConfig): Promise<Record<string, {
|
|
12
11
|
type: import("./optimizer-types").DiagnosticType;
|
|
13
12
|
loc: {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
|
+
import { EnumStringMember } from "@markw65/prettier-plugin-monkeyc/build/estree-types";
|
|
2
3
|
import { xmlUtil } from "./sdk-util";
|
|
4
|
+
import { ExactOrUnion } from "./type-flow/types";
|
|
3
5
|
export declare type DiagnosticType = "ERROR" | "WARNING" | "INFO";
|
|
4
6
|
export declare type LookupRules = "COMPILER1" | "COMPILER2" | "DEFAULT";
|
|
5
7
|
export declare type EnforceStatic = "YES" | "NO";
|
|
@@ -33,8 +35,11 @@ export declare type BuildConfig = {
|
|
|
33
35
|
prettier?: Record<string, unknown>;
|
|
34
36
|
extensionVersion?: string;
|
|
35
37
|
useLocalOptimizer?: boolean;
|
|
38
|
+
propagateTypes?: boolean;
|
|
39
|
+
trustDeclaredTypes?: boolean;
|
|
40
|
+
checkTypes?: DiagnosticType | "OFF";
|
|
36
41
|
};
|
|
37
|
-
export declare type StateNodeDecl = StateNode | mctree.EnumStringMember | mctree.TypedIdentifier
|
|
42
|
+
export declare type StateNodeDecl = StateNode | mctree.EnumStringMember | mctree.TypedIdentifier;
|
|
38
43
|
export declare type StateNodeDecls = {
|
|
39
44
|
[key: string]: StateNodeDecl[];
|
|
40
45
|
};
|
|
@@ -80,6 +85,7 @@ export interface ClassStateNode extends BaseStateNode {
|
|
|
80
85
|
fullName: string;
|
|
81
86
|
superClass?: ClassStateNode[] | true;
|
|
82
87
|
hasInvoke?: boolean;
|
|
88
|
+
superClasses?: Set<ClassStateNode>;
|
|
83
89
|
}
|
|
84
90
|
export declare type FunctionInfo = {
|
|
85
91
|
modifiedDecls: Set<VariableStateNode>;
|
|
@@ -96,7 +102,7 @@ export interface FunctionStateNode extends BaseStateNode {
|
|
|
96
102
|
fullName: string;
|
|
97
103
|
stack?: ProgramStateStack;
|
|
98
104
|
decls?: undefined;
|
|
99
|
-
info?: FunctionInfo;
|
|
105
|
+
info?: FunctionInfo | false;
|
|
100
106
|
next_info?: FunctionInfo;
|
|
101
107
|
}
|
|
102
108
|
export interface BlockStateNode extends BaseStateNode {
|
|
@@ -111,6 +117,9 @@ export interface TypedefStateNode extends BaseStateNode {
|
|
|
111
117
|
node: mctree.TypedefDeclaration;
|
|
112
118
|
name: string;
|
|
113
119
|
fullName: string;
|
|
120
|
+
isExpanding?: true;
|
|
121
|
+
isRecursive?: true;
|
|
122
|
+
resolvedType?: ExactOrUnion;
|
|
114
123
|
}
|
|
115
124
|
export interface VariableStateNode extends BaseStateNode {
|
|
116
125
|
type: "VariableDeclarator";
|
|
@@ -120,7 +129,14 @@ export interface VariableStateNode extends BaseStateNode {
|
|
|
120
129
|
stack: ProgramStateStack;
|
|
121
130
|
used?: true;
|
|
122
131
|
}
|
|
123
|
-
export
|
|
132
|
+
export interface EnumStateNode extends BaseStateNode {
|
|
133
|
+
type: "EnumDeclaration";
|
|
134
|
+
node: mctree.EnumDeclaration;
|
|
135
|
+
name: string;
|
|
136
|
+
fullName: string;
|
|
137
|
+
stack: ProgramStateStack;
|
|
138
|
+
}
|
|
139
|
+
export declare type StateNode = ProgramStateNode | FunctionStateNode | BlockStateNode | ClassStateNode | ModuleStateNode | TypedefStateNode | VariableStateNode | EnumStateNode;
|
|
124
140
|
export declare type ProgramStateStack = StateNode[];
|
|
125
141
|
export declare type LookupDefinition = {
|
|
126
142
|
parent: StateNode | null;
|
|
@@ -130,6 +146,7 @@ export declare type LookupResult = [string, LookupDefinition[]] | [null, null] |
|
|
|
130
146
|
export declare type ProgramState = {
|
|
131
147
|
allFunctions?: Record<string, FunctionStateNode[]>;
|
|
132
148
|
allClasses?: ClassStateNode[];
|
|
149
|
+
invokeInfo?: FunctionInfo;
|
|
133
150
|
fnMap?: FilesToOptimizeMap;
|
|
134
151
|
rezAst?: mctree.Program;
|
|
135
152
|
manifestXML?: xmlUtil.Document;
|
|
@@ -180,12 +197,13 @@ export declare type ProgramState = {
|
|
|
180
197
|
};
|
|
181
198
|
message: string;
|
|
182
199
|
}[]>;
|
|
200
|
+
enumMap?: Map<EnumStringMember, EnumStateNode>;
|
|
183
201
|
};
|
|
184
|
-
declare type Finalized<T, Keys extends keyof T> = T & {
|
|
202
|
+
export declare type Finalized<T, Keys extends keyof T> = T & {
|
|
185
203
|
[key in Keys]-?: NonNullable<T[key]>;
|
|
186
204
|
};
|
|
187
205
|
export declare type ProgramStateLive = Finalized<ProgramState, "stack" | "lookup" | "lookupValue" | "lookupType" | "lookupNonlocal" | "stackClone" | "traverse" | "index" | "constants" | "removeNodeComments" | "inType" | "nextExposed" | "lookupRules">;
|
|
188
|
-
export declare type ProgramStateAnalysis = Finalized<ProgramStateLive, "allClasses" | "allFunctions" | "fnMap">;
|
|
206
|
+
export declare type ProgramStateAnalysis = Finalized<ProgramStateLive, "allClasses" | "allFunctions" | "fnMap" | "invokeInfo">;
|
|
189
207
|
export declare type ProgramStateOptimizer = Finalized<ProgramStateAnalysis, "localsStack" | "exposed" | "calledFunctions" | "usedByName">;
|
|
190
208
|
export declare type ExcludeAnnotationsMap = {
|
|
191
209
|
[key: string]: boolean;
|
package/build/src/pre.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FunctionStateNode, ProgramStateAnalysis } from "./optimizer-types";
|
|
2
2
|
export declare function sizeBasedPRE(state: ProgramStateAnalysis, func: FunctionStateNode): void;
|
package/build/src/projects.d.ts
CHANGED
|
@@ -13,9 +13,10 @@ export declare type RemoteProject = string | {
|
|
|
13
13
|
sourcePath?: string;
|
|
14
14
|
jungleContent?: string[];
|
|
15
15
|
garminOptLevel?: number;
|
|
16
|
+
test?: boolean;
|
|
16
17
|
};
|
|
17
18
|
export declare const githubProjects: RemoteProject[];
|
|
18
|
-
export declare function fetchGitProjects(projects: RemoteProject[]): Promise<(string | {
|
|
19
|
+
export declare function fetchGitProjects(projects: RemoteProject[], testOnly: boolean): Promise<(string | {
|
|
19
20
|
jungle: string;
|
|
20
21
|
build: boolean | null;
|
|
21
22
|
options: BuildConfig | null;
|
package/build/src/util.d.ts
CHANGED
|
@@ -5,9 +5,14 @@ export declare function globa(pattern: string, options?: glob.Options & {
|
|
|
5
5
|
export declare function globSome(pattern: string, predicate: (path: string) => boolean, options?: glob.Options & {
|
|
6
6
|
mark?: boolean;
|
|
7
7
|
}): Promise<boolean>;
|
|
8
|
+
export declare function forEach<T>(val: T | T[] | null | undefined, fn: (v: T) => void): void;
|
|
9
|
+
export declare function map<T, U>(val: T | T[] | null | undefined, fn: (v: T) => U): U[];
|
|
10
|
+
export declare function every<T>(val: T | T[] | null | undefined, fn: (v: T) => void): boolean | void;
|
|
11
|
+
export declare function some<T>(val: T | T[] | null | undefined, fn: (v: T) => void): boolean | void;
|
|
12
|
+
export declare function reduce<T, U>(val: T | T[] | null | undefined, fn: (p: U, v: T) => U, init: U): U;
|
|
8
13
|
export declare function last_modified(inputs: string[]): Promise<number>;
|
|
9
14
|
export declare function first_modified(inputs: string[]): Promise<number>;
|
|
10
|
-
export declare function pushUnique<T, U extends T>(arr: T[], value: U):
|
|
15
|
+
export declare function pushUnique<T, U extends T>(arr: T[], value: U): boolean;
|
|
11
16
|
export declare function sameArrays<T>(a1: T[], a2: T[], check: (a: T, b: T) => boolean): boolean;
|
|
12
17
|
export declare type LineHandler = (line: string) => void;
|
|
13
18
|
export declare function spawnByLine(command: string, args: string[], lineHandlers: LineHandler | LineHandler[], options?: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { WorkerTask, WorkerTaskResult } from "./worker-task";
|
|
2
|
-
export declare function startPool(): void;
|
|
2
|
+
export declare function startPool(parallelism?: number): void;
|
|
3
3
|
export declare function stopPool(): void;
|
|
4
4
|
export declare function runTaskInPool<T extends WorkerTask>(task: T): Promise<WorkerTaskResult<T>>;
|
|
@@ -1,29 +1,60 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BuildConfig } from "./optimizer";
|
|
2
2
|
interface BaseNode {
|
|
3
3
|
type: string;
|
|
4
4
|
data: unknown;
|
|
5
5
|
}
|
|
6
|
-
interface
|
|
6
|
+
interface BuildOptimizedProject extends BaseNode {
|
|
7
|
+
type: "buildOptimizedProject";
|
|
7
8
|
data: {
|
|
8
|
-
|
|
9
|
-
options
|
|
9
|
+
product: string | null;
|
|
10
|
+
options: BuildConfig;
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
|
-
interface
|
|
13
|
-
type: "
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
interface XmlParserTask extends ParserData {
|
|
19
|
-
type: "parseXml";
|
|
13
|
+
interface GenerateOptimizedProject extends BaseNode {
|
|
14
|
+
type: "generateOptimizedProject";
|
|
15
|
+
data: {
|
|
16
|
+
options: BuildConfig;
|
|
17
|
+
};
|
|
20
18
|
}
|
|
21
|
-
export declare type WorkerTask =
|
|
19
|
+
export declare type WorkerTask = BuildOptimizedProject | GenerateOptimizedProject;
|
|
22
20
|
export declare const workerTaskHandlers: {
|
|
23
|
-
readonly
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
readonly buildOptimizedProject: (data: BuildOptimizedProject["data"]) => Promise<{
|
|
22
|
+
exe: string;
|
|
23
|
+
args: string[];
|
|
24
|
+
program: string;
|
|
25
|
+
product: string | null;
|
|
26
|
+
hasTests: boolean;
|
|
27
|
+
diagnostics: Record<string, {
|
|
28
|
+
type: import("./optimizer-types").DiagnosticType;
|
|
29
|
+
loc: {
|
|
30
|
+
start: import("@markw65/prettier-plugin-monkeyc/build/estree-types").Position;
|
|
31
|
+
end: import("@markw65/prettier-plugin-monkeyc/build/estree-types").Position;
|
|
32
|
+
};
|
|
33
|
+
message: string;
|
|
34
|
+
}[]> | undefined;
|
|
35
|
+
}>;
|
|
36
|
+
readonly generateOptimizedProject: (data: GenerateOptimizedProject["data"]) => Promise<{
|
|
37
|
+
jungleFiles: string | undefined;
|
|
38
|
+
xml: import("./xml-util").Document;
|
|
39
|
+
program: string;
|
|
40
|
+
hasTests: boolean;
|
|
41
|
+
diagnostics?: undefined;
|
|
42
|
+
} | {
|
|
43
|
+
jungleFiles: string;
|
|
44
|
+
xml: import("./xml-util").Document;
|
|
45
|
+
program: string;
|
|
46
|
+
hasTests: boolean;
|
|
47
|
+
diagnostics: Record<string, {
|
|
48
|
+
type: import("./optimizer-types").DiagnosticType;
|
|
49
|
+
loc: {
|
|
50
|
+
start: import("@markw65/prettier-plugin-monkeyc/build/estree-types").Position;
|
|
51
|
+
end: import("@markw65/prettier-plugin-monkeyc/build/estree-types").Position;
|
|
52
|
+
};
|
|
53
|
+
message: string;
|
|
54
|
+
}[]>;
|
|
55
|
+
}>;
|
|
26
56
|
};
|
|
27
|
-
|
|
28
|
-
export declare
|
|
57
|
+
declare type RemovePromise<T> = T extends Promise<infer U> ? U : T;
|
|
58
|
+
export declare type WorkerTaskResult<T> = T extends WorkerTask ? RemovePromise<ReturnType<typeof workerTaskHandlers[T["type"]]>> : never;
|
|
59
|
+
export declare function performTask<T extends WorkerTask>(task: T): Promise<WorkerTaskResult<T>>;
|
|
29
60
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/build/util.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
0 && (module.exports = {copyRecursiveAsNeeded,first_modified,globSome,globa,last_modified,promiseAll,pushUnique,readByLine,sameArrays,spawnByLine});
|
|
1
|
+
0 && (module.exports = {copyRecursiveAsNeeded,every,first_modified,forEach,globSome,globa,last_modified,map,promiseAll,pushUnique,readByLine,reduce,sameArrays,some,spawnByLine});
|
|
2
2
|
/******/ (() => { // webpackBootstrap
|
|
3
3
|
/******/ var __webpack_modules__ = ({
|
|
4
4
|
|
|
@@ -7713,14 +7713,19 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
7713
7713
|
// EXPORTS
|
|
7714
7714
|
__webpack_require__.d(__webpack_exports__, {
|
|
7715
7715
|
"copyRecursiveAsNeeded": () => (/* binding */ copyRecursiveAsNeeded),
|
|
7716
|
+
"every": () => (/* binding */ every),
|
|
7716
7717
|
"first_modified": () => (/* binding */ first_modified),
|
|
7718
|
+
"forEach": () => (/* binding */ forEach),
|
|
7717
7719
|
"globSome": () => (/* binding */ globSome),
|
|
7718
7720
|
"globa": () => (/* binding */ globa),
|
|
7719
7721
|
"last_modified": () => (/* binding */ last_modified),
|
|
7722
|
+
"map": () => (/* binding */ map),
|
|
7720
7723
|
"promiseAll": () => (/* binding */ promiseAll),
|
|
7721
7724
|
"pushUnique": () => (/* binding */ pushUnique),
|
|
7722
7725
|
"readByLine": () => (/* binding */ readByLine),
|
|
7726
|
+
"reduce": () => (/* binding */ reduce),
|
|
7723
7727
|
"sameArrays": () => (/* binding */ sameArrays),
|
|
7728
|
+
"some": () => (/* binding */ some),
|
|
7724
7729
|
"spawnByLine": () => (/* binding */ spawnByLine)
|
|
7725
7730
|
});
|
|
7726
7731
|
|
|
@@ -7770,6 +7775,56 @@ function globSome(pattern, predicate, options) {
|
|
|
7770
7775
|
});
|
|
7771
7776
|
});
|
|
7772
7777
|
}
|
|
7778
|
+
function forEach(val, fn) {
|
|
7779
|
+
if (!val)
|
|
7780
|
+
return;
|
|
7781
|
+
if (Array.isArray(val)) {
|
|
7782
|
+
val.forEach(fn);
|
|
7783
|
+
}
|
|
7784
|
+
else {
|
|
7785
|
+
fn(val);
|
|
7786
|
+
}
|
|
7787
|
+
}
|
|
7788
|
+
function map(val, fn) {
|
|
7789
|
+
if (!val)
|
|
7790
|
+
return [];
|
|
7791
|
+
if (Array.isArray(val)) {
|
|
7792
|
+
return val.map(fn);
|
|
7793
|
+
}
|
|
7794
|
+
else {
|
|
7795
|
+
return [fn(val)];
|
|
7796
|
+
}
|
|
7797
|
+
}
|
|
7798
|
+
function every(val, fn) {
|
|
7799
|
+
if (!val)
|
|
7800
|
+
return true;
|
|
7801
|
+
if (Array.isArray(val)) {
|
|
7802
|
+
return val.every(fn);
|
|
7803
|
+
}
|
|
7804
|
+
else {
|
|
7805
|
+
return fn(val);
|
|
7806
|
+
}
|
|
7807
|
+
}
|
|
7808
|
+
function some(val, fn) {
|
|
7809
|
+
if (!val)
|
|
7810
|
+
return false;
|
|
7811
|
+
if (Array.isArray(val)) {
|
|
7812
|
+
return val.some(fn);
|
|
7813
|
+
}
|
|
7814
|
+
else {
|
|
7815
|
+
return fn(val);
|
|
7816
|
+
}
|
|
7817
|
+
}
|
|
7818
|
+
function reduce(val, fn, init) {
|
|
7819
|
+
if (!val)
|
|
7820
|
+
return init;
|
|
7821
|
+
if (Array.isArray(val)) {
|
|
7822
|
+
return val.reduce(fn, init);
|
|
7823
|
+
}
|
|
7824
|
+
else {
|
|
7825
|
+
return fn(init, val);
|
|
7826
|
+
}
|
|
7827
|
+
}
|
|
7773
7828
|
async function modified_times(inputs, missing) {
|
|
7774
7829
|
return Promise.all(inputs.map(async (path) => {
|
|
7775
7830
|
try {
|
|
@@ -7789,8 +7844,9 @@ async function first_modified(inputs) {
|
|
|
7789
7844
|
}
|
|
7790
7845
|
function pushUnique(arr, value) {
|
|
7791
7846
|
if (arr.find((v) => v === value) != null)
|
|
7792
|
-
return;
|
|
7847
|
+
return false;
|
|
7793
7848
|
arr.push(value);
|
|
7849
|
+
return true;
|
|
7794
7850
|
}
|
|
7795
7851
|
function sameArrays(a1, a2, check) {
|
|
7796
7852
|
return a1.length === a2.length && a1.every((e, i) => check(e, a2[i]));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markw65/monkeyc-optimizer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.1.0",
|
|
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",
|
|
@@ -21,8 +21,10 @@
|
|
|
21
21
|
"build-debug": "webpack --mode development",
|
|
22
22
|
"build-release": "webpack --mode production",
|
|
23
23
|
"prepack": "webpack --mode production",
|
|
24
|
-
"test": "npm run test-optimized && npm run test-unopt && npm run test-remote",
|
|
24
|
+
"test": "npm run test-mocha && npm run test-optimized && npm run test-unopt && npm run test-remote && npm run test-remote-tests",
|
|
25
|
+
"test-mocha": "npx mocha --timeout 999999 build/mocha.cjs",
|
|
25
26
|
"test-remote": "node ./test/test.js --product=pick-one --github",
|
|
27
|
+
"test-remote-tests": "node ./test/test.js --product=pick-one --run-tests --github",
|
|
26
28
|
"test-optimized": "node test/test.js --typeCheckLevel Strict --run-tests --product=fenix5 --product=fr235 --jungle ./test/OptimizerTests/monkey.jungle",
|
|
27
29
|
"test-unopt": "node test/test.js --typeCheckLevel Strict --skipOptimization --run-tests --product=fenix5 --product=fr235 --jungle ./test/OptimizerTests/monkey.jungle",
|
|
28
30
|
"test-garmin-opt": "node test/test.js --typeCheckLevel Strict --skipOptimization --garminOptLevel=2 --run-tests --product=fenix5 --product=fr235 --jungle ./test/OptimizerTests/monkey.jungle",
|
|
@@ -38,17 +40,21 @@
|
|
|
38
40
|
"author": "markw65",
|
|
39
41
|
"license": "MIT",
|
|
40
42
|
"dependencies": {
|
|
41
|
-
"@markw65/prettier-plugin-monkeyc": "^1.0.
|
|
43
|
+
"@markw65/prettier-plugin-monkeyc": "^1.0.41"
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|
|
46
|
+
"@types/chai": "^4.3.4",
|
|
44
47
|
"@types/glob": "^8.0.0",
|
|
48
|
+
"@types/mocha": "^10.0.1",
|
|
45
49
|
"@types/prettier": "^2.6.1",
|
|
46
50
|
"@types/priorityqueuejs": "^1.0.1",
|
|
47
51
|
"@typescript-eslint/eslint-plugin": "^5.28.0",
|
|
48
52
|
"@typescript-eslint/parser": "^5.28.0",
|
|
53
|
+
"chai": "^4.3.7",
|
|
49
54
|
"eslint": "^8.12.0",
|
|
50
55
|
"extract-zip": "^2.0.1",
|
|
51
56
|
"fast-glob": "^3.2.12",
|
|
57
|
+
"mocha": "^10.2.0",
|
|
52
58
|
"peggy": "^2.0.1",
|
|
53
59
|
"prettier": "^2.6.2",
|
|
54
60
|
"prettier-plugin-pegjs": "https://github.com/markw65/prettier-plugin-pegjs/releases/download/v0.5.2/prettier-plugin-pegjs-0.5.2.tgz",
|