如何更换,在罗斯林一个变种一个字符串变量? [英] How do I replace a string variable with a var in Roslyn?

查看:198
本文介绍了如何更换,在罗斯林一个变种一个字符串变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关本地声明,如:
字符串=的String.Empty;

For local declarations like: string a = string.Empty;

我怎么能写一个诊断将其更改为:
变种A =的String.Empty;

How can I write a diagnostic to change it to: var a = string.Empty;

推荐答案

我已经把代码补丁与诊断。
这里的有趣的部分:

I've put together a code fix with diagnostic. Here's the interesting parts:

实施

public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
    {
        var localDeclaration = (LocalDeclarationStatementSyntax)node;
        if (localDeclaration.Declaration.Type.IsVar) return;
        var variable = localDeclaration.Declaration.Variables.First();
        var initialiser = variable.Initializer;
        if (initialiser == null) return;
        var variableTypeName = localDeclaration.Declaration.Type;
        var variableType = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;
        var initialiserInfo = semanticModel.GetTypeInfo(variable.Initializer.Value);
        var typeOfRightHandSideOfDeclaration = initialiserInfo.Type;
        if (Equals(variableType, typeOfRightHandSideOfDeclaration))
        {
            addDiagnostic(Diagnostic.Create(Rule, node.GetLocation(), localDeclaration.Declaration.Variables.First().Identifier.Value));
        }
    }

这基本上是着眼于上的两侧的类型。声明,如果它们是相同的(和RHS是不是已经VAR)然后添加一个诊断

This essentially looks at the types on both sides of the declaration and if they're the same (and the RHS isn't already var) then add a diagnostic.

和这里的代码修复的代码:

And here's the code for the Code Fix:

public async Task<IEnumerable<CodeAction>> GetFixesAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken)
    {
        var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
        var diagnosticSpan = diagnostics.First().Location.SourceSpan;
        var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<LocalDeclarationStatementSyntax>().First();
        return new[] { CodeAction.Create("Use var", c => ChangeDeclarationToVar(document, declaration, c)) };
    }

private async Task<Document> ChangeDeclarationToVar(Document document, LocalDeclarationStatementSyntax localDeclaration, CancellationToken cancellationToken)
    {
        var root = await document.GetSyntaxRootAsync(cancellationToken);
        var variableTypeName = localDeclaration.Declaration.Type;
        var varTypeName = SyntaxFactory.IdentifierName("var").WithAdditionalAnnotations(Formatter.Annotation);
        var newDeclaration = localDeclaration.ReplaceNode(variableTypeName, varTypeName);            
        var newRoot = root.ReplaceNode(localDeclaration, newDeclaration);
        return document.WithSyntaxRoot(newRoot);
    }

这一点是好的,简单,只需得到语法工厂和开关VAR出来。
请注意,VAR没有它在SyntaxFactory自己的静态方法所以不是按名称引用。

This bit is nice and simple, just get var from the Syntax factory and switch it out. Note that var doesn't have it's own static method in the SyntaxFactory so instead is reference by name.

这篇关于如何更换,在罗斯林一个变种一个字符串变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