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

Source Generators crash/fail with duplicate types #14158

Closed
mattleibow opened this issue Mar 23, 2023 · 1 comment · Fixed by #14171
Closed

Source Generators crash/fail with duplicate types #14158

mattleibow opened this issue Mar 23, 2023 · 1 comment · Fixed by #14171
Assignees
Labels
area-tooling XAML & C# Hot Reload, XAML Editor, Live Visual Tree, Live Preview, Debugging area-xaml XAML, CSS, Triggers, Behaviors fixed-in-8.0.0-preview.4.8333 Look for this fix in 8.0.0-preview.4.8333! platform/android 🤖 platform/iOS 🍎 platform/macOS 🍏 macOS / Mac Catalyst platform/windows 🪟 t/bug Something isn't working

Comments

@mattleibow
Copy link
Member

mattleibow commented Mar 23, 2023

Description

If you define the XmlnsDefinitionAttribute in any library/app, then the source generators just stop resolving types:

namespace Microsoft.Maui.Controls;

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class XmlnsDefinitionAttribute : Attribute
{
}

This is notable as it does not distinguish between public/internal/private. The Compilation.GetTypeByMetadataName() method returns null if zero or more than one type exists. So, when we define a type internally for any reason (in my case I am merging all the dlls for the build tasks) the source generators just stop:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a .NET MAUI source generator.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

[assembly: global::Microsoft.Maui.Controls.Xaml.XamlResourceId("MauiApp96.MainPage.xaml", "MainPage.xaml", typeof(global::MauiApp96.MainPage))]
namespace MauiApp96
{
	[global::Microsoft.Maui.Controls.Xaml.XamlFilePath("MainPage.xaml")]
	public partial class MainPage : global::
	{
		[global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Maui.Controls.SourceGen", "1.0.0.0")]
		private global:: CounterBtn;

		[global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Maui.Controls.SourceGen", "1.0.0.0")]
#if NET5_0_OR_GREATER
		[global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(CounterBtn))]
#endif
		private void InitializeComponent()
		{
			global::Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml(this, typeof(MainPage));
			CounterBtn = global::Microsoft.Maui.Controls.NameScopeExtensions.FindByName<global::>(this, "CounterBtn");
		}
	}
}

And this issue also appears when you define multiple types and expose them with this attribute. If the app does this:

<CustomButton x:Name="CounterBtn" />

And there are 2projects:

My Maui App:

[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "MyMauiApp")]

namespace MauiLib1;
public class CustomButton : Button { }

Third Party Library:

namespace MauiLib1;
internal class CustomButton : Button { }

Steps to Reproduce

See the description...

Link to public reproduction project repository

I have a PR in the works with unit tests

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

iOS, Android, Windows, macOS, Other (Tizen, Linux, etc. not supported by Microsoft directly)

Affected platform versions

All things - this is the compiler

Did you find any workaround?

Not really. I do not control one of the assemblies.

Relevant log output

No response

@mattleibow mattleibow added t/bug Something isn't working area-xaml XAML, CSS, Triggers, Behaviors area-tooling XAML & C# Hot Reload, XAML Editor, Live Visual Tree, Live Preview, Debugging labels Mar 23, 2023
@mattleibow mattleibow self-assigned this Mar 23, 2023
@mattleibow mattleibow added this to the Backlog milestone Mar 23, 2023
@ghost
Copy link

ghost commented Mar 23, 2023

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

@mattleibow mattleibow moved this from Todo to In Progress in MAUI SDK Ongoing Mar 27, 2023
rmarinho added a commit that referenced this issue Apr 12, 2023
…14158

### Description of Change

This PR fixes the case where duplicate types exist and then the source
generator just stops. This issue actually also affects both the XAML
parser and the IL generator. The parser throws a cast exception at
runtime and the IL generator will result in a method access exception.

* In one case we may have duplicate `XmlnsDefinitionAttribute`
declarations because we are going to IL merge all the dlls into the
build tasks - and then use unit tests to reference this. As a result, we
end up with an internal type in the build tasks and the public one in
Controls.

* The other case is just duplicate types in different assemblies. This
can easily be reproduced by creating an internal type in an external
assembly - and not even externals as it can also happen if you declare
it in the main assembly - and it happens to be the same of some other
type in the maui dll.

Both issues are a case of `Compilation.GetTypeByMetadataName()`
returning null if there are _any_ duplicate types. This even happens if
the type is internal in both assemblies. Similarly, the XAML parser and
IL generator also just get the type and never make sure it is a
_visible_ type.

### Tests

This PR has some tests:

* Generator does not fail if there are duplicate
`XmlnsDefinitionAttribute` attributes defined - one being internal and
custom and the other being the maui one.
* Generator does not select internal types that it should not
* Generator can select types if the InternalsVisibleTo says it can


### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #14158

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
@github-project-automation github-project-automation bot moved this from In Progress to Done in MAUI SDK Ongoing Apr 12, 2023
@samhouts samhouts modified the milestones: Backlog, .NET 8 Planning May 1, 2023
@ghost ghost locked as resolved and limited conversation to collaborators May 31, 2023
@samhouts samhouts added the fixed-in-8.0.0-preview.4.8333 Look for this fix in 8.0.0-preview.4.8333! label Jun 8, 2023
@hartez hartez removed this from MAUI SDK Ongoing Jul 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-tooling XAML & C# Hot Reload, XAML Editor, Live Visual Tree, Live Preview, Debugging area-xaml XAML, CSS, Triggers, Behaviors fixed-in-8.0.0-preview.4.8333 Look for this fix in 8.0.0-preview.4.8333! platform/android 🤖 platform/iOS 🍎 platform/macOS 🍏 macOS / Mac Catalyst platform/windows 🪟 t/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants