diff options
author | Jose Miguel Torres <jostor@microsoft.com> | 2019-09-27 00:02:57 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-27 00:02:57 +0300 |
commit | c714c192e8533e0b84ee7c66cbf16360d7d2ed8e (patch) | |
tree | ae93500cb0979096c0cad6fa5d29622714da4ed6 | |
parent | 0f586e47c3c7a11f5ba1eb9550c84e6b7faadf41 (diff) | |
parent | 2742edd6a96d50a3c7f76b6042652c09681ade61 (diff) |
Merge pull request #8803 from mono/backport-pr-8798-to-release-8.3
[release-8.3] [FileNesting] Include multiple nested files on move operations
6 files changed, 129 insertions, 60 deletions
diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Tests/MonoDevelop.AspNetCore.Tests/AspNetCoreProjectTests.cs b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Tests/MonoDevelop.AspNetCore.Tests/AspNetCoreProjectTests.cs index 9eef6888ae..97cfa418fd 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Tests/MonoDevelop.AspNetCore.Tests/AspNetCoreProjectTests.cs +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.Tests/MonoDevelop.AspNetCore.Tests/AspNetCoreProjectTests.cs @@ -63,6 +63,12 @@ namespace MonoDevelop.AspNetCore.Tests } } + static ProjectFile AddFile (Project project, string file) + { + File.WriteAllText (file, ""); + return project.AddFile (file); + } + [Test] public async Task AspNetCore_FileNesting () { @@ -89,10 +95,8 @@ namespace MonoDevelop.AspNetCore.Tests string inputFileDestination = Path.Combine (dir, "FileNesting", f.Item1); string parentFileDestination = Path.Combine (dir, "FileNesting", f.Item2); - File.WriteAllText (parentFileDestination, ""); - var parentFile = project.AddFile (parentFileDestination); - File.WriteAllText (inputFileDestination, ""); - var inputFile = project.AddFile (inputFileDestination); + var parentFile = AddFile (project, parentFileDestination); + var inputFile = AddFile (project, inputFileDestination); var actualParentFile = FileNestingService.GetParentFile (inputFile); Assert.That (parentFile, Is.EqualTo (actualParentFile), $"Was expecting parent file {parentFileDestination} for {inputFileDestination} but got {actualParentFile}"); @@ -115,6 +119,63 @@ namespace MonoDevelop.AspNetCore.Tests } [Test] + public async Task AspNetCore_MultiFileNesting () + { + string projectFileName = Util.GetSampleProject ("aspnetcore-empty-30", "aspnetcore-empty-30.sln"); + using (var sol = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), projectFileName)) { + var project = sol.GetAllProjectsWithFlavor<AspNetCoreProjectExtension> ().FirstOrDefault (); + + var dir = project.BaseDirectory; + project.AddDirectory ("FileNesting"); + + var rootFile = AddFile (project, Path.Combine (dir, "FileNesting", "bootstrap.css")); + Assert.That (FileNestingService.GetChildren (rootFile), Is.Null); + Assert.That (FileNestingService.GetDependentOrNestedChildren (rootFile)?.Count () ?? 0, Is.EqualTo (0)); + Assert.That (FileNestingService.GetDependentOrNestedTree (rootFile)?.Count () ?? 0, Is.EqualTo (0)); + + // This should be nested under bootstrap.css + var mapFile = AddFile (project, Path.Combine (dir, "FileNesting", "bootstrap.css.map")); + Assert.That (FileNestingService.GetChildren (rootFile), Contains.Item (mapFile)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (rootFile), Contains.Item (mapFile)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (rootFile)?.Count () ?? 0, Is.EqualTo (1)); + Assert.That (FileNestingService.GetDependentOrNestedTree (rootFile), Contains.Item (mapFile)); + Assert.That (FileNestingService.GetDependentOrNestedTree (rootFile)?.Count () ?? 0, Is.EqualTo (1)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (mapFile)?.Count () ?? 0, Is.EqualTo (0)); + Assert.That (FileNestingService.GetDependentOrNestedTree (mapFile)?.Count () ?? 0, Is.EqualTo (0)); + + // This should be nested under bootstrap.css + var minFile = AddFile (project, Path.Combine (dir, "FileNesting", "bootstrap.min.css")); + Assert.That (FileNestingService.GetChildren (rootFile), Contains.Item (minFile)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (rootFile), Contains.Item (minFile)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (rootFile)?.Count () ?? 0, Is.EqualTo (2)); + Assert.That (FileNestingService.GetDependentOrNestedTree (rootFile), Contains.Item (minFile)); + Assert.That (FileNestingService.GetDependentOrNestedTree (rootFile)?.Count () ?? 0, Is.EqualTo (2)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (minFile)?.Count () ?? 0, Is.EqualTo (0)); + Assert.That (FileNestingService.GetDependentOrNestedTree (minFile)?.Count () ?? 0, Is.EqualTo (0)); + + // This should be nested under bootstrap.min.css + var minMapFile = AddFile (project, Path.Combine (dir, "FileNesting", "bootstrap.min.css.map")); + Assert.That (FileNestingService.GetChildren (rootFile), !Contains.Item (minMapFile)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (rootFile), !Contains.Item (minMapFile)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (rootFile)?.Count () ?? 0, Is.EqualTo (2)); + Assert.That (FileNestingService.GetDependentOrNestedTree (rootFile), Contains.Item (minMapFile)); + Assert.That (FileNestingService.GetDependentOrNestedTree (rootFile)?.Count () ?? 0, Is.EqualTo (3)); + Assert.That (FileNestingService.GetChildren (minFile), Contains.Item (minMapFile)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (minFile), Contains.Item (minMapFile)); + Assert.That (FileNestingService.GetDependentOrNestedChildren (minFile)?.Count () ?? 0, Is.EqualTo (1)); + Assert.That (FileNestingService.GetDependentOrNestedTree (minFile), Contains.Item (minMapFile)); + Assert.That (FileNestingService.GetDependentOrNestedTree (minFile)?.Count () ?? 0, Is.EqualTo (1)); + + // Check if all files are taken into account when renaming the top one + var files = MonoDevelop.Ide.ProjectOperations.GetDependentFilesToRename (rootFile, "reboot.css"); + Assert.That (files.Count, Is.EqualTo (3)); + Assert.True (files.Any (x => x.File == mapFile && x.NewName == "reboot.css.map")); + Assert.True (files.Any (x => x.File == minFile && x.NewName == "reboot.min.css")); + Assert.True (files.Any (x => x.File == minMapFile && x.NewName == "reboot.min.css.map")); + } + } + + [Test] public async Task RazorClassLib_Supports_FileNesting () { string projectFileName = Util.GetSampleProject ("aspnetcore-razor-class-lib", "aspnetcore-razor-class-lib.csproj"); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/FolderNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/FolderNodeBuilder.cs index 4ecfe5e8c8..d2328e2434 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/FolderNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/FolderNodeBuilder.cs @@ -201,7 +201,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad var groupedFiles = new HashSet<ProjectFile> (); foreach (var pf in dataObjects.OfType<ProjectFile> ()) { - var children = FileNestingService.GetDependentOrNestedChildren (pf); ; + var children = FileNestingService.GetDependentOrNestedChildren (pf); if (children != null) { foreach (var child in children) groupedFiles.Add (child); @@ -252,7 +252,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad } else { source = file.FilePath; } - groupedChildren = FileNestingService.GetDependentOrNestedChildren (file); ; + groupedChildren = FileNestingService.GetDependentOrNestedTree (file); what = null; } else if (dataObject is Gtk.SelectionData) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs index 0b6ac8b351..a965935f85 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads.ProjectPad/ProjectFileNodeBuilder.cs @@ -175,7 +175,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad if (oldFileName == newFileName) return; - var dependentFilesToRename = GetDependentFilesToRename (file, newName); + var dependentFilesToRename = ProjectOperations.GetDependentFilesToRename (file, newName); try { if (CanRenameFile (file, newName)) { @@ -213,31 +213,6 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad return file.FilePath.ParentDirectory.Combine (newName); } - /// <summary> - /// Returns all dependent files that have names that start with the old name of the file. - /// </summary> - static List<(ProjectFile File, string NewName)> GetDependentFilesToRename (ProjectFile file, string newName) - { - var children = FileNestingService.GetDependentOrNestedChildren (file); - if (children == null) - return null; - - List<(ProjectFile File, string NewName)> files = null; - - string oldName = file.FilePath.FileName; - foreach (ProjectFile child in children) { - string oldChildName = child.FilePath.FileName; - if (oldChildName.StartsWith (oldName, StringComparison.CurrentCultureIgnoreCase)) { - string childNewName = newName + oldChildName.Substring (oldName.Length); - - if (files == null) - files = new List<(ProjectFile projectFile, string name)> (); - files.Add ((child, childNewName)); - } - } - return files; - } - static bool CanRenameFile (ProjectFile file, string newName) { ProjectFile newProjectFile = null; @@ -351,7 +326,7 @@ namespace MonoDevelop.Ide.Gui.Pads.ProjectPad project.Files.Add (folderFile); } - var children = FileNestingService.GetDependentOrNestedChildren (file); + var children = FileNestingService.GetDependentOrNestedTree (file); if (children != null) { foreach (var child in children.ToArray ()) { project.Files.Remove (child); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.FileNesting/FileNestingService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.FileNesting/FileNestingService.cs index 65178f33ca..b10336aea4 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.FileNesting/FileNestingService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.FileNesting/FileNestingService.cs @@ -125,6 +125,31 @@ namespace MonoDevelop.Ide.Projects.FileNesting return GetChildren (inputFile); } + + public static IEnumerable<ProjectFile> GetDependentOrNestedTree (ProjectFile inputFile) + { + if (inputFile.HasChildren) { + foreach (var dep in inputFile.DependentChildren) { + yield return dep; + } + } else { + var children = GetChildren (inputFile); + if (children != null && children.Count > 0) { + var stack = new Stack<ProjectFile> (children); + while (stack.Count > 0) { + var current = stack.Pop (); + yield return current; + + children = GetChildren (current); + if (children != null) { + foreach (var child in children) { + stack.Push (child); + } + } + } + } + } + } } sealed class ProjectNestingInfo : IDisposable diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs index edfd4b8359..c0e4b136ad 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs @@ -1345,7 +1345,7 @@ namespace MonoDevelop.Ide.TypeSystem FileService.RenameFile (document.FilePath, newName); - var childrenToRename = GetDependentFilesToRename (mdFile, newName); + var childrenToRename = ProjectOperations.GetDependentFilesToRename (mdFile, newName); if (childrenToRename != null) { // we also need to rename children! foreach (var child in childrenToRename) { @@ -1358,30 +1358,6 @@ namespace MonoDevelop.Ide.TypeSystem tryApplyState_changedProjects.Add (mdProject); }
- static List<(MonoDevelop.Projects.ProjectFile File, string NewName)> GetDependentFilesToRename ( - MonoDevelop.Projects.ProjectFile file, - string newName) - { - var children = FileNestingService.GetDependentOrNestedChildren (file); - if (children == null) - return null; - - List<(MonoDevelop.Projects.ProjectFile File, string NewName)> files = null; - - string oldName = file.FilePath.FileName; - foreach (MonoDevelop.Projects.ProjectFile child in children) { - string oldChildName = child.FilePath.FileName; - if (oldChildName.StartsWith (oldName, StringComparison.CurrentCultureIgnoreCase)) { - string childNewName = newName + oldChildName.Substring (oldName.Length); - - if (files == null) - files = new List<(MonoDevelop.Projects.ProjectFile projectFile, string name)> (); - files.Add ((child, childNewName)); - } - } - return files; - }
-
static void FailIfDocumentInfoChangesNotSupported (Document document, DocumentInfo updatedInfo) { if (document.SourceCodeKind != updatedInfo.SourceCodeKind) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs index 42854627f3..3e3c7c0f9f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs @@ -342,7 +342,39 @@ namespace MonoDevelop.Ide await workspace.SavePreferencesAsync (); } } - + + /// <summary> + /// Returns all dependent files that have names that start with the old name of the file. + /// </summary> + internal static List<(MonoDevelop.Projects.ProjectFile File, string NewName)> GetDependentFilesToRename ( + MonoDevelop.Projects.ProjectFile file, + string newName) + { + var children = FileNestingService.GetDependentOrNestedTree (file); + if (children == null) + return null; + + List<(MonoDevelop.Projects.ProjectFile File, string NewName)> files = null; + + string oldName = file.FilePath.FileName; + foreach (ProjectFile child in children) { + string oldChildName = child.FilePath.FileName; + string childNewName = null; + if (oldChildName.StartsWith (oldName, StringComparison.CurrentCultureIgnoreCase)) { + childNewName = newName + oldChildName.Substring (oldName.Length); + } else if (oldChildName.StartsWith (Path.GetFileNameWithoutExtension (oldName), StringComparison.CurrentCultureIgnoreCase)) { + childNewName = Path.GetFileNameWithoutExtension (newName) + oldChildName.Substring (Path.GetFileNameWithoutExtension (oldName).Length); + } + + if (childNewName != null) { + if (files == null) + files = new List<(MonoDevelop.Projects.ProjectFile projectFile, string name)> (); + files.Add ((child, childNewName)); + } + } + return files; + } + public void Export (Solution item) { Export (item, null); @@ -2257,7 +2289,7 @@ namespace MonoDevelop.Ide if (filesToMove.Count == 1 && sourceProject != null) { var pf = filesToMove[0]; if (pf != null) { - var children = FileNestingService.GetDependentOrNestedChildren (pf); + var children = FileNestingService.GetDependentOrNestedTree (pf); if (children != null) { foreach (ProjectFile child in children) { |