Skip to content

Commit 6f60f65

Browse files
committed
fix: try fixing analyser flagging incorrectly cross assembly
1 parent 491e171 commit 6f60f65

2 files changed

Lines changed: 35 additions & 15 deletions

File tree

Generator.Equals/Analyzers/EquatableAnalyzer.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ private static void AnalyzeMemberInEquatableType(
177177
return;
178178

179179
// GE002: Complex type without [Equatable]
180-
if (memberType.IsComplexType() && !HasEquatableAttribute(memberType))
180+
if (memberType.IsComplexType() && !memberType.HasEquatableAttribute())
181181
{
182182
var location = GetMemberTypeLocation(member) ?? member.Locations.FirstOrDefault() ?? Location.None;
183183
context.ReportDiagnostic(Diagnostic.Create(
@@ -191,7 +191,7 @@ private static void AnalyzeMemberInEquatableType(
191191
if (memberType.IsCollection())
192192
{
193193
var elementType = memberType.GetCollectionElementType();
194-
if (elementType != null && elementType.IsComplexType() && !HasEquatableAttribute(elementType))
194+
if (elementType != null && elementType.IsComplexType() && !elementType.HasEquatableAttribute())
195195
{
196196
var location = GetMemberTypeLocation(member) ?? member.Locations.FirstOrDefault() ?? Location.None;
197197
context.ReportDiagnostic(Diagnostic.Create(
@@ -458,11 +458,4 @@ private static bool GetExplicitMode(AttributeData? equatableAttr)
458458
return false;
459459
}
460460

461-
private static bool HasEquatableAttribute(ITypeSymbol typeSymbol)
462-
{
463-
if (typeSymbol is not INamedTypeSymbol namedType)
464-
return false;
465-
466-
return namedType.HasAttribute(Metadata.Equatable);
467-
}
468461
}

Generator.Equals/Extensions/TypeSymbolExtensions.cs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public static bool IsComplexType(this ITypeSymbol typeSymbol)
8080
return false;
8181

8282
// Not complex if it has [Equatable] attribute (including from other assemblies)
83-
if (typeSymbol is INamedTypeSymbol namedTypeSymbol && HasEquatableAttribute(namedTypeSymbol))
83+
if (typeSymbol.HasEquatableAttribute())
8484
return false;
8585

8686
// Records and structs with only value-equatable members are not complex
@@ -180,7 +180,7 @@ private static bool IsDeepValueEquatable(ITypeSymbol typeSymbol, HashSet<ITypeSy
180180
return true;
181181

182182
// Types with [Equatable] are value-equatable (works across assemblies)
183-
if (typeSymbol is INamedTypeSymbol namedType && HasEquatableAttribute(namedType))
183+
if (typeSymbol.HasEquatableAttribute())
184184
return true;
185185

186186
// Records and structs - recursively check their members
@@ -212,11 +212,38 @@ private static bool IsPrimitiveType(ITypeSymbol typeSymbol)
212212
/// <summary>
213213
/// Checks if a type has the [Equatable] attribute (works across assemblies).
214214
/// </summary>
215-
private static bool HasEquatableAttribute(INamedTypeSymbol typeSymbol)
215+
public static bool HasEquatableAttribute(this ITypeSymbol typeSymbol)
216216
{
217-
return typeSymbol.GetAttributes().Any(a =>
218-
a.AttributeClass?.Name is "EquatableAttribute" or "Equatable" &&
219-
a.AttributeClass.ContainingNamespace?.ToDisplayString() == "Generator.Equals");
217+
if (typeSymbol is not INamedTypeSymbol namedType)
218+
return false;
219+
220+
foreach (var attribute in namedType.GetAttributes())
221+
{
222+
var attrClass = attribute.AttributeClass;
223+
if (attrClass == null)
224+
continue;
225+
226+
// Check by name - attribute class is typically "EquatableAttribute"
227+
if (attrClass.Name is not ("EquatableAttribute" or "Equatable"))
228+
continue;
229+
230+
// Check namespace - could be via ToDisplayString or by walking the namespace chain
231+
var ns = attrClass.ContainingNamespace;
232+
if (ns == null || ns.IsGlobalNamespace)
233+
continue;
234+
235+
// Check the full namespace path
236+
var nsName = ns.ToDisplayString();
237+
if (nsName == "Generator.Equals")
238+
return true;
239+
240+
// Also try the fully qualified format in case ToDisplayString differs
241+
var fullName = attrClass.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
242+
if (fullName is "global::Generator.Equals.EquatableAttribute" or "global::Generator.Equals.Equatable")
243+
return true;
244+
}
245+
246+
return false;
220247
}
221248

222249
private static bool IsWellKnownSystemType(ITypeSymbol typeSymbol)

0 commit comments

Comments
 (0)