CommunityToolkit / dotnet

.NET Community Toolkit is a collection of helpers and APIs that work for all .NET developers and are agnostic of any specific UI platform. The toolkit is maintained and published by Microsoft, and part of the .NET Foundation.
https://docs.microsoft.com/dotnet/communitytoolkit/?WT.mc_id=dotnet-0000-bramin
Other
3.05k stars 300 forks source link

Source generator from MVVM Toolkit requiring LangVersion to be set with Visual Studio 2022 Mac #227

Open anotherlab opened 2 years ago

anotherlab commented 2 years ago

Describe the bug

When using the source generator from the MVVM Toolkit with Visual Studio 2022 for Mac Release Candidate for a Xamarin Forms 5 app, the following error message is generated:

CSC : error MVVMTK0008: The source generator features from the MVVM Toolkit require consuming projects to set the C# language version to at least C# 8.0

Work around on the Mac: Edit the .csproj and add the following

<PropertyGroup>
      <LangVersion>preview</LangVersion>
</PropertyGroup>

When LangVersion is explicitly set, the code compiles and runs as expected. The autogenerated partial classes do not show up in the solution explorer as they would on the Windows Visual Studio.

Regression

No response

Steps to reproduce

On Mac with Visual Studio 2022 Release Candidate
1. Create new Xamarin.Forms "blank page" project.
2. Add CommunityToolkit.Mvvm, 8.0.0-preview3 via "Manage nuget packages"
3. Create a new public partial class and add `[INotifyPropertyChanged]` and `[ObservableProperty]` attributes.
4. Build the project.

Expected behavior

Project should compile normally.

Screenshots

No response

IDE and version

VS 2022 Preview

IDE version

17.0 build 8754

Nuget packages

Nuget package version(s)

8.0.0-preview3

Additional context

Sample project to illustrate the problem can be found at https://github.com/anotherlab/mvvmgen

Help us help you

No, just wanted to report this

Sergio0694 commented 2 years ago

Just to clarify, what is the default language version for a new Xamarin Forms 5 app? If it's lower than C# 8, then this is just by design, as the diagnostic message says. If it's not and this is being detected incorrectly, then it's a bug in the generator.

anotherlab commented 2 years ago

@Sergio0694 The new project template for Xamarin.Forms 5 sets the TargetFramework to netstandard2.0 with both the Windows and Mac versions of Visual Studio 2022. The source generators work as expected with the Windows edition, but generate the compiler error on the Mac for the project.

Sergio0694 commented 2 years ago

That's... Weird. I would assume the language version to be the same for the same project template. @sharwell any ideas on what could be happening here? Are there any Roslyn differences on VS for Mac? Just trying to understand whether this is just the expected behavior and VS for Mac just happens to be picking a lower C# version for some reason here, or whether it might be our target or language version check that might be messing up on VS for Mac, again, for some reason ๐Ÿ˜†

anotherlab commented 2 years ago

I thought it was weird too. Xamarin projects target netstandard2.0, which is documented to be C# 7.3. if C# 8 is a requirement, then I get why it didn't work out of the box with Visual Studio 2022 Mac, but why are the source generators working with Visual Studio 2022 for Xamarin.Forms? Is there a link for the C# 8 requirement?

Sergio0694 commented 2 years ago

To clarify, source generators don't require C# 8 on their own. It's our generators in the MVVM Toolkit that do ๐Ÿ™‚

anotherlab commented 2 years ago

Are the MVVM Toolkit generators being compiled along with project code? What determines which version of C# they will get? This sounds like a difference between the Windows & Mac versions of VS 20220, and they should behave the same.

sharwell commented 2 years ago

netstandard2.0 does not support C# 8. If you override (or encourage a user to override) the language version in this scenario to be C# 8, the user's project is in an unsupported build configuration and is not guaranteed to work correctly.

Note that the source generator itself doesn't care what language version the project is using. It's the code generated by that source generator which may be using newer language features; other source generators work around this by either restricting themselves to earlier language features or by detecting the current language version and adjusting the generated code to adhere to that version.

Sergio0694 commented 2 years ago

To be clear, we're not overriding the language version for consumers, but we decided to just use C# 8 as a baseline for the generated code (as going lower would've been just too much of a hassle as we would've had to also strip nullability annotations everywhere). So I just setup the generators to do nothing and just emit a diagnostic if you try to use them when using a lower C# version. I guess I'm just confused here as to why the same Xamarin template is apparently using two different C# versions on VS on Windows and on Mac? Unless I'm missing something here ๐Ÿค”

sharwell commented 2 years ago

I edited my previous comment. I wasn't saying this project is setting the language version, but rather saying it's perhaps not ideal to suggest a user manually edit their project into an unsupported state. If you instead say the source generators required netstandard2.1 or higher, the users can update their target framework to enable C# 8 and also still be in a supported scenario.

Sergio0694 commented 2 years ago

Yeah no worries, just wanted to make sure other folks reading this thread couldn't misunderstand things ๐Ÿ™‚

"it's perhaps not ideal to suggest a user manually edit their project into an unsupported state. If you instead say the source generators required netstandard2.1 or higher, the users can update their target framework to enable C# 8 and also still be in a supported scenario."

That is a good point, the issue for us though is that this would basically mean anyone on .NET Framework / UWP / etc. would be completely cut out, and that's a lot of folks, especially on the UWP side given that the MVVM Toolkit has just now branched off from the Windows Community Toolkit, which was entirely dedicated to UWP devs. We're kinda in an awkward spot here.

The approach we had so was to leave the generators there, require C# 8, and then devs have the ability to choose on their own to either bump TFM, or manually bump the language version on their current TFM and use the generators. For instance, we're using C# 10 in the Microsoft Store too, which is on UWP, so .NET Standard 2.0 based ๐Ÿ˜…

anotherlab commented 2 years ago

@Sergio0694 The Xamarin.Forms new project templates are using the same framework on Windows and Mac, they both use netstandard2.0. I think this is more of a difference in how Visual Studio is handling which version of C# is being used on each platform. I can see it getting confusing for developers who build/debug from VS Win, but use a Mac build server to generate the iOS .ipa files. Something that will build correctly from Windows, will fail when built from the Mac.