public CSharpProject(Solution solution, string title, string fileName) { // Normalize the file name fileName = Path.GetFullPath(fileName); this.Solution = solution; this.Title = title; this.FileName = fileName; // Use MSBuild to open the .csproj var msbuildProject = new Microsoft.Build.Evaluation.Project(fileName); // Figure out some compiler settings this.AssemblyName = msbuildProject.GetPropertyValue("AssemblyName"); this.CompilerSettings.AllowUnsafeBlocks = GetBoolProperty(msbuildProject, "AllowUnsafeBlocks") ?? false; this.CompilerSettings.CheckForOverflow = GetBoolProperty(msbuildProject, "CheckForOverflowUnderflow") ?? false; string defineConstants = msbuildProject.GetPropertyValue("DefineConstants"); foreach (string symbol in defineConstants.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) this.CompilerSettings.ConditionalSymbols.Add(symbol.Trim()); // Initialize the unresolved type system IProjectContent pc = new CSharpProjectContent(); pc = pc.SetAssemblyName(this.AssemblyName); pc = pc.SetProjectFileName(fileName); pc = pc.SetCompilerSettings(this.CompilerSettings); // Parse the C# code files foreach (var item in msbuildProject.GetItems("Compile")) { var file = new CSharpFile(this, Path.Combine(msbuildProject.DirectoryPath, item.EvaluatedInclude)); Files.Add(file); } // Add parsed files to the type system pc = pc.AddOrUpdateFiles(Files.Select(f => f.UnresolvedTypeSystemForFile)); // Add referenced assemblies: foreach (string assemblyFile in ResolveAssemblyReferences(msbuildProject)) { IUnresolvedAssembly assembly = solution.LoadAssembly(assemblyFile); pc = pc.AddAssemblyReferences(new [] { assembly }); } // Add project references: foreach (var item in msbuildProject.GetItems("ProjectReference")) { string referencedFileName = Path.Combine(msbuildProject.DirectoryPath, item.EvaluatedInclude); // Normalize the path; this is required to match the name with the referenced project's file name referencedFileName = Path.GetFullPath(referencedFileName); pc = pc.AddAssemblyReferences(new[] { new ProjectReference(referencedFileName) }); } this.ProjectContent = pc; }
public static void Main(string[] args) { if (args.Length != 4) { Console.WriteLine("use: RenameClass.exe <SolutionPath> <ClassNamespace> <CurrentClassName> <NewClassName>"); return; } var solutionFile = args[0]; // "C:\\Users\\v-ezeqs\\Documents\\Visual Studio 2010\\Projects\\Application36\\Application36.sln" var classNamespace = args[1]; // "Application36.WebHost" var className = args[2]; // "SiteMaster" var classNewName = args[3]; // "SiteMaster2" if (!File.Exists(solutionFile)) { Console.WriteLine("Solution not found at {0}", solutionFile); return; } Console.WriteLine("Loading solution..."); // Loading Solution in Memory Solution solution = new Solution(solutionFile); Console.WriteLine("Finding references..."); // Define which Type I'm looking for var typeReference = new GetClassTypeReference(classNamespace, className) as ITypeReference; // Try to find the Type definition in solution's projects foreach (var proj in solution.Projects) { var type = typeReference.Resolve(proj.Compilation); if (type.Kind != TypeKind.Unknown) { SetSearchedMembers(new List<object>() { type }); } } if (searchedMembers == null) { Console.WriteLine("Not References found. Refactoring Done."); return; } // Find all related members related with the Type (like Members, Methods, etc) ICSharpCode.NRefactory.CSharp.Resolver.FindReferences refFinder = new ICSharpCode.NRefactory.CSharp.Resolver.FindReferences(); var scopes = searchedMembers.Select (e => refFinder.GetSearchScopes (e as IEntity)); // Finding references to the Type on the one of the different Solution files refs = new List<dynamic>(); foreach (var file in solution.AllFiles.Distinct (new CSharpFileEqualityComparer())) { foreach (var scope in scopes) { refFinder.FindReferencesInFile( scope, file.UnresolvedTypeSystemForFile, file.SyntaxTree, file.Project.Compilation, (astNode, result) => { var newRef = GetReference(result, astNode, file); if (newRef == null || refs.Any(r => r.File.FileName == newRef.File.FileName && r.Region == newRef.Region)) return; refs.Add(newRef); }, CancellationToken.None ); } } Console.WriteLine("Refactoring {0} places in {1} files...", refs.Count(), refs.Select(x => x.File.FileName).Distinct().Count()); // Perform replace for each of the References found foreach (var r in refs) { // DocumentScript expects the the AST to stay unmodified (so that it fits // to the document state at the time of the DocumentScript constructor call), // so we call Freeze() to prevent accidental modifications (e.g. forgetting a Clone() call). r.File.SyntaxTree.Freeze(); // Create a document containing the file content: var fileText = File.ReadAllText(r.File.FileName); var document = new StringBuilderDocument(fileText); using (var script = new DocumentScript(document, FormattingOptionsFactory.CreateAllman(), new TextEditorOptions())) { // Alternative 1: clone a portion of the AST and modify it //var copy = (InvocationExpression)expr.Clone(); //copy.Arguments.Add(stringComparisonAst.Member("Ordinal")); //script.Replace(expr, copy); // Alternative 2: perform direct text insertion / replace int offset = script.GetCurrentOffset(r.Region.Begin); var length = r.Region.End.Column - r.Region.Begin.Column; script.Replace(offset, length, classNewName); } File.WriteAllText(r.File.FileName, document.Text); } Console.WriteLine("Refactoring Done."); }