Skip to content

Commit 3f6cabb

Browse files
committed
Refactor generated-code checks and helper
Improve detection of generated ICustomPropertyProvider implementations and simplify attribute handling. Make GeneratedCodeAttribute resolution non-nullable and add HasNonGeneratedImplementedMembers helper to centralize logic for checking implemented interface members that were not emitted by this generator. Simplify attribute checks in ISymbolExtensions by using TryGetAttributeWithType and validating the constructor argument, and replace manual loop with LINQ.Any in ITypeSymbolExtensions (added System.Linq). Removes duplicate/nullable checks and streamlines the analyzer to avoid false diagnostics for generator-emitted members.
1 parent a5bf97e commit 3f6cabb

3 files changed

Lines changed: 23 additions & 34 deletions

File tree

src/Authoring/WinRT.SourceGenerator2/Diagnostics/Analyzers/GeneratedCustomPropertyProviderExistingMemberImplementationAnalyzer.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public override void Initialize(AnalysisContext context)
4343
}
4444

4545
// Resolve the '[GeneratedCode]' attribute type, used to skip generated implementations
46-
INamedTypeSymbol? generatedCodeAttributeType = context.Compilation.GetTypeByMetadataName("System.CodeDom.Compiler.GeneratedCodeAttribute");
46+
INamedTypeSymbol generatedCodeAttributeType = context.Compilation.GetTypeByMetadataName("System.CodeDom.Compiler.GeneratedCodeAttribute")!;
4747

4848
context.RegisterSymbolAction(context =>
4949
{
@@ -59,8 +59,20 @@ public override void Initialize(AnalysisContext context)
5959
return;
6060
}
6161

62+
// Helper to check whether a symbol has any generated interface members that are not emitted by this generator. his covers
63+
// both manually implemented members and those produced by other generators, and explicitly interface implementations too.
64+
static bool HasNonGeneratedImplementedMembers(
65+
INamedTypeSymbol typeSymbol,
66+
INamedTypeSymbol? interfaceType,
67+
INamedTypeSymbol generatedCodeAttributeType)
68+
{
69+
return
70+
interfaceType is not null &&
71+
!typeSymbol.EnumerateImplementedMembersForInterface(interfaceType).AreAllImplementedByGenerator(generatedCodeAttributeType, nameof(CustomPropertyProviderGenerator));
72+
}
73+
6274
// Check whether the type has or inherits any 'ICustomPropertyProvider' member implementations.
63-
// We don't warn if all implementations are generated by CustomPropertyProviderGenerator itself,
75+
// We don't warn if all implementations are generated by 'CustomPropertyProviderGenerator' itself,
6476
// so that only user-authored implementations trigger this diagnostic.
6577
if (HasNonGeneratedImplementedMembers(typeSymbol, windowsUIXamlCustomPropertyProviderType, generatedCodeAttributeType) ||
6678
HasNonGeneratedImplementedMembers(typeSymbol, microsoftUIXamlCustomPropertyProviderType, generatedCodeAttributeType))
@@ -70,16 +82,6 @@ public override void Initialize(AnalysisContext context)
7082
typeSymbol.Locations.FirstOrDefault(),
7183
typeSymbol));
7284
}
73-
74-
static bool HasNonGeneratedImplementedMembers(
75-
INamedTypeSymbol typeSymbol,
76-
INamedTypeSymbol? interfaceType,
77-
INamedTypeSymbol? generatedCodeAttributeType)
78-
{
79-
return interfaceType is not null && (generatedCodeAttributeType is not null
80-
? !typeSymbol.EnumerateImplementedMembersForInterface(interfaceType).AreAllImplementedByGenerator(generatedCodeAttributeType, nameof(CustomPropertyProviderGenerator))
81-
: typeSymbol.HasAnyImplementedMembersForInterface(interfaceType));
82-
}
8385
}, SymbolKind.NamedType);
8486
});
8587
}

src/Authoring/WinRT.SourceGenerator2/Extensions/ISymbolExtensions.cs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,29 +92,20 @@ public bool AreAllImplementedByGenerator(INamedTypeSymbol generatedCodeAttribute
9292
{
9393
foreach (ISymbol symbol in symbols)
9494
{
95-
if (!HasGeneratedCodeAttributeWithName(symbol, generatedCodeAttributeType, generatorName))
95+
// Stop if the symbol doesn't have '[GeneratedCode]' on it
96+
if (!symbol.TryGetAttributeWithType(generatedCodeAttributeType, out AttributeData? attributeData))
9697
{
9798
return false;
9899
}
99-
}
100-
101-
return true;
102100

103-
// Checks whether a symbol has a [GeneratedCode] attribute with the specified generator name.
104-
static bool HasGeneratedCodeAttributeWithName(ISymbol symbol, INamedTypeSymbol generatedCodeAttributeType, string generatorName)
105-
{
106-
foreach (AttributeData attribute in symbol.GetAttributes())
101+
// Check that the symbol was specifically generated by the target generator
102+
if (attributeData.ConstructorArguments is not [{ Value: string name }, ..] || name != generatorName)
107103
{
108-
if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, generatedCodeAttributeType) &&
109-
attribute.ConstructorArguments is [{ Value: string name }, ..] &&
110-
name == generatorName)
111-
{
112-
return true;
113-
}
104+
return false;
114105
}
115-
116-
return false;
117106
}
107+
108+
return true;
118109
}
119110
}
120111
}

src/Authoring/WinRT.SourceGenerator2/Extensions/ITypeSymbolExtensions.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Linq;
67
using Microsoft.CodeAnalysis;
78

89
#pragma warning disable CS1734, IDE0046
@@ -85,12 +86,7 @@ public IEnumerable<ISymbol> EnumerateImplementedMembersForInterface(INamedTypeSy
8586
/// <returns>Whether <paramref name="symbol"/> has any implemented members for <paramref name="interfaceType"/>.</returns>
8687
public bool HasAnyImplementedMembersForInterface(INamedTypeSymbol interfaceType)
8788
{
88-
foreach (ISymbol _ in symbol.EnumerateImplementedMembersForInterface(interfaceType))
89-
{
90-
return true;
91-
}
92-
93-
return false;
89+
return symbol.EnumerateImplementedMembersForInterface(interfaceType).Any();
9490
}
9591

9692
/// <summary>

0 commit comments

Comments
 (0)