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]

  • OK, this work in launch.json, but that's not the way I usually use it (I use Ctrl+Shift+P > ...) so I guess that'll only work after it's being added to the settings.
    However this was enough to find a bug, however one that seems to be not mine but Garmin's and maybe even a new one:
    My code:

                var msg = new Ant.Message();
                msg.messageId = Ant.MSG_ID_BROADCAST_DATA;
    

    optimized code:

            var msg = new Ant.Message();
            msg.messageId = 78 as Toybox.Ant.MessageId;
    

    Error message:
    ERROR: fenix6: /home/gavriel.fleischer/private/garmin/ExtHRM/bin/optimized/group000-debug/source/source/ExtHRMApp.mc:121,8: Cannot assign value '$.Toybox.Ant.MessageId' to member ':messageId'.

    According to the documentation messageId is Number?, however the optimized code thinks MSG_ID_BROADCAST_DATA is Toybox.Ant.MessageId . Is this a bug in the optimizer? I don't see such type in the docs. Or it's the way it's declared in the sdk?

  • Just installed this extension, and tried it on one of my project.  When I use "Generate Optimized Project", I got following error:

    =====
    Starting optimization step...
    ERROR: Internal: Error: ENOENT: no such file or directory, open 'f:\xxx\bin\optimized\group000-release\build-info.json'
    Error: ENOENT: no such file or directory, open 'f:\xxx\bin\optimized\group000-release\build-info.json'
    =====

    bin\optimized folder is created with one file "release.jungle", but no "group000-release" folder and no "build-info.json" file.

    Could you please let me know what I'm missing?

  • Just installed this extension, and tried it on one of my project

    Sorry, this is embarrassing. I didn't test the latest release on windows. For now you can downgrade to v2.0.34 (open the extensions panel on the left, then click the cog-wheel icon next to "Prettier Monkey C", and select "Install another version...").

    I'll try to get a fixed version out later today.

  • According to the documentation messageId is Number?, however the optimized code thinks MSG_ID_BROADCAST_DATA is Toybox.Ant.MessageId . Is this a bug in the optimizer? I don't see such type in the docs. Or it's the way it's declared in the sdk

    This is exactly the same bug. If you look at the documentation for MSG_ID_BROADCAST_DATA, above the table you'll see "MessageId", which indicates that it's an enum of type "MessageId". You can also see that by looking in sdk/bin/api.mir.

    So if I do:

    class Foo {
      var x as Ant.MessageId;
      var y as Number;
      function initialize() {
        x = Ant.MSG_ID_BROADCAST_DATA; // works
        x = 78; // fails
        x = 78 as Ant.MessageId; // works
        // but
        y = Ant.MSG_ID_BROADCAST_DATA; // works
        y = 78; // works
        y = 78 as Ant.MessageId; // fails
      }
     }

    The Garmin type checker treats Ant.MESSAGE_ID_BROADCAST_DATA as a special type that can be used anywhere a Number OR an Ant.MessageId can be used. But there is no other way to produce such a type (note that "Ant.MessageId or Number" doesn't do it - that type can't be assigned to *either* variable).

    The fix is to write "msg.messageId = Ant.MSG_ID_BROADCAST_DATA as Number" in your original code. Or "msg.messageId = Ant.MSG_ID_BROADCAST_DATA | 0" if you prefer.

  • v2.0.35 is out.

    • Fixes windows issues
    • Propagates `:typecheck(false)` when inlining
    • Adds new setting `prettierMonkeyC.useLocalOptimizer` which can be used to prevent a locally installed copy of @markw65/monkeyc-optimizer from being used (this could be useful if you wanted an export task that uses a pinned version of the optimizer, for reproducibility, while all other build tasks used the latest version of the optimizer)
    • Adds new setting `prettierMonkeyC.typeCheckLevel` which can be used to set the level to use for optimized code independently of `monkeyC.typeCheckLevel`
  • I didn't have the time to try it yet, but I wonder: doesn't propagating type check have the side effect that we might miss type errors in function a() because it inlined function b() that disabled type check?

  • This works.  And one of my prg got saved 5k bytes with your optimized codes.  Thank you!

  • doesn't propagating type check have the side effect that we might miss type errors

    Yes, of course. But presumably you build the unoptimized code during normal development, so the type checker does run on the original code.

    Since Garmin's type checker can't be disabled on an expression.by expression (or even statement by statement) basis, there doesn't seem to be an alternative. And other than the one issue I mentioned above, I'm not aware of any case where the original code type checks, but the optimized does not; and that one issue really is a problem with the type checker, not with the optimizer (since the optimized code really is correct).

  • There were cases when I only realized some problem in one device that i did not check manually because it failed to compile. I guess similarly i could theoretically miss some type checker thing. So maybe best practice from now to 1st export (all devices) without the optimizer and only then with it.

  • v2.0.37 is out.

    • More improvements to analysis of code in resource files, so that (I think) the optimizer sees all the code involved in the project (this should enable slightly better optimizations in future)
    • Upgraded the constant folding code to handle most legal combinations. I don't fold Float or Double vs String because of bugs in the latest monkeyc compiler.