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]

  • , First let me say, this optimizer saved me enough space to add a new feature to my app, thanks for that!

    I found something interesting... 

    This code optimizes a bit oddly.

    Before:

    if(hasTouchscreen and System.getDeviceSettings().isTouchScreen) {
        Push_Main_Menu();
    } else if (hasButtons) {
    	parseUpDown(evt);
    }
    

    After:

    {
      Push_Main_Menu();
    }

    The intent of this code is to send the user to the menu when a button is tapped on touchscreen watches, but for button devices to parse the input, and interact with the UI.

    hasTouchscreen and hasButtons are defined like this:

    (:touchscreen)
    const hasTouchscreen = true;
    (:no_touchscreen)
    const hasTouchscreen = false;
    (:buttons)
    const hasButtons = true;
    (:no_buttons)
    const hasButtons = false;

    and monkey.jungle:

    base.excludeAnnotations = no_buttons;no_touchscreen;no_wifi;no_routing;no_phone
    

    In this particular situation, on a fenix6s, `hasTouchscreen` should be evaluated as True, while `System.getDeviceSettings().isTouchScreen` should be false. So the whole expression should evaluate to false, instead of true.

    -------------

    Side note, when `touchscreen` is excluded in monkey.jungle, the produced code looks like this (works correctly):

    if (false and System.getDeviceSettings().isTouchScreen) {
      Push_Main_Menu();
    } else {
      parseUpDown(evt);
    }

    Any idea what is happening here?

    Thanks,

    Lance

  • Aha! It has to do with using `and` instead of `&&`. When I use && the code works properly.

  • Aha! It has to do with using `and` instead of `&&`

    Thanks - with that I found the bug. The problem was that I added support for "and" and "or" relatively late (because I hadn't initially noticed they were alternative spellings for && and ||), and when I did, I didn't update every reference to "&&" and "||". In some places, the code assumed that if a LogicalExpression's operator wasn't "&&" it must be a logical or, and then optimized accordingly. So "if (true and X)" just became "if (true)".

    I've fixed it and will try to get a new release out over the next couple of days.

  • v2.0.34 is out.

    I went down a rabbit hole with this one. Since compiler2 uses slightly different lookup rules than compiler1 I decided it was time to make my optimizer understand both, and optionally warn about the differences (so that, for example, it doesn't report "Unknown symbols" for things that would work). But along the way, I found all sorts of issues relating to differences between what the type checker reports, and what actually works at runtime - especially in static functions (I filed some bugs). But I eventually got everything more or less resolved. So this version:

    • reports missing symbols more accurately (especially in static methods)
    • reports diagnostics for symbols that will only be found when using compiler2. This seems important, because even with the latest sdk, -O0 uses compiler1 while -O1 and above use compiler2. So even with the same sdk you could write code that works at -O1 and fails at -O0. But the optimizer will warn you (by default) about such things.
    • sdk-4.1.6 has bugs relating to private and protected statics. You'll get diagnostics about any issues that may show up if you're using 4.1.6 (and the solution is to go to 4.1.7).

    The typechecker in 4.1.7 (just released) has actually fixed several of the bugs I reported; for the most part it now matches the diagnostics my optimizer produces in these cases.

    I also fixed the bug reported by a few days ago, and made Goto References, and Goto Definition a little more precise.

  • I just noticed that when I execute "Prettier Monkey C: Build and Run Optimized Project" then the compiler is called with -l 0 even though I have it set to 3 both in the extension settings and in my monkey.jungle file

  • compiler is called with -l 0 even though I have it set to 3 both in the extension settings

    Yes, I've mentioned this before. This bug makes it impossible for me to guarantee to transform a type-correct, unoptimized program into a type-correct optimized program.

    That said, it's easy to fix such issues in the source (by adding an "as Number" where necessary), and these issues are rare. In my code, it came up exactly once, and I think there were a couple of cases in the Garmin samples.

    So by default, I ignore the Garmin typeCheckLevel setting, but you can use the prettierMonkeyC.typeCheckLevel to request that the optimized code be compiled with whatever level you want. You can also control it on a task-by-task basis in tasks.json, or per launch config in launch.json (and this is what I've done with my project).

    I just realized that since that original issue, there's a new one that *could* bite. If you have an (:inline,:typecheck(false)) function, the :typecheck(false) will be lost when it gets inlined, so the error will be reported in the inlinee. I've not hit that issue myself, but I guess I could just transfer any :typecheck(false) to the target function (I'll do that in a future release).

    So try it. If you hit any issues other than those two, let me know.

    and in my monkey.jungle file

    That reminds me. Currently, I will drop typecheck and optimization settings that occur in the jungle file (they didn't exist when I wrote the jungle processing code, so didn't know to copy them over). I will add support for that.

  • how am I supposed to use prettierMonkeyC.typeCheckLevel?

  • how am I supposed to use prettierMonkeyC.typeCheckLevel

    Sorry, you're right; I never added it as an extension setting (I thought I had, but apparently left it out). Once I fix that it will be there in settings (eg type prettierMonkeyC.typeCheckLevel into the search box).

    But it *is* there in tasks.json and launch.json. Here's an extract from my tasks.json

        {
          "type": "omonkeyc",
          "device": "fenix5xplus",
          "simulatorBuild": true,
          "typeCheckLevel": "Strict",
          "label": "Optimized: fenix5xplus",
          "group": {
            "kind": "build",
            "isDefault": true
          }
        },
        {
          "type": "omonkeyc",
          "device": "export",
          "simulatorBuild": false,
          "typeCheckLevel": "Strict",
          "compilerWarnings": true,
          "label": "Export Optimized",
          "group": {
            "kind": "build",
            "isDefault": false
          }
        },
        {
          "type": "omonkeyc",
          "device": "fr235",
          "simulatorBuild": false,
          "typeCheckLevel": "Strict",
          "releaseBuild": true,
          "label": "FR235 Device Build",
          "group": {
            "kind": "build",
            "isDefault": false
          }
        },
        {
          "type": "omonkeyc",
          "device": "fenix5xplus",
          "simulatorBuild": false,
          "releaseBuild": true,
          "typeCheckLevel": "Strict",
          "label": "Fenix5xPlus Device Build",
          "group": {
            "kind": "build",
            "isDefault": false
          }
        }

    and launch.json

        {
          "type": "monkeyc",
          "request": "launch",
          "name": "Run Unoptimized",
          "stopAtLaunch": false,
          "device": "${command:GetTargetDevice}",
        },
        {
          "type": "omonkeyc",
          "request": "launch",
          "name": "Optimized Release",
          "stopAtLaunch": false,
          "device": "${command:GetTargetDevice}",
          "preLaunchTask": "Preprocess",
          "releaseBuild": true,
          "typeCheckLevel": "Strict"
        },
        {
          "type": "omonkeyc",
          "request": "launch",
          "name": "Optimized Debug",
          "stopAtLaunch": false,
          "device": "${command:GetTargetDevice}",
          "releaseBuild": false,
          "typeCheckLevel": "Strict"
        },

  • v2.0.35 is out.

    Main features of this release are

    • Performance improvements: This mostly affects how quickly refs and defs are available after you type (which should now be really fast); but for certain projects build times were significant (several minutes) but should now be no more than a few seconds (and probably less than a second).
    • Full support for resource and manifest files. You can now click on an @Strings.Foo and goto all refs and refs. Outlines and workspace symbols work across resource files now too.