From b01d17d5ddd69dcede9d57a6d13a722c6e900762 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Wed, 30 May 2012 20:40:00 +0100 Subject: [PATCH] Implement EnvDTE.CodeClass.ImplementedInterfaces. --- .../Project/PackageManagement.csproj | 1 + .../Project/Src/EnvDTE/CodeClass.cs | 2 +- .../Project/Src/EnvDTE/CodeInterface.cs | 30 ++++++++++++ .../Project/Src/EnvDTE/CodeType.cs | 2 + .../EnvDTE/ImplementedInterfacesOnClass.cs | 41 +++++++++++++++++ .../Test/Src/EnvDTE/CodeClass2Tests.cs | 46 +++++++++++++++++++ .../Test/Src/Helpers/ProjectContentHelper.cs | 25 ++++++++++ 7 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ImplementedInterfacesOnClass.cs diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj index f41bb9bc4a..cff9bf8c30 100644 --- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj +++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj @@ -102,6 +102,7 @@ + diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs index 973eaa4da9..6045ab52ae 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass.cs @@ -18,7 +18,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE } public virtual CodeElements ImplementedInterfaces { - get { throw new NotImplementedException(); } + get { return new ImplementedInterfacesOnClass(ProjectContent, Class); } } public virtual CodeVariable AddVariable(string name, object type, object Position = null, vsCMAccess Access = vsCMAccess.vsCMAccessPublic, object Location = null) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeInterface.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeInterface.cs index df1b58a376..3a5a564450 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeInterface.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeInterface.cs @@ -8,14 +8,44 @@ namespace ICSharpCode.PackageManagement.EnvDTE { public class CodeInterface : CodeType { + string fullName; + public CodeInterface(IProjectContent projectContent, IClass c) : base(projectContent, c) { + fullName = base.FullName; + } + + public CodeInterface(IProjectContent projectContent, IReturnType type, IClass c) + : base(projectContent, c) + { + fullName = GetFullName(type); + } + + string GetFullName(IReturnType type) + { + return type.DotNetName.Replace("{", "<").Replace("}", ">"); + } + + /// + /// Returns null if base type is not an interface. + /// + public static CodeInterface CreateFromBaseType(IProjectContent projectContent, IReturnType baseType) + { + IClass baseTypeClass = baseType.GetUnderlyingClass(); + if (baseTypeClass.ClassType == ClassType.Interface) { + return new CodeInterface(projectContent, baseType, baseTypeClass); + } + return null; } public CodeFunction AddFunction(string name, vsCMFunction kind, object type, object Position = null, vsCMAccess Access = vsCMAccess.vsCMAccessPublic) { throw new NotImplementedException(); } + + public override string FullName { + get { return fullName; } + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs index acca0888e0..f839e2bddc 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs @@ -19,6 +19,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE : base(c) { this.Class = c; + this.ProjectContent = projectContent; InfoLocation = GetInfoLocation(projectContent, c); } @@ -35,6 +36,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE } protected IClass Class { get; private set; } + protected IProjectContent ProjectContent { get; private set; } public virtual vsCMAccess Access { get { return GetAccess(); } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ImplementedInterfacesOnClass.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ImplementedInterfacesOnClass.cs new file mode 100644 index 0000000000..434d03636f --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ImplementedInterfacesOnClass.cs @@ -0,0 +1,41 @@ +// 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.Dom; + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class ImplementedInterfacesOnClass : CodeElementsList + { + IProjectContent projectContent; + IClass c; + + public ImplementedInterfacesOnClass(IProjectContent projectContent, IClass c) + { + this.projectContent = projectContent; + this.c = c; + AddCodeInterfaces(); + } + + void AddCodeInterfaces() + { + foreach (IReturnType baseType in c.BaseTypes) { + CodeInterface codeInterface = CodeInterface.CreateFromBaseType(projectContent, baseType); + if (codeInterface != null) { + AddCodeElement(codeInterface); + } + } + } + + void AddCodeInterface(IReturnType baseType, IClass baseTypeClass) + { + AddCodeElement(CreateCodeInterface(baseType, baseTypeClass)); + } + + CodeInterface CreateCodeInterface(IReturnType baseType, IClass baseTypeClass) + { + return new CodeInterface(projectContent, baseType, baseTypeClass); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeClass2Tests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeClass2Tests.cs index 8e563e04c2..a29b0dec79 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeClass2Tests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeClass2Tests.cs @@ -45,6 +45,26 @@ namespace PackageManagement.Tests.EnvDTE codeClass = new CodeClass2(helper.FakeProjectContent, fakeClass); } + void AddInterfaceToProjectContent(string fullName) + { + helper.AddInterfaceToProjectContent(fullName); + } + + void AddClassToProjectContent(string fullName) + { + helper.AddClassToProjectContent(fullName); + } + + void AddBaseTypeInterfaceToClass(string fullName, string dotNetName) + { + helper.AddInterfaceToClassBaseTypes(fakeClass, fullName, dotNetName); + } + + void AddBaseTypeClassToClass(string fullName) + { + helper.AddClassToClassBaseTypes(fakeClass, fullName); + } + [Test] public void Language_CSharpProject_ReturnsCSharpModelLanguage() { @@ -90,5 +110,31 @@ namespace PackageManagement.Tests.EnvDTE Assert.AreEqual(vsCMAccess.vsCMAccessPrivate, access); } + + [Test] + public void ImplementedInterfaces_ClassImplementsGenericICollectionOfString_ReturnsCodeInterfaceForICollection() + { + CreateProjectContent(); + CreatePublicClass("MyClass"); + AddBaseTypeInterfaceToClass("System.Collections.Generic.ICollection", "System.Collections.Generic.ICollection{System.String}"); + + CodeElements codeElements = codeClass.ImplementedInterfaces; + CodeInterface codeInterface = codeElements.FirstOrDefault() as CodeInterface; + + Assert.AreEqual(1, codeElements.Count); + Assert.AreEqual("System.Collections.Generic.ICollection", codeInterface.FullName); + } + + [Test] + public void ImplementedInterfaces_ClassHasBaseTypeButNoInterfaces_ReturnsNoItems() + { + CreateProjectContent(); + CreatePublicClass("MyClass"); + AddBaseTypeClassToClass("MyNamespace.MyBaseClass"); + + CodeElements codeElements = codeClass.ImplementedInterfaces; + + Assert.AreEqual(0, codeElements.Count); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectContentHelper.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectContentHelper.cs index 86ceda6e7e..912f50f154 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectContentHelper.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectContentHelper.cs @@ -223,5 +223,30 @@ namespace PackageManagement.Tests.Helpers MakeClassPrivate(fakeDelegate); return fakeDelegate; } + + public void AddInterfaceToClassBaseTypes(IClass fakeClass, string interfaceFullName, string dotNetName) + { + IClass interfaceClass = AddInterfaceToProjectContent(interfaceFullName); + AddClassToClassBaseTypes(fakeClass, interfaceClass, interfaceFullName, dotNetName); + } + + public void AddClassToClassBaseTypes(IClass fakeClass, IClass baseTypeClass, string baseTypeFullName, string baseTypeDotNetName) + { + IReturnType baseType = MockRepository.GenerateStub(); + baseType.Stub(b => b.GetUnderlyingClass()).Return(baseTypeClass); + baseType.Stub(b => b.FullyQualifiedName).Return(baseTypeFullName); + baseType.Stub(b => b.DotNetName).Return(baseTypeDotNetName); + + var baseTypes = new List(); + baseTypes.Add(baseType); + + fakeClass.Stub(c => c.BaseTypes).Return(baseTypes); + } + + public void AddClassToClassBaseTypes(IClass fakeClass, string fullName) + { + IClass baseTypeClass = AddClassToProjectContent(fullName); + AddClassToClassBaseTypes(fakeClass, baseTypeClass, fullName, fullName); + } } }