Under Review
over 1 year ago

COMPILER BUG: cannot compile classes with static functions

There are several issues with the available compilers (SDK 4.1.7 and SDK 4.2.0 Beta 1) if a class contains a static function and the parameters of the function are Monkey Typed with the compiler set to "Gradual" or higher.

  1. Cannot find symbol errors for functions on core classes (eg. Position.Location); and
  2. Error parsing the global namespace ($.) when specifying the Monkey Type for a function parameter.

I tried the broken, replicateable code on SDK 4.1.5, SDK 4.1.6, SDK 4.1.7 and SDK 4.2.0 Beta 1.

Error #1 occurs only on SDK 4.1.7 (ie. it works fine on SDK 4.1.5, SDK 4.1.6, SDK 4.2.0 Beta 1).

Error #2 occurs on all the SDKs listed above -- SDK 4.1.5, SDK 4.1.6, SDK 4.1.7 and SDK 4.2.0 Beta 1.

These errors may or may not be related to this issue: https://forums.garmin.com/developer/connect-iq/i/bug-reports/bug-report-static-lang-dictionary-class-variable-broken-in-sdk-4-1-6

I am not able to attach my test project that will easily replicate both issues/bugs but I have emailed the ZIP to the Connect IQ team. If anyone would like the project file to validate the issue or use it as the basis for a similar sounding bug or just out of curiosity, then DM me. For reference, the function within the class looks like this:

    static function compilerErrorOne(location as Position.Location, waypoint) as BrokenClass {
        var decimalDeg = location.toDegrees();
        var wpDecDeg = waypoint.getLocation().toDegrees();
        var brokenClass = new BrokenClass(null);
        return (brokenClass);
    }
    
    static function compilerErrorTwo(location, waypoint as $.Waypoint) as BrokenClass {
        var decimalDeg = location.toDegrees();
        var wpDecDeg = waypoint.getLocation().toDegrees();
        var brokenClass = new BrokenClass(null);
        return (brokenClass);
    }

  • I'll add some other example:

    import Toybox.Background;
    import Toybox.Time;
    
    class Static {
        function nonStaticTest() as Void {
            var lastTime = Background.getTemporalEventRegisteredTime();
            var nextTime = lastTime != null ? lastTime.add(new Time.Duration(300)) : Time.now();
            Background.registerForTemporalEvent(nextTime);
        }
    
        static function staticTest() as Void {
            var lastTime = Background.getTemporalEventRegisteredTime();
            var nextTime = lastTime != null ? lastTime.add(new Time.Duration(300)) : Time.now();
            Background.registerForTemporalEvent(nextTime);
        }
    }
    

    staticTest doesn't compile with SDK 4.1.7:

    ERROR: fr255: Test.mc:13,8: Cannot find symbol ':add' on type 'PolyType<$.Toybox.Time.Duration or $.Toybox.Time.Moment>'.
    ERROR: fr255: Test.mc:13,8: Cannot determine type for method invocation.
    ERROR: fr255: Test.mc:14,8: Passing 'Any' as parameter 1 of poly type 'PolyType<$.Toybox.Time.Duration or $.Toybox.Time.Moment>

  • I see the same behaviour, I have several utility classes with static functions that work fine with SDK 4.1.6 but not with 4.1.7

    static function formatTime(is24Hour as Boolean, gregorianInfo as Time.Gregorian.Info, flexField as FlexField, showAmPm as Boolean) as Void{
    var hour = gregorianInfo.hour;
    var ampm = "";
    if (!is24Hour) {
    hour = gregorianInfo.hour % 12 == 0 ? 12 : gregorianInfo.hour % 12 ;
    if (showAmPm) {
    ampm = gregorianInfo.hour >= 12 && gregorianInfo.hour < 24 ? "PM" : "AM";
    }
    }
    flexField.fieldValue = Lang.format("$1$:$2$",[hour.format("%d"), gregorianInfo.min.format("%02d")] );
    flexField.fieldUnitUpper = ampm;
    }

    The second line cause the error: Cannot find symbol ':hour' on type '$.Toybox.Time.Gregorian.Info'. when using SDK 4.1.7

        static function secondsToTimeString(totalSeconds as Long) as String {
            var hours = totalSeconds / 3600;
            var minutes = (totalSeconds / 60) % 60;
            var seconds = totalSeconds % 60;
            var timeString = Lang.format("$1$:$2$:$3$", [hours.format("%02d"), minutes.format("%02d"), seconds.format("%02d")]);
            return timeString;
        }
    The 5th line gives: Cannot find symbol ':format' on type '$.Toybox.Lang.Long'.

  • I am using SDK 4.1.7 -- I wrote the wrong version in my post (I was looking at the other referenced post at the same time) and hadn't caffeinated enough yet.

    However, you got me thinking, and I tried my same project with SDK 4.1.6 and encountered results similar to SDK 4.2.0 Beta 1. So whatever was changed in SDK 4.1.7 broke my first example (though it may have fixed the other issue/post that I linked to).

  • Try the 4.1.7 SDK.  The README indicates fixes that may be involved.