@@ -17,43 +17,29 @@ internal static class SymbolNameHelpers
1717 private const string GenericTypeParametersClose = ">" ;
1818 private const string GenericSeparator = ", " ;
1919
20+ private const string TupleTypeOpen = "(" ;
21+ private const string TupleTypeClose = ")" ;
22+ private const string TupleElementSeparator = ", " ;
23+
2024 /// <summary>
2125 /// Generates the qualified name for the given symbol.
2226 /// </summary>
2327 /// <param name="symbol">The symbol to use.</param>
28+ /// <param name="name">The syntax node which resolves to the symbol.</param>
2429 /// <returns>The generated qualified name.</returns>
25- public static string ToQualifiedString ( this ISymbol symbol )
30+ public static string ToQualifiedString ( this ISymbol symbol , NameSyntax name )
2631 {
2732 var builder = ObjectPools . StringBuilderPool . Allocate ( ) ;
28-
29- if ( symbol is INamedTypeSymbol namedTypeSymbol )
30- {
31- if ( SpecialTypeHelper . TryGetPredefinedType ( namedTypeSymbol . SpecialType , out PredefinedTypeSyntax specialTypeSyntax ) )
32- {
33- return specialTypeSyntax . ToFullString ( ) ;
34- }
35-
36- if ( namedTypeSymbol . IsTupleType ( ) )
37- {
38- namedTypeSymbol = namedTypeSymbol . TupleUnderlyingType ( ) ;
39- }
40-
41- AppendQualifiedSymbolName ( builder , namedTypeSymbol ) ;
42- }
43- else
44- {
45- AppendQualifiedSymbolName ( builder , symbol ) ;
46- }
47-
33+ AppendQualifiedSymbolName ( builder , symbol , name ) ;
4834 return ObjectPools . StringBuilderPool . ReturnAndFree ( builder ) ;
4935 }
5036
51- private static bool AppendQualifiedSymbolName ( StringBuilder builder , ISymbol symbol )
37+ private static bool AppendQualifiedSymbolName ( StringBuilder builder , ISymbol symbol , TypeSyntax type )
5238 {
5339 switch ( symbol )
5440 {
5541 case IArrayTypeSymbol arraySymbol :
56- AppendQualifiedSymbolName ( builder , arraySymbol . ElementType ) ;
42+ AppendQualifiedSymbolName ( builder , arraySymbol . ElementType , ( type as ArrayTypeSyntax ) ? . ElementType ) ;
5743 builder
5844 . Append ( "[" )
5945 . Append ( ',' , arraySymbol . Rank - 1 )
@@ -70,36 +56,79 @@ private static bool AppendQualifiedSymbolName(StringBuilder builder, ISymbol sym
7056 return true ;
7157
7258 case INamedTypeSymbol namedTypeSymbol :
73- if ( AppendQualifiedSymbolName ( builder , symbol . ContainingSymbol ) )
59+ if ( SpecialTypeHelper . TryGetPredefinedType ( namedTypeSymbol . SpecialType , out var specialTypeSyntax ) )
7460 {
75- builder . Append ( "." ) ;
61+ builder . Append ( specialTypeSyntax . ToFullString ( ) ) ;
62+ return true ;
7663 }
77-
78- builder . Append ( symbol . Name ) ;
79- if ( namedTypeSymbol . IsGenericType && ! namedTypeSymbol . TypeArguments . IsEmpty )
64+ else if ( namedTypeSymbol . IsTupleType ( ) )
8065 {
81- builder . Append ( GenericTypeParametersOpen ) ;
82-
83- foreach ( var typeArgument in namedTypeSymbol . TypeArguments )
66+ if ( TupleTypeSyntaxWrapper . IsInstance ( type ) )
8467 {
85- if ( typeArgument is INamedTypeSymbol namedTypeArgument && typeArgument . IsTupleType ( ) )
68+ var tupleType = ( TupleTypeSyntaxWrapper ) type ;
69+
70+ builder . Append ( TupleTypeOpen ) ;
71+ var elements = namedTypeSymbol . TupleElements ( ) ;
72+ for ( int i = 0 ; i < elements . Length ; i ++ )
8673 {
87- builder . Append ( namedTypeArgument . TupleUnderlyingType ( ) . ToQualifiedString ( ) ) ;
74+ var field = elements [ i ] ;
75+ var fieldType = tupleType . Elements . Count > i ? tupleType . Elements [ i ] : default ;
76+
77+ if ( i > 0 )
78+ {
79+ builder . Append ( TupleElementSeparator ) ;
80+ }
81+
82+ AppendQualifiedSymbolName ( builder , field . Type , fieldType . Type ) ;
83+ if ( field != field . CorrespondingTupleField ( ) )
84+ {
85+ builder . Append ( " " ) . Append ( field . Name ) ;
86+ }
8887 }
89- else
88+
89+ builder . Append ( TupleTypeClose ) ;
90+ return true ;
91+ }
92+ else
93+ {
94+ return AppendQualifiedSymbolName ( builder , namedTypeSymbol . TupleUnderlyingType ( ) , type ) ;
95+ }
96+ }
97+ else
98+ {
99+ if ( AppendQualifiedSymbolName ( builder , symbol . ContainingSymbol , ( type as QualifiedNameSyntax ) ? . Left ) )
100+ {
101+ builder . Append ( "." ) ;
102+ }
103+
104+ builder . Append ( symbol . Name ) ;
105+ if ( namedTypeSymbol . IsGenericType && ! namedTypeSymbol . TypeArguments . IsEmpty )
106+ {
107+ builder . Append ( GenericTypeParametersOpen ) ;
108+ var arguments = namedTypeSymbol . TypeArguments ;
109+ var argumentTypes = type is QualifiedNameSyntax qualifiedName
110+ ? ( qualifiedName . Right as GenericNameSyntax ) ? . TypeArgumentList
111+ : ( type as GenericNameSyntax ) ? . TypeArgumentList ;
112+
113+ for ( int i = 0 ; i < arguments . Length ; i ++ )
90114 {
91- builder . Append ( typeArgument . ToQualifiedString ( ) ) ;
115+ var argument = arguments [ i ] ;
116+ var argumentType = argumentTypes . Arguments . Count > i ? argumentTypes . Arguments [ i ] : null ;
117+
118+ if ( i > 0 )
119+ {
120+ builder . Append ( GenericSeparator ) ;
121+ }
122+
123+ AppendQualifiedSymbolName ( builder , argument , argumentType ) ;
92124 }
93125
94- builder . Append ( GenericSeparator ) ;
126+ builder . Append ( GenericTypeParametersClose ) ;
95127 }
96128
97- builder . Remove ( builder . Length - GenericSeparator . Length , GenericSeparator . Length ) ;
98- builder . Append ( GenericTypeParametersClose ) ;
129+ return true ;
99130 }
100131
101- return true ;
102-
103132 default :
104133 builder . Append ( symbol . Name ) ;
105134 return true ;
0 commit comments