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]

  • This is intentional. It's not safe to pass something typed as { "foo" as String } to something typed as Dictionary<String, String>, even though Garmin's type checker allows it.

    There are various issues. An object of type { "foo" as String } could contain other fields, of arbitrary types. Also, it's not required to have a "foo" field at all. In this case we can prove that's not true, because it's a literal that hasn't been modified. I have another open issue relating to tuples that's very similar, so when I get to that I'll probably roll this in...

  • I thought that the optimizer removes unused classes, methods, but it looks like I was wrong (or maybe this changed recently?)

    module FooModule {
      function foo() {
        // Bar1.bar();
        Bar2.bar();
      }
    
      class Bar1 {
        static function bar() as Void {
          System.println("Bar1.bar");
        }
      }
    
      class Bar2 {
        static function bar() as Void {
          System.println("Bar2.bar");
        }
      }
    }
    

    I thought Bar1 won't be added to the compiled code, but apparently it is, even though it's not used anywhere in my code (it's intentionally commented out, I am comparing whether I'll want to use Bar1 or Bar2 in the final app)

  • , I think, I've found a bug.

    PMC analysis fails for my project with "Maximum call stack size exceeded" message. I run node test/test.js --analyze-only --jungle path-to-my/monkey.jungle, just like you taught me a year ago for the error with the same message, and got the stack trace:

    While building '.../monkey.jungle
    RangeError: Maximum call stack size exceeded
    at tupleMap (.../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:13566:18)
    at intersectionValue (.../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:8531:14)
    at .../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:8490:20
    at forEachUnionComponent (.../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:13077:9)
    at intersection (.../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:8476:3)
    at .../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:8563:27
    at tupleMap (.../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:13567:141)
    at .../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:8553:17
    at tupleMap (.../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:13567:141)
    at intersectionValue (.../monkeyc-optimizer/build/chunk-X4PG4KKA.cjs:8531:14)
    Total runtime: 10585ms
    Failed:
    Error: Failed to build '.../monkey.jungle' with error RangeError: Maximum call stack size exceeded
    at driver (.../monkeyc-optimizer/build/driver.cjs:1354:11)
    I can't exactly catch the "tupleMap" at the moment it crashes in debugger to inspect its arguments, but with some "console.log()"s I've found the name of the tuple, that causes this error (though with this logging stack trace becomes slightly different - it fails inside console.log).
    In the test project it fails with different stack trace, but I think, the reason is the same. The stack from dummy project is in the next post.
  • RangeError: Maximum call stack size exceeded
        at Object.forEach (.../monkeyc-optimizer/build/chunk-45MXKLQ5.cjs:37:12)
        at Object.get [as forEach] (.../monkeyc-optimizer/build/chunk-45MXKLQ5.cjs:16:45)
        at expandTypedef (.../monkeyc-optimizer/build/chunk-WUBZIGRN.cjs:8411:29)
        at subtypeOf (.../monkeyc-optimizer/build/chunk-WUBZIGRN.cjs:13380:22)
        at .../monkeyc-optimizer/build/chunk-WUBZIGRN.cjs:13461:30
        at tupleForEach (.../monkeyc-optimizer/build/chunk-WUBZIGRN.cjs:13562:7)
        at .../monkeyc-optimizer/build/chunk-WUBZIGRN.cjs:13456:11
        at tupleForEach (.../monkeyc-optimizer/build/chunk-WUBZIGRN.cjs:13562:7)
        at subtypeOfValue (.../monkeyc-optimizer/build/chunk-WUBZIGRN.cjs:13440:7)
        at .../monkeyc-optimizer/build/chunk-WUBZIGRN.cjs:13415:28
    Total runtime: 6471ms
    Failed:
    Error: Failed to build '.../monkey.jungle' with error RangeError: Maximum call stack size exceeded
        at driver (.../monkeyc-optimizer/build/driver.cjs:1354:11)
  • The code is the following:

    manifest.xml: fenix8solar51mm and fenix847mm in products.

    monkey.jungle:

    base.sourcePath = source
    fenix8solar51mm.sourcePath = $(fenix8solar51mm.sourcePath);source-mip
    fenix847mm.sourcePath = $(fenix847mm.sourcePath);source-amoled
    source-amoled/tuple.mc and source-mip/tuple.mc (the same code in two files):
    import Toybox.Lang;
    typedef Tuple as [Number, Array<Tuple>?];
    var dictionary as Dictionary<Number, Array<Tuple>> = {} as Dictionary<Number, Array<Tuple>>;

    P.S. I'm sorry for multiple posts and crazy formatting. Garmin doesn't allow me to do it nicely.
  • I think you actually found two bugs - one with "intersection", and one with "subtype" - but "intersection" and "subtype" have very similar structure, so whatever is going wrong in subtype probably has a parallel in intersection.

    I'm afraid Im a bit swamped at the moment, but I should get back to the optimizer in a week or so...