From c1835c0fbce29305eac82cc9c7187f1b635402cd Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sat, 19 May 2012 15:24:20 +0100 Subject: [PATCH] Implement IVsSolution and FlavoredProject for T4 scaffolding. --- .../Project/PackageManagement.csproj | 2 + .../Project/Src/EnvDTE/ProjectType.cs | 6 ++ .../Src/VisualStudio/FlavoredProject.cs | 29 ++++- .../Project/Src/VisualStudio/Package.cs | 5 +- .../Project/Src/VisualStudio/VsConstants.cs | 14 +++ .../Project/Src/VisualStudio/VsSolution.cs | 57 ++++++++++ .../Test/PackageManagement.Tests.csproj | 2 + .../Src/VisualStudio/FlavoredProjectTests.cs | 75 +++++++++++++ .../Test/Src/VisualStudio/PackageTests.cs | 9 ++ .../Test/Src/VisualStudio/VsSolutionTests.cs | 102 ++++++++++++++++++ 10 files changed, 298 insertions(+), 3 deletions(-) create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/VsConstants.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/VsSolution.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/FlavoredProjectTests.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/VsSolutionTests.cs diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj index 6650a684b4..0473bbb41d 100644 --- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj +++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj @@ -405,6 +405,8 @@ + + diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectType.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectType.cs index 9615f1a8f2..06012ac303 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectType.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectType.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.PackageManagement.EnvDTE { @@ -15,6 +16,11 @@ namespace ICSharpCode.PackageManagement.EnvDTE this.Type = GetProjectType(project); } + public ProjectType(MSBuildBasedProject project) + : this(new Project(project)) + { + } + string GetProjectType(Project project) { string extension = project.GetLowercaseFileExtension(); diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/FlavoredProject.cs b/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/FlavoredProject.cs index f9a3c3ff47..2a82552659 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/FlavoredProject.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/FlavoredProject.cs @@ -2,19 +2,44 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.PackageManagement.EnvDTE; +using ICSharpCode.SharpDevelop.Project; using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.Shell.Flavor { public class FlavoredProject : MarshalByRefObject, IVsAggregatableProject, IVsHierarchy { - public FlavoredProject() + MSBuildBasedProject project; + + public FlavoredProject(MSBuildBasedProject project) { + this.project = project; } public int GetAggregateProjectTypeGuids(out string projTypeGuids) { - throw new NotImplementedException(); + projTypeGuids = GetProjectTypeGuidsFromProject(); + if (projTypeGuids == null) { + projTypeGuids = GetProjectTypeGuidsBasedOnProjectFileExtension(); + } + return VsConstants.S_OK; } + + string GetProjectTypeGuidsFromProject() + { + return project.GetUnevalatedProperty("ProjectTypeGuids"); + } + + string GetProjectTypeGuidsBasedOnProjectFileExtension() + { + var projectType = new ProjectType(project); + if (projectType.Type == ProjectType.CSharp) { + return ProjectTypeGuids.CSharp; + } else if (projectType.Type == ProjectType.VBNet) { + return ProjectTypeGuids.VBNet; + } + return String.Empty; + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/Package.cs b/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/Package.cs index 496a25d96b..75ec928424 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/Package.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/Package.cs @@ -3,7 +3,9 @@ using System; using ICSharpCode.PackageManagement.EnvDTE; +using ICSharpCode.PackageManagement.VisualStudio; using Microsoft.VisualStudio.ExtensionManager; +using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.Shell { @@ -11,12 +13,13 @@ namespace Microsoft.VisualStudio.Shell { public static object GetGlobalService(Type serviceType) { - //typeof(IVsSolution) //typeof(SComponentModel) --> not used - console initializer. if (serviceType == typeof(DTE)) { return new DTE(); } else if (serviceType == typeof(SVsExtensionManager)) { return new SVsExtensionManager(); + } else if (serviceType == typeof(IVsSolution)) { + return new VsSolution(); } return null; } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/VsConstants.cs b/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/VsConstants.cs new file mode 100644 index 0000000000..4eb5edd5b1 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/VsConstants.cs @@ -0,0 +1,14 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Microsoft.VisualStudio +{ + public class VsConstants + { + public const int S_OK = 0; + + public const int E_FAIL = -2147467259; + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/VsSolution.cs b/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/VsSolution.cs new file mode 100644 index 0000000000..f525db7fcf --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/VisualStudio/VsSolution.cs @@ -0,0 +1,57 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using System.Linq; + +using ICSharpCode.SharpDevelop.Project; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Shell.Flavor; +using Microsoft.VisualStudio.Shell.Interop; + +namespace ICSharpCode.PackageManagement.VisualStudio +{ + public class VsSolution : MarshalByRefObject, IVsSolution + { + IPackageManagementProjectService projectService; + + public VsSolution() + : this(new PackageManagementProjectService()) + { + } + + public VsSolution(IPackageManagementProjectService projectService) + { + this.projectService = projectService; + } + + public int GetProjectOfUniqueName(string uniqueName, out IVsHierarchy hierarchy) + { + hierarchy = null; + MSBuildBasedProject project = FindProject(uniqueName); + if (project != null) { + hierarchy = new FlavoredProject(project); + return VsConstants.S_OK; + } + return VsConstants.E_FAIL; + } + + MSBuildBasedProject FindProject(string uniqueName) + { + return projectService + .GetOpenProjects() + .SingleOrDefault(project => ProjectUniqueNameMatches(project, uniqueName)) as MSBuildBasedProject; + } + + bool ProjectUniqueNameMatches(IProject project, string uniqueName) + { + return IsCaseInsensitiveMatch(Path.GetFileName(project.FileName), uniqueName); + } + + bool IsCaseInsensitiveMatch(string a, string b) + { + return String.Equals(a, b, StringComparison.OrdinalIgnoreCase); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj index 3bb3f3a5dc..be34d23df6 100644 --- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj +++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj @@ -268,8 +268,10 @@ + + diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/FlavoredProjectTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/FlavoredProjectTests.cs new file mode 100644 index 0000000000..d5bab67447 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/FlavoredProjectTests.cs @@ -0,0 +1,75 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Project; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Shell.Flavor; +using NUnit.Framework; +using PackageManagement.Tests.Helpers; + +namespace PackageManagement.Tests.VisualStudio +{ + [TestFixture] + public class FlavoredProjectTests + { + FlavoredProject project; + TestableProject msbuildProject; + + void CreateFlavoredProject(MSBuildBasedProject msbuildProject) + { + project = new FlavoredProject(msbuildProject); + } + + void CreateMSBuildProject(string fileName) + { + msbuildProject = ProjectHelper.CreateTestProject(); + msbuildProject.FileName = fileName; + } + + void AddProjectTypeGuidsToMSBuildProject(string guids) + { + msbuildProject.SetProperty("ProjectTypeGuids", guids, false); + } + + [Test] + public void GetAggregateProjectTypeGuids_VisualBasicProject_ReturnsVisualBasicProjectTypeGuid() + { + CreateMSBuildProject(@"d:\projects\test\test.vbproj"); + CreateFlavoredProject(msbuildProject); + + string guids; + int result = project.GetAggregateProjectTypeGuids(out guids); + + Assert.AreEqual(VsConstants.S_OK, result); + Assert.AreEqual(ProjectTypeGuids.VBNet, guids); + } + + [Test] + public void GetAggregateProjectTypeGuids_UnknownProject_ReturnsEmptyString() + { + CreateMSBuildProject(@"d:\projects\test\test.unknown"); + CreateFlavoredProject(msbuildProject); + + string guids; + int result = project.GetAggregateProjectTypeGuids(out guids); + + Assert.AreEqual(VsConstants.S_OK, result); + Assert.AreEqual(String.Empty, guids); + } + + [Test] + public void GetAggregateProjectTypeGuids_MSBuildProjectHasProjectTypeGuidsDefined_ReturnsGuidsFromMSBuildProject() + { + CreateMSBuildProject(@"d:\projects\test\test.csproj"); + string expectedGuids = "{E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}"; + AddProjectTypeGuidsToMSBuildProject(expectedGuids); + CreateFlavoredProject(msbuildProject); + + string guids; + project.GetAggregateProjectTypeGuids(out guids); + + Assert.AreEqual(expectedGuids, guids); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/PackageTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/PackageTests.cs index eb6ff4bbb2..4fbf9adcee 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/PackageTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/PackageTests.cs @@ -5,6 +5,7 @@ using System; using ICSharpCode.PackageManagement.EnvDTE; using Microsoft.VisualStudio.ExtensionManager; using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; using NUnit.Framework; namespace PackageManagement.Tests.VisualStudio @@ -35,5 +36,13 @@ namespace PackageManagement.Tests.VisualStudio Assert.IsNull(instance); } + + [Test] + public void GetGlobalService_GetIVsSolution_ReturnsIVsSolution() + { + object solution = Package.GetGlobalService(typeof(IVsSolution)) as IVsSolution; + + Assert.IsInstanceOf(typeof(IVsSolution), solution); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/VsSolutionTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/VsSolutionTests.cs new file mode 100644 index 0000000000..b052ef71f0 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/VisualStudio/VsSolutionTests.cs @@ -0,0 +1,102 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.PackageManagement.Design; +using ICSharpCode.PackageManagement.VisualStudio; +using ICSharpCode.SharpDevelop.Project; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Shell.Interop; +using NUnit.Framework; +using PackageManagement.Tests.Helpers; + +namespace PackageManagement.Tests.VisualStudio +{ + [TestFixture] + public class VsSolutionTests + { + VsSolution solution; + IVsHierarchy hierarchy; + FakePackageManagementProjectService fakeProjectService; + + void CreateVsSolution() + { + fakeProjectService = new FakePackageManagementProjectService(); + solution = new VsSolution(fakeProjectService); + } + + int GetProjectOfUniqueName(string name) + { + return solution.GetProjectOfUniqueName(name, out hierarchy); + } + + void AddProjectToMSBuildSolution(string fileName) + { + TestableProject project = ProjectHelper.CreateTestProject(); + project.FileName = fileName; + fakeProjectService.AddFakeProject(project); + } + + [Test] + public void GetProjectOfUniqueName_NoSolutionOpen_ReturnsError() + { + CreateVsSolution(); + + int result = GetProjectOfUniqueName("Test.csproj"); + + Assert.AreEqual(VsConstants.E_FAIL, result); + } + + [Test] + public void GetProjectOfUniqueName_SolutionHasProjectMatchingUniqueName_ReturnsSuccessAndVsHierarchy() + { + CreateVsSolution(); + AddProjectToMSBuildSolution(@"d:\projects\test\Test.csproj"); + + int result = GetProjectOfUniqueName("Test.csproj"); + + Assert.AreEqual(VsConstants.S_OK, result); + Assert.IsNotNull(hierarchy); + } + + [Test] + public void GetProjectOfUniqueName_SolutionHasProjectButDoesNotMatchUniqueName_ReturnsError() + { + CreateVsSolution(); + AddProjectToMSBuildSolution(@"d:\projects\test\unknown.vbproj"); + + int result = GetProjectOfUniqueName("Test.csproj"); + + Assert.AreEqual(VsConstants.E_FAIL, result); + } + + [Test] + public void GetProjectOfUniqueName_UniqueNameCaseIsIgnored_ReturnsSuccess() + { + CreateVsSolution(); + AddProjectToMSBuildSolution(@"d:\projects\test\test.csproj"); + + int result = GetProjectOfUniqueName("TEST.CSPROJ"); + + Assert.AreEqual(VsConstants.S_OK, result); + Assert.IsNotNull(hierarchy); + } + + [Test] + public void GetProjectOfUniqueName_ProjectTypeGuidsRetrievedFromAggregatableCSharpProject_ReturnsCSharpProjectTypeGuid() + { + CreateVsSolution(); + AddProjectToMSBuildSolution(@"d:\projects\test\test.csproj"); + + GetProjectOfUniqueName("test.csproj"); + + var project = hierarchy as IVsAggregatableProject; + + string guids; + int result = project.GetAggregateProjectTypeGuids(out guids); + + Assert.AreEqual(VsConstants.S_OK, result); + Assert.AreEqual(ProjectTypeGuids.CSharp, guids); + } + } +}