@@ -5,23 +5,20 @@ namespace WpfAnalyzers;
55using System . Composition ;
66using System . Globalization ;
77using System . Threading . Tasks ;
8+
89using Gu . Roslyn . AnalyzerExtensions ;
910using Gu . Roslyn . CodeFixExtensions ;
11+
1012using Microsoft . CodeAnalysis ;
1113using Microsoft . CodeAnalysis . CodeFixes ;
1214using Microsoft . CodeAnalysis . CSharp ;
1315using Microsoft . CodeAnalysis . CSharp . Syntax ;
16+ using Microsoft . CodeAnalysis . Editing ;
1417
1518[ ExportCodeFixProvider ( LanguageNames . CSharp , Name = nameof ( ImplementValueConverterFix ) ) ]
1619[ Shared ]
1720internal class ImplementValueConverterFix : DocumentEditorCodeFixProvider
1821{
19- private static readonly MethodDeclarationSyntax IValueConverterConvert = ParseMethod (
20- @" public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
21- {
22- throw new System.NotImplementedException();
23- }" ) ;
24-
2522 private static readonly MethodDeclarationSyntax IMultiValueConverterConvert = ParseMethod (
2623 @" public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
2724 {
@@ -47,7 +44,7 @@ protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContex
4744 {
4845 context . RegisterCodeFix (
4946 "Implement IValueConverter.Convert for one way bindings." ,
50- ( editor , _ ) => editor . AddMethod ( classDeclaration , IValueConverterConvert ) ,
47+ ( editor , _ ) => editor . AddMethod ( classDeclaration , Convert ( editor . Generator ) ) ,
5148 "Implement IValueConverter" ,
5249 diagnostic ) ;
5350 }
@@ -57,7 +54,7 @@ protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContex
5754 {
5855 context . RegisterCodeFix (
5956 "Implement IValueConverter.ConvertBack for one way bindings." ,
60- ( editor , _ ) => editor . AddMethod ( classDeclaration , IValueConverterConvertBack ( classDeclaration . Identifier . ValueText ) ) ,
57+ ( editor , _ ) => editor . AddMethod ( classDeclaration , ConvertBack ( editor . Generator , classDeclaration . Identifier . ValueText ) ) ,
6158 "Implement IValueConverter" ,
6259 diagnostic ) ;
6360 }
@@ -109,15 +106,64 @@ private static bool HasInterface(ClassDeclarationSyntax classDeclaration, Qualif
109106 return false ;
110107 }
111108
112- private static MethodDeclarationSyntax IValueConverterConvertBack ( string containingTypeName )
109+ private static MethodDeclarationSyntax Convert ( SyntaxGenerator generator )
113110 {
114- var code = StringBuilderPool . Borrow ( )
115- . AppendLine ( " object System.Windows.Data.IValueConverter.ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)" )
116- . AppendLine ( " {" )
117- . AppendLine ( $ " throw new System.NotSupportedException($\" {{nameof({ containingTypeName } )}} can only be used in OneWay bindings\" );")
118- . AppendLine ( " }" )
119- . Return ( ) ;
120- return ParseMethod ( code ) ;
111+ return ( MethodDeclarationSyntax ) generator . MethodDeclaration (
112+ accessibility : Accessibility . Public ,
113+ returnType : SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ObjectKeyword ) ) ,
114+ name : "Convert" ,
115+ parameters : new [ ]
116+ {
117+ generator . ParameterDeclaration ( "value" , SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ObjectKeyword ) ) ) ,
118+ generator . ParameterDeclaration ( "targetType" , SyntaxFactory . ParseTypeName ( "System.Type" ) . WithSimplifiedNames ( ) ) ,
119+ generator . ParameterDeclaration ( "parameter" , SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ObjectKeyword ) ) ) ,
120+ generator . ParameterDeclaration ( "culture" , SyntaxFactory . ParseTypeName ( "System.Globalization.CultureInfo" ) . WithSimplifiedNames ( ) ) ,
121+ } ,
122+ statements : new [ ] { generator . ThrowStatement ( generator . ObjectCreationExpression ( SyntaxFactory . ParseTypeName ( "System.NotImplementedException" ) . WithSimplifiedNames ( ) ) ) } ) ;
123+ }
124+
125+ private static MethodDeclarationSyntax ConvertBack ( SyntaxGenerator generator , string containingTypeName )
126+ {
127+ return ( ( MethodDeclarationSyntax ) generator . MethodDeclaration (
128+ returnType : SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ObjectKeyword ) ) ,
129+ name : "ConvertBack" ,
130+ parameters : new [ ]
131+ {
132+ generator . ParameterDeclaration ( "value" , SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ObjectKeyword ) ) ) ,
133+ generator . ParameterDeclaration ( "targetType" , SyntaxFactory . ParseTypeName ( "System.Type" ) . WithSimplifiedNames ( ) ) ,
134+ generator . ParameterDeclaration ( "parameter" , SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ObjectKeyword ) ) ) ,
135+ generator . ParameterDeclaration ( "culture" , SyntaxFactory . ParseTypeName ( "System.Globalization.CultureInfo" ) . WithSimplifiedNames ( ) ) ,
136+ } ,
137+ statements : new [ ] { Throw ( ) } ) )
138+ . WithExplicitInterfaceSpecifier ( SyntaxFactory . ExplicitInterfaceSpecifier ( SyntaxFactory . ParseName ( "IValueConverter" ) ) ) ;
139+
140+ ThrowStatementSyntax Throw ( )
141+ {
142+ return ( ThrowStatementSyntax ) generator . ThrowStatement (
143+ generator . ObjectCreationExpression (
144+ SyntaxFactory . ParseTypeName ( "System.NotSupportedException" ) ,
145+ SyntaxFactory . Argument (
146+ expression : SyntaxFactory . InterpolatedStringExpression (
147+ stringStartToken : SyntaxFactory . Token ( SyntaxKind . InterpolatedStringStartToken ) ,
148+ contents : SyntaxFactory . List (
149+ new InterpolatedStringContentSyntax [ ]
150+ {
151+ SyntaxFactory . Interpolation (
152+ openBraceToken : SyntaxFactory . Token ( SyntaxKind . OpenBraceToken ) ,
153+ expression : ( ExpressionSyntax ) generator . NameOfExpression ( SyntaxFactory . ParseTypeName ( containingTypeName ) ) ,
154+ alignmentClause : default ,
155+ formatClause : default ,
156+ closeBraceToken : SyntaxFactory . Token ( SyntaxKind . CloseBraceToken ) ) ,
157+ SyntaxFactory . InterpolatedStringText (
158+ textToken : SyntaxFactory . Token (
159+ leading : default ,
160+ kind : SyntaxKind . InterpolatedStringTextToken ,
161+ text : " can only be used in OneWay bindings" ,
162+ valueText : " can only be used in OneWay bindings" ,
163+ trailing : default ) ) ,
164+ } ) ,
165+ stringEndToken : SyntaxFactory . Token ( SyntaxKind . InterpolatedStringEndToken ) ) ) ) ) ;
166+ }
121167 }
122168
123169 private static MethodDeclarationSyntax IMultiValueConverterConvertBack ( string containingTypeName )
0 commit comments