簡體   English   中英

使用roslyn替換所有類用法

[英]Replace all class usages using roslyn

我正在嘗試做的事情:假設我們在程序集OldAssembly有一個Class1類。 許多未知項目引用了此程序集。 我將把此類移到新的程序集NewAssembly ,最終名稱和名稱空間也會更改。 現在必須調整所有用法。 我想創建一個將這些代碼調整自動化的工具。

到目前為止,我所做的:我和roslyn Renamer一起玩過:

var workspace = MSBuildWorkspace.Create();
var originalSln = workspace.OpenSolutionAsync(@"D:\spikes\ToBeFixed\ToBeFixed.sln").Result;

var project = originalSln.Projects.Single();
var compilation = project.GetCompilationAsync().Result;

var renameFrom = compilation.GetSymbolsWithName(s => s.Contains("Class1")).Single();
const string renameTo = "Class2";
var optionSet = originalSln.Workspace.Options;
var modifiedSln = Renamer.RenameSymbolAsync(originalSln, renameFrom, renameTo, optionSet).Result;

workspace.TryApplyChanges(modifiedSln);

但它也重命名了源類。 因此,我研究了重Renamer代碼,並嘗試使其適應我的用例,但由於其中使用了一些內部組件,因此失敗了。

問題:將類從一個程序集中移動到另一個程序集后,如何自動執行代碼調整。

您可以通過以下方式實現所需的功能:

  1. 在整個解決方案中重命名該類的所有用法
  2. 用原始的自己替換重命名的類本身。

     public async static Task TestingRenamer() { var code = @" using System; //We do not want to rename MyClass (we want to keep it the same) public class MyClass { public MyClass() { } } public class Program { public static void Main() { //We want to rename this usage var x = new MyClass(); } }"; var newClassName = "MY_NEW_CLASS_NAME"; var document = getDocumentForCode(code); var compilation = await document.Project.GetCompilationAsync(); var root = await document.GetSyntaxRootAsync(); var originalClass = root.DescendantNodesAndSelf().OfType<ClassDeclarationSyntax>().First(); var model = compilation.GetSemanticModel(root.SyntaxTree); var originalSymbol = model.GetDeclaredSymbol(originalClass); //Rename all var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, originalSymbol, newClassName, document.Project.Solution.Workspace.Options); //Revert the original class var newDocument = newSolution.GetDocument(document.Id); var newSyntaxRoot = await newDocument.GetSyntaxRootAsync(); var newClass = newSyntaxRoot.DescendantNodes().OfType<ClassDeclarationSyntax>().Where(n => n.Identifier.ToString() == newClassName).Single(); newSyntaxRoot = newSyntaxRoot.ReplaceNode(newClass, originalClass); newDocument = newDocument.WithSyntaxRoot(newSyntaxRoot); //We've now renamed all usages and reverted the class back to its original self. var finalSolution = newDocument.Project.Solution; } //Helper method to build Document private static Document getDocumentForCode(string code) { var ws = new AdhocWorkspace(); var Mscorlib = MetadataReference.CreateFromAssembly(typeof(object).Assembly); var references = new List<MetadataReference>() { Mscorlib }; var projInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "MyProject", "MyAssembly", "C#", metadataReferences: references); var project = ws.AddProject(projInfo); var text = SourceText.From(code); var myDocument = ws.AddDocument(project.Id, "MyDocument.cs", text); return myDocument; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM