@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.
@@ -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
 
@@ -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;
@@ -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;
@@ -1,11 +1,10 @@
1
1
  import { mctree } from "@markw65/prettier-plugin-monkeyc";
2
- import { FunctionStateNode, ProgramState, ProgramStateAnalysis } from "./optimizer-types";
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;
@@ -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 & {
@@ -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 | mctree.EnumDeclaration;
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 declare type StateNode = ProgramStateNode | FunctionStateNode | BlockStateNode | ClassStateNode | ModuleStateNode | TypedefStateNode | VariableStateNode;
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;
@@ -1,2 +1,2 @@
1
- import { ProgramStateAnalysis, FunctionStateNode } from "./optimizer-types";
1
+ import { FunctionStateNode, ProgramStateAnalysis } from "./optimizer-types";
2
2
  export declare function sizeBasedPRE(state: ProgramStateAnalysis, func: FunctionStateNode): void;
@@ -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;
@@ -0,0 +1,3 @@
1
+ import { FunctionStateNode, ProgramStateAnalysis } from "./optimizer-types";
2
+ import { InterpState } from "./type-flow/interp";
3
+ export declare function buildTypeInfo(state: ProgramStateAnalysis, func: FunctionStateNode): InterpState | undefined;
@@ -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): void;
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 { mctree } from "@markw65/prettier-plugin-monkeyc";
1
+ import { BuildConfig } from "./optimizer";
2
2
  interface BaseNode {
3
3
  type: string;
4
4
  data: unknown;
5
5
  }
6
- interface ParserData extends BaseNode {
6
+ interface BuildOptimizedProject extends BaseNode {
7
+ type: "buildOptimizedProject";
7
8
  data: {
8
- source: string;
9
- options?: Record<string, unknown>;
9
+ product: string | null;
10
+ options: BuildConfig;
10
11
  };
11
12
  }
12
- interface JungleParserTask extends ParserData {
13
- type: "parseJungle";
14
- }
15
- interface MonkeyCParserTask extends ParserData {
16
- type: "parseMonkeyC";
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 = JungleParserTask | MonkeyCParserTask | XmlParserTask;
19
+ export declare type WorkerTask = BuildOptimizedProject | GenerateOptimizedProject;
22
20
  export declare const workerTaskHandlers: {
23
- readonly parseJungle: (data: JungleParserTask["data"]) => Assignment[];
24
- readonly parseMonkeyC: (data: MonkeyCParserTask["data"]) => mctree.Program;
25
- readonly parseXml: (data: XmlParserTask["data"]) => ParserResult;
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
- export declare type WorkerTaskResult<T> = T extends WorkerTask ? ReturnType<typeof workerTaskHandlers[T["type"]]> : never;
28
- export declare function performTask<T extends WorkerTask>(task: T): WorkerTaskResult<T>;
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.44",
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.40"
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",