-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[generator] Allow a constant map to explicitly set deprecated-since
for an enum value.
#1070
Conversation
… for an enum value.
@@ -23,5 +23,15 @@ public int GetFieldAsInt (int index) | |||
{ | |||
return int.Parse (GetField (index)); | |||
} | |||
|
|||
public int? GetFieldAsIntNullable (int index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming: I would prefer GetFieldAsNullableInt32()
.
"Meta"-wise, two thoughts:
However, there likely will be instances where an enum field should use This suggests one of two things:
My normal preference is toward the "more verbose" (1), but (2) may be preferable. |
Added to the output function, since our .csv file is regenerated during enumification.
|
While "cute" and efficient, i wonder if this could bite us in ~10+ years when our minimum supported API level is 30 (which is the API level frequently used in dotnet/android#7670). Which makes for an interesting side thought: by having a "sliding window" in which members can move from For the sake of argument, assume that in .NET 8 our minimum API level becomes API-22, up from API-21. Further assume that there is existing .NET 7 code which does: if (!OperatingSystem.IsAndroidVersionAtLeast(23)) {
// Resources.GetDrawable(int) is Obsoleted in API-22
var d = Android.Content.Res.Resources.System.GetDrawable(42);
} would there be any implications if/when Perhaps not, but I do not entirely understand how |
For your example, classic A few potential solutions we could consider:
Note that the "sliding window" is an existing feature and not something this PR is adding. 😁 |
@jpobst: hilariously, the more I think about this, the more confused I get. :-) So on the one hand, the nice thing about the "sliding window" is it means that we have a "reasonable mechanism" to stop processing older API levels. Consider:
Currently "Sliding window" means we have (part of) a reasonable mechanism to say that API-21 is our baseline, and stop downloading everything prior to API-21, and slowly increment that minimum over time. …on the other hand, IIRC (many years ago!) there were API breaks in
then within One of the matches is Meaning if we took "full advantage" of our sliding window, we would remove API! API which aren't currently Which means this is yet another issue. :-) |
There are thus two questions on my mind right now:
Regarding (1), I'm inclined to go forward with this PR "conceptually", with a few minor tweeks. I'll try to write up a commit message to summarize things. Regarding (2), you're already auditing parts of the …but we need to see what havoc that actually does, and what we can do to minimize harm. …or we just never move the sliding window, leave it forever at 21, and continue processing API-10…API-20 for all time. |
@jpobst: please update the docs (we have docs?!) to mention this new column: https://github.com/xamarin/java.interop/blob/f8d77faf55347a58030a694332ba97f0dee88246/Documentation/EnumMappingFile.md |
Draft commit message: Context: https://github.com/xamarin/xamarin-android/pull/7670
While auditing the `Mono.Android.dll`, we've found that some constants
were added to the wrong enums.
Consider [`xamarin-android/src/Mono.Android/map.csv`][0],
lines 739-743:
E,28,android/app/usage/UsageStatsManager.STANDBY_BUCKET_ACTIVE,10,Android.App.Usage.StandbyBucket,Active,remove,
E,28,android/app/usage/UsageStatsManager.STANDBY_BUCKET_FREQUENT,30,Android.App.Usage.StandbyBucket,Frequent,remove,
E,28,android/app/usage/UsageStatsManager.STANDBY_BUCKET_RARE,40,Android.App.Usage.StandbyBucket,Rare,remove,
E,30,android/app/usage/UsageStatsManager.STANDBY_BUCKET_RESTRICTED,45,Android.App.Usage.UsageStatsInterval,Restricted,remove,
E,28,android/app/usage/UsageStatsManager.STANDBY_BUCKET_WORKING_SET,20,Android.App.Usage.StandbyBucket,WorkingSet,remove,
`STANDBY_BUCKET_RESTRICTED` should have been added to `StandbyBucket`
instead of `UsageStatsInterval`.
To fix this in a backwards-compatible way, we can add it to both enums:
E,30,android/app/usage/UsageStatsManager.STANDBY_BUCKET_RESTRICTED,45,Android.App.Usage.StandbyBucket,Restricted,remove,
A,30,,45,Android.App.Usage.UsageStatsInterval,Restricted,remove,
However, we have no way to mark `UsageStatsInterval.Restricted` as
`[Obsolete]`, so people may still unintentionally use it.
Add a new field to our csv that allows us to set a constant's
`@deprecated-since` field, the `30` at the end:
A,30,,45,Android.App.Usage.UsageStatsInterval,Restricted,remove,,30
This allows us to generate:
[global::System.Runtime.Versioning.ObsoletedOSPlatform ("android30.0")]
Restricted = 45
Additionally, when the cause is that we accidentally added an invalid
value to the enum, we should provide a better obsolete message, letting
the user know that the value will not function. This is done by
setting `@deprecated-since` to `-1`:
A,30,,45,Android.App.Usage.UsageStatsInterval,Restricted,remove,,-1
resulting in:
[global::System.Obsolete (@"This value was incorrectly added to the enumeration and is not a valid value")]
Restricted = 45
[0]: https://github.com/xamarin/xamarin-android/blob/cc70ce20aff6934532a8cb6a7bddbf3710fd7e1c/src/Mono.Android/map.csv |
My eventual plan for this was to commit a baseline .xml to git which could be even newer like API-31. These ~never change so there is no reason to recalculate it on every build. We would still have a manual process we could run if we wanted to look for updates.
This also seems to make sense. I dabbled in something similar before, but never followed through: dotnet/android#5172. Another thought is dotnet/android#4278 might surface missing API? |
"Deprecated Since", | ||
}; | ||
|
||
writer.WriteLine (string.Join (",", column_names)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this need to include the comment //
start?
Changes: dotnet/java-interop@f8d77fa...cf80deb * dotnet/java-interop@cf80deb7: [Java.Interop.Tools.JavaCallableWrappers] use IMetadataResolver more (dotnet/java-interop#1069) * dotnet/java-interop@5c5dc086: [generator] enum map.csv can set `@deprecated-since` for enum values (dotnet/java-interop#1070) Any place we used: * `TypeDefinitionCache?` * `IMetadataResolver?` As of dotnet/java-interop@cf80deb7, Java.Interop no longer allows `null` values for these parameters, so overloads which were] `[Obsolete]` now emit errors instead of warnings: [Obsolete ("Use the TypeDefinitionCache overload for better performance.", error: true)] public static MethodDefinition GetBaseDefinition (this MethodDefinition method) => GetBaseDefinition (method, resolver: null!); This results in 3 compiler errors in xamarin-android: src\Xamarin.Android.Build.Tasks\Mono.Android\ApplicationAttribute.Partial.cs(65,11): error CS0619: 'TypeDefinitionRocks.IsSubclassOf(TypeDefinition, string)' is obsolete: 'Use the TypeDefinitionCache overload for better performance.' src\Xamarin.Android.Build.Tasks\Mono.Android\ApplicationAttribute.Partial.cs(268,12): error CS0619: 'JavaNativeTypeManager.ToJniName(TypeDefinition)' is obsolete: 'Use the TypeDefinitionCache overload for better performance.' src\Xamarin.Android.Build.Tasks\Utilities\ManifestDocumentElement.cs(28,11): error CS0619: 'JavaNativeTypeManager.ToJniName(TypeDefinition)' is obsolete: 'Use the TypeDefinitionCache overload for better performance.' After these changes, it appears we will improve the performance further of apps that use: * `ApplicationAttribute.BackupAgent` * `ApplicationAttribute.Name` * `AndroidManifest.xml` attributes that take a `System.Type` values Additionally, fix a `NullReferenceException` in the linker: Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. at Java.Interop.Tools.Cecil.TypeDefinitionRocks.GetBaseType(TypeDefinition type, IMetadataResolver resolver) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs:line 21 at Java.Interop.Tools.Cecil.TypeDefinitionRocks.GetTypeAndBaseTypes(TypeDefinition type, IMetadataResolver resolver)+MoveNext() in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs:line 36 at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName, IMetadataResolver resolver) in /Users/builder/azdo/_work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs:line 87 at MonoDroid.Tuner.FixAbstractMethodsStep.ProcessType(TypeDefinition type) in /Users/builder/azdo/_work/1/s/xamarin-android/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs:line 81 at Mono.Linker.Steps.MarkStep.MarkType(TypeReference reference, DependencyInfo reason, Nullable`1 origin) at Mono.Linker.Steps.MarkStep.MarkField(FieldDefinition field, DependencyInfo& reason, MessageOrigin& origin) at Mono.Linker.Steps.MarkStep.MarkEntireType(TypeDefinition type, DependencyInfo& reason) at Mono.Linker.Steps.MarkStep.MarkEntireAssembly(AssemblyDefinition assembly) at Mono.Linker.Steps.MarkStep.MarkAssembly(AssemblyDefinition assembly, DependencyInfo reason) at Mono.Linker.Steps.MarkStep.MarkModule(ModuleDefinition module, DependencyInfo reason) at Mono.Linker.Steps.MarkStep.ProcessMarkedPending() at Mono.Linker.Steps.MarkStep.Initialize() at Mono.Linker.Steps.MarkStep.Process(LinkContext context) at Mono.Linker.Pipeline.Process(LinkContext context) at Mono.Linker.Driver.Run(ILogger customLogger) at Mono.Linker.Driver.Main(String[] args) This was caused by removing `null` checks in Java.Interop. Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Context: dotnet/android#7670
Through some auditing, we've found that some constants have been added to the wrong enums.
Example:
STANDBY_BUCKET_RESTRICTED
should have been added toStandbyBucket
instead ofUsageStatsInterval
.To fix this in a backwards-compatible way, we can add it to both enums:
However, we have no way to mark
UsageStatsInterval.Restricted
as[Obsolete]
, so people may still unintentionally use it.Add a new field to our csv that allows us to set a constant's
deprecated-since
field (the "30" at the end):This allows us to generate:
Additionally, when the cause is that we accidentally added an invalid value to the enum, we should provide a better obsolete message letting the user know the value will not function. Thus, setting
deprecated-since
to-1
will result in: