-
Notifications
You must be signed in to change notification settings - Fork 520
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
[Xamarin.Android.Build.Tasks] Try a case insensitive lookup as a backup for Legacy Designer fixup #8376
Conversation
src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs
Show resolved
Hide resolved
src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs
Outdated
Show resolved
Hide resolved
@dellis1972 wrote:
(macOS is case-insensitive by default, like Windows, so you can't have two files with different cases unless you create a new filesystem, e.g. APFS Case Sensitive.) I think we may be overthinking this? For file-backed resources, we always lowercase the filename before passing on to It thus should not be possible to have two file-based Android resources which differ only in case. @dellis1972: does If Though I suspect that |
|
a4127be
to
c3fb7cc
Compare
c3fb7cc
to
bd190c0
Compare
output.Add (key, property.GetMethod); | ||
caseInsensitiveLookup.Add (key, property.GetMethod); |
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.
This could be a problem, as .Add()
will throw if a "duplicate key" already exists:
var d = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
d.Add ("A", "a");
d.Add ("a", "a");
// throws System.ArgumentException: An item with the same key has already been added. Key: a
Either we should use caseInsensitiveLookup.TryAdd(key, property.GetMethod)
(.NET Standard 2.1), or we should use the indexer caseInsensitiveLookup[key] = property.GetMethod
, though using the indexer means that caseInsensitiveLookup
will always contain the last case-insensitive value encountered rather than the first (which might be fine?).
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.
well we only use .netstandard 2.0 so I guess that makes the decision for us.
[Xamarin.Android.Build.Tasks] case-insensitive Legacy Designer fixup (#8376)
Context: 628d6cb869c872c34d17b014724a43e8d451fb93
Context: dc3ccf28cdbe9f8c0a705400b83c11a85c81a980
We have a very odd situation with the
[`Xamarin.CommunityToolkit.MauiCompat` NuGet package][0]:
The NuGet package ships with a file `.net/__res_name_case_map.txt`
(628d6cb8) in `Xamarin.CommunityToolkit.MauiCompat.aar` which contains
the case mapchanges for the `@(AndroidResource)` items. The purpose
of this file is to allow the user to use PascalCase (or any case) names
in C# code, while the Android Resource compilation is left as all
lowercase. This is because Android requires that file-backed resource
names consist of only lowercase letters.
The contents of this file includes:
Resources/Layout/CameraFragment.axml;layout/camerafragment.xml
which tells us that the Android `R.layout.camerafragment` resource id
should be "bound" as `Resouce.Layout.CameraFragment`, which allows
[`CameraFragment.android.cs` to build][1]:
public override AView? OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) =>
inflater.Inflate(Resource.Layout.CameraFragment, null);
However, when we look at the IL that comes from the NuGet package we
see the following
ikdasm ~/.nuget/packages/xamarin.communitytoolkit.mauicompat/2.0.2-preview1013/lib/net6.0-android31.0/Xamarin.CommunityToolkit.MauiCompat.dll| grep Layout::camerafragment
…
IL_0131: stsfld int32 Xamarin.CommunityToolkit.MauiCompat.Resource/Layout::camerafragment
IL_0001: ldsfld int32 Xamarin.CommunityToolkit.MauiCompat.Resource/Layout::camerafragment
For some reason as part of the maui release [the following script][2]
was run on the code:
sed -i '' 's/MauiCompat.Resource.Layout.CameraFragment/MauiCompat.Resource.Layout.camerafragment/g' ./src/CommunityToolkit/Xamarin.CommunityToolkit.MauiCompat/**/CameraFragment.android.cs
This force changes the case of `CameraFragment` to `camerafragment`.
However, the NuGet still includes the `.aar` with the case map
changes, which are now inconsistent.
I'm not sure why this happens but it results in the following build
error when trying to consume this package under net8.0-android with
the new Resource Designer Assembly (dc3ccf28):
error XA8000: Could not find Android Resource ‘@layout/camerafragment’. Please update @(AndroidResource) to add the missing resource.
This is because we are looking for the lowercase version of the
resource in the Designer assembly property list, but because of the
remap file we only know about the PascalCase version.
As a workaround, fallback to a *case-insensitive* lookup.
[0]: https://www.nuget.org/packages/Xamarin.CommunityToolkit.MauiCompat/
[1]: https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/Android/CameraFragment.android.cs#L129
[2]: https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/MauiCompat.sh#L561 |
* main: [Xamarin.Android.Build.Tasks] case-insensitive Legacy Designer fixup (xamarin#8376) [build] Update docs and remove `xabuild` mentions (xamarin#8406) Bump to xamarin/java.interop/main@ed63d890 (xamarin#8407)
…8376) Context: 628d6cb Context: dc3ccf2 We have a very odd situation with the [`Xamarin.CommunityToolkit.MauiCompat` NuGet package][0]: The NuGet package ships with a file `.net/__res_name_case_map.txt` (628d6cb) in `Xamarin.CommunityToolkit.MauiCompat.aar` which contains the case map changes for the `@(AndroidResource)` items. The purpose of this file is to allow the user to use PascalCase (or any case) names in C# code, while the Android Resource compilation is left as all lowercase. This is because Android requires that file-backed resource names consist of only lowercase letters. The contents of this file includes: Resources/Layout/CameraFragment.axml;layout/camerafragment.xml which tells us that the Android `R.layout.camerafragment` resource id should be "bound" as `Resouce.Layout.CameraFragment`, which allows [`CameraFragment.android.cs` to build][1]: public override AView? OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) => inflater.Inflate(Resource.Layout.CameraFragment, null); However, when we look at the IL that comes from the NuGet package we see the only lowercase `camerafragment`: ikdasm ~/.nuget/packages/xamarin.communitytoolkit.mauicompat/2.0.2-preview1013/lib/net6.0-android31.0/Xamarin.CommunityToolkit.MauiCompat.dll| grep Layout::camerafragment … IL_0131: stsfld int32 Xamarin.CommunityToolkit.MauiCompat.Resource/Layout::camerafragment … IL_0001: ldsfld int32 Xamarin.CommunityToolkit.MauiCompat.Resource/Layout::camerafragment For some reason as part of the XamarinCommunityToolkit build [the following script][2] was run on the code: sed -i '' 's/MauiCompat.Resource.Layout.CameraFragment/MauiCompat.Resource.Layout.camerafragment/g' ./src/CommunityToolkit/Xamarin.CommunityToolkit.MauiCompat/**/CameraFragment.android.cs This changes `Resource.Layout.CameraFragment` to `Resource.Layout.camerafragment`, apparently because *something* is renaming [`CameraFragment.axml`][3] to `camerafragment.axml` *after* `__res_name_case_map.txt` is generated, but before `CameraFragment.android.cs` is compiled. The NuGet still includes the `.aar` with the case map changes, which are now inconsistent with the assembly contents. I'm not sure why XamarinCommunityToolkit does all this. The result of the above XamarinCommunityToolkit build and packaging behavior is that it interacts badly with the new net8.0-android Resource Designer Assembly (dc3ccf2) work, with a build-time error: error XA8000: Could not find Android Resource ‘@layout/camerafragment’. Please update @(AndroidResource) to add the missing resource. This is because we are looking for the lowercase version of the resource in the Designer assembly property list, but because of the remap file we only know about the PascalCase version. As a workaround, fallback to a *case-insensitive* resource name lookup if a case-sensitive lookup fails. [0]: https://www.nuget.org/packages/Xamarin.CommunityToolkit.MauiCompat/ [1]: https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/Android/CameraFragment.android.cs#L129 [2]: https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/MauiCompat.sh#L561 [3]: https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/src/CommunityToolkit/Xamarin.CommunityToolkit/Resources/Layout/CameraFragment.axml
…8376) Context: 628d6cb Context: dc3ccf2 We have a very odd situation with the [`Xamarin.CommunityToolkit.MauiCompat` NuGet package][0]: The NuGet package ships with a file `.net/__res_name_case_map.txt` (628d6cb) in `Xamarin.CommunityToolkit.MauiCompat.aar` which contains the case map changes for the `@(AndroidResource)` items. The purpose of this file is to allow the user to use PascalCase (or any case) names in C# code, while the Android Resource compilation is left as all lowercase. This is because Android requires that file-backed resource names consist of only lowercase letters. The contents of this file includes: Resources/Layout/CameraFragment.axml;layout/camerafragment.xml which tells us that the Android `R.layout.camerafragment` resource id should be "bound" as `Resouce.Layout.CameraFragment`, which allows [`CameraFragment.android.cs` to build][1]: public override AView? OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) => inflater.Inflate(Resource.Layout.CameraFragment, null); However, when we look at the IL that comes from the NuGet package we see the only lowercase `camerafragment`: ikdasm ~/.nuget/packages/xamarin.communitytoolkit.mauicompat/2.0.2-preview1013/lib/net6.0-android31.0/Xamarin.CommunityToolkit.MauiCompat.dll| grep Layout::camerafragment … IL_0131: stsfld int32 Xamarin.CommunityToolkit.MauiCompat.Resource/Layout::camerafragment … IL_0001: ldsfld int32 Xamarin.CommunityToolkit.MauiCompat.Resource/Layout::camerafragment For some reason as part of the XamarinCommunityToolkit build [the following script][2] was run on the code: sed -i '' 's/MauiCompat.Resource.Layout.CameraFragment/MauiCompat.Resource.Layout.camerafragment/g' ./src/CommunityToolkit/Xamarin.CommunityToolkit.MauiCompat/**/CameraFragment.android.cs This changes `Resource.Layout.CameraFragment` to `Resource.Layout.camerafragment`, apparently because *something* is renaming [`CameraFragment.axml`][3] to `camerafragment.axml` *after* `__res_name_case_map.txt` is generated, but before `CameraFragment.android.cs` is compiled. The NuGet still includes the `.aar` with the case map changes, which are now inconsistent with the assembly contents. I'm not sure why XamarinCommunityToolkit does all this. The result of the above XamarinCommunityToolkit build and packaging behavior is that it interacts badly with the new net8.0-android Resource Designer Assembly (dc3ccf2) work, with a build-time error: error XA8000: Could not find Android Resource ‘@layout/camerafragment’. Please update @(AndroidResource) to add the missing resource. This is because we are looking for the lowercase version of the resource in the Designer assembly property list, but because of the remap file we only know about the PascalCase version. As a workaround, fallback to a *case-insensitive* resource name lookup if a case-sensitive lookup fails. [0]: https://www.nuget.org/packages/Xamarin.CommunityToolkit.MauiCompat/ [1]: https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/Android/CameraFragment.android.cs#L129 [2]: https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/MauiCompat.sh#L561 [3]: https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/src/CommunityToolkit/Xamarin.CommunityToolkit/Resources/Layout/CameraFragment.axml
We have a very odd situation regarding the NuGet
Xamarin.CommunityToolkit.MauiCompat
.The NuGet package ships with a file
.net/__res_name_case_map.txt
in theXamarin.CommunityToolkit.MauiCompat.aar
which contains thecase map changes for the
AndroidResource
items. The purpose of this file is to allowthe user to use Camel case (or any case) names in C# code, while the android resource
compilation is left as all lowercase. This is because android requires lowercase resource
items.
The contents of this file are as follows
As you can see from this
camerafragment
is remaped toCameraFragment
. With thischange we would expect to see code in C# which uses
CameraFragment
. This is trueas per https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/src/CommunityToolkit/Xamarin.CommunityToolkit/Views/CameraView/Android/CameraFragment.android.cs#L129.
We can see that the code in the NuGet is using the
CameraFragment
casing.However when we look at the IL that comes from the NuGet package we see the following
For some reason as part of the maui release the following script was run on the code
https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/MauiCompat.sh#L561.
This force changes the case of the
CameraFragment
tocamerafragment
across the whole project.But the NuGet still includes the .aar with the case map changes (which are no longer needed).
I'm not sure why this happens but it results in the following build error when trying to consume this package
under .net8.0-android with the new Resource Designer.
This is because we are looking for the lowercase version of the resource in the Designer assembly property list, but because
of the remap file. We only have the Camel case version.
The current workaround is to fallback to a case insensitive lookup... My first thought was to always use a case insensitive
lookup. But there are cases where users have two files with different cases. This is possible on systems like Linux and MacOS.