建立标准编码规则(三)-CodeFixProvider 给代码分析器增加修复建议

给代码分析器增加修复建议

既然代码分析器,向代码编写者提出了错误或警告,那么有没有可能向代码编写者提交有效的改进建议?

相对于 DiagnosticAnalyzer,代码修复继承与 CodeFixProvider

CodeFixProvider,是基于DiagnosticAnalyzer,也就是说,必须给CodeFixProvider提供FixableDiagnosticIds。

1.增加继承CodeFixProvider的类RegexAnalyzerCodeFixProvider对我们刚才编写RegexAnalyzer进行代码修复提示

继承CodeFixProvider必须要实现

public abstract ImmutableArray<string> FixableDiagnosticIds { get; } //这里是对应的诊断代码ID
public virtual FixAllProvider GetFixAllProvider() //获取修复的方式 这里没搞明白
public abstract Task RegisterCodeFixesAsync(CodeFixContext context)//注册到方法中

 

 

2 编写业务代码

        /// <summary>
        /// 修复代码
        /// 1 获取语义模型
        /// 2 找到正值表达式
        /// 3 给出正确的表达式
        /// 4 返回语法树新节点document
        /// </summary>
        /// <param name="document"></param>
        /// <param name="invocationExpr"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task<Document> FixRegexAsync(Document document,InvocationExpressionSyntax invocationExpr,CancellationToken cancellationToken)
        {
            var sementicModel = await document.GetSemanticModelAsync(cancellationToken);
            var memberAccessExpr = invocationExpr.Expression as MemberAccessExpressionSyntax;
            var memberSymbol = sementicModel.GetSymbolInfo(memberAccessExpr).Symbol as IMethodSymbol;
            var argumentList = invocationExpr.ArgumentList as ArgumentListSyntax;
            var regexLiteral =
                argumentList.Arguments[1].Expression as LiteralExpressionSyntax;
            var regexOpt = sementicModel.GetConstantValue(regexLiteral);
            var regx = regexOpt.Value as string;
            var newLiteral = SyntaxFactory.ParseExpression("\"valid regex\"")
                .WithLeadingTrivia(regexLiteral.GetLeadingTrivia())
                .WithTrailingTrivia(regexLiteral.GetTrailingTrivia())
                .WithAdditionalAnnotations(Formatter.Annotation);
            var root = await document.GetSyntaxRootAsync();
            var newroot = root.ReplaceNode(regexLiteral, newLiteral);
            var newDocument = document.WithSyntaxRoot(newroot);
            return newDocument;
        }

实际效果如下:类似我们重命名

 

 

 

 

 

总结:

至此,我们知道,编写标准的代码规则步骤很容易,核心的部分是要写个我们定义的规则。

1 基于Roslyn模板新建代码分析器项目

2 编写诊断代码

3 编写修复代码

 

posted @ 2017-11-22 20:21  fishpro  阅读(775)  评论(0编辑  收藏  举报