Skip to content

Commit 25933c5

Browse files
Merge branch 'main' into user/arcadiog/clearReferenceInfo
2 parents a7a9a71 + 5dfc575 commit 25933c5

File tree

184 files changed

+8781
-1931
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+8781
-1931
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ What kind of change does this PR introduce?
3838
Please check if your PR fulfills the following requirements: <!-- and remove the ones that are not applicable to the current PR -->
3939

4040
- [ ] Tested code with current [supported SDKs](../#supported)
41-
- [ ] Pull Request has been submitted to the documentation repository [instructions](../blob/main/Contributing.md#docs). Link: <!-- docs PR link -->
41+
- [ ] New component
42+
- [ ] Pull Request has been submitted to the documentation repository [instructions](../blob/main/Contributing.md#docs). Link: <!-- docs PR link -->
43+
- [ ] Added description of major feature to project description for NuGet package (4000 total character limit, so don't push entire description over that)
44+
- [ ] If control, added to Visual Studio Design project
4245
- [ ] Sample in sample app has been added / updated (for bug fixes / features)
4346
- [ ] Icon has been created (if new sample) following the [Thumbnail Style Guide and templates](https://github.com/CommunityToolkit/WindowsCommunityToolkit-design-assets)
4447
- [ ] New major technical changes in the toolkit have or will be added to the [Wiki](https://github.com/CommunityToolkit/WindowsCommunityToolkit/wiki) e.g. build changes, source generators, testing infrastructure, sample creation changes, etc...
@@ -51,4 +54,4 @@ Please note that breaking changes are likely to be rejected within minor release
5154

5255
## Other information
5356

54-
<!-- Please add any other information that might be helpful to reviewers. -->
57+
<!-- Please add any other information that might be helpful to reviewers. -->

Microsoft.Toolkit.Mvvm.SourceGenerators/AnalyzerReleases.Unshipped.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ MVVMTK0009 | Microsoft.Toolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator
1717
MVVMTK0010 | Microsoft.Toolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/error
1818
MVVMTK0011 | Microsoft.Toolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/error
1919
MVVMTK0012 | Microsoft.Toolkit.Mvvm.SourceGenerators.ICommandGenerator | Error | See https://aka.ms/mvvmtoolkit/error
20+
MVVMTK0013 | Microsoft.CodeAnalysis.CSharp.CSharpParseOptions | Error | See https://aka.ms/mvvmtoolkit/error

Microsoft.Toolkit.Mvvm.SourceGenerators/Attributes/NullabilityAttributesGenerator.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ public void Execute(GeneratorExecutionContext context)
3434
/// </summary>
3535
private void AddSourceCodeIfTypeIsNotPresent(GeneratorExecutionContext context, string typeFullName)
3636
{
37-
if (context.Compilation.GetTypeByMetadataName(typeFullName) is not null)
37+
// Check that the target attributes are not available in the consuming project. To ensure that
38+
// this works fine both in .NET (Core) and .NET Standard implementations, we also need to check
39+
// that the target types are declared as public (we assume that in this case those types are from the BCL).
40+
// This avoids issues on .NET Standard with Roslyn also seeing internal types from referenced assemblies.
41+
if (context.Compilation.GetTypeByMetadataName(typeFullName) is { DeclaredAccessibility: Accessibility.Public })
3842
{
3943
return;
4044
}

Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ public void Execute(GeneratorExecutionContext context)
4141
return;
4242
}
4343

44+
// Validate the language version. Note that we're emitting this diagnostic in each generator (excluding the one
45+
// only emitting the nullability annotation attributes if missing) so that the diagnostic is emitted only when
46+
// users are using one of these generators, and not by default as soon as they add a reference to the MVVM Toolkit.
47+
// This ensures that users not using any of the source generators won't be broken when upgrading to this new version.
48+
if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 })
49+
{
50+
context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null));
51+
}
52+
4453
// Sets of discovered property names
4554
HashSet<string>
4655
propertyChangedNames = new(),
@@ -240,6 +249,14 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
240249
}
241250
}
242251

252+
// In case the backing field is exactly named "value", we need to add the "this." prefix to ensure that comparisons and assignments
253+
// with it in the generated setter body are executed correctly and without conflicts with the implicit value parameter.
254+
ExpressionSyntax fieldExpression = fieldSymbol.Name switch
255+
{
256+
"value" => MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName("value")),
257+
string name => IdentifierName(name)
258+
};
259+
243260
BlockSyntax setterBlock;
244261

