@markw65/monkeyc-optimizer 1.0.33 → 1.0.36

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
@@ -393,3 +393,30 @@ Bug Fixes
393
393
 
394
394
  - Bug fixes
395
395
  - Fix PRE to not merge values with different types. ie Number, Long, Float and Double literals should all be treated separately, even when the compare the same.
396
+
397
+ ### 1.0.34
398
+
399
+ - Bug fixes
400
+
401
+ - Fix parser to allow white space to separate attributes, in addition to comma
402
+ - Fix optimizer to respect prettier options when formatting the optimized code
403
+
404
+ - Testing
405
+ - rewrite test harness in typescript
406
+ - fix up tests to work with compiler2 again, and also with compiler2 at -O0
407
+
408
+ ### 1.0.35
409
+
410
+ - Testing
411
+
412
+ - Add a new open source project
413
+ - Fixup tests to work with compiler2beta2
414
+
415
+ - Bug fixes
416
+ - Fixed a bug that caused the optimizer to fail if a top level variable declared in a case statement had an initializer with side effects. This didn't produce incorrect results, the optimizer simply bailed out with an obscure error, and refused to optimize the project.
417
+
418
+ ### 1.0.36
419
+
420
+ - Update to [@markw65/prettier-plugin-monkeyc@1.0.34](https://github.com/markw65/prettier-plugin-monkeyc#1034).
421
+ - Fixes [prettier-plugin-monkeyc#1](https://github.com/markw65/prettier-plugin-monkeyc/issues/1)
422
+ - Fixes [monkeyc-optimizer#1](https://github.com/markw65/monkeyc-optimizer/issues/1)
package/build/api.cjs CHANGED
@@ -2920,18 +2920,35 @@ function unused_exprs_cleanupUnusedVars(state, node) {
2920
2920
  });
2921
2921
  if (toRemove) {
2922
2922
  const varDeclarations = new Map();
2923
- traverseAst(node, null, (node) => {
2923
+ const stack = [];
2924
+ traverseAst(node, (node) => {
2924
2925
  switch (node.type) {
2926
+ case "SwitchCase":
2927
+ stack.push(node.consequent);
2928
+ break;
2929
+ case "BlockStatement":
2930
+ stack.push(node.body);
2931
+ break;
2932
+ }
2933
+ }, (node) => {
2934
+ switch (node.type) {
2935
+ case "SwitchCase":
2936
+ case "BlockStatement":
2937
+ stack.pop();
2938
+ break;
2925
2939
  case "VariableDeclaration": {
2926
2940
  node.declarations.forEach((decl, i) => {
2927
2941
  const name = variableDeclarationName(decl.id);
2928
2942
  if (hasProperty(toRemove, name)) {
2929
- const indices = varDeclarations.get(node);
2930
- if (indices) {
2931
- indices.push(i);
2943
+ const info = varDeclarations.get(node);
2944
+ if (info) {
2945
+ info.indices.push(i);
2932
2946
  }
2933
2947
  else {
2934
- varDeclarations.set(node, [i]);
2948
+ varDeclarations.set(node, {
2949
+ parent: stack[stack.length - 1],
2950
+ indices: [i],
2951
+ });
2935
2952
  }
2936
2953
  }
2937
2954
  });
@@ -2979,10 +2996,10 @@ function unused_exprs_cleanupUnusedVars(state, node) {
2979
2996
  }
2980
2997
  return null;
2981
2998
  });
2982
- varDeclarations.forEach((indices, decl) => {
2999
+ varDeclarations.forEach((info, decl) => {
2983
3000
  let index = -1;
2984
- for (let ii = indices.length, j = decl.declarations.length; ii--;) {
2985
- const i = indices[ii];
3001
+ for (let ii = info.indices.length, j = decl.declarations.length; ii--;) {
3002
+ const i = info.indices[ii];
2986
3003
  const vdecl = decl.declarations[i];
2987
3004
  const name = variableDeclarationName(vdecl.id);
2988
3005
  if (hasProperty(toRemove, name)) {
@@ -2994,7 +3011,7 @@ function unused_exprs_cleanupUnusedVars(state, node) {
2994
3011
  continue;
2995
3012
  }
2996
3013
  if (index < 0) {
2997
- index = parent.node.body.findIndex((s) => s === decl);
3014
+ index = info.parent.findIndex((s) => s === decl);
2998
3015
  if (index < 0) {
2999
3016
  throw new Error(`Failed to find variable declaration for ${variableDeclarationName(vdecl.id)}`);
3000
3017
  }
@@ -3015,7 +3032,7 @@ function unused_exprs_cleanupUnusedVars(state, node) {
3015
3032
  decl.end = vdecl.start;
3016
3033
  }
3017
3034
  decl.declarations.splice(i);
3018
- parent.node.body.splice(index + 1, 0, ...rep);
3035
+ info.parent.splice(index + 1, 0, ...rep);
3019
3036
  j = i;
3020
3037
  continue;
3021
3038
  }
@@ -5059,7 +5076,7 @@ function api_collectNamespaces(ast, stateIn) {
5059
5076
  }
5060
5077
  return state.stack[0];
5061
5078
  }
5062
- function api_formatAst(node, monkeyCSource = null) {
5079
+ function api_formatAst(node, monkeyCSource = null, options = null) {
5063
5080
  /*
5064
5081
  * The estree printer sometimes looks at the parent node without
5065
5082
  * checking that there *is* a parent node (eg it assumes all
@@ -5087,6 +5104,7 @@ function api_formatAst(node, monkeyCSource = null) {
5087
5104
  // looking for in the source.
5088
5105
  const source = (monkeyCSource || "") + "\n" + (0,prettier_plugin_monkeyc_namespaceObject.serializeMonkeyC)(node);
5089
5106
  return external_prettier_namespaceObject.format(source, {
5107
+ ...(options || {}),
5090
5108
  parser: "monkeyc-json",
5091
5109
  plugins: [(prettier_plugin_monkeyc_default())],
5092
5110
  endOfLine: "lf",
@@ -10024,6 +10024,8 @@ const external_crypto_namespaceObject = require("crypto");
10024
10024
  const promises_namespaceObject = require("fs/promises");
10025
10025
  // EXTERNAL MODULE: external "path"
10026
10026
  var external_path_ = __webpack_require__(1423);
10027
+ ;// CONCATENATED MODULE: external "prettier"
10028
+ const external_prettier_namespaceObject = require("prettier");
10027
10029
  ;// CONCATENATED MODULE: external "./api.cjs"
10028
10030
  const external_api_cjs_namespaceObject = require("./api.cjs");
10029
10031
  ;// CONCATENATED MODULE: external "./sdk-util.cjs"
@@ -13612,18 +13614,35 @@ function cleanupUnusedVars(state, node) {
13612
13614
  });
13613
13615
  if (toRemove) {
13614
13616
  const varDeclarations = new Map();
13615
- traverseAst(node, null, (node) => {
13617
+ const stack = [];
13618
+ traverseAst(node, (node) => {
13616
13619
  switch (node.type) {
13620
+ case "SwitchCase":
13621
+ stack.push(node.consequent);
13622
+ break;
13623
+ case "BlockStatement":
13624
+ stack.push(node.body);
13625
+ break;
13626
+ }
13627
+ }, (node) => {
13628
+ switch (node.type) {
13629
+ case "SwitchCase":
13630
+ case "BlockStatement":
13631
+ stack.pop();
13632
+ break;
13617
13633
  case "VariableDeclaration": {
13618
13634
  node.declarations.forEach((decl, i) => {
13619
13635
  const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(decl.id);
13620
13636
  if (hasProperty(toRemove, name)) {
13621
- const indices = varDeclarations.get(node);
13622
- if (indices) {
13623
- indices.push(i);
13637
+ const info = varDeclarations.get(node);
13638
+ if (info) {
13639
+ info.indices.push(i);
13624
13640
  }
13625
13641
  else {
13626
- varDeclarations.set(node, [i]);
13642
+ varDeclarations.set(node, {
13643
+ parent: stack[stack.length - 1],
13644
+ indices: [i],
13645
+ });
13627
13646
  }
13628
13647
  }
13629
13648
  });
@@ -13671,10 +13690,10 @@ function cleanupUnusedVars(state, node) {
13671
13690
  }
13672
13691
  return null;
13673
13692
  });
13674
- varDeclarations.forEach((indices, decl) => {
13693
+ varDeclarations.forEach((info, decl) => {
13675
13694
  let index = -1;
13676
- for (let ii = indices.length, j = decl.declarations.length; ii--;) {
13677
- const i = indices[ii];
13695
+ for (let ii = info.indices.length, j = decl.declarations.length; ii--;) {
13696
+ const i = info.indices[ii];
13678
13697
  const vdecl = decl.declarations[i];
13679
13698
  const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(vdecl.id);
13680
13699
  if (hasProperty(toRemove, name)) {
@@ -13686,7 +13705,7 @@ function cleanupUnusedVars(state, node) {
13686
13705
  continue;
13687
13706
  }
13688
13707
  if (index < 0) {
13689
- index = parent.node.body.findIndex((s) => s === decl);
13708
+ index = info.parent.findIndex((s) => s === decl);
13690
13709
  if (index < 0) {
13691
13710
  throw new Error(`Failed to find variable declaration for ${(0,external_api_cjs_namespaceObject.variableDeclarationName)(vdecl.id)}`);
13692
13711
  }
@@ -13707,7 +13726,7 @@ function cleanupUnusedVars(state, node) {
13707
13726
  decl.end = vdecl.start;
13708
13727
  }
13709
13728
  decl.declarations.splice(i);
13710
- parent.node.body.splice(index + 1, 0, ...rep);
13729
+ info.parent.splice(index + 1, 0, ...rep);
13711
13730
  j = i;
13712
13731
  continue;
13713
13732
  }
@@ -15047,6 +15066,7 @@ function optimizeCall(state, node, context) {
15047
15066
 
15048
15067
 
15049
15068
 
15069
+
15050
15070
  function relative_path_no_dotdot(relative) {
15051
15071
  return relative.replace(/^(\.\.[\\/])+/, (str) => `__${"dot".repeat(str.length / 3)}__${str.slice(-1)}`);
15052
15072
  }
@@ -15469,28 +15489,35 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
15469
15489
  // the oldest optimized file, we don't need to regenerate
15470
15490
  const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
15471
15491
  const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
15472
- if (source_time < opt_time && 1658088370253 < opt_time) {
15492
+ if (source_time < opt_time && 1662763619992 < opt_time) {
15473
15493
  return { hasTests, diagnostics: prevDiagnostics };
15474
15494
  }
15475
15495
  }
15476
15496
  await promises_namespaceObject.rm(output, { recursive: true, force: true });
15477
15497
  await promises_namespaceObject.mkdir(output, { recursive: true });
15478
15498
  const diagnostics = await optimizeMonkeyC(fnMap, Object.keys(buildConfig.barrelMap || {}), config);
15479
- return Promise.all(Object.values(fnMap).map(async (info) => {
15480
- const name = info.output;
15481
- const dir = external_path_.dirname(name);
15482
- await promises_namespaceObject.mkdir(dir, { recursive: true });
15483
- const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
15484
- await promises_namespaceObject.writeFile(name, opt_source);
15485
- return info.hasTests;
15486
- })).then((results) => {
15487
- const hasTests = results.some((v) => v);
15488
- return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
15489
- hasTests,
15490
- diagnostics,
15491
- ...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
15492
- }))
15493
- .then(() => ({ hasTests, diagnostics }));
15499
+ return external_prettier_namespaceObject.resolveConfig(config.workspace, {
15500
+ useCache: false,
15501
+ editorconfig: true,
15502
+ }).then((prettierConfig) => {
15503
+ const options = { ...prettierConfig, ...(config.prettier || {}) };
15504
+ return Promise.all(Object.values(fnMap).map(async (info) => {
15505
+ const name = info.output;
15506
+ const dir = external_path_.dirname(name);
15507
+ await promises_namespaceObject.mkdir(dir, { recursive: true });
15508
+ options.filepath = name;
15509
+ const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource, options);
15510
+ await promises_namespaceObject.writeFile(name, opt_source);
15511
+ return info.hasTests;
15512
+ })).then((results) => {
15513
+ const hasTests = results.some((v) => v);
15514
+ return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
15515
+ hasTests,
15516
+ diagnostics,
15517
+ ...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
15518
+ }))
15519
+ .then(() => ({ hasTests, diagnostics }));
15520
+ });
15494
15521
  });
15495
15522
  }
15496
15523
  async function getProjectAnalysis(targets, analysis, options) {
@@ -1,4 +1,4 @@
1
- 0 && (module.exports = {appSupport,connectiq,getDeviceInfo,getLanguages,getSdkPath,isWin});
1
+ 0 && (module.exports = {SectionKinds,appSupport,connectiq,getDeviceInfo,getLanguages,getSdkPath,isWin,readPrg});
2
2
  /******/ (() => { // webpackBootstrap
3
3
  /******/ var __webpack_modules__ = ({
4
4
 
@@ -7171,12 +7171,14 @@ __webpack_require__.r(__webpack_exports__);
7171
7171
 
7172
7172
  // EXPORTS
7173
7173
  __webpack_require__.d(__webpack_exports__, {
7174
+ "SectionKinds": () => (/* reexport */ SectionKinds),
7174
7175
  "appSupport": () => (/* binding */ appSupport),
7175
7176
  "connectiq": () => (/* binding */ connectiq),
7176
7177
  "getDeviceInfo": () => (/* binding */ getDeviceInfo),
7177
7178
  "getLanguages": () => (/* binding */ getLanguages),
7178
7179
  "getSdkPath": () => (/* binding */ getSdkPath),
7179
- "isWin": () => (/* binding */ isWin)
7180
+ "isWin": () => (/* binding */ isWin),
7181
+ "readPrg": () => (/* reexport */ readPrg)
7180
7182
  });
7181
7183
 
7182
7184
  ;// CONCATENATED MODULE: external "fs/promises"
@@ -7187,11 +7189,38 @@ const external_path_namespaceObject = require("path");
7187
7189
  var xml2js = __webpack_require__(5055);
7188
7190
  ;// CONCATENATED MODULE: external "./util.cjs"
7189
7191
  const external_util_cjs_namespaceObject = require("./util.cjs");
7192
+ ;// CONCATENATED MODULE: ./src/readprg.ts
7193
+
7194
+ var SectionKinds;
7195
+ (function (SectionKinds) {
7196
+ SectionKinds[SectionKinds["TEXT"] = -1059145026] = "TEXT";
7197
+ SectionKinds[SectionKinds["DATA"] = -629491010] = "DATA";
7198
+ })(SectionKinds || (SectionKinds = {}));
7199
+ async function readPrg(path) {
7200
+ const data = await promises_namespaceObject.readFile(path);
7201
+ const view = new DataView(data.buffer);
7202
+ const sections = {};
7203
+ let offset = 0;
7204
+ while (view.byteLength - offset > 8) {
7205
+ const type = view.getInt32(offset);
7206
+ offset += 4;
7207
+ const length = view.getInt32(offset);
7208
+ offset += 4;
7209
+ if (length > view.byteLength - offset) {
7210
+ throw new Error(`Invalid length for section ${type}`);
7211
+ }
7212
+ sections[type] = length;
7213
+ offset += length;
7214
+ }
7215
+ return sections;
7216
+ }
7217
+
7190
7218
  ;// CONCATENATED MODULE: ./src/sdk-util.ts
7191
7219
 
7192
7220
 
7193
7221
 
7194
7222
 
7223
+
7195
7224
  const isWin = process.platform == "win32";
7196
7225
  const appSupport = isWin
7197
7226
  ? `${process.env.APPDATA}`.replace(/\\/g, "/")
@@ -9,7 +9,7 @@ export declare function variableDeclarationName(node: mctree.TypedIdentifier | m
9
9
  export declare function sameLookupResult(a: LookupDefinition[], b: LookupDefinition[]): boolean;
10
10
  export declare function isLookupCandidate(node: mctree.MemberExpression): false | mctree.Identifier;
11
11
  export declare function collectNamespaces(ast: mctree.Program, stateIn?: ProgramState): ProgramStateNode;
12
- export declare function formatAst(node: mctree.Node, monkeyCSource?: string | null): string;
12
+ export declare function formatAst(node: mctree.Node, monkeyCSource?: string | null, options?: Record<string, unknown> | null): string;
13
13
  export declare function findUsingForNode(state: ProgramStateLive, stack: ProgramStateStack, i: number, node: mctree.Identifier, isType: boolean): StateNodeDecl[] | null;
14
14
  export declare function getApiFunctionInfo(func: FunctionStateNode): FunctionInfo;
15
15
  export declare function markInvokeClassMethod(func: FunctionStateNode): void;
@@ -0,0 +1,2 @@
1
+ export declare function driver(): Promise<void>;
2
+ export declare function error(message: string): never;
@@ -6,7 +6,7 @@ export declare function analyze(fnMap: FilesToOptimizeMap, barrelList?: string[]
6
6
  export declare function getLiteralFromDecls(lookupDefns: LookupDefinition[]): mctree.Literal | mctree.AsExpression | null;
7
7
  export declare function getLiteralNode(node: mctree.Node | null | undefined): null | mctree.Literal | mctree.AsExpression;
8
8
  export declare function optimizeMonkeyC(fnMap: FilesToOptimizeMap, barrelList?: string[], config?: BuildConfig): Promise<Record<string, {
9
- type: "ERROR" | "WARNING" | "INFO";
9
+ type: import("./optimizer-types").DiagnosticType;
10
10
  loc: {
11
11
  start: mctree.Position;
12
12
  end: mctree.Position;
@@ -1,6 +1,6 @@
1
1
  import { mctree } from "@markw65/prettier-plugin-monkeyc";
2
2
  import { ResolvedJungle } from "./jungles";
3
- declare type DiagnosticType = "ERROR" | "WARNING" | "INFO";
3
+ export declare type DiagnosticType = "ERROR" | "WARNING" | "INFO";
4
4
  export declare type BuildConfig = {
5
5
  workspace?: string;
6
6
  jungleFiles?: string;
@@ -25,6 +25,7 @@ export declare type BuildConfig = {
25
25
  checkBuildPragmas?: boolean;
26
26
  checkInvalidSymbols?: DiagnosticType | "OFF";
27
27
  sizeBasedPRE?: boolean | string;
28
+ prettier?: Record<string, unknown>;
28
29
  _cache?: {
29
30
  barrels?: Record<string, ResolvedJungle>;
30
31
  barrelMap?: Record<string, Record<string, ResolvedJungle>>;
@@ -30,7 +30,7 @@ export declare function buildOptimizedProject(product: string | null, options: B
30
30
  product: string | null;
31
31
  hasTests: boolean;
32
32
  diagnostics: Record<string, {
33
- type: "ERROR" | "WARNING" | "INFO";
33
+ type: import("./optimizer-types").DiagnosticType;
34
34
  loc: {
35
35
  start: mctree.Position;
36
36
  end: mctree.Position;
@@ -50,7 +50,7 @@ export declare function generateOptimizedProject(options: BuildConfig): Promise<
50
50
  program: string;
51
51
  hasTests: boolean;
52
52
  diagnostics: Record<string, {
53
- type: "ERROR" | "WARNING" | "INFO";
53
+ type: import("./optimizer-types").DiagnosticType;
54
54
  loc: {
55
55
  start: mctree.Position;
56
56
  end: mctree.Position;
@@ -0,0 +1,21 @@
1
+ import { BuildConfig } from "./optimizer-types";
2
+ export declare type RemoteProject = string | {
3
+ root: string;
4
+ options?: BuildConfig;
5
+ rename?: {
6
+ from: string;
7
+ to: string;
8
+ }[];
9
+ build?: boolean;
10
+ comment?: string;
11
+ exclude?: string;
12
+ include?: string;
13
+ sourcePath?: string;
14
+ jungleContent?: string[];
15
+ };
16
+ export declare const githubProjects: RemoteProject[];
17
+ export declare function fetchGitProjects(projects: RemoteProject[]): Promise<(string | {
18
+ jungle: string;
19
+ build: boolean | null;
20
+ options: BuildConfig | null;
21
+ })[]>;
@@ -0,0 +1,5 @@
1
+ export declare enum SectionKinds {
2
+ TEXT = -1059145026,
3
+ DATA = -629491010
4
+ }
5
+ export declare function readPrg(path: string): Promise<Record<number, number>>;
@@ -1,3 +1,4 @@
1
+ export { readPrg, SectionKinds } from "./readprg";
1
2
  export declare const isWin: boolean;
2
3
  export declare const appSupport: string;
3
4
  export declare const connectiq: string;
@@ -9,5 +9,5 @@ export declare function spawnByLine(command: string, args: string[], lineHandler
9
9
  [key: string]: unknown;
10
10
  }): Promise<void>;
11
11
  export declare function readByLine(file: string, lineHandler: LineHandler): Promise<unknown>;
12
- export declare function promiseAll<T>(promiseFn: (i: number) => Promise<T>, parallelism: number): Promise<T[]>;
12
+ export declare function promiseAll<T>(promiseFn: (i: number) => Promise<T> | null, parallelism: number): Promise<T[]>;
13
13
  export declare function copyRecursiveAsNeeded(source: string, target: string, filter?: (src: string, tgt: string) => boolean): Promise<void>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@markw65/monkeyc-optimizer",
3
3
  "type": "module",
4
- "version": "1.0.33",
4
+ "version": "1.0.36",
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",
@@ -37,7 +37,7 @@
37
37
  "author": "markw65",
38
38
  "license": "MIT",
39
39
  "dependencies": {
40
- "@markw65/prettier-plugin-monkeyc": "^1.0.33"
40
+ "@markw65/prettier-plugin-monkeyc": "^1.0.35"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/glob": "^7.2.0",