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]

  • Converting my code to SDK 9.1.0 compatible I get to this annoyance.

    import Toybox.Application;
    import Toybox.Application.Properties;
    import Toybox.Application.Storage;
    import Toybox.Lang;
    import Toybox.System;
    
    (:inline)
    function getConfig(key as String) as Properties.ValueType or Null {
        var val;
        if (Application has :Properties) {
            val = Properties.getValue(key);
        } else {
            val = ((POCApp as Object?) as POCApp).getProperty(key) as Properties.ValueType?;
        }
        return val;
    }
    
    function getConfigNumber(key as String, defaultValue as Number) as Number {
        return toConfigNumber(getConfig(key), defaultValue);
    }
    
    function getStorage(key as String) as Storage.ValueType or Null {
        var val = null;
        if (Application has :Storage) { // ciq_2_4_0
            val = Storage.getValue(key);
        }
        return val;
    }
    
    function getStorageNumber(key as String, defaultValue as Number) as Number {
        return toConfigNumber(getStorage(key), defaultValue);
    }
    
    function toConfigNumber(value as Properties.ValueType /*or Storage.ValueType*/ or Null, defaultValue as Number) as Number {
        if (value instanceof Lang.Boolean) {
            return value ? 1 : 0;
        }
        // this should cover Float, Double, Number, String, Long, Char, Symbol
        value = value != null && value has :toNumber ? value.toNumber() : null;
        return value != null ? value as Number : defaultValue;
    }

    If I add "or Storage.ValueType" to the 1st parameter of toConfigNumber, then I get this error:

    ERROR> fr245: Config.mc:19:27: Argument 1 to $.toConfigNumber: passing Null or Boolean or Number or Long or Float or Double or String or Array<Toybox.Application.Properties.ValueType> to parameter Null or Boolean or Number or Long or Float or Double or Char or String or Array<Toybox.Application.Properties.ValueType> or Array<Toybox.Application.Storage.ValueType> or Dictionary<Boolean or Number or Long or Float or Double or Char or String, Toybox.Application.Storage.ValueType> or Toybox.Application.WatchFaceConfig.Id or Toybox.BluetoothLowEnergy.ScanResult or Toybox.Complications.Id or Toybox.Graphics.BitmapReference or Toybox.Lang.ByteArray or Toybox.WatchUi.AnimationResource or Toybox.WatchUi.BitmapResource is not type safe [more info: github.com/.../Extra-Reference-Type-Checks-(prettierMonkeyC.extraReferenceTypeChecks)]

    Until now it worked with PropertyValueType. I know it's just a warning, but maybe there can be done something about it? I mean I even guess that it's a problem that it's hard to detetmine what value.someMethod() can do, and so value.toNumber() is kind of risky, but I get the same error if I remove this line from toConfigNumber:

    value = value != null && value has :toNumber ? value.toNumber() : null;
    return value != null ? value as Number : defaultValue;
    But can't you determine that value is just passed along?
  • You're talking about Garmin's optimizer here, yes?

  • No. When I compile without Prettier Optimizer, then there's no warning at all. Only when I compile with Prettier I get this error(warning)

  • It's complaining about passing the result of getConfig(key) (not sure what that is) to a parameter of type Storage.ValueType.

    So yes, in theory it could analyze toConfigNumber and see that it doesn't do anything dangerous with value, and suppress the warning - but that's not something I've implemented (it does do some analysis for very simple callees, but that doesn't apply here).

    As far as I can see, the warning has nothing to do with the toNumber call - I'm not quite sure what you're asking?

  • Hmm. As it says in the header, I was replying to  https://forums.garmin.com/developer/connect-iq/f/discussion/294852/big-update-to-prettier-extension-monkeyc/2018297 which doesn't mention an error or warning. So again, I assume your post about the failure to optimize constants is talking about Garmin's compiler, not my optimizer...

  • I edited my previous comments to address the missing information in your last 2 comments.