I've got a type check WARNING

Hi all!

I've got a type check warning. I tried to add "as xxx" (Array, Float and so on...) to no avail.
What's missing here?

It's about ANT+ radar data gathering. Works fine - but throws the warnings...

INITIALIZE:

bikeRadar = new AntPlus.BikeRadar(null);

ON COMPUTE:

            var radarInfo = bikeRadar.getRadarInfo();

            if (radarInfo != null) {
                System.println("RadarInfo: ok!");
                isRadar = true;                
                myRadarSpeed1 = radarInfo[0].speed;
                myRadarThreat1 = radarInfo[0].threat;
            }    

            var batObj = bikeRadar.getBatteryStatus(null);
            if ( batObj != null ) {
                myRadarBattery = batObj.batteryStatus; 
                System.println(myRadarBattery);
            }

Row 6 and 7 throw a WARNING (radarInfo[0].speed and .threat) :

WARNING: edge1050: C:\Garmin_IQ_Projekte\Edge1_Ebike_Beta\source\EdgeAllinOne1View.mc:1187,16: Cannot determine if container access is using container type.
WARNING: edge1050: C:\Garmin_IQ_Projekte\Edge1_Ebike_Beta\source\EdgeAllinOne1View.mc:1188,16: Cannot determine if container access is using container type.

What is missing here?

Thank you!

  • I can't reproduce your problem. Which SDK are you using and what code are you using to declare bikeRadar?

    Also, do you need to check the length of radarInfo, to make sure it's >= 0? Even if a zero-length array is never returned in practice, this would be a good defensive coding practice, unless you are very short on memory.

  • Thank you for responding.

    It‘s the latest SDK (I‘m not at the desk, but I think it is called 7.21)

    Declaring bikeradar is in the code window above: var bikeradar = new AntPlus.BikeRadar(null);

  • But obviously bikeRadar is a class member variable (or less likely, a global variable), as it's assigned in initialize and used in compute (two different functions). It can't be a local variable (or if it is, something else is very wrong.)

    The code that you posted actually says:

    bikeRadar = new AntPlus.BikeRadar(null);

    (without var). Clearly if you had var in the statement, then it would be a local variable declaration and compute would be unable to access bikeRadar.

    So I'm assuming it's declared as follows, but I can't be sure:

    var bikeRadar as AntPlus.BikeRadar;

    I also tried:

    var bikeRadar;

    Either way, I can't reproduce the warnings that you are seeing.

    EDIT: this is where it might help to post a more complete outline of your code.

    e.g.

    class Foo extends View {
      var bikeRadar;

      function initialize() {
        bikeRadar = ...;
      }

      function compute() {
        var radarInfo = bikeRadar.getRadarInfo();
        //...
      }
    }

  • bikeradar is declared in class. You can see in my original posting in the INITIALIZE code window. There is no „var“.

  • Declaring bikeradar is in the code window above: var bikeradar = new AntPlus.BikeRadar(null);
    bikeradar is declared in class. You can see in my original posting in the INITIALIZE code window. There is no „var“.

    'There is no "var"' (before bikeRadar).

    That's exactly what I said the first time, but your initial reply literally says there's "var" before bikeradar lol, when we can both see there isn't.

    And your two statements above contradict each other. First you said "declaring bikerader is in the code window above: var bikeradar = ....", then you said "bikeradar is declared in class" (i.e. not in the OP) and in the OP there is no "var".

    That's why I asked "what code are you using to declare bikeRadar"? I wanted to see the declaration, as in the actual code, not just me guessing what it was, or you telling me it was "declared in class". I wanted to see the TYPE that you declared it with.

    It probably doesn't matter since I can't recreate your problem with either of the declarations I tried, but when you're asking for help with code, it would be helpful to provide all the relevant code.

  • I have separated the radar code into an own project.

    Find enclosed a ZIP with the Radar Test Project.

    BTW: type check is set to Default -> throws the warnings.
    With type check = OFF -> no warnings.

    Radar_Test.zip

  • Well I was wrong about the type not mattering haha. Not sure why I was unable to recreate it on my end, but it goes to show how having sample code to demonstrate the problem is very helpful.

    If you change the bikeRadar declaration from

    var bikeRadar;

    to

    var bikeRadar as AntPlus.BikeRadar;

    it fixes the warnings and generates a few errors. This is why setting a type checking level of strict (3) can be useful, as you'll be forced to explicitly declare types for all class members (among other things).

    The new errors are:

    ERROR: edge1030: ...\source\RadarTestView.mc:36,8: Invalid 'Null' passed as parameter 1 of type '$.Toybox.Lang.Number'.
    ERROR: edge1030: ...\source\RadarTestView.mc:49,12: Cannot find symbol ':format' on type '$.Toybox.AntPlus.ThreatLevel'.

    For the benefit of anyone else reading this:

    36: var batObj = bikeRadar.getBatteryStatus(null as Number);
    ...
    46: var radarInfo = bikeRadar.getRadarInfo();
    ...
    49: rThreat = radarInfo[0].threat.format("%0d");

    The first error is clearly due to a bug in the API docs/types, since the docs say that the parameter to getBatteryStatus has to be a Number, but then they go on to describe the meaning of the parameter when it's null, and to show an example where it's null

    https://developer.garmin.com/connect-iq/api-docs/Toybox/AntPlus/Device.html#getBatteryStatus-instance_function

    The fix for this, while you wait for Garmin to fix the SDK, would be to insert a silly type cast:

    var batObj = bikeRadar.getBatteryStatus(null as Number);

    The second error is another dumb type checking thing. threat is a ThreatLevel (integer/Number enum), and apparently the type checker doesn't treat ThreatLevel the same as a Number. I think I've seen other bugs like this with enums and the type checker.

    The fix here is another type cast:

    rThreat = ((radarInfo[0].threat) as Number).format("%0d");

    I'll report these bugs in the bug reports forum.