You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We could use this model even for feature switches similar to `StartupHookSupport`, which don't currently have a `StartupHoopSupportAttribute`. There's no need to actually annotate related APIs with the attribute if that is overkill for a small feature. In this case the attribute definition would just serve as metadata that allows us to define a feature switch in a uniform way.
349
349
350
+
This is fundamentally the same idea outlined in https://github.com/dotnet/designs/pull/261. The hope is that this document provides the motivation for using a unified representation for the attributes that are related to feature switches and trim/AOT analysis.
351
+
352
+
## Comparison with platform compatibility analyzer
353
+
354
+
The platform compatibility analyzer is semantically very similar to the behavior describedhere, exceptthatitdoesn'tcomewithILLink/ILCompilersupportforremovingremovingbranchesthatareunreachablewhenpublishingforagivenplatform.
CallSomeAndroidAPI(); // warns if not targeting android
362
+
363
+
[SupportedOSPlatform("android")]
364
+
staticvoidCallSomeAndroidAPI() {
365
+
// ...
366
+
}
367
+
```
368
+
369
+
- Platform checks are like feature switchproperties, andcanguardcallstoannotatedAPIs:
370
+
371
+
```csharp
372
+
if (OperatingSystem.IsAndroid())
373
+
CallSomeAndroidAPI(); // no warning for guarded call
374
+
```
375
+
376
+
The analyzer has built-in knowledge of fact that `IsAndroid` corresponds to the `SupportedOSPlatform("android")`. ThisissimilartotheILLinkanalyzer'scurrenthard-codedknowledgeofthefactthat `IsDynamicCodeSupported` correspondsto `RequiresDynamicCodeAttribute`.
It would be possible to define an attribute that indicates _lack_ of support for a feature, similar to the `UnsupportedOSPlatformAttribute`. The attribute-based model should make it possible to differentiate these from the `Requires` attributes, for example with a different base class.
434
+
435
+
It's not clear whether we have a use case for such an attribute, so these examples aren't meant to suggest realistic names, but just the semantics:
- Versioning support for feature attributes/checks/guards
444
+
445
+
The model here would extend naturally to include support for version checks the same way that the platform compatibility analyzer does. Versions would likely be represented as strings because they are encodable in custom attributes:
// Breaking change was made in version 2.0, where this API is no longer supported.
468
+
thrownewNotSupportedException();
469
+
}
470
+
}
471
+
```
472
+
473
+
Code that was originally built against the 1.0 version, and broken on the upgrade to the 2.0 version, could then be updated with a feature check like this:
474
+
```csharp
475
+
if (Foo.IsSupportedWithVersionAtLeast("2.0")) {
476
+
Foo.Impl_2_0();
477
+
} else {
478
+
Foo.Impl_1_0();
479
+
}
480
+
```
481
+
482
+
Although it's not clear in practice where this would be useful. This is not meant as a realistic example.
483
+
484
+
485
+
486
+
<hr />
487
+
350
488
# Two models for custom feature checks
351
489
352
490
In practice, custom feature checks in dotnet/runtime broadly fall into two categories:
@@ -597,46 +735,6 @@ For example, in a trimmed app, the feature `RequiresUnreferencedCodeAttribute` i
597
735
In a native AOT app, `"System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported"` is set to `false` by default because native AOT doesn't provide a JIT or interpreter, and calls to APIs annotated with `RequiresDynamicCodeAttribute` will produce warnings. There is also an independent feature switch `CanEmitObjectArrayDelegate` that is disabled by default because it depends on APIs marked `RequiresDynamicCode`.
598
736
599
737
600
-
## Comparison with platform compatibility analyzer
601
-
602
-
The platform compatibility analyzer is semantically very similar to the behavior described here, except that it doesn't come with ILLink/ILCompiler support for removing removing branches that are unreachable when publishing for a given platform.
603
-
604
-
"Platforms" (instead of "features") are represented as strings, with optional versions.
605
-
606
-
-`SupportedOSPlatformAttribute` is similar to the `RequiresDynamicCodeAttribute`, etc, and will produce warnings if called in an unguarded context.
607
-
608
-
```csharp
609
-
CallSomeAndroidAPI(); // warns if not targeting android
610
-
611
-
[SupportedOSPlatform("android")]
612
-
staticvoidCallSomeAndroidAPI() {
613
-
// ...
614
-
}
615
-
```
616
-
617
-
- Platform checks are like feature switch properties, and can guard calls to annotated APIs:
618
-
619
-
```csharp
620
-
if (OperatingSystem.IsAndroid())
621
-
CallSomeAndroidAPI(); // no warning for guarded call
622
-
```
623
-
624
-
The analyzer has built-in knowledge of fact that `IsAndroid` corresponds to the `SupportedOSPlatform("android")`. This is similar to the ILLink analyzer's current hard-coded knowledge of the fact that `IsDynamicCodeSupported` corresponds to `RequiresDynamicCodeAttribute`.
625
-
626
-
- Platform guards are like feature guards, allowing libraries to incroduce custom guards for existing platforms:
It would be possible to define an attribute that indicates _lack_ of support for a feature, similar to the `UnsupportedOSPlatformAttribute`. The attribute-based model should make it possible to differentiate these from the `Requires` attributes, for example with a different base class.
784
-
785
-
It's not clear whether we have a use case for such an attribute, so these examples aren't meant to suggest realistic names, but just the semantics:
- Versioning support for feature attributes/checks/guards
794
-
795
-
The model here would extend naturally to include support for version checks the same way that the platform compatibility analyzer does. Versions would likely be represented as strings because they are encodable in custom attributes:
// Breaking change was made in version 2.0, where this API is no longer supported.
818
-
thrownewNotSupportedException();
819
-
}
820
-
}
821
-
```
822
-
823
-
Code that was originally built against the 1.0 version, and broken on the upgrade to the 2.0 version, could then be updated with a feature check like this:
824
-
```csharp
825
-
if (Foo.IsSupportedWithVersionAtLeast("2.0")) {
826
-
Foo.Impl_2_0();
827
-
} else {
828
-
Foo.Impl_1_0();
829
-
}
830
-
```
831
-
832
-
Although it's not clear in practice where this would be useful. This is not meant as a realistic example.
833
-
834
-
835
-
836
843
837
844
838
845
<hr />
@@ -911,7 +918,6 @@ Do both!
911
918
912
919
This would allow us to get rid of ILLink.Substitutions.xml entirely.
913
920
914
-
915
921
# Terminology
916
922
917
923
- "Incompatible with trimming/AOT": means it would produce trim/AOT warnings if enabled.
0 commit comments