From 1cdc439a1060c5d5f5663dc3544aea18b772f94d Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sat, 28 Jul 2012 13:43:14 +0100 Subject: [PATCH] Fix duplicate directory project items being returned by EnvDTE.ProjectItems. --- .../Project/Src/EnvDTE/ChildProjectItems.cs | 29 ++++++++++++-- .../Project/Src/EnvDTE/ProjectItem.cs | 2 +- .../Test/Src/EnvDTE/ProjectItemsTests.cs | 39 +++++++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ChildProjectItems.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ChildProjectItems.cs index 1b13e76149..3f592ca19e 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ChildProjectItems.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ChildProjectItems.cs @@ -18,10 +18,12 @@ namespace ICSharpCode.PackageManagement.EnvDTE { this.ProjectItem = projectItem; this.Project = projectItem.ContainingProject; + this.ChildDirectoryProjectItems = new List(); } ProjectItem ProjectItem { get; set; } Project Project { get; set; } + List ChildDirectoryProjectItems { get; set; } IEnumerator IEnumerable.GetEnumerator() { @@ -37,17 +39,38 @@ namespace ICSharpCode.PackageManagement.EnvDTE IEnumerable GetProjectItems() { foreach (SD.ProjectItem msbuildProjectItem in Project.MSBuildProject.Items) { - ProjectItem item = ConvertToProjectItem(msbuildProjectItem); - if (item != null) { + ProjectItem item = GetChildProjectItem(msbuildProjectItem); + if (!IgnoreChildProjectItem(item)) { yield return item; } } } - ProjectItem ConvertToProjectItem(SD.ProjectItem msbuildProjectItem) + ProjectItem GetChildProjectItem(SD.ProjectItem msbuildProjectItem) { ProjectItemRelationship relationship = ProjectItem.GetRelationship(msbuildProjectItem); return relationship.GetChild(); } + + bool IgnoreChildProjectItem(ProjectItem item) + { + if (item == null) { + return true; + } + + if (item.IsDirectory) { + return ChildDirectoryProjectItemSeenBefore(item); + } + return false; + } + + bool ChildDirectoryProjectItemSeenBefore(ProjectItem directoryProjectItem) + { + if (ChildDirectoryProjectItems.Any(item => item.Name == directoryProjectItem.Name)) { + return true; + } + ChildDirectoryProjectItems.Add(directoryProjectItem); + return false; + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs index 251fd4d0c2..c8eee851f4 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs @@ -42,7 +42,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE return Constants.VsProjectItemKindPhysicalFile; } - bool IsDirectory { + internal bool IsDirectory { get { return projectItem.ItemType == ItemType.Folder; } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs index 804b77da8c..3360357cda 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemsTests.cs @@ -69,6 +69,11 @@ namespace PackageManagement.Tests.EnvDTE return projectItems.OfType().FirstOrDefault(); } + List GetAllChildItems(ProjectItems projectItems) + { + return projectItems.OfType().ToList(); + } + [Test] public void AddFromFileCopy_AddFileNameOutsideProjectFolder_FileIsIncludedInProjectInProjectFolder() { @@ -723,5 +728,39 @@ namespace PackageManagement.Tests.EnvDTE Assert.AreEqual("jQueryPlugin.ps1", jqueryPluginFileItem.Name); } + + [Test] + public void GetEnumerator_ProjectHasTwoFilesInFolderTwoLevelsDeep_TopLevelFolderOnlyHasOneProjectItemForChildFolder() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\MyProject\MyProject.csproj"; + msbuildProject.AddFile(@"CodeTemplates\Scaffolders\File1.cs"); + msbuildProject.AddFile(@"CodeTemplates\Scaffolders\File2.cs"); + + DTE.ProjectItem codeTemplatesFolderItem = GetChildItem(projectItems, "CodeTemplates"); + List childItems = GetAllChildItems(codeTemplatesFolderItem.ProjectItems); + DTE.ProjectItem scaffoldersFolderItem = childItems.FirstOrDefault(); + + Assert.AreEqual(1, childItems.Count); + Assert.AreEqual("Scaffolders", scaffoldersFolderItem.Name); + } + + [Test] + public void GetEnumerator_ProjectHasTwoFilesInFolderTwoLevelsDeepAndProjectItemsForChildFolderCalledTwice_TopLevelFolderOnlyHasOneProjectItemForChildFolder() + { + CreateProjectItems(); + msbuildProject.FileName = @"d:\projects\MyProject\MyProject.csproj"; + msbuildProject.AddFile(@"CodeTemplates\Scaffolders\File1.cs"); + msbuildProject.AddFile(@"CodeTemplates\Scaffolders\File2.cs"); + + DTE.ProjectItem codeTemplatesFolderItem = GetChildItem(projectItems, "CodeTemplates"); + List childItems = GetAllChildItems(codeTemplatesFolderItem.ProjectItems); + // Call ProjectItems again. + childItems = GetAllChildItems(codeTemplatesFolderItem.ProjectItems); + DTE.ProjectItem scaffoldersFolderItem = childItems.FirstOrDefault(); + + Assert.AreEqual(1, childItems.Count); + Assert.AreEqual("Scaffolders", scaffoldersFolderItem.Name); + } } }