@@ -4309,18 +4309,46 @@ private static bool TryGetDictionaryValueType(ITypeSymbol type, out ITypeSymbol
43094309 }
43104310
43114311 private static bool HasAttribute ( ISymbol symbol , string attributeMetadataName )
4312+ => TryGetAttribute ( symbol , attributeMetadataName , out _ ) ;
4313+
4314+ private static bool TryGetAttribute ( ISymbol symbol , string attributeMetadataName , out AttributeData attribute )
43124315 {
4313- foreach ( var attr in symbol . GetAttributes ( ) )
4316+ foreach ( var current in EnumerateSelfAndBaseSymbols ( symbol ) )
43144317 {
4315- if ( attr . AttributeClass ? . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) == "global::" + attributeMetadataName )
4318+ foreach ( var attr in current . GetAttributes ( ) )
43164319 {
4317- return true ;
4320+ if ( attr . AttributeClass ? . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) == "global::" + attributeMetadataName )
4321+ {
4322+ attribute = attr ;
4323+ return true ;
4324+ }
43184325 }
43194326 }
43204327
4328+ attribute = null ! ;
43214329 return false ;
43224330 }
43234331
4332+ private static IEnumerable < ISymbol > EnumerateSelfAndBaseSymbols ( ISymbol symbol )
4333+ {
4334+ for ( var current = symbol ; current is not null ; current = GetBaseSymbol ( current ) )
4335+ {
4336+ yield return current ;
4337+ }
4338+ }
4339+
4340+ private static ISymbol ? GetBaseSymbol ( ISymbol symbol )
4341+ {
4342+ return symbol switch
4343+ {
4344+ IPropertySymbol property => property . OverriddenProperty ,
4345+ IMethodSymbol method => method . OverriddenMethod ,
4346+ IEventSymbol @event => @event . OverriddenEvent ,
4347+ INamedTypeSymbol named => named . BaseType ,
4348+ _ => null ,
4349+ } ;
4350+ }
4351+
43244352 private static bool ImplementsInterface ( ITypeSymbol type , string interfaceMetadataName )
43254353 {
43264354 if ( type is not INamedTypeSymbol named )
@@ -4341,22 +4369,18 @@ private static bool ImplementsInterface(ITypeSymbol type, string interfaceMetada
43414369
43424370 private static string GetSerializedName ( ISymbol member , string memberName , string ? namingPolicyExpression )
43434371 {
4344- foreach ( var attr in member . GetAttributes ( ) )
4372+ if ( TryGetAttribute ( member , "Tomlyn.Serialization.TomlPropertyNameAttribute" , out var tomlAttr ) &&
4373+ tomlAttr . ConstructorArguments . Length == 1 &&
4374+ tomlAttr . ConstructorArguments [ 0 ] . Value is string tomlName )
43454375 {
4346- var attrName = attr . AttributeClass ? . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ;
4347- if ( attrName == "global::Tomlyn.Serialization.TomlPropertyNameAttribute" &&
4348- attr . ConstructorArguments . Length == 1 &&
4349- attr . ConstructorArguments [ 0 ] . Value is string tomlName )
4350- {
4351- return tomlName ;
4352- }
4376+ return tomlName ;
4377+ }
43534378
4354- if ( attrName == "global::System.Text.Json.Serialization.JsonPropertyNameAttribute" &&
4355- attr . ConstructorArguments . Length == 1 &&
4356- attr . ConstructorArguments [ 0 ] . Value is string jsonName )
4357- {
4358- return jsonName ;
4359- }
4379+ if ( TryGetAttribute ( member , "System.Text.Json.Serialization.JsonPropertyNameAttribute" , out var jsonAttr ) &&
4380+ jsonAttr . ConstructorArguments . Length == 1 &&
4381+ jsonAttr . ConstructorArguments [ 0 ] . Value is string jsonName )
4382+ {
4383+ return jsonName ;
43604384 }
43614385
43624386 if ( namingPolicyExpression is not null && TryConvertKnownName ( memberName , namingPolicyExpression , out var converted ) )
@@ -4369,13 +4393,8 @@ private static string GetSerializedName(ISymbol member, string memberName, strin
43694393
43704394 private static ObjectCreationHandlingKind GetObjectCreationHandling ( ISymbol symbol )
43714395 {
4372- foreach ( var attr in symbol . GetAttributes ( ) )
4396+ if ( TryGetAttribute ( symbol , JsonObjectCreationHandlingAttributeMetadataName , out var attr ) )
43734397 {
4374- if ( attr . AttributeClass ? . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) != "global::" + JsonObjectCreationHandlingAttributeMetadataName )
4375- {
4376- continue ;
4377- }
4378-
43794398 if ( attr . ConstructorArguments . Length == 1 && attr . ConstructorArguments [ 0 ] . Value is int constructorValue )
43804399 {
43814400 return constructorValue switch
@@ -4405,27 +4424,21 @@ private static ObjectCreationHandlingKind GetObjectCreationHandling(ISymbol symb
44054424
44064425 private static int GetOrder ( ISymbol member )
44074426 {
4408- int ? tomlOrder = null ;
4409- int ? jsonOrder = null ;
4427+ if ( TryGetAttribute ( member , "Tomlyn.Serialization.TomlPropertyOrderAttribute" , out var tomlAttr ) &&
4428+ tomlAttr . ConstructorArguments . Length == 1 &&
4429+ tomlAttr . ConstructorArguments [ 0 ] . Value is int tomlOrder )
4430+ {
4431+ return tomlOrder ;
4432+ }
44104433
4411- foreach ( var attr in member . GetAttributes ( ) )
4434+ if ( TryGetAttribute ( member , "System.Text.Json.Serialization.JsonPropertyOrderAttribute" , out var jsonAttr ) &&
4435+ jsonAttr . ConstructorArguments . Length == 1 &&
4436+ jsonAttr . ConstructorArguments [ 0 ] . Value is int jsonOrder )
44124437 {
4413- var attrName = attr . AttributeClass ? . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ;
4414- if ( attrName == "global::Tomlyn.Serialization.TomlPropertyOrderAttribute" &&
4415- attr . ConstructorArguments . Length == 1 &&
4416- attr . ConstructorArguments [ 0 ] . Value is int toml )
4417- {
4418- tomlOrder = toml ;
4419- }
4420- else if ( attrName == "global::System.Text.Json.Serialization.JsonPropertyOrderAttribute" &&
4421- attr . ConstructorArguments . Length == 1 &&
4422- attr . ConstructorArguments [ 0 ] . Value is int json )
4423- {
4424- jsonOrder = json ;
4425- }
4438+ return jsonOrder ;
44264439 }
44274440
4428- return tomlOrder ?? jsonOrder ?? 0 ;
4441+ return 0 ;
44294442 }
44304443
44314444 private static bool TryConvertKnownName ( string name , string namingPolicyExpression , out string converted )
@@ -4452,36 +4465,21 @@ private static bool TryConvertKnownName(string name, string namingPolicyExpressi
44524465
44534466 private static IgnoreBehavior GetIgnoreBehavior ( ISymbol symbol )
44544467 {
4455- TomlIgnoreAttributeModel ? toml = null ;
4456- JsonIgnoreAttributeModel ? json = null ;
4457-
4458- foreach ( var attr in symbol . GetAttributes ( ) )
4459- {
4460- var attrName = attr . AttributeClass ? . ToDisplayString ( SymbolDisplayFormat . FullyQualifiedFormat ) ;
4461- if ( attrName == "global::Tomlyn.Serialization.TomlIgnoreAttribute" )
4462- {
4463- toml = TomlIgnoreAttributeModel . From ( attr ) ;
4464- }
4465- else if ( attrName == "global::System.Text.Json.Serialization.JsonIgnoreAttribute" )
4466- {
4467- json = JsonIgnoreAttributeModel . From ( attr ) ;
4468- }
4469- }
4470-
4471- if ( toml is not null )
4468+ if ( TryGetAttribute ( symbol , "Tomlyn.Serialization.TomlIgnoreAttribute" , out var tomlAttr ) )
44724469 {
4470+ var toml = TomlIgnoreAttributeModel . From ( tomlAttr ) ;
44734471 // Interpret [TomlIgnore] with default Condition as "ignore always".
4474- return toml . Value . Condition switch
4472+ return toml . Condition switch
44754473 {
44764474 1 => new IgnoreBehavior ( ignoreAlways : false , writeIgnore : WriteIgnoreKind . WhenWritingNull ) ,
44774475 2 => new IgnoreBehavior ( ignoreAlways : false , writeIgnore : WriteIgnoreKind . WhenWritingDefault ) ,
44784476 _ => new IgnoreBehavior ( ignoreAlways : true , writeIgnore : WriteIgnoreKind . None ) ,
44794477 } ;
44804478 }
44814479
4482- if ( json is not null )
4480+ if ( TryGetAttribute ( symbol , "System.Text.Json.Serialization.JsonIgnoreAttribute" , out var jsonAttr ) )
44834481 {
4484- var condition = json . Value . Condition ?? JsonIgnoreCondition . Always ;
4482+ var condition = JsonIgnoreAttributeModel . From ( jsonAttr ) . Condition ?? JsonIgnoreCondition . Always ;
44854483 return condition switch
44864484 {
44874485 JsonIgnoreCondition . Never => new IgnoreBehavior ( ignoreAlways : false , writeIgnore : WriteIgnoreKind . None ) ,
0 commit comments