diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileProjectItemExtensions.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileProjectItemExtensions.cs index a685092279..ca9941192b 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileProjectItemExtensions.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileProjectItemExtensions.cs @@ -2,6 +2,8 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.IO; +using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.PackageManagement.EnvDTE @@ -17,5 +19,16 @@ namespace ICSharpCode.PackageManagement.EnvDTE { return projectItem.DependentUpon == otherProjectItem.Include; } + + public static bool IsDependentUponFileName(this FileProjectItem projectItem, string fileName) + { + return FileUtility.IsEqualFileName(projectItem.GetDependentUponFileName(), fileName); + } + + public static string GetDependentUponFileName(this FileProjectItem projectItem) + { + string directory = Path.GetDirectoryName(projectItem.FileName); + return Path.Combine(directory, projectItem.DependentUpon); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/UpdateProjectBrowserFileNodesVisitor.cs b/src/AddIns/Misc/PackageManagement/Project/Src/UpdateProjectBrowserFileNodesVisitor.cs index 2c67688086..12edaef7a8 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/UpdateProjectBrowserFileNodesVisitor.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/UpdateProjectBrowserFileNodesVisitor.cs @@ -10,6 +10,7 @@ using System.Windows.Forms; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; +using DTE = ICSharpCode.PackageManagement.EnvDTE; namespace ICSharpCode.PackageManagement { @@ -48,7 +49,9 @@ namespace ICSharpCode.PackageManagement return null; if (IsImmediateParentForNewFile(directoryNode)) { - if (IsChildFileNodeMissingForNewFile(directoryNode)) { + if (IsNewFileIsDependentUponAnotherFile()) { + base.Visit(directoryNode, data); + } else if (IsChildFileNodeMissingForNewFile(directoryNode)) { AddFileOrDirectoryNodeTo(directoryNode); } } else if (IsChildDirectoryNodeMissingForNewFile(directoryNode)) { @@ -79,6 +82,11 @@ namespace ICSharpCode.PackageManagement return FileUtility.IsBaseDirectory(DirectoryForNewFileAddedToProject, directoryNode.Directory); } + bool IsNewFileIsDependentUponAnotherFile() + { + return !String.IsNullOrEmpty(newFileAddedToProject.DependentUpon); + } + string GetDirectoryForFileAddedToProject() { return Path.GetDirectoryName(newFileAddedToProject.FileName); @@ -121,10 +129,10 @@ namespace ICSharpCode.PackageManagement AddFileNodeTo(directoryNode); } } - - void AddFileNodeTo(TreeNode node) + + void AddFileNodeTo(TreeNode node, FileNodeStatus status = FileNodeStatus.InProject) { - var fileNode = new FileNode(newFileAddedToProject.FileName, FileNodeStatus.InProject); + var fileNode = new FileNode(newFileAddedToProject.FileName, status); fileNode.InsertSorted(node); } @@ -169,5 +177,21 @@ namespace ICSharpCode.PackageManagement { return parentNode.AllNodes.OfType(); } + + public override object Visit(FileNode fileNode, object data) + { + if (IsNewFileIsDependentUponAnotherFile()) { + if (IsImmediateParentForNewFile(fileNode)) { + AddFileNodeTo(fileNode, FileNodeStatus.BehindFile); + return null; + } + } + return base.Visit(fileNode, data); + } + + bool IsImmediateParentForNewFile(FileNode fileNode) + { + return DTE.FileProjectItemExtensions.IsDependentUponFileName(newFileAddedToProject, fileNode.FileName); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/ProjectBrowserUpdaterTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/ProjectBrowserUpdaterTests.cs index 3341a49b7a..d56d4dac73 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/ProjectBrowserUpdaterTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/ProjectBrowserUpdaterTests.cs @@ -131,6 +131,15 @@ namespace PackageManagement.Tests AddProjectItemToProject(fileProjectItem); } + void AddDependentFileToProject(string fileName, string dependentUpon) + { + var fileProjectItem = new FileProjectItem(project, ItemType.Compile) { + FileName = fileName, + DependentUpon = dependentUpon + }; + AddProjectItemToProject(fileProjectItem); + } + void AddReferenceToProject(string name) { var reference = new ReferenceProjectItem(project, name); @@ -585,5 +594,150 @@ namespace PackageManagement.Tests AssertChildFileNodesCountAreEqual(1, subfolderNode); } + + [Test] + public void Constructor_NewDependentFileAddedWhenParentFileHasNoChildren_DependentFileAddedToParentFile() + { + string projectFileName = @"d:\projects\MyProject\MyProject.csproj"; + string fileName = @"d:\projects\MyProject\MainForm.cs"; + CreateProjectNodeWithOneFileInRootDirectoryExpanded(projectFileName, fileName); + string newFileName = @"d:\projects\MyProject\MainForm.Designer.cs"; + + AddDependentFileToProject(newFileName, "MainForm.cs"); + + FileNode mainFormFileNode = GetFirstFileChildNode(projectNode); + FileNode mainFormDesignerFileNode = GetFirstFileChildNode(mainFormFileNode); + Assert.AreEqual(newFileName, mainFormDesignerFileNode.FileName); + Assert.AreEqual(FileNodeStatus.BehindFile, mainFormDesignerFileNode.FileNodeStatus); + } + + [Test] + public void Constructor_NewDependentFileAddedWhenParentFileHasNoChildren_FileNotAddedToSameDirectoryAsParentFile() + { + string projectFileName = @"d:\projects\MyProject\MyProject.csproj"; + string fileName = @"d:\projects\MyProject\MainForm.cs"; + CreateProjectNodeWithOneFileInRootDirectoryExpanded(projectFileName, fileName); + string newFileName = @"d:\projects\MyProject\MainForm.Designer.cs"; + + AddDependentFileToProject(newFileName, "MainForm.cs"); + + // Should be only two project child nodes. + // References + MainForm.cs + Assert.AreEqual(2, projectNode.Nodes.Count); + } + + [Test] + public void Constructor_ProjectHasFileInProjectAndInSubdirectoryAndNewFileAddedInSubdirectory_NewFileNotAddedAsChildToExistingFile() + { + CreateExpandedProjectNodeWithFiles( + @"d:\projects\MyProject\MyProject.csproj", + @"d:\projects\MyProject\a.cs", + @"d:\projects\MyProject\src\b.cs"); + DirectoryNode srcDirectoryNode = GetFirstDirectoryChildNode(projectNode); + srcDirectoryNode.Expanding(); + + AddFileToProject(@"d:\projects\MyProject\src\c.cs"); + + FileNode firstFileNode = GetFirstFileChildNode(projectNode); + Assert.AreEqual(0, firstFileNode.Nodes.Count); + } + + [Test] + public void Constructor_ProjectHasThreeFilesAndDependentFileAddedToSecondFile_DependentFileAddedToSecondFile() + { + CreateExpandedProjectNodeWithFiles( + @"d:\projects\MyProject\MyProject.csproj", + @"d:\projects\MyProject\A.cs", + @"d:\projects\MyProject\MainForm.cs", + @"d:\projects\MyProject\Z.cs"); + + AddDependentFileToProject(@"d:\projects\MyProject\MainForm.Designer.cs", "MainForm.cs"); + + FileNode mainFormFileNode = GetFirstChildNode(projectNode, n => n.Text == "MainForm.cs") as FileNode; + FileNode mainFormDesignerFileNode = GetFirstFileChildNode(mainFormFileNode); + Assert.AreEqual(@"d:\projects\MyProject\MainForm.Designer.cs", mainFormDesignerFileNode.FileName); + } + + [Test] + public void Constructor_ProjectHasThreeFilesAndDependentFileAddedToSecondFile_DependentFileNotAddedToFirst() + { + CreateExpandedProjectNodeWithFiles( + @"d:\projects\MyProject\MyProject.csproj", + @"d:\projects\MyProject\A.cs", + @"d:\projects\MyProject\MainForm.cs", + @"d:\projects\MyProject\Z.cs"); + + AddDependentFileToProject(@"d:\projects\MyProject\MainForm.Designer.cs", "MainForm.cs"); + + FileNode fileNode = GetFirstFileChildNode(projectNode); + Assert.AreEqual(0, fileNode.Nodes.Count); + } + + [Test] + public void Constructor_ProjectHasOneFileAndDependentFileAddedWithDifferentCaseToParentFile_DependentFileAddedToParentFile() + { + CreateExpandedProjectNodeWithFiles( + @"d:\projects\MyProject\MyProject.csproj", + @"d:\projects\MyProject\MainForm.cs"); + + AddDependentFileToProject(@"d:\projects\MyProject\MainForm.Designer.cs", "MAINFORM.CS"); + + FileNode mainFormFileNode = GetFirstFileChildNode(projectNode); + FileNode mainFormDesignerFileNode = GetFirstFileChildNode(mainFormFileNode); + Assert.AreEqual(@"d:\projects\MyProject\MainForm.Designer.cs", mainFormDesignerFileNode.FileName); + } + + [Test] + public void Constructor_DependentFileAddedWhenProjectHasTwoFilesWithSameParentNameButInDifferentFolders_DependentFileNotAddedToFileInDifferentDirectoryWithSameDependentName() + { + CreateExpandedProjectNodeWithFiles( + @"d:\projects\MyProject\MyProject.csproj", + @"d:\projects\MyProject\a.cs", + @"d:\projects\MyProject\src\a.cs", + @"d:\projects\MyProject\src\b.cs"); + DirectoryNode srcDirectoryNode = GetFirstDirectoryChildNode(projectNode); + srcDirectoryNode.Expanding(); + + AddDependentFileToProject(@"d:\projects\MyProject\src\c.cs", "a.cs"); + + FileNode firstFileNode = GetFirstFileChildNode(projectNode); + Assert.AreEqual(0, firstFileNode.Nodes.Count); + } + + [Test] + public void Constructor_DependentFileAddedWhenProjectHasTwoFilesWithSameParentNameButInDifferentFolders_DependentFileAddedToFileInSameDirectory() + { + CreateExpandedProjectNodeWithFiles( + @"d:\projects\MyProject\MyProject.csproj", + @"d:\projects\MyProject\a.cs", + @"d:\projects\MyProject\src\a.cs", + @"d:\projects\MyProject\src\b.cs"); + DirectoryNode srcDirectoryNode = GetFirstDirectoryChildNode(projectNode); + srcDirectoryNode.Expanding(); + + AddDependentFileToProject(@"d:\projects\MyProject\src\c.cs", "a.cs"); + + FileNode fileNode = GetFirstFileChildNode(srcDirectoryNode); + FileNode childNode = GetFirstFileChildNode(fileNode); + Assert.AreEqual(@"d:\projects\MyProject\src\c.cs", childNode.FileName); + } + + [Test] + public void Constructor_DependentFileAddedWhenProjectHasTwoFilesWithSameParentNameButInDifferentFoldersAndFolderCasingDifferent_DependentFileAddedToFileInSameDirectory() + { + CreateExpandedProjectNodeWithFiles( + @"d:\projects\MyProject\MyProject.csproj", + @"d:\projects\MyProject\a.cs", + @"d:\projects\MYPROJECT\SRC\a.cs", + @"d:\projects\MyProject\src\b.cs"); + DirectoryNode srcDirectoryNode = GetFirstDirectoryChildNode(projectNode); + srcDirectoryNode.Expanding(); + + AddDependentFileToProject(@"d:\projects\MyProject\src\c.cs", "a.cs"); + + FileNode fileNode = GetFirstFileChildNode(srcDirectoryNode); + FileNode childNode = GetFirstFileChildNode(fileNode); + Assert.AreEqual(@"d:\projects\MyProject\src\c.cs", childNode.FileName); + } } }