@@ -86,104 +86,64 @@ public static string ToDisplayString(
8686 this IParameterSymbol symbol ,
8787 SymbolDisplayFormat displayFormat ,
8888 List < string > generatedInterfaceNames
89- )
90- {
91- var parameterDisplayString = symbol . ToDisplayString ( displayFormat ) ;
92-
93- var parameterTypeDisplayString = symbol . Type . ToDisplayString (
94- displayFormat ,
95- generatedInterfaceNames
96- ) ;
89+ ) => ToDisplayString ( ( ISymbol ) symbol , displayFormat , generatedInterfaceNames ) ;
9790
98- // Replace the type part of the parameter definition - we don't try to generate the whole parameter definition
99- // as it's quite complex - we leave that to Roslyn.
100- return ParameterTypeMatcher . Replace ( parameterDisplayString , parameterTypeDisplayString ) ;
101- }
102-
103- /// <summary>
104- /// Matches the type part of a parameter definition (Type name[ = defaultValue])
105- /// </summary>
106- private static readonly Regex ParameterTypeMatcher =
107- new ( @"[^\s=]+(?=\s\S+(\s?=\s?\S+)?$)" , RegexOptions . Compiled ) ;
108-
109- /// <summary>
110- /// Wraps <see cref="ITypeSymbol.ToDisplayString(Microsoft.CodeAnalysis.SymbolDisplayFormat?)" /> with custom resolution for generated types
111- /// </summary>
112- /// <returns></returns>
11391 public static string ToDisplayString (
11492 this ITypeSymbol symbol ,
11593 SymbolDisplayFormat displayFormat ,
11694 List < string > generatedInterfaceNames
117- )
118- {
119- var builder = new StringBuilder ( ) ;
120-
121- AppendTypeSymbolDisplayString ( symbol , displayFormat , generatedInterfaceNames , builder ) ;
95+ ) => ToDisplayString ( ( ISymbol ) symbol , displayFormat , generatedInterfaceNames ) ;
12296
123- return builder . ToString ( ) ;
124- }
125-
126- private static void AppendTypeSymbolDisplayString (
127- ITypeSymbol typeSymbol ,
97+ /// <summary>
98+ /// Wraps <see cref="ITypeSymbol.ToDisplayString(Microsoft.CodeAnalysis.SymbolDisplayFormat?)" /> with custom resolution for generated types
99+ /// </summary>
100+ private static string ToDisplayString (
101+ this ISymbol symbol ,
128102 SymbolDisplayFormat displayFormat ,
129- List < string > generatedInterfaceNames ,
130- StringBuilder builder
103+ List < string > generatedInterfaceNames
131104 )
132105 {
133- if ( typeSymbol is not IErrorTypeSymbol errorTypeSymbol )
134- {
135- // This symbol contains no unresolved types. Fall back to the default generation provided by Roslyn
136- builder . Append ( typeSymbol . ToDisplayString ( displayFormat ) ) ;
137- return ;
138- }
106+ var displayStringBuilder = new StringBuilder ( ) ;
139107
140- var symbolName =
141- InferGeneratedInterfaceName ( errorTypeSymbol , generatedInterfaceNames )
142- ?? errorTypeSymbol . Name ;
108+ var displayParts = symbol . ToDisplayParts ( displayFormat ) ;
143109
144- builder . Append ( symbolName ) ;
145-
146- if ( errorTypeSymbol . IsGenericType )
110+ foreach ( var part in displayParts )
147111 {
148- builder . Append ( '<' ) ;
149-
150- bool isFirstTypeArgument = true ;
151- foreach ( var typeArgument in errorTypeSymbol . TypeArguments )
112+ if ( part . Kind == SymbolDisplayPartKind . ErrorTypeName )
152113 {
153- if ( ! isFirstTypeArgument )
154- {
155- builder . Append ( ", " ) ;
156- }
157-
158- AppendTypeSymbolDisplayString (
159- typeArgument ,
160- displayFormat ,
161- generatedInterfaceNames ,
162- builder
114+ var unrecognisedName = part . ToString ( ) ;
115+
116+ var inferredName = ReplaceWithInferredInterfaceName (
117+ unrecognisedName ,
118+ generatedInterfaceNames
163119 ) ;
164120
165- isFirstTypeArgument = false ;
121+ displayStringBuilder . Append ( inferredName ) ;
122+ }
123+ else
124+ {
125+ displayStringBuilder . Append ( part . ToString ( ) ) ;
166126 }
167-
168- builder . Append ( '>' ) ;
169127 }
128+
129+ return displayStringBuilder . ToString ( ) ;
170130 }
171131
172- private static string ? InferGeneratedInterfaceName (
173- IErrorTypeSymbol unrecognisedSymbol ,
132+ private static string ReplaceWithInferredInterfaceName (
133+ string unrecognisedName ,
174134 List < string > generatedInterfaceNames
175135 )
176136 {
177137 var matches = generatedInterfaceNames
178- . Where ( name => Regex . IsMatch ( name , $ "[.:]{ unrecognisedSymbol . Name } $") )
138+ . Where ( name => Regex . IsMatch ( name , $ "[.:]{ unrecognisedName } $") )
179139 . ToList ( ) ;
180140
181141 if ( matches . Count != 1 )
182142 {
183143 // Either there's no match or an ambiguous match - we can't safely infer the interface name.
184144 // This is very much a "best effort" approach - if there are two interfaces with the same name,
185145 // there's no obvious way to work out which one the symbol is referring to.
186- return null ;
146+ return unrecognisedName ;
187147 }
188148
189149 return matches [ 0 ] ;
0 commit comments