245262
if (validationAttributes.Count > 0)
@@ -263,10 +280,10 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
263280

264281
// Generate the inner setter block as follows:
265282
//
266-
// if (!global::System.Collections.Generic.EqualityComparer<<FIELD_TYPE>>.Default.Equals(<FIELD_NAME>, value))
283+
// if (!global::System.Collections.Generic.EqualityComparer<<FIELD_TYPE>>.Default.Equals(this.<FIELD_NAME>, value))
267284
// {
268285
// OnPropertyChanging(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.PropertyNamePropertyChangingEventArgs); // Optional
269-
// <FIELD_NAME> = value;
286+
// this.<FIELD_NAME> = value;
270287
// OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.PropertyNamePropertyChangedEventArgs);
271288
// ValidateProperty(value, <PROPERTY_NAME>);
272289
// OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.Property1PropertyChangedEventArgs); // Optional
@@ -291,7 +308,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
291308
IdentifierName("Default")),
292309
IdentifierName("Equals")))
293310
.AddArgumentListArguments(
294-
Argument(IdentifierName(fieldSymbol.Name)),
311+
Argument(fieldExpression),
295312
Argument(IdentifierName("value")))),
296313
Block(
297314
ExpressionStatement(
@@ -303,7 +320,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
303320
ExpressionStatement(
304321
AssignmentExpression(
305322
SyntaxKind.SimpleAssignmentExpression,
306-
IdentifierName(fieldSymbol.Name),
323+
fieldExpression,
307324
IdentifierName("value"))),
308325
ExpressionStatement(
309326
InvocationExpression(IdentifierName("OnPropertyChanged"))
@@ -346,7 +363,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
346363
ExpressionStatement(
347364
AssignmentExpression(
348365
SyntaxKind.SimpleAssignmentExpression,
349-
IdentifierName(fieldSymbol.Name),
366+
fieldExpression,
350367
IdentifierName("value"))),
351368
ExpressionStatement(
352369
InvocationExpression(IdentifierName("OnPropertyChanged"))
@@ -384,7 +401,7 @@ private static PropertyDeclarationSyntax CreatePropertyDeclaration(
384401
IdentifierName("Default")),
385402
IdentifierName("Equals")))
386403
.AddArgumentListArguments(
387-
Argument(IdentifierName(fieldSymbol.Name)),
404+
Argument(fieldExpression),
388405
Argument(IdentifierName("value")))),
389406
updateAndNotificationBlock));
390407
}

Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using Microsoft.CodeAnalysis.Text;
1515
using Microsoft.Toolkit.Mvvm.SourceGenerators.Extensions;
1616
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
17+
using static Microsoft.Toolkit.Mvvm.SourceGenerators.Diagnostics.DiagnosticDescriptors;
1718

1819
namespace Microsoft.Toolkit.Mvvm.SourceGenerators
1920
{
@@ -39,6 +40,12 @@ public void Execute(GeneratorExecutionContext context)
3940
return;
4041
}
4142

43+
// Validate the language version
44+
if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 })
45+
{
46+
context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null));
47+
}
48+
4249
// Get the symbol for the ValidationAttribute type
4350
INamedTypeSymbol validationSymbol = context.Compilation.GetTypeByMetadataName("System.ComponentModel.DataAnnotations.ValidationAttribute")!;
4451

Microsoft.Toolkit.Mvvm.SourceGenerators/ComponentModel/TransitiveMembersGenerator.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using Microsoft.Toolkit.Mvvm.SourceGenerators.Extensions;
1919
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
2020
using static Microsoft.CodeAnalysis.SymbolDisplayTypeQualificationStyle;
21+
using static Microsoft.Toolkit.Mvvm.SourceGenerators.Diagnostics.DiagnosticDescriptors;
2122

2223
namespace Microsoft.Toolkit.Mvvm.SourceGenerators
2324
{
@@ -67,6 +68,12 @@ public void Execute(GeneratorExecutionContext context)
6768
return;
6869
}
6970

71+
// Validate the language version
72+
if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 })
73+
{
74+
context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null));
75+
}
76+
7077
// Load the syntax tree with the members to generate
7178
SyntaxTree sourceSyntaxTree = LoadSourceSyntaxTree();
7279

Microsoft.Toolkit.Mvvm.SourceGenerators/Diagnostics/DiagnosticDescriptors.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System.ComponentModel;
66
using Microsoft.CodeAnalysis;
7+
using Microsoft.CodeAnalysis.CSharp;
78

89
namespace Microsoft.Toolkit.Mvvm.SourceGenerators.Diagnostics
910
{
@@ -201,7 +202,23 @@ internal static class DiagnosticDescriptors
201202
category: typeof(ICommandGenerator).FullName,
202203
defaultSeverity: DiagnosticSeverity.Error,
203204
isEnabledByDefault: true,
204-
description: $"Cannot apply [ICommand] to methods with a signature that doesn't match any of the existing relay command types.",
205+
description: "Cannot apply [ICommand] to methods with a signature that doesn't match any of the existing relay command types.",
206+
helpLinkUri: "https://aka.ms/mvvmtoolkit");
207+
208+
/// <summary>
209+
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when an unsupported C# language version is being used.
210+
/// <para>
211+
/// Format: <c>"The method {0}.{1} cannot be used to generate a command property, as its signature isn't compatible with any of the existing relay command types"</c>.
212+
/// </para>
213+
/// </summary>
214+
public static readonly DiagnosticDescriptor UnsupportedCSharpLanguageVersionError = new(
215+
id: "MVVMTK0013",
216+
title: "Unsupported C# language version",
217+
messageFormat: "The source generator features from the MVVM Toolkit require consuming projects to set the C# language version to at least C# 9.0",
218+
category: typeof(CSharpParseOptions).FullName,
219+
defaultSeverity: DiagnosticSeverity.Error,
220+
isEnabledByDefault: true,
221+
description: "The source generator features from the MVVM Toolkit require consuming projects to set the C# language version to at least C# 9.0. Make sure to add <LangVersion>9.0</LangVersion> (or above) to your .csproj file.",
205222
helpLinkUri: "https://aka.ms/mvvmtoolkit");
206223
}
207224
}

Microsoft.Toolkit.Mvvm.SourceGenerators/Input/ICommandGenerator.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ public void Execute(GeneratorExecutionContext context)
4343
return;
4444
}
4545

46+
// Validate the language version
47+
if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 })
48+
{
49+
context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null));
50+
}
51+
4652
foreach (var items in syntaxReceiver.GatheredInfo.GroupBy<SyntaxReceiver.Item, INamedTypeSymbol>(static item => item.MethodSymbol.ContainingType, SymbolEqualityComparer.Default))
4753
{
4854
if (items.Key.DeclaringSyntaxReferences.Length > 0 &&

Microsoft.Toolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Microsoft.CodeAnalysis.Text;
1414
using Microsoft.Toolkit.Mvvm.SourceGenerators.Extensions;
1515
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
16+
using static Microsoft.Toolkit.Mvvm.SourceGenerators.Diagnostics.DiagnosticDescriptors;
1617

1718
namespace Microsoft.Toolkit.Mvvm.SourceGenerators
1819
{
@@ -38,6 +39,12 @@ public void Execute(GeneratorExecutionContext context)
3839
return;
3940
}
4041

42+
// Validate the language version
43+
if (context.ParseOptions is not CSharpParseOptions { LanguageVersion: >= LanguageVersion.CSharp9 })
44+
{
45+
context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, null));
46+
}
47+
4148
// Get the symbol for the IRecipient<T> interface type
4249
INamedTypeSymbol iRecipientSymbol = context.Compilation.GetTypeByMetadataName("Microsoft.Toolkit.Mvvm.Messaging.IRecipient`1")!;
4350

Microsoft.Toolkit.Uwp.DeveloperTools/VisualStudioToolsManifest.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<FileList>
22
<File Reference="Microsoft.Toolkit.Uwp.DeveloperTools.dll">
3-
<ToolboxItems VSCategory="Windows Community Toolkit" BlendCategory="Windows Community Toolkit">
3+
<ToolboxItems UIFramework="UAP"
4+
VSCategory="Windows Community Toolkit"
5+
BlendCategory="Windows Community Toolkit">
46
<Item Type="Microsoft.Toolkit.Uwp.DeveloperTools.AlignmentGrid" />
57
<Item Type="Microsoft.Toolkit.Uwp.DeveloperTools.FocusTracker" />
68
</ToolboxItems>

0 commit comments

Comments
 (0)