Acknowledged
CIQQA-3064

Compiler warns about deprecated symbol even when building for device where symbol is not deprecated

e.g.


// in entry point class that extends appbase

var val;
if (Toybox.Application has :Properties) {
// ciq >= 2.4.0
  val = Application.Properties.getValue("foo");
} else {
// ciq < 2.4.0
  val = AppBase.getProperty("foo"); // compiler warns that AppBase.getProperty is deprecated
}

Regardless of what device this code is built for, the compiler will warn that AppBase.getProperty is deprecated. I would argue this is confusing and misleading because:

1) getProperty is not deprecated for devices with CIQ < 2.4.0. In fact, for those devices getProperty is *required*, if you want to read persisted data

2) Even for devices with CIQ >= 2.4.0, the warning may be confusing because it still implies that your code is wrong because it calls that function (even though as written, it will never be called for those devices.)

Here's an example of where the deprecation warning may have led to confusion (or not, it's hard to say):

(it's a deprecation warning triggered by an SDK sample which correctly shows code which can run on both older devices and newer devices, using old deprecated enums for older devices, and new non-deprecated enums for newer devices)

https://forums.garmin.com/developer/connect-iq/i/bug-reports/bug-documentation-typos-in-toybox-position-enablelocationevents-example

Nonetheless, the issue of the deprecation warnings has come up many times in the forums.

I realize this is sort of a no-win situation here. I don't have any good suggestions for fixing it. But I do think there needs to be a way for the compiler to convey that code which uses deprecated symbols *may* be correct after all.

Parents
  •  I realize that Monkey C implements has checks, but the limitation here is that the compiler won't do things like decide that if your call is wrapped in has checks, then it won't warn about deprecation. Ofc arguably this is the wrong thing to do, since it would only encourage devs targetting newer CIQ versions to use deprecated functions like AppBase.getProperty[] forever - which has happened anyway. I would argue that without having some kind of compile-time / run-time branch based on CIQ *version*, then the optimal behaviour for both devs and the CIQ team will never be implemented.

    In other words, if the compiler sees the following code, there's no way for it to know that the dev only intends for it to run on devices with CIQ < 2.4.0:

    if (!(Toybox.Application has :Properties) { 
    // ciq < 2.4.0
      val = AppBase.getProperty("foo"); // compiler warns that AppBase.getProperty is deprecated
    }

    That's obviously why the compiler warning is unconditional.

    For example, CIQ had a feature like if #available, devs could write code like this:

    if #available(ciq_2.4.0) {
      // use Application.Properties()
    } else {
      // use AppBase.getProperty()
    }

    Here the intent is explicit and the version availability check excludes the possibility of using AppBase.getProperty() on a platform for which it is deprecated. AppBase.getProperty() will only be used for CIQ < 2.4.0, where it is *not* deprecated, so there's no reason for the compiler to raise a deprecation warning.

    As a matter of fact, if this version check feature were available, the compiler could be even stricter and raise an *error* if certain deprecated functions are used without a version check.

Comment
  •  I realize that Monkey C implements has checks, but the limitation here is that the compiler won't do things like decide that if your call is wrapped in has checks, then it won't warn about deprecation. Ofc arguably this is the wrong thing to do, since it would only encourage devs targetting newer CIQ versions to use deprecated functions like AppBase.getProperty[] forever - which has happened anyway. I would argue that without having some kind of compile-time / run-time branch based on CIQ *version*, then the optimal behaviour for both devs and the CIQ team will never be implemented.

    In other words, if the compiler sees the following code, there's no way for it to know that the dev only intends for it to run on devices with CIQ < 2.4.0:

    if (!(Toybox.Application has :Properties) { 
    // ciq < 2.4.0
      val = AppBase.getProperty("foo"); // compiler warns that AppBase.getProperty is deprecated
    }

    That's obviously why the compiler warning is unconditional.

    For example, CIQ had a feature like if #available, devs could write code like this:

    if #available(ciq_2.4.0) {
      // use Application.Properties()
    } else {
      // use AppBase.getProperty()
    }

    Here the intent is explicit and the version availability check excludes the possibility of using AppBase.getProperty() on a platform for which it is deprecated. AppBase.getProperty() will only be used for CIQ < 2.4.0, where it is *not* deprecated, so there's no reason for the compiler to raise a deprecation warning.

    As a matter of fact, if this version check feature were available, the compiler could be even stricter and raise an *error* if certain deprecated functions are used without a version check.

Children
No Data