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]

  • I noticed something that looks strange, tough I am not sure if it's just a strange warning or an actual problem. When I compile my app for fenix3 with 4.1.7 -l3 -O2z I see the following warnings:

    Executing task: java -Xms1g -Dfile.encoding=UTF-8 -Dapple.awt.UIElement=true -jar ~/.Garmin/ConnectIQ/Sdks/connectiq-sdk-lin-4.1.7-2022-11-21-562b8a195/bin/monkeybrains.jar -o bin/MyHRM.prg -f monkey.jungle;barrels.jungle -y developer_key.der -d fenix3_sim -w -l 3 -O2z 
    
    WARNING: The optimization level is specified both at the command line and in a Jungle file. The Jungle file specification will be ignored.
    WARNING: fenix3: The launcher icon (130x130) isn't compatible with the specified launcher icon size of the device 'fenix3' (40x40). Image will be scaled to the target size.
    WARNING: fenix3: /home/gavriel.fleischer/private/garmin/ExtHRM/source/ExtHRMApp.mc:19: Class 'ExtHRMApp' does not initialize its super class 'AppBase'.
    WARNING: fenix3: /home/gavriel.fleischer/private/garmin/ExtHRM/source/ExtHRMField.mc:21: Class 'BaseExtHRMField' does not initialize its super class 'SimpleDataField'.
    WARNING: fenix3: String ID 'fieldFound' undefined for language 'eng'.
    WARNING: fenix3: String ID 'fieldNoChannel' undefined for language 'eng'.
    WARNING: fenix3: String ID 'fitAntId' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitAntName' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitAvgHeartRate' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitBpm' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitCurrentHeartRateChartTitle' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitCurrentHeartRateDataLabel' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitEmptyUnit' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitMaxHeartRate' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitMinHeartRate' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsAntIdPrompt' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsAntId' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsDisplayFormatStr' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsForceAntIdPrompt' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsForceAntId' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsName' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsSaveAlias' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsSensor1Title' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsSensor2Title' undefined for language 'deu'.
    WARNING: monkey.jungle:202: d2bravo_titanium does not support language 'heb'
    WARNING: monkey.jungle:203: d2bravo does not support language 'heb'
    WARNING: monkey.jungle:204: fenix3_hr does not support language 'heb'
    WARNING: monkey.jungle:205: fenix3 does not support language 'heb'
    WARNING: monkey.jungle:206: fr230 does not support language 'heb'
    WARNING: monkey.jungle:207: fr235 does not support language 'heb'
    WARNING: monkey.jungle:208: fr630 does not support language 'heb'
    WARNING: monkey.jungle:209: fr920xt does not support language 'heb'
    WARNING: monkey.jungle:210: vivoactive does not support language 'heb'
    

    When I compile with prettier then I see different warnings:

     *  Executing task: omonkeyc: fenix3 
    
    Starting optimization step...
    Optimization step completed successfully...
    
    > Executing task: "~/.Garmin/ConnectIQ/Sdks/connectiq-sdk-lin-4.1.7-2022-11-21-562b8a195/bin/monkeyc" "-o" "bin/optimized-MyHRM.prg" "-f" "MyHRM/bin/optimized/debug.jungle" "-y" "developer_key.der" "-O2z" "-w" "-l" "0" "-d" "fenix3_sim" <
    
    WARNING: fenix3: The launcher icon (130x130) isn't compatible with the specified launcher icon size of the device 'fenix3' (40x40). Image will be scaled to the target size.
    WARNING: fenix3: String ID 'fieldFound' undefined for language 'eng'.
    WARNING: fenix3: String ID 'fieldLabelWithName' undefined for language 'hun'.
    WARNING: fenix3: String ID 'fieldNoChannel' undefined for language 'eng'.
    WARNING: fenix3: String ID 'fitAntId' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitAntName' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitAvgHeartRate' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitBpm' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitCurrentHeartRateChartTitle' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitCurrentHeartRateDataLabel' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitEmptyUnit' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitMaxHeartRate' undefined for language 'deu'.
    WARNING: fenix3: String ID 'fitMinHeartRate' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsAlertHr' undefined for language 'hun'.
    WARNING: fenix3: String ID 'settingsAntIdPrompt' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsAntId' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsDisplayFormatStr1' undefined for language 'hun'.
    WARNING: fenix3: String ID 'settingsDisplayFormatStr2' undefined for language 'hun'.
    WARNING: fenix3: String ID 'settingsDisplayFormatStr' undefined for language 'heb'.
    WARNING: fenix3: String ID 'settingsForceAntIdPrompt' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsForceAntId' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsName' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsSaveAlias' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsSensor1Title' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsSensor2Title' undefined for language 'deu'.
    WARNING: fenix3: String ID 'settingsSeparator' undefined for language 'hun'.
    WARNING: fenix3: String ID 'settingsShowHrZoneColor' undefined for language 'hun'.
    WARNING: fenix3: String ID 'settingsShowHrZoneGauge' undefined for language 'hun'.
    WARNING: fenix3: String ID 'settingsUser1Title' undefined for language 'hun'.
    WARNING: fenix3: String ID 'settingsUser2Title' undefined for language 'hun'.
    WARNING: fenix3: String ID 'settingsUserZones' undefined for language 'hun'.

    (I intentionally sorted the warnings to compare them with diff):

    1,2d0
    < WARNING: fenix3: /home/gavriel.fleischer/private/garmin/ExtHRM/source/ExtHRMApp.mc:19: Class 'ExtHRMApp' does not initialize its super class 'AppBase'.
    < WARNING: fenix3: /home/gavriel.fleischer/private/garmin/ExtHRM/source/ExtHRMField.mc:21: Class 'BaseExtHRMField' does not initialize its super class 'SimpleDataField'.
    3a2
    > WARNING: fenix3: String ID 'fieldLabelWithName' undefined for language 'hun'.
    13a13
    > WARNING: fenix3: String ID 'settingsAlertHr' undefined for language 'hun'.
    16c16,18
    < WARNING: fenix3: String ID 'settingsDisplayFormatStr' undefined for language 'deu'.
    ---
    > WARNING: fenix3: String ID 'settingsDisplayFormatStr1' undefined for language 'hun'.
    > WARNING: fenix3: String ID 'settingsDisplayFormatStr2' undefined for language 'hun'.
    > WARNING: fenix3: String ID 'settingsDisplayFormatStr' undefined for language 'heb'.
    23,31c25,30
    < WARNING: monkey.jungle:202: d2bravo_titanium does not support language 'heb'
    < WARNING: monkey.jungle:203: d2bravo does not support language 'heb'
    < WARNING: monkey.jungle:204: fenix3_hr does not support language 'heb'
    < WARNING: monkey.jungle:205: fenix3 does not support language 'heb'
    < WARNING: monkey.jungle:206: fr230 does not support language 'heb'
    < WARNING: monkey.jungle:207: fr235 does not support language 'heb'
    < WARNING: monkey.jungle:208: fr630 does not support language 'heb'
    < WARNING: monkey.jungle:209: fr920xt does not support language 'heb'
    < WARNING: monkey.jungle:210: vivoactive does not support language 'heb'
    ---
    > WARNING: fenix3: String ID 'settingsSeparator' undefined for language 'hun'.
    > WARNING: fenix3: String ID 'settingsShowHrZoneColor' undefined for language 'hun'.
    > WARNING: fenix3: String ID 'settingsShowHrZoneGauge' undefined for language 'hun'.
    > WARNING: fenix3: String ID 'settingsUser1Title' undefined for language 'hun'.
    > WARNING: fenix3: String ID 'settingsUser2Title' undefined for language 'hun'.
    > WARNING: fenix3: String ID 'settingsUserZones' undefined for language 'hun'.
    

    So why are these so different?

    Also I compiled for fenix3, and when I look in bin/optimized/debug.jungle I see it generated the file for fenix3,fr235,vivoactive. Why? Why not only for fenix3? Or for everything that is "similar" to fenix3 (for example fenix3_hr that has the exact same settings in my monkey.jungle)?

    Compiler without prettier (correctly IMHO) doesn't warn for "fenix3: String ID 'fieldLabelWithName' undefined for language 'hun'" because fieldLabelWithName is a) not in the resources that are used for fenix nor is it used anywhere in the code (because of excludeAnnotations) So how come that when I compile with prettier then it does warn about it?

    The regular compiler warns: "monkey.jungle:205: fenix3 does not support language 'heb'" which "kind of" makes sense because indeed fenix3 device doesn't support Hebrew. (However I do have the translations and I do want to include PART pf it even for fenix3 for the settings. And this seems to work in simulator (I don't have a real fenix3 device)) So how come that when I compile with prettier this warning disappeared?  

    When I run in the simulator on fenix3 compiled with prettier then 1 string is missing in the settings (it's displayed in English instead of Hebrew even though the other strings are in Hebrew). When I test the same without prettier I also see that string in Hebrew. I GUESS it's "accidentally" optimized out by prettier. Can that happen?

    The code you will need to reproduce this in monkey.jungle is this:
    fenix3.lang.heb = memory16K/resources-heb

    Inside that directory there are some files that are also in resources-heb, so I guess that's the reason I see the other strings, but there's also 1 small file in memory16K/resources-heb that is not in resources-heb: strings-settings-memory16K.xml. There's only 1 line in it, exactly the string that is missing. The reason it's here because it's ONLY used for memory16K devices so I don't want to add it to resourced-heb because I don't want it in devices that have more than 16K memory:


    memory16K/resources/strings-settings-memory16K.xml:
    <string id="settingsDisplayFormatStr">Something in English</string>

    memory16K/resources-heb/strings-settings-memory16K.xml:
    <string id="settingsDisplayFormatStr">Something in Hebrew</string>

    And settingsDisplayFormatStr is only used in the settings of devices with low memory.

    Update: I just noticed that I was right, the optimizer removed this line:
    fenix3.lang.heb = memory16K/resources-heb

    Update: I think I know why fenix3, rf235, vivoactive were generated into optimized/debug.jungle. Even though there are 9 devices in monkey.jungle only these 3 appear in my manifest-debug.xml.

  • Sorry, don't have time to dig into it too much right now, but yes, in the generated jungle file, I only include supported languages for each device. And I do that precisely to suppress the "<device> does not support language <foo>" messages which would pop up otherwise.

    But you seem to be claiming that, even though it spits out that warning, it actually uses the resources on the device? ie you're actually seeing Hebrew resources on a fenix3, even after it warned that those resources aren't supported?

    So by dropping that from the jungle I'm not just getting rid of a warning, I'm changing what ends up on the device?

    If thats the case it's relatively easy to keep them...

  • Not exactly.

    1. I don't have an actual fenix3 (or any device that doesn't have Hebrew)

    2. The simulator doesn't display Hebrew. It does't even have the fonts for it. So this seems to be correct.

    3. However what I can do is to open the settings from the sim and change the language of the settings to Hebrew. And for the strings I have in resources-heb I do see them in Hebrew.

    4. But because the optimizer removed the line:
    fenix3.lang.heb = memory16K/resources-heb
    thos strings defined in that directory are missing.

    And we can know for certain that those strings are not in the prg/iq file. They don't affect how the app works on the device/sim, because the device doesn't know Hebrew, but it affects how settings look.

    Now what I can't confirm that someone who has a watch that doesn't support Hebrew is indeed capable to see the settings in Connect IQ in Hebrew. But it looks like it works. I can't imagine how the simulator's settings could display the Hebrew strings if not from the prg file, so it should work with ConnectIQ as well IMHO.


    Anyway, I think this is another "over-optimization", and I would prefer to see the 1 line that tells that fenix3 doesn't support heb instead of seeing a warning for each missing string :) Even more so that this is not just a harmless warning but it actually breaks functionality.

    BTW: this feature would help: https://forums.garmin.com/developer/connect-iq/i/bug-reports/feature-request-split-the-strings-xml-for-in-device-and-settings-related-strings Let's hope it'll come soon...

  • I think I found another bug, but not sure if it's in your code or in prettier itself or maybe VSC. I have the following property and setting:


    <string id="settingsSeparator">-----------------------</string>
    <property id="-" type="string"></property><!--separator-->
    <setting propertyKey="@Properties.-" title="@Strings.settingsSeparator">
      <settingConfig type="alphaNumeric" readonly="true"/>
    </setting>

    It's just a placeholder for a separator.

    In VSC the file with the setting (the above are in separate files) is red, and the "-" is underlined with red. However it does compile without error or warnig and it works as intended.
    What's interesting is that when I compile with prettier optimizer then I have an error in red but it still continues and works:
    Starting optimization step...
    Optimization step completed successfully...

    ERROR: fenix6: memory32K/resources-array-settings-0/settings-memory32K-as0.xml:96,37: Expected comment, end of line, identifier, or whitespace but "-" found.
    What's even more interesting is this: When I switch "-" with "_" (both in property id and in propertyKey, I get the exact same error message (that reports that a "-" is found.
    And if that's not enough then even when I switch them to "e" I still get the same error message about "-" (and BTW VSC still underlines "e" with red). Only when I close VSC and open again then "e" is no longer underlined with red. However the error message during optimization is still the same.
    Update: after compiling with prettier optimizer when it's "e" it again is underlined...
    Update2: I know now what happens, but not why, maybe you'll find that. The only way I could get rid of the problem was to prettier-optimize-compile the code for another device when there's either "_" or "e". Then it works, and no error. Even when I compile again with the previous device it's OK now.
    So the way to reproduce the problem is to use "-" as a propertyKey. And it seems to cache something that is never overridden afterwards as long as I try to compile for the same device, even when I change the file's content.
  • Anyway, I think this is another "over-optimization", and I would prefer to see the 1 line that tells that fenix3 doesn't support heb instead of seeing a warning for each missing string

    The reason I did this is that if you *don't* put anything in your jungle file relating to Hebrew, but have a resources-heb directory, then you get no warnings, and resources-heb is used on the devices that support it (because its picked up via the default rules). But if I then explicitly include resources-heb in my generated jungle even for devices that don't support it, there's a warning line for each such device; and that gets quite noisy.

    It looks like *you* have a high tolerance for warnings in your build, but a lot of people don't (me included), so creating warnings that wouldn't have been there originally isn't a good look...

    But in your case, you're explicitly adding the language support to a device that claims not to support it, so you're already getting the warning.

    So what I need to do is figure out whether the heb language support for a particular device was added explicitly, rather than just getting inherited from the default jungle; if so, I should include it, otherwise I shouldn't. Again, I won't be able to look at this for a few days, but the jungle processing code is pretty complex, and figuring out exactly where a particular instruction came from may not be trivial. At the very least, I suppose that if you've specified a non-default location (as you appear to do), it obviously didn't come from the defaults...

  • So the way to reproduce the problem is to use "-" as a propertyKey

    So in order to make goto-ref and goto-def etc work, I generate a "fake" mc file which has actual definitions and references in it, and uses the ids as identifiers. Obviously using "-" is going to be a problem. I can probably fix that by just translating it to some unique sequence.

    Btw, I'm surprised that Garmin's compiler accepts it, because it does something similar (to build the actual Rez modules). But maybe properties and settings are special since they don't actually appear under Rez.

    And I'll have to check the code, but I think the failure to update is because it skips the build if it thinks it already built everything. I think what's going on is that until recently, my optimizer didn't even look at the resources, so it only considers the .mc files when deciding whether anything changed; and when I added the resource support, I didn't update that code. Assuming thats the problem, it should be easy to fix.

    Meanwhile your other alternative would be Ctrl-P - "Clean Optimized Build" to get a full rebuild.

  • Well I tend to disagree, because there are 2 things that play here:

    1. the real one that might (knowingly or "accidentally") be used by others as well is that they have all their translations in resources-heb, so even when the user has fenix3 they still can see the settings in ConnectIQ in Hebrew.

    2. my special case is an optimization I made so both the 16K and the 32K devices only include the settings strings that they actually use.

    You seem to give more weight to the 2nd case (which is probably because I explained it longly) but I don't think that's the interesting part here.

    You say that you detected that fenix3 doesn't support Hebrew so you removed the Hebrew specific EXPLICIT resources folder I set. However you did not remove resources-heb :) I mean it's not there explicitly in the generated jungle file, but that's the default even for fenix3, that's the reason that even when I compile with the prettier optimizer I still see the rest of the Hebrew labels in the settings.

    So if you really want to try to decide what can you remove, then I wouldn't try to deduct whether some directory was explicitly set by the developer, but rather if it contains resources (strings/properties/settings) that are used in settings. If not, then maybe it's OK to remove them.

    BTW You are wrong about my high tolerance for warnings :) If you would know how much time (and even complex projects) I spend in my day job to remove useless / information-less logs you would understand.

    I for sure hate the lots of yellow warnings when I export a project for hundred devices. But in this case I prefer functionality over less warnings :) Ah and BTW it's not that I have less warnings now, they're just different. And it's even not just that instead of many warnings bout missing translations now I have less about devices that don't support Hebrew. Because as you can see in the 1st post about this I posted the diff and for some reason the optimizer also introduces other missing translations that are incorrect IMHO. For example settingsDisplayFormatStr1 is only used in devices with 32K memory, so I "eliminated" it including the warning about it from the fenix3 code, but for some reason the optimizer warns about it being missing from the Hungarian translation. In fact that's an interesting issue that you might look into. settingsDisplayFormatStr1 only occures in directories and files that have memory32K in their name, so they're not included for fenix3. The only exception is in resources-hun/strings-settings-memory32K.xml. I think your optimizer sees this string on one hand, so it adds it to the pool of strings, but on the other hand in a later stage it correctly detects that this file is not included for fenix3, and that somehow generates the warning about it:
    fenix3: String ID 'settingsDisplayFormatStr1' undefined for language 'hun'.

  • Well I tend to disagree, because

    That's because you're not listening to what Im saying.

    The one thing we both agree on (I hope!) is that my optimizer should not change the behavior of the program.

    I've simply been trying to explain how we got to this situation.

    At no point did I decide "Oh - that produces warnings, so I'll break Gavriel's code to avoid them". I noticed there were warnings, and assumed that if the compiler spits out a warning saying that something isn't supported, then there's no point in trying to do it. But I should have figured that Garmin being Garmin they would warn that its not supported, and then go ahead and support it.

    So... yes, of course I'm going to fix it. But I'm going to fix it in a way that doesn't cause those warnings if the original jungle didn't trigger them.

    I think your optimizer sees this string on one hand, so it adds it to the pool of strings, but on the other hand in a later stage it correctly detects that this file is not included for fenix3, and that somehow generates the warning about it:
    fenix3: String ID 'settingsDisplayFormatStr1' undefined for language 'hun'.

    Hmm. I'm absolutely certain that error message is generated by Garmin's compiler, not my optimizer. My optimizer will warn about missing resources; but only if it doesn't see them in any of the resource files associated with a device. and it certainly won't say "for language <bla>".

  • I agree.

    I understood how we got here, and it's logical, I never assumed you purposefully changed the behaviour. I know (from this thread for example) that  you're very careful with these things. I just reported this bug and gave as much context as possible to help you to find it.

    I'll try to rephrase the last thing: from the diff I see that these warnings were not present when compiled without the optimizer, so I assume that the reason for them to appear is that the optimizer changed something.

    Actually I have a theory: when the regular compiler is run (without the optimizer) then it is run from the root directory of the repository, so when I have code like:
    fenix3.lang.hun = memory16K/resources-hun
    it probably still finds resources-hun and in it the strings-settings-memory32K.xml with all the strings that are only used in devices with more than 16K ram.

    However when the optimizer runs the compiler it is in bin/optimized (thus the generated jungle file has ../../ at the beginning of all the directories) so it has the following line:
    fenix3.lang.hun = ../../memory16K/resources-hun
    which is equivalent to the above line. But what probably happens is that it's looking for resources-hun under bin/optimized and doesn't find it, so it doesn't see all the strings for memory32K devices (and that is a good thing I guess), thus we see the warnings.

    So the assumption about the optimizer is incorrect about the optimizer but probably something like that happens in the Garmin compiler.

  • Ok, for now I changed it to underline anyway and that works.