Big update to prettier-extension-monkeyc

I've posted about prettier-extension-monkeyc before, but I've added a bunch of new features that developers will probably like (well, I've been missing them, so maybe you have too).

The new features it implements for VSCode include:

  • Goto Definition. Point at a symbol, Ctrl/Cmd click, and it will take you to the definition. Or F12
  • Goto References. Right click on a symbol and select "Goto References". It will show you all the references. Or Shift-F12
  • Peek Definition/Peek References. Same as above, but in a popup window so you don't lose your place in the original document.
  • Rename Symbol. Right click on a local, function, class or module name, and select "Rename Symbol". It will rename all the references. It doesn't yet work for class members/methods.
  • Goto Symbol. Type Ctrl/Cmd-Shift-O and pick a symbol from the drop down (which has a hierarchical view of all symbols in the current file). This also appears as an outline across the top of the file.
  • Open Symbol By Name. Type Ctrl/Cmd-T, then start typing letters from a symbol name. A drop down will be populated with all matching symbols from anywhere in your project.

Older features include a prettier based formatter for monkeyc, and a monkeyc optimizer that will build/run/export an optimized version of your project.

[edit: My last couple of replies seem to have just disappeared, and the whole conversation seems to be in a jumbled order, so tldr: there's a new test-release at https://github.com/markw65/prettier-extension-monkeyc/releases/tag/v2.0.9 which seems to work for me on linux. I'll do more verification tomorrow, and push a proper update to the vscode store once I'm sure everything is working]

  • 2.0.124, SDK 8.4.0: optimization fails (venu441mm, DFApp):

    Starting optimization step...
    ERROR: Internal: RangeError: Maximum call stack size exceeded
    RangeError: Maximum call stack size exceeded
    at String.match (<anonymous>)
    at Object.parse (.vscode/extensions/markw65.prettier-extension-monkeyc-2.0.124/node_modules/@markw65/prettier-plugin-monkeyc/build/prettier-plugin-monkeyc.cjs:15:54942)
    at parse5 (vscode/extensions/markw65.prettier-extension-monkeyc-2.0.124/node_modules/prettier/index.mjs:16420:24)
    at async coreFormat (.vscode/extensions/markw65.prettier-extension-monkeyc-2.0.124/node_modules/prettier/index.mjs:16952:7)
    at async formatWithCursor (.vscode/extensions/markw65.prettier-extension-monkeyc-2.0.124/node_modules/prettier/index.mjs:17172:14)
    at async Module.format2 (.vscode/extensions/markw65.prettier-extension-monkeyc-2.0.124/node_modules/prettier/index.mjs:18730:25)
    at async .vscode/extensions/markw65.prettier-extension-monkeyc-2.0.124/node_modules/@markw65/monkeyc-optimizer/build/chunk-BPXB3WQQ.cjs:27415:11
    at async Promise.all (index 12)
    at async Promise.all (index 6)
    at async generateOptimizedProject (.vscode/extensions/markw65.prettier-extension-monkeyc-2.0.124/node_modules/@markw65/monkeyc-optimizer/build/chunk-BPXB3WQQ.cjs:27209:5)
    at async buildOptimizedProject (.vscode/extensions/markw65.prettier-extension-monkeyc-2.0.124/node_modules/@markw65/monkeyc-optimizer/build/chunk-BPXB3WQQ.cjs:26878:59)

  • 2.0.124, SDK 8.4.0, fr955, DFApp:

    I get the following error that I believe is a bug in the optimizer:

    ERROR: fr955: optimized/group004-debug/source/__dot__/source/POC.mc:981,6: Passing 'PolyType<$.Toybox.Lang.Float or $.Toybox.Lang.Number>' as parameter 1 of poly type 'PolyType<Null or $.Toybox.Lang.Float>'.

    After an hour of playing with it to create a POC I found the bug:

    original code:

    class POC {
      private var stepData as DataQueue = new DataQueue(STEP_DATA_SIZE, false); // DataQueue<[Number, Float, Number]>

      function foo() as Void {
        var time = 1;
        
        var oldestStepData = stepData.oldest() as [Number, Float, Number]?;
        var newestStepData = stepData.newest() as [Number, Float, Number]?;
        var deltaDistance = (newestStepData as [Number, Float, Number])[1- (oldestStepData as [Number, Float, Number])[1];
      }

    optimized:

    function foo() {
      var pre_1, pre_3, time, newestStepData
    ;
      pre_1 = 1;
      pre_3 /*>oldestStepData<*/ = stepData.oldest() as [Number, Float, Number]?;
      newestStepData = stepData.newest() as [Number, Float, Number]?;

      // PROBLEMATIC LINE:
      time 
    /*>deltaDistance<*/ =
        (newestStepData as [Number, Float, Number])[pre_1] -
        (pre_3 /*>oldestStepData<*/ as [Number, Float, Number])[pre_1];

      var distStr = formatDistance(time /*>deltaDistance<*/); // ERROR on this line
      System.println("d:" + distStr);
    }

    if the optimizer would produce this line instead:

    time = ((newestStepData as [Number, Float, Number])[1] as Float)- ((pre_3 as [Number, Float, Number])[1] as Float);

    then it works.

    The issue is some kind of optimization in the compiler. When you have:
    var a = newestStepData as [Number, Float, Number])[1] => it knows a is Float

    but when you have:
    pre_1 
    = 1;
    newestStepData as [Number, Float, Number])[pre_1] => it is not sure what is pre_1, so it assumes that a is either Number or Float;


    I have found a "workaround" for now: in my code I change the problematic line to:

        var deltaDistance = (newestStepData as [Number, Float, Number])[1] as Float - (oldestStepData as [Number, Float, Number])[1] as Float;
  • 2.0.124, SDK 8.4.0: optimization fails (venu441mm, DFApp):

    This looks like an error in the parser itself. Can you send me the code - or a cut down version of the code that reproduces the error?

    Also, is that the whole stack trace? It seems way too short for a "Maximum call stack size exceeded" error...

  • Yes this was the whole error in the terminal. I'll try to create a POC for this one too, though interestingly after I added the cast to Float for the other issue, this didn't happen any more (I found both while Exporting Optimized Project)

  • This one has been reported before.

    The problem is that Garmin's type checker isn't good enough to handle the (correct) code that the optimizer produces.

    My recommendation (as I've mentioned before, for similar issues) is that you turn off Garmin's type checker when building optimized code; or at least set it to level 2 so that it only generates warnings.

    Alternatively, you insert the necessary casts.

    The problems with tying to make the optimizer insert the right casts are:

    • it's just playing whack-a-mole; who knows when or whether they'll fix it or introduce new warnings etc
    • I'm going to have to overdo the casts just to be safe, and if I start throwing in casts everywhere, it defeats the type checker anyway
  • Actually, I think I know what's going on here. It's using prettier to format the optimized code. To do that I need to pass in the original text, and the optimized AST - but prettier only accepts a single string argument, so I stringize the AST, and append it to the original source.

    Then the "parser" strips off the last line using a regex. And apparently that regex is causing a huge amount of backtracking, which results in the stack overflow. There's an easy fix...

  • Sorry for bringing this up again, but since you're back to development, could you please take another look at this issue with enums? I have hundreds of instances of this message in the problems panel, making it barely usable for finding other errors in my code. There is a workaround which is to lower the type check level, but I'd like to avoid using it.