我尝试使用新的Roslyn和Visual Studio API编写UnmatchedClassAndFilename
诊断和代码修复程序。我们的想法是重命名一个类或文件名,以防它们不相等。
如何使用Roslyn API在Visual Studio中重命名文件? Workspace
课程似乎不支持这一点。
更新:在CodePlex上创建了一个问题(https://roslyn.codeplex.com/workitem/258)
答案 0 :(得分:0)
不,Workspaces API目前没有这方面的支持。这是一个常见的请求,但我不确定我们是否有明确跟踪该工作的内容,因此请随意在CodePlex上提交错误。
答案 1 :(得分:0)
我正在使用Visual Studio 2017和Code Refactoring VSIX项目模板来完成此任务。
这是我的代码:
private async Task<Solution> ConvertTypeNameToPascalCaseAsync(Document document, TypeDeclarationSyntax typeDecl, CancellationToken cancellationToken)
{
// Produce a PascalCased version of the type declaration's identifier token.
var identifierToken = typeDecl.Identifier;
var newName = identifierToken.Text.ToPascalCase();
// Get the symbol representing the type to be renamed.
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
var typeSymbol = semanticModel.GetDeclaredSymbol(typeDecl, cancellationToken);
// Produce a new solution that has all references to that type renamed, including the declaration.
var originalSolution = document.Project.Solution;
var optionSet = originalSolution.Workspace.Options;
var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, typeSymbol, newName, optionSet, cancellationToken).ConfigureAwait(false);
var newDocId = DocumentId.CreateNewId(document.Project.Id);
var newText = await newSolution.GetDocument(document.Id).GetTextAsync(cancellationToken).ConfigureAwait(false);
// rename document by adding a new document with the new name and removing the old document
newSolution = newSolution.AddAdditionalDocument(newDocId, newName + ".cs", newText);
newSolution = newSolution.RemoveDocument(document.Id);
// Return the new solution with the now PascalCased type name.
return newSolution;
}
注意:ToPascalCase()
是我添加到字符串类的扩展方法。
需要注意的一点是,我使用AddAdditionalDocument()
和RemoveDocument()
来有效地重命名现有文档以匹配我的新名称。
以下是设置代码重构引擎的代码:
public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
// Find the node at the selection.
var node = root.FindNode(context.Span);
// Only offer a refactoring if the selected node is a type declaration node.
var typeDecl = node as TypeDeclarationSyntax;
if (typeDecl == null)
{
return;
}
if (typeDecl.Identifier.Text.IsUpper())
{
// For any type declaration node, create a code action to reverse the identifier text.
var action = CodeAction.Create("Convert type name to PascalCase", c => ConvertTypeNameToPascalCaseAsync(context.Document, typeDecl, c));
// Register this code action.
context.RegisterRefactoring(action);
}
}
注意:IsUpper()
也是我添加到字符串类的扩展方法。
顺便提一下,我的具体用例是将带有下划线的所有大写类名转换为PascalCased类名。例子:
TEST
= Test
TEST_CLASS
= TestClass
TEST_A_CLASS
= TestAClass