建立标准编码规则(三)-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 编写修复代码