@@ -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