Skip to content
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

Change Namespace to _Microsoft.Android.Resource.Designer #7681

Merged
merged 5 commits into from
Jan 18, 2023

Conversation

dellis1972
Copy link
Contributor

@dellis1972 dellis1972 commented Jan 10, 2023

We if we used the current Microsoft.Android.Resource.Designer namespace we can get into issues with any other library which uses Microsoft in the namespace. When building maui we see the following build error

src\Essentials\src\AppActions\AppActions.shared.cs(62,28): error CS0234: The type or namespace name 'Content' does not exist in the namespace 'Microsoft.Android' (are you missing an assembly reference?)

This is because rather than looking for Content in the global Android namespace, it looks for it in the Microsfot.Android namespace. This can be fixed by the end user by adding global:: to the type usage, but this is not desireable in all senarios. Given this is an internal class which really should not be used lets change the namespace instead.

In addition we should add a #pragma for IDE0002[1] so that users are NOT asked to simplify the Resource designer class declaration. We also need to add the EditorBrowsable attribute so that the types do not show up in code completion in the IDE.

[1] https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0002

@dellis1972
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@dellis1972
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jonpryor
Copy link
Member

Context: dc3ccf28cdbe9f8c0a705400b83c11a85c81a980
Context: https://github.com/dotnet/maui/pull/12520#issuecomment-1376431313
Context: https://discord.com/channels/732297728826277939/732297837953679412/1062137297438519296
Context: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0002

Consider this C# fragment:

	namespace Android.Content {
	    public class Intent {        
	    }
	}

	namespace Microsoft.Maui.Example {
	    public class Helper {
	        public static void UseIntent (Android.Content.Intent intent) {}
	    }
	}

Given a C# *namespace_or_type_name* such as `Android.Content.Intent`,
[ECMA 334 §7.8.1][0] will be used to determine what the type refers
to, resolving it to `global::Android.Content.Intent`.

All is good.

However, once dc3ccf28 enters the picture, we now have:

	// via dc3ccf28 & _Microsoft.Android.Resource.Designer.dll
	namespace Microsoft.Android.Resource.Designer {
	    public class Resource {
	    }
	}

	namespace Android.Content {
	    public class Intent {        
	    }
	}

	namespace Microsoft.Maui.Example {
	    public class Helper {
	        // CS0234 on the following line:		
	        public static void UseIntent (Android.Content.Intent intent) {}
	    }
	}

…and it fails to build with [error CS0234][1]:

	error CS0234: The type or namespace name 'Content' does not exist in the namespace 'Microsoft.Android' (are you missing an assembly reference?)

This only happens if the usage of `Android.Content.Intent` happens
*within* a `Microsoft.`-prefixed namespace.  Which is most of MAUI.

The cause of the error is that while attempting to resolve
`Android.Content.Intent`, search starts from the *current* namespace
`Microsoft.Maui.Example`, and the compiler will attempt to resolve
the types:

  * `Microsoft.Maui.Example.Android.Content.Intent`
    (because the usage site is in the `Microsoft.Maui.Example` namespace.)
  * `Microsoft.Maui.Android.Content.Intent`
    (because `Microsoft.Maui` is a parent namespace)
  * `Microsoft.Android.Content.Intent`
    (because `Microsoft` is a parent parent namespace)

These are the *only* types that are resolved, and none of those exist.
This results in the CS0234 error.

There are two workarounds that the "offending" code can employ:

 1. Use `global`:

        namespace Microsoft.Maui.Example {
            public class Helper {
                public static void UseIntent (global::Android.Content.Intent intent) {}
            }
        }

 2. Add a `using Android.Content` and use `Intent`

        using Android.Content;
        namespace Microsoft.Maui.Example {
            public class Helper {
                public static void UseIntent (Intent intent) {}
            }
        }

Both of these require changing things *outside* of xamarin-android.

Rephrasing & simplifying: commit dc3ccf28 constitutes an *API break*,
as code which *previously* compiled *no longer compiles*.

Fix this by updating the `<GenerateResourceDesignerAssembly/>` task
emits types into the `_Microsoft.Android.Resource.Designer` namespace;
note `_` prefix.  No One™ should have their code in a `_Microsoft.*`
namespace, so this shouldn't break anybody.  Additionally, update
`_Microsoft.Android.Resource.Designer.dll` so that
[`EditorBrowsableAttribute`][2] is placed on all the types, a'la:

	namespace _Microsoft.Android.Resource.Designer;
	[EditorBrowsable (EditorBrowsableState.Never)]
	public partial class Resource {
	}

	// For App project builds
	[EditorBrowsable (EditorBrowsableState.Never)]
	internal partial class ResourceConstant {
	}

Finally, update the Source Compatibility types so that the `Resource`
type disables the IDE0002 warning:

	namespace %CompatibilityNamespace% {
	    #pragma warning disable IDE0002
	    public partial class Resource : _Microsoft.Android.Resource.Designer.Resource {
	    }
	    #pragma warning restore IDE0002
	}

[0]: https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/basic-concepts.md#78-namespace-and-type-names
[1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0234
[2]: https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.editorbrowsableattribute?view=net-7.0
[3]: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0002

@jonpryor jonpryor merged commit 3ec1b15 into xamarin:main Jan 18, 2023
grendello added a commit to grendello/xamarin-android that referenced this pull request Jan 18, 2023
* main:
  [Mono.Android] Android.Telecom.InCallService.SetAudioRoute() + enum (xamarin#7711)
  [Mono.Android] Fix some incorrect enums. (xamarin#7670)
  [Xamarin.Android.Build.Tasks] _Microsoft.Android.Resource.Designer namespace (xamarin#7681)
  LEGO: Merge pull request 7713
  [Xamarin.Android.Build.Tasks] lazily populate Resource lookup (xamarin#7686)
grendello added a commit to grendello/xamarin-android that referenced this pull request Jan 19, 2023
* main:
  [ci] Pass token when building Designer tests (xamarin#7715)
  [Mono.Android] Android.Telecom.InCallService.SetAudioRoute() + enum (xamarin#7711)
  [Mono.Android] Fix some incorrect enums. (xamarin#7670)
  [Xamarin.Android.Build.Tasks] _Microsoft.Android.Resource.Designer namespace (xamarin#7681)
  LEGO: Merge pull request 7713
  [Xamarin.Android.Build.Tasks] lazily populate Resource lookup (xamarin#7686)
grendello added a commit to grendello/xamarin-android that referenced this pull request Jan 26, 2023
* main: (32 commits)
  [monodroid] Replace `exit()` with `abort()` in native code (xamarin#7734)
  Bump to xamarin/java.interop@8a1ae57 (xamarin#7738)
  [build] bump `$(AndroidNet7Version)` (xamarin#7737)
  Bump to xamarin/java.interop@1366d99 (xamarin#7718)
  [Xamarin.Android.Build.Tasks] fix AndroidGenerateResourceDesigner (xamarin#7721)
  Bump to xamarin/monodroid@50faac94 (xamarin#7725)
  Revert "[Xamarin.Android.Build.Tasks] fix cases of missing `@(Reference)` (xamarin#7642)" (xamarin#7726)
  [marshal methods] Properly support arrays of arrays (xamarin#7707)
  Bump to dotnet/installer@9962c6a 8.0.100-alpha.1.23063.11 (xamarin#7677)
  [Actions] Add action to bump the hash used for the unified pipeline (xamarin#7712)
  Bump to xamarin/xamarin-android-tools@099fd95 (xamarin#7709)
  [ci] Move build stages into yaml templates (xamarin#7553)
  [Xamarin.Android.Build.Tasks] fix NRE in `<GenerateResourceCaseMap/>` (xamarin#7716)
  [ci] Pass token when building Designer tests (xamarin#7715)
  [Mono.Android] Android.Telecom.InCallService.SetAudioRoute() + enum (xamarin#7711)
  [Mono.Android] Fix some incorrect enums. (xamarin#7670)
  [Xamarin.Android.Build.Tasks] _Microsoft.Android.Resource.Designer namespace (xamarin#7681)
  LEGO: Merge pull request 7713
  [Xamarin.Android.Build.Tasks] lazily populate Resource lookup (xamarin#7686)
  [Xamarin.Android.Build.Tasks] skip XA1034 logic in some cases (xamarin#7680)
  ...
@github-actions github-actions bot locked and limited conversation to collaborators Jan 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants