Skip to content

Commit bebb6cf

Browse files
authored
Add Roslyn 5.0 support to source generators (#364)
* Add Roslyn 5.0 support to source generators Introduces a new ReactiveUI.SourceGenerators.Roslyn5000 project targeting Roslyn 5.0, updates conditional compilation to support ROSYLN_500, and integrates the new project into the solution and main source generators package. This enables compatibility with the latest Roslyn compiler and ensures proper packaging of analyzers for Roslyn 5.0. * Add ROSYLN_500 support for attribute generation Extended conditional compilation to include ROSYLN_500 in attribute and generator logic. Updated README to clarify partial property initializer support now requires C# 14 or newer.
1 parent d150a5c commit bebb6cf

File tree

8 files changed

+73
-18
lines changed

8 files changed

+73
-18
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ This documentation covers using ReactiveUI Source Generators to simplify and enh
2424

2525
ReactiveUI Source Generators automatically generate ReactiveUI objects to streamline your code. These Source Generators are designed to work with ReactiveUI V19.5.31+ and support the following features:
2626

27-
- `[Reactive]` With field and access modifiers, partial property support (C# 13 Visual Studio Version 17.12.0), partial properties with initializer support (C# preview only)
27+
- `[Reactive]` With field and access modifiers, partial property support (C# 13 Visual Studio Version 17.12.0), partial properties with initializer support (C# 14+/preview only)
2828
- `[Reactive(SetModifier = AccessModifier.Protected)]` With field and access modifiers, (Not Required for partial properties, configure set accessor with the property declaration).
2929
- `[Reactive(Inheritance = InheritanceModifier.Virtual)]` With field and access modifiers. This will generate a virtual property.
3030
- `[Reactive(UseRequired = true)]` With field and access modifiers. This will generate a required property, (Not Required for partial properties, use required keyword for property declaration).

src/ReactiveUI.SourceGenerators.Roslyn/AttributeDefinitions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ internal sealed class ReactiveCommandAttribute : global::System.Attribute
164164
/// <value>
165165
/// The reactive attribute.
166166
/// </value>
167-
#if ROSYLN_412
167+
#if ROSYLN_412 || ROSYLN_500
168168
public static string ReactiveAttribute => $$"""
169169
// Copyright (c) {{DateTime.Now.Year}} .NET Foundation and Contributors. All rights reserved.
170170
// Licensed to the .NET Foundation under one or more agreements.
@@ -275,7 +275,7 @@ public ReactiveAttribute(params string[] alsoNotify)
275275
#endif
276276

277277
public const string ObservableAsPropertyAttributeType = "ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute";
278-
#if ROSYLN_412
278+
#if ROSYLN_412 || ROSYLN_500
279279
public static string ObservableAsPropertyAttribute => $$"""
280280
// Copyright (c) {{DateTime.Now.Year}} .NET Foundation and Contributors. All rights reserved.
281281
// Licensed to the .NET Foundation under one or more agreements.

src/ReactiveUI.SourceGenerators.Roslyn/ObservableAsProperty/ObservableAsPropertyGenerator{FromObservable}.Execute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public sealed partial class ObservableAsPropertyGenerator
159159

160160
isNullableType = propertySymbol.Type is INamedTypeSymbol nullcheck && nullcheck.TypeArguments[0].IsNullableType();
161161
}
162-
#if ROSYLN_412
162+
#if ROSYLN_412 || ROSYLN_500
163163
else
164164
{
165165
if (!propertySymbol.IsPartialDefinition || propertySymbol.IsStatic)

src/ReactiveUI.SourceGenerators.Roslyn/Reactive/ReactiveGenerator.Execute.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public sealed partial class ReactiveGenerator
2626
internal static readonly string GeneratorName = typeof(ReactiveGenerator).FullName!;
2727
internal static readonly string GeneratorVersion = typeof(ReactiveGenerator).Assembly.GetName().Version.ToString();
2828

29-
#if ROSYLN_412
29+
#if ROSYLN_412 || ROSYLN_500
3030
private static Result<PropertyInfo?>? GetPropertyInfo(in GeneratorAttributeSyntaxContext context, CancellationToken token)
3131
{
3232
using var builder = ImmutableArrayBuilder<DiagnosticInfo>.Rent();
@@ -123,11 +123,17 @@ public sealed partial class ReactiveGenerator
123123

124124
var typeNameWithNullabilityAnnotations = propertySymbol.Type.GetFullyQualifiedNameWithNullabilityAnnotations();
125125
var fieldName = propertySymbol.GetGeneratedFieldName();
126-
126+
#if ROSYLN_500
127+
if (context.SemanticModel.Compilation is CSharpCompilation compilation && compilation.LanguageVersion >= LanguageVersion.CSharp14)
128+
{
129+
fieldName = "field";
130+
}
131+
#else
127132
if (context.SemanticModel.Compilation is CSharpCompilation compilation && compilation.LanguageVersion == LanguageVersion.Preview)
128133
{
129134
fieldName = "field";
130135
}
136+
#endif
131137

132138
var propertyName = propertySymbol.Name;
133139

@@ -176,14 +182,14 @@ public sealed partial class ReactiveGenerator
176182
}
177183
#endif
178184

179-
/// <summary>
180-
/// Gets the observable method information.
181-
/// </summary>
182-
/// <param name="context">The context.</param>
183-
/// <param name="token">The token.</param>
184-
/// <returns>
185-
/// The value.
186-
/// </returns>
185+
/// <summary>
186+
/// Gets the observable method information.
187+
/// </summary>
188+
/// <param name="context">The context.</param>
189+
/// <param name="token">The token.</param>
190+
/// <returns>
191+
/// The value.
192+
/// </returns>
187193
private static Result<PropertyInfo?>? GetVariableInfo(in GeneratorAttributeSyntaxContext context, CancellationToken token)
188194
{
189195
using var builder = ImmutableArrayBuilder<DiagnosticInfo>.Rent();

src/ReactiveUI.SourceGenerators.Roslyn/Reactive/ReactiveGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
3232
});
3333

3434
RunReactiveFromField(context);
35-
#if ROSYLN_412
35+
#if ROSYLN_412 || ROSYLN_500
3636
RunReactiveFromProperty(context);
3737
#endif
3838
}
@@ -87,7 +87,7 @@ private static void RunReactiveFromField(IncrementalGeneratorInitializationConte
8787
});
8888
}
8989

90-
#if ROSYLN_412
90+
#if ROSYLN_412 || ROSYLN_500
9191
private static void RunReactiveFromProperty(IncrementalGeneratorInitializationContext context)
9292
{
9393
// Gather info for all annotated variable with at least one attribute.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>$(RoslynTfm)</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<LangVersion>latest</LangVersion>
7+
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
8+
<IsRoslynComponent>true</IsRoslynComponent>
9+
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
10+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
11+
<IncludeBuildOutput>false</IncludeBuildOutput>
12+
<DevelopmentDependency>true</DevelopmentDependency>
13+
<IsPackable>false</IsPackable>
14+
15+
<PackageDescription>A MVVM framework that integrates with the Reactive Extensions for .NET to create elegant, testable User Interfaces that run on any mobile or desktop platform. This is the Source Generators package for ReactiveUI</PackageDescription>
16+
<AssemblyName>ReactiveUI.SourceGenerators</AssemblyName>
17+
<DefineConstants>$(DefineConstants);ROSYLN_500</DefineConstants>
18+
</PropertyGroup>
19+
20+
<ItemGroup>
21+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" PrivateAssets="all" VersionOverride="5.0.0" />
22+
<PackageReference Include="Microsoft.CodeAnalysis.Common" PrivateAssets="all" VersionOverride="5.0.0" />
23+
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" PrivateAssets="all" VersionOverride="5.0.0" />
24+
<PackageReference Include="Microsoft.CodeAnalysis" PrivateAssets="all" VersionOverride="5.0.0" />
25+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" PrivateAssets="all" VersionOverride="5.0.0" />
26+
</ItemGroup>
27+
28+
<ItemGroup>
29+
<InternalsVisibleTo Include="ReactiveUI.CodeFixes" />
30+
</ItemGroup>
31+
32+
<ItemGroup>
33+
<Compile Include="..\ReactiveUI.SourceGenerators.Roslyn\**\*.cs" LinkBase="Shared" />
34+
</ItemGroup>
35+
36+
<ItemGroup>
37+
<AdditionalFiles Include="..\ReactiveUI.SourceGenerators.Roslyn\AnalyzerReleases.Shipped.md" />
38+
<AdditionalFiles Include="..\ReactiveUI.SourceGenerators.Roslyn\AnalyzerReleases.Unshipped.md" />
39+
</ItemGroup>
40+
41+
</Project>

src/ReactiveUI.SourceGenerators.sln

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Microsoft Visual Studio Solution File, Format Version 12.00
2-
# Visual Studio Version 17
3-
VisualStudioVersion = 17.10.35027.167
2+
# Visual Studio Version 18
3+
VisualStudioVersion = 18.1.11312.151 d18.0
44
MinimumVisualStudioVersion = 10.0.40219.1
55
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionConfig", "SolutionConfig", "{F29AF2F3-DEC8-58BC-043A-1447862C832D}"
66
ProjectSection(SolutionItems) = preProject
@@ -38,6 +38,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.SourceGenerators
3838
EndProject
3939
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.SourceGenerators.Roslyn4120", "ReactiveUI.SourceGenerators.Roslyn4120\ReactiveUI.SourceGenerators.Roslyn4120.csproj", "{BF121262-7F30-4EC0-9F03-324AC3B834B8}"
4040
EndProject
41+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.SourceGenerators.Roslyn5000", "ReactiveUI.SourceGenerators.Roslyn5000\ReactiveUI.SourceGenerators.Roslyn5000.csproj", "{93D7DF9A-791F-4DCF-ADBA-95BFAF3E98A7}"
42+
EndProject
4143
Global
4244
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4345
Debug|Any CPU = Debug|Any CPU
@@ -84,6 +86,10 @@ Global
8486
{BF121262-7F30-4EC0-9F03-324AC3B834B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
8587
{BF121262-7F30-4EC0-9F03-324AC3B834B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
8688
{BF121262-7F30-4EC0-9F03-324AC3B834B8}.Release|Any CPU.Build.0 = Release|Any CPU
89+
{93D7DF9A-791F-4DCF-ADBA-95BFAF3E98A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
90+
{93D7DF9A-791F-4DCF-ADBA-95BFAF3E98A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
91+
{93D7DF9A-791F-4DCF-ADBA-95BFAF3E98A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
92+
{93D7DF9A-791F-4DCF-ADBA-95BFAF3E98A7}.Release|Any CPU.Build.0 = Release|Any CPU
8793
EndGlobalSection
8894
GlobalSection(SolutionProperties) = preSolution
8995
HideSolutionNode = FALSE

src/ReactiveUI.SourceGenerators/ReactiveUI.SourceGenerators.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
<ItemGroup>
3131
<ProjectReference Include="..\ReactiveUI.SourceGenerators.Analyzers.CodeFixes\ReactiveUI.SourceGenerators.Analyzers.CodeFixes.csproj" />
32+
<ProjectReference Include="..\ReactiveUI.SourceGenerators.Roslyn5000\ReactiveUI.SourceGenerators.Roslyn5000.csproj" ReferenceOutputAssembly="false" />
3233
<ProjectReference Include="..\ReactiveUI.SourceGenerators.Roslyn4120\ReactiveUI.SourceGenerators.Roslyn4120.csproj" ReferenceOutputAssembly="false" />
3334
<ProjectReference Include="..\ReactiveUI.SourceGenerators.Roslyn480\ReactiveUI.SourceGenerators.Roslyn480.csproj" ReferenceOutputAssembly="false" />
3435
</ItemGroup>
@@ -37,5 +38,6 @@
3738
<ItemGroup>
3839
<None Include="..\ReactiveUI.SourceGenerators.Roslyn480\bin\$(Configuration)\netstandard2.0\ReactiveUI.SourceGenerators.dll" PackagePath="analyzers\dotnet\roslyn4.8\cs" Pack="true" Visible="false" />
3940
<None Include="..\ReactiveUI.SourceGenerators.Roslyn4120\\bin\$(Configuration)\netstandard2.0\ReactiveUI.SourceGenerators.dll" PackagePath="analyzers\dotnet\roslyn4.12\cs" Pack="true" Visible="false" />
41+
<None Include="..\ReactiveUI.SourceGenerators.Roslyn5000\\bin\$(Configuration)\netstandard2.0\ReactiveUI.SourceGenerators.dll" PackagePath="analyzers\dotnet\roslyn5.0\cs" Pack="true" Visible="false" />
4042
</ItemGroup>
4143
</Project>

0 commit comments

Comments
 (0)