11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4- using System . Text . RegularExpressions ;
4+ using System . Text ;
55using Microsoft . CodeAnalysis ;
66using Microsoft . CodeAnalysis . CSharp ;
77using Microsoft . CodeAnalysis . CSharp . Syntax ;
@@ -10,9 +10,6 @@ namespace AutomaticInterface;
1010
1111public static class Builder
1212{
13- private static Regex ParamWithDefaultValueRegex { get ; } =
14- new ( pattern : @"^(?<type>\S+)(?<rest>\s+\S+\s+=.+)$" , options : RegexOptions . Compiled ) ;
15-
1613 private static string InheritDoc ( ISymbol source ) =>
1714 $ "/// <inheritdoc cref=\" { source . ToDisplayString ( ) . Replace ( '<' , '{' ) . Replace ( '>' , '}' ) } \" />"; // we use inherit doc because that should be able to fetch documentation from base classes.
1815
@@ -159,19 +156,7 @@ private static void AddMethod(InterfaceBuilder codeGenerator, IMethodSymbol meth
159156
160157 var paramResult = new HashSet < string > ( ) ;
161158 method
162- . Parameters . Select ( x =>
163- {
164- var dispString = x . ToDisplayString ( FullyQualifiedDisplayFormat ) ;
165- if ( x . HasExplicitDefaultValue && x . ExplicitDefaultValue is null && x . NullableAnnotation != NullableAnnotation . Annotated )
166- {
167- var match = ParamWithDefaultValueRegex . Match ( dispString ) ;
168- if ( match . Success )
169- {
170- dispString = $ "{ match . Groups [ "type" ] . Value } ?{ match . Groups [ "rest" ] . Value } ";
171- }
172- }
173- return dispString ;
174- } )
159+ . Parameters . Select ( GetParameterDisplayString )
175160 . ToList ( )
176161 . ForEach ( x => paramResult . Add ( x ) ) ;
177162
@@ -242,6 +227,35 @@ private static bool IsNullable(ITypeSymbol typeSymbol)
242227 return false ;
243228 }
244229
230+ private static string GetParameterDisplayString ( IParameterSymbol param )
231+ {
232+ var paramParts = param . ToDisplayParts ( FullyQualifiedDisplayFormat ) ;
233+ var typeSb = new StringBuilder ( ) ;
234+ var restSb = new StringBuilder ( ) ;
235+ var isInsideType = true ;
236+ // The part before the first space is the parameter type
237+ foreach ( var part in paramParts )
238+ {
239+ if ( isInsideType && part . Kind == SymbolDisplayPartKind . Space )
240+ {
241+ isInsideType = false ;
242+ }
243+ if ( isInsideType )
244+ {
245+ typeSb . Append ( part . ToString ( ) ) ;
246+ } else
247+ {
248+ restSb . Append ( part . ToString ( ) ) ;
249+ }
250+ }
251+ // If this parameter has default value null, we need to force the nullable annotation
252+ if ( param . HasExplicitDefaultValue && param . ExplicitDefaultValue is null && param . NullableAnnotation != NullableAnnotation . Annotated )
253+ {
254+ typeSb . Append ( '?' ) ;
255+ }
256+ return typeSb . Append ( restSb ) . ToString ( ) ;
257+ }
258+
245259 private static void AddEventsToInterface ( List < ISymbol > members , InterfaceBuilder codeGenerator )
246260 {
247261 members
0 commit comments