From 13b519f0623d6c7e6c2d6f1b100e76936f4ee0a5 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sun, 24 Nov 2013 18:45:12 +0000 Subject: [PATCH] Implement parts of EnvDTE.CodeModel --- .../Project/PackageManagement.csproj | 2 + .../Project/Src/EnvDTE/CodeClass2.cs | 20 +- .../Project/Src/EnvDTE/CodeElement.cs | 38 +- .../Src/EnvDTE/CodeElementsInNamespace.cs | 71 +++ .../Project/Src/EnvDTE/CodeElementsList.cs | 41 ++ .../Project/Src/EnvDTE/CodeInterface.cs | 48 +- .../Project/Src/EnvDTE/CodeModel.cs | 117 +++-- .../Project/Src/EnvDTE/CodeModelContext.cs | 1 + .../Project/Src/EnvDTE/CodeNamespace.cs | 102 +++- .../Project/Src/EnvDTE/CodeType.cs | 73 +-- .../Project/Src/EnvDTE/FileCodeModel2.cs | 43 +- .../Src/EnvDTE/FileCodeModelCodeNamespace.cs | 2 +- .../Project/Src/EnvDTE/NamespaceName.cs | 43 ++ .../Project/Src/EnvDTE/Project.cs | 14 +- .../Project/Src/EnvDTE/ProjectItem.cs | 16 +- .../Src/IPackageManagementFileService.cs | 2 + .../Project/Src/IProjectContentExtensions.cs | 6 +- .../Src/PackageManagementFileService.cs | 6 + .../Test/PackageManagement.Tests.csproj | 1 + .../Test/Src/EnvDTE/CodeClass2Tests.cs | 8 +- .../Test/Src/EnvDTE/CodeInterfaceTests.cs | 18 +- .../Test/Src/EnvDTE/CodeModelTests.cs | 460 +++++++++--------- .../Test/Src/EnvDTE/ProjectItemTests.cs | 41 +- .../Test/Src/EnvDTE/ProjectTests.cs | 91 ++-- .../Src/Helpers/CodeElementsExtensions.cs | 196 ++++---- .../Test/Src/Helpers/FakeFileService.cs | 14 +- .../Test/Src/Helpers/TestableProject.cs | 22 + .../Src/Helpers/TestableSolutionSnapshot.cs | 44 ++ 28 files changed, 968 insertions(+), 572 deletions(-) create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElementsInNamespace.cs create mode 100644 src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/NamespaceName.cs create mode 100644 src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableSolutionSnapshot.cs diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj index 35d0e8e672..6cc54ecc1c 100644 --- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj +++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj @@ -98,6 +98,7 @@ + @@ -128,6 +129,7 @@ + diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass2.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass2.cs index 003be6f526..3cf8a5e434 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass2.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeClass2.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop.Dom; namespace ICSharpCode.PackageManagement.EnvDTE @@ -17,10 +18,10 @@ namespace ICSharpCode.PackageManagement.EnvDTE public global::EnvDTE.CodeElements PartialClasses { get { var list = new CodeElementsList(); - var td = typeModel.Resolve(); - if (td != null) { - foreach (var fileName in td.Parts.Select(p => p.UnresolvedFile.FileName).Distinct()) { - var newContext = context.WithFilteredFileName(fileName); + ITypeDefinition typeDefinition = typeModel.Resolve(); + if (typeDefinition != null) { + foreach (string fileName in typeDefinition.Parts.Select(p => p.UnresolvedFile.FileName).Distinct()) { + CodeModelContext newContext = context.WithFilteredFileName(fileName); list.Add(CodeType.Create(newContext, typeModel)); } } else { @@ -42,13 +43,16 @@ namespace ICSharpCode.PackageManagement.EnvDTE return global::EnvDTE.vsCMClassKind.vsCMClassKindMainClass; } set { - if (value == this.ClassKind) + if (value == this.ClassKind) { return; + } + if (value == global::EnvDTE.vsCMClassKind.vsCMClassKindPartialClass) { - var td = typeModel.Resolve(); - if (td == null) + ITypeDefinition typeDefinition = typeModel.Resolve(); + if (typeDefinition == null) { throw new NotSupportedException(); - context.CodeGenerator.MakePartial(td); + } + context.CodeGenerator.MakePartial(typeDefinition); } else { throw new NotSupportedException(); } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElement.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElement.cs index db802abec0..a05b747f8e 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElement.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElement.cs @@ -11,7 +11,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE public class CodeElement : global::EnvDTE.CodeElementBase, global::EnvDTE.CodeElement { DTE dte; - protected readonly CodeModelContext context; + protected CodeModelContext context; readonly ISymbolModel symbolModel; public CodeElement() @@ -27,8 +27,9 @@ namespace ICSharpCode.PackageManagement.EnvDTE { this.context = context; this.symbolModel = symbolModel; - if (symbolModel.ParentProject != null) + if (symbolModel.ParentProject != null) { this.Language = symbolModel.ParentProject.GetCodeModelLanguage(); + } } public static CodeElement CreateMember(CodeModelContext context, IMemberModel m) @@ -61,28 +62,19 @@ namespace ICSharpCode.PackageManagement.EnvDTE // default is vsCMPart.vsCMPartWholeWithAttributes public virtual global::EnvDTE.TextPoint GetStartPoint() { - if (symbolModel != null) - return TextPoint.CreateStartPoint(context, symbolModel.Region); - else - return null; +// if (symbolModel != null) +// return TextPoint.CreateStartPoint(context, symbolModel.Region); + return null; } public virtual global::EnvDTE.TextPoint GetEndPoint() { - if (symbolModel != null) - return TextPoint.CreateEndPoint(context, symbolModel.Region); - else - return null; +// if (symbolModel != null) +// return TextPoint.CreateEndPoint(context, symbolModel.Region); + return null; } - public virtual global::EnvDTE.vsCMInfoLocation InfoLocation { - get { - if (symbolModel != null && symbolModel.ParentProject == context) - return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationProject; - else - return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal; - } - } + public virtual global::EnvDTE.vsCMInfoLocation InfoLocation { get; protected set; } public virtual global::EnvDTE.DTE DTE { get { @@ -99,19 +91,21 @@ namespace ICSharpCode.PackageManagement.EnvDTE protected bool IsInFilter(DomRegion region) { - if (context.FilteredFileName == null) + if (context.FilteredFileName == null) { return true; + } return context.FilteredFileName == region.FileName; } protected CodeElementsList GetAttributes(IEntityModel entityModel) { var list = new CodeElementsList(); - var td = entityModel.Resolve(); + IEntity td = entityModel.Resolve(); if (td != null) { - foreach (var attr in td.Attributes) { - if (IsInFilter(attr.Region)) + foreach (IAttribute attr in td.Attributes) { + if (IsInFilter(attr.Region)) { list.Add(new CodeAttribute2(context, attr)); + } } } return list; diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElementsInNamespace.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElementsInNamespace.cs new file mode 100644 index 0000000000..05b522af1b --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElementsInNamespace.cs @@ -0,0 +1,71 @@ +// 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.Collections; +using System.Collections.Generic; +using System.Linq; + +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Dom; + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class CodeElementsInNamespace : CodeElementsList2 + { + CodeModelContext context; + NamespaceName namespaceName; + INamespace ns; + + public CodeElementsInNamespace(CodeModelContext context) + : this(context, context.DteProject.GetCompilationUnit().RootNamespace) + { + } + + public CodeElementsInNamespace(CodeModelContext context, INamespace ns) + { + this.context = context; + this.ns = ns; + GetCodeElements(); + } + +// public CodeElementsInNamespace(CodeModelContext context, string qualifiedNamespaceName) +// : this(context, new NamespaceName(qualifiedNamespaceName)) +// { +// } +// +// public CodeElementsInNamespace(CodeModelContext context, NamespaceName namespaceName) +// { +// this.context = context; +// this.namespaceName = namespaceName; +// GetCodeElements(); +// } + + void GetCodeElements() + { + foreach (INamespace childNamespace in ns.ChildNamespaces) { + AddCodeNamespace(childNamespace); + } + + foreach (IType type in ns.Types) { + AddType(type); + } + } + + void AddCodeNamespace(INamespace ns) + { + AddCodeElement(new CodeNamespace(context, ns)); + } + + void AddType(IType type) + { + ITypeDefinitionModel typeDefinition = type.GetDefinition().GetModel(); + if (typeDefinition.TypeKind == TypeKind.Interface) { + + } else { + AddCodeElement(new CodeClass2(context, typeDefinition)); + } + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElementsList.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElementsList.cs index cf0bd0be5b..c9d6242248 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElementsList.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeElementsList.cs @@ -9,6 +9,47 @@ using ICSharpCode.SharpDevelop.Dom; namespace ICSharpCode.PackageManagement.EnvDTE { + public class CodeElementsList2 : MarshalByRefObject, global::EnvDTE.CodeElements + { + List elements = new List(); + + public CodeElementsList2() + { + } + + protected virtual void AddCodeElement(CodeElement element) + { + elements.Add(element); + } + + public int Count { + get { return elements.Count; } + } + + public IEnumerator GetEnumerator() + { + return elements.GetEnumerator(); + } + + public global::EnvDTE.CodeElement Item(object index) + { + if (index is int) { + return Item((int)index); + } + return Item((string)index); + } + + global::EnvDTE.CodeElement Item(int index) + { + return elements[index - 1]; + } + + global::EnvDTE.CodeElement Item(string name) + { + return elements.Single(item => item.Name == name); + } + } + public class CodeElementsList : MarshalByRefObject, global::EnvDTE.CodeElements, IList where T : global::EnvDTE.CodeElement { diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeInterface.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeInterface.cs index 4675fe047e..2760d0f50d 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeInterface.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeInterface.cs @@ -1,21 +1,28 @@ -//// 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; +// 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; + //using ICSharpCode.SharpDevelop.Dom; -// -//namespace ICSharpCode.PackageManagement.EnvDTE -//{ -// public class CodeInterface : CodeType, global::EnvDTE.CodeInterface -// { -// string fullName; -// + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class CodeInterface : CodeType, global::EnvDTE.CodeInterface + { + string fullName; + // public CodeInterface(IProjectContent projectContent, IClass c) // : base(projectContent, c) // { -// fullName = base.FullName; // } -// + + public CodeInterface(CodeModelContext context, ITypeDefinitionModel typeModel) + : base(context, typeModel) + { +// fullName = base.FullName; + } + // public CodeInterface(IProjectContent projectContent, IReturnType type, IClass c) // : base(projectContent, c) // { @@ -38,14 +45,15 @@ // return null; // } // -// public global::EnvDTE.CodeFunction AddFunction(string name, global::EnvDTE.vsCMFunction kind, object type, object Position = null, global::EnvDTE.vsCMAccess Access = global::EnvDTE.vsCMAccess.vsCMAccessPublic) -// { -// var codeGenerator = new ClassCodeGenerator(Class); -// return codeGenerator.AddPublicMethod(name, (string)type); -// } + public global::EnvDTE.CodeFunction AddFunction(string name, global::EnvDTE.vsCMFunction kind, object type, object Position = null, global::EnvDTE.vsCMAccess Access = global::EnvDTE.vsCMAccess.vsCMAccessPublic) + { + // var codeGenerator = new ClassCodeGenerator(Class); + // return codeGenerator.AddPublicMethod(name, (string)type); + return null; + } // // public override string FullName { // get { return fullName; } // } -// } -//} + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModel.cs index dad758e68a..4379e42497 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModel.cs @@ -1,49 +1,72 @@ -//// 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 CodeModel : MarshalByRefObject, global::EnvDTE.CodeModel -// { -// IProjectContent projectContent; -// CodeElementsInNamespace codeElements; -// -// public CodeModel(IProjectContent projectContent) -// { -// this.projectContent = projectContent; -// } -// -// public global::EnvDTE.CodeElements CodeElements { -// get { -// if (codeElements == null) { -// codeElements = new CodeElementsInNamespace(projectContent, String.Empty); +// 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.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Dom; + +namespace ICSharpCode.PackageManagement.EnvDTE +{ + public class CodeModel : MarshalByRefObject, global::EnvDTE.CodeModel + { + Project project; + CodeElementsInNamespace codeElements; + CodeModelContext context; + + public CodeModel(CodeModelContext context, Project project) + { + this.context = context; + this.project = project; + } + + public global::EnvDTE.CodeElements CodeElements { + get { + if (codeElements == null) { + codeElements = new CodeElementsInNamespace(context); + } + return codeElements; + } + } + + public global::EnvDTE.CodeType CodeTypeFromFullName(string name) + { + ITypeDefinitionModel typeDefinition = GetTypeDefinition(name); + if (typeDefinition != null) { + return CreateCodeTypeForTypeDefinition(typeDefinition); + } + return null; + } + + ITypeDefinitionModel GetTypeDefinition(string name) + { + ICompilation compilation = project.GetCompilationUnit(); + var typeName = new TopLevelTypeName(name); + ITypeDefinitionModel typeDefinitionModel = project.MSBuildProject.AssemblyModel.TopLevelTypeDefinitions[typeName]; + if (typeDefinitionModel != null) { + return typeDefinitionModel; + } + +// foreach (IAssembly assembly in compilation.ReferencedAssemblies) { +// ITypeDefinition typeDefinition = assembly.GetTypeDefinition(typeName); +// if (typeDefinition != null) { +// return typeDefinition.GetModel(); // } -// return codeElements; // } -// } -// -// public global::EnvDTE.CodeType CodeTypeFromFullName(string name) -// { -// IClass matchedClass = projectContent.GetClass(name, 0); -// if (matchedClass != null) { -// return CreateCodeTypeForClass(matchedClass); -// } -// return null; -// } -// -// CodeType CreateCodeTypeForClass(IClass c) -// { -// if (c.ClassType == ClassType.Interface) { -// return new CodeInterface(projectContent, c); -// } -// return new CodeClass2(projectContent, c); -// } -// -// public string Language { -// get { return projectContent.GetCodeModelLanguage(); } -// } -// } -//} + + return null; + } + + CodeType CreateCodeTypeForTypeDefinition(ITypeDefinitionModel typeDefinition) + { + if (typeDefinition.TypeKind == TypeKind.Interface) { + return new CodeInterface(null, typeDefinition); + } + return new CodeClass2(null, typeDefinition); + } + + public string Language { + get { return project.MSBuildProject.GetCodeModelLanguage(); } + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModelContext.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModelContext.cs index 6a23cc9a11..36141cf1fe 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModelContext.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeModelContext.cs @@ -9,6 +9,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE { public class CodeModelContext { + public EnvDTE.Project DteProject { get; set; } public IProject CurrentProject { get; set; } public IDocumentLoader DocumentLoader { get; set; } public CodeGenerator CodeGenerator { get; set; } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespace.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespace.cs index a83587a998..d76e2c83d1 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespace.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeNamespace.cs @@ -3,52 +3,110 @@ using System; using System.Collections.Generic; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop.Dom; namespace ICSharpCode.PackageManagement.EnvDTE { public class CodeNamespace : CodeElement, global::EnvDTE.CodeNamespace { - readonly string fullName; - INamespaceModel model; + INamespace ns; - public CodeNamespace(CodeModelContext context, INamespaceModel model) - : base(context, model) + public CodeNamespace(CodeModelContext context, INamespace ns) { - this.model = model; + this.ns = ns; + //this.InfoLocation = global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal; + //this.Language = context.CurrentProject.GetCodeModelLanguage(); } - public CodeNamespace(CodeModelContext context, string fullName) - : base(context) + public override global::EnvDTE.vsCMElement Kind { + get { return global::EnvDTE.vsCMElement.vsCMElementNamespace; } + } + +// internal NamespaceName NamespaceName { +// get { return namespaceName; } +// } + + public string FullName { + get { return ns.FullName; } + } + + public override string Name { + get { return ns.Name; } + } + + public virtual global::EnvDTE.CodeElements Members { + get { return new CodeElementsInNamespace(context, ns); } + } + +// CodeElementsList members; + +// public virtual global::EnvDTE.CodeElements Members { +// get { +// if (members == null) { +// if (model == null) +// throw new NotSupportedException(); +// IModelCollection namespaceMembers = model.ChildNamespaces.Select(ns => new CodeNamespace(context, ns)); +// IModelCollection typeMembers = model.Types.Select(td => CodeType.Create(context, td)); +// members = namespaceMembers.Concat(typeMembers).AsCodeElements(); +// } +// return members; +// } +// } + } + + // Move code below into FileCodeModelNamespace + public class CodeNamespaceBase : CodeElement, global::EnvDTE.CodeNamespace + { + NamespaceName namespaceName; + + public CodeNamespaceBase(CodeModelContext context, string qualifiedName) + : this(context, new NamespaceName(qualifiedName)) { - this.fullName = fullName; + } + + public CodeNamespaceBase(CodeModelContext context, NamespaceName namespaceName) + { + this.context = context; + this.namespaceName = namespaceName; + this.InfoLocation = global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal; + this.Language = context.CurrentProject.GetCodeModelLanguage(); } public override global::EnvDTE.vsCMElement Kind { get { return global::EnvDTE.vsCMElement.vsCMElementNamespace; } } - public override global::EnvDTE.vsCMInfoLocation InfoLocation { - get { return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal; } + internal NamespaceName NamespaceName { + get { return namespaceName; } } public string FullName { - get { return fullName; } + get { return namespaceName.QualifiedName; } } - CodeElementsList members; + public override string Name { + get { return namespaceName.LastPart; } + } public virtual global::EnvDTE.CodeElements Members { - get { - if (members == null) { - if (model == null) - throw new NotSupportedException(); - IModelCollection namespaceMembers = model.ChildNamespaces.Select(ns => new CodeNamespace(context, ns)); - IModelCollection typeMembers = model.Types.Select(td => CodeType.Create(context, td)); - members = namespaceMembers.Concat(typeMembers).AsCodeElements(); - } - return members; - } + get { throw new NotImplementedException(); } + //get { return new CodeElementsInNamespace(context, namespaceName); } } + +// CodeElementsList members; + +// public virtual global::EnvDTE.CodeElements Members { +// get { +// if (members == null) { +// if (model == null) +// throw new NotSupportedException(); +// IModelCollection namespaceMembers = model.ChildNamespaces.Select(ns => new CodeNamespace(context, ns)); +// IModelCollection typeMembers = model.Types.Select(td => CodeType.Create(context, td)); +// members = namespaceMembers.Concat(typeMembers).AsCodeElements(); +// } +// return members; +// } +// } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs index 5fa3f7f37d..e18ae87e21 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs @@ -16,15 +16,17 @@ namespace ICSharpCode.PackageManagement.EnvDTE public class CodeType : CodeElement, global::EnvDTE.CodeType { protected readonly ITypeDefinitionModel typeModel; + CodeElementsList members; public static CodeType Create(CodeModelContext context, IType type) { - var typeDef = type.GetDefinition(); + ITypeDefinition typeDef = type.GetDefinition(); if (typeDef != null) { - var typeModel = typeDef.GetModel(); - if (typeModel != null) + ITypeDefinitionModel typeModel = typeDef.GetModel(); + if (typeModel != null) { return Create(context.WithFilteredFileName(null), typeModel); + } } return null; } @@ -49,15 +51,19 @@ namespace ICSharpCode.PackageManagement.EnvDTE } } - /// - /// Note that projectContent may be different to the IClass.ProjectContent since the class - /// is retrieved from the namespace contents and could belong to a separate project or - /// referenced assembly. - /// public CodeType(CodeModelContext context, ITypeDefinitionModel typeModel) : base(context, typeModel) { this.typeModel = typeModel; + this.InfoLocation = GetInfoLocation(); + } + + global::EnvDTE.vsCMInfoLocation GetInfoLocation() + { + if (typeModel != null) { + return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationProject; + } + return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal; } public CodeType() @@ -67,27 +73,27 @@ namespace ICSharpCode.PackageManagement.EnvDTE public virtual global::EnvDTE.vsCMAccess Access { get { return typeModel.Accessibility.ToAccess(); } set { - var td = typeModel.Resolve(); - if (td != null) { - context.CodeGenerator.ChangeAccessibility(td, value.ToAccessibility()); + ITypeDefinition typeDefinition = typeModel.Resolve(); + if (typeDefinition != null) { + context.CodeGenerator.ChangeAccessibility(typeDefinition, value.ToAccessibility()); } } } public virtual string FullName { get { - var fullTypeName = typeModel.FullTypeName; - StringBuilder b = new StringBuilder(); + FullTypeName fullTypeName = typeModel.FullTypeName; + var fullName = new StringBuilder(); if (!string.IsNullOrEmpty(fullTypeName.TopLevelTypeName.Namespace)) { - b.Append(fullTypeName.TopLevelTypeName.Namespace); - b.Append('.'); + fullName.Append(fullTypeName.TopLevelTypeName.Namespace); + fullName.Append('.'); } - b.Append(fullTypeName.TopLevelTypeName.Name); + fullName.Append(fullTypeName.TopLevelTypeName.Name); for (int i = 0; i < fullTypeName.NestingLevel; i++) { - b.Append('.'); - b.Append(fullTypeName.GetNestedTypeName(i)); + fullName.Append('.'); + fullName.Append(fullTypeName.GetNestedTypeName(i)); } - return b.ToString(); + return fullName.ToString(); } } @@ -106,17 +112,19 @@ namespace ICSharpCode.PackageManagement.EnvDTE public virtual global::EnvDTE.CodeElements Bases { get { var list = new CodeElementsList(); - var td = typeModel.Resolve(); - if (td != null) { + ITypeDefinition typeDefinition = typeModel.Resolve(); + if (typeDefinition != null) { IEnumerable baseTypes; - if (td.Kind == TypeKind.Interface) - baseTypes = td.DirectBaseTypes; - else - baseTypes = td.DirectBaseTypes.Where(t => t.Kind != TypeKind.Interface); - foreach (var baseType in baseTypes) { + if (typeDefinition.Kind == TypeKind.Interface) { + baseTypes = typeDefinition.DirectBaseTypes; + } else { + baseTypes = typeDefinition.DirectBaseTypes.Where(type => type.Kind != TypeKind.Interface); + } + foreach (IType baseType in baseTypes) { CodeType element = Create(context, baseType); - if (element != null) + if (element != null) { list.Add(element); + } } } return list; @@ -131,11 +139,12 @@ namespace ICSharpCode.PackageManagement.EnvDTE public virtual global::EnvDTE.CodeNamespace Namespace { get { - if (context.FilteredFileName != null) - return new FileCodeModel2(context).GetNamespace(typeModel.Namespace); - else + if (context.FilteredFileName != null) { + return new FileCodeModel2(context, null).GetNamespace(typeModel.Namespace); + } else { throw new NotImplementedException(); // return new CodeNamespace(context, typeModel.Namespace); + } } } @@ -154,8 +163,8 @@ namespace ICSharpCode.PackageManagement.EnvDTE /// protected override bool GetIsDerivedFrom(string fullName) { - var td = typeModel.Resolve(); - return td != null && td.GetAllBaseTypeDefinitions().Any(b => b.FullName == fullName); + ITypeDefinition typeDefinition = typeModel.Resolve(); + return typeDefinition != null && typeDefinition.GetAllBaseTypeDefinitions().Any(baseType => baseType.FullName == fullName); } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileCodeModel2.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileCodeModel2.cs index 39a80beb6d..1e5f6f8c62 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileCodeModel2.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileCodeModel2.cs @@ -16,29 +16,34 @@ namespace ICSharpCode.PackageManagement.EnvDTE { public class FileCodeModel2 : MarshalByRefObject, global::EnvDTE.FileCodeModel2 { - readonly CodeModelContext context; + CodeModelContext context; CodeElementsList codeElements = new CodeElementsList(); Dictionary namespaces = new Dictionary(); - public FileCodeModel2(CodeModelContext context) + public FileCodeModel2(CodeModelContext context, Project project) { - if (context == null || context.FilteredFileName == null) + if (context == null || context.FilteredFileName == null) { throw new ArgumentException("context must be restricted to a file"); + } + this.context = context; - var compilation = SD.ParserService.GetCompilation(context.CurrentProject); + ICompilation compilation = project.GetCompilationUnit(); var projectContent = compilation.MainAssembly.UnresolvedAssembly as IProjectContent; if (projectContent != null) { IUnresolvedFile file = projectContent.GetFile(context.FilteredFileName); if (file != null) { var csharpFile = file as CSharpUnresolvedFile; - if (csharpFile != null) + if (csharpFile != null) { AddUsings(codeElements, csharpFile.RootUsingScope, compilation); + } var resolveContext = new SimpleTypeResolveContext(compilation.MainAssembly); - AddTypes(file.TopLevelTypeDefinitions - .Select(td => td.Resolve(resolveContext) as ITypeDefinition) - .Where(td => td != null).Distinct()); + AddTypes( + file.TopLevelTypeDefinitions + .Select(td => td.Resolve(resolveContext) as ITypeDefinition) + .Where(td => td != null) + .Distinct()); } } } @@ -49,23 +54,25 @@ namespace ICSharpCode.PackageManagement.EnvDTE void AddTypes(IEnumerable types) { - foreach (var td in types) { - var model = td.GetModel(); - if (model == null) + foreach (ITypeDefinition typeDefinition in types) { + ITypeDefinitionModel model = typeDefinition.GetModel(); + if (model == null) { continue; - var codeType = CodeType.Create(context, td); - if (string.IsNullOrEmpty(td.Namespace)) + } + CodeType codeType = CodeType.Create(context, typeDefinition); + if (string.IsNullOrEmpty(typeDefinition.Namespace)) { codeElements.Add(codeType); - else - GetNamespace(td.Namespace).AddMember(codeType); + } else { + GetNamespace(typeDefinition.Namespace).AddMember(codeType); + } } - codeElements.AddRange(types.Select(td => CodeType.Create(context, td))); + codeElements.AddRange(types.Select(typeDefinition => CodeType.Create(context, typeDefinition))); } public static void AddUsings(CodeElementsList codeElements, UsingScope usingScope, ICompilation compilation) { - var resolvedUsingScope = usingScope.Resolve(compilation); - foreach (var ns in resolvedUsingScope.Usings) { + ResolvedUsingScope resolvedUsingScope = usingScope.Resolve(compilation); + foreach (INamespace ns in resolvedUsingScope.Usings) { codeElements.Add(new CodeImport(ns.FullName)); } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileCodeModelCodeNamespace.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileCodeModelCodeNamespace.cs index 1dfc8fe3fc..6766ba63c6 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileCodeModelCodeNamespace.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/FileCodeModelCodeNamespace.cs @@ -13,7 +13,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE /// This differs from the CodeModel CodeNamespace which breaks up the namespaces into /// parts. /// - public class FileCodeModelCodeNamespace : CodeNamespace + public class FileCodeModelCodeNamespace : CodeNamespaceBase { public FileCodeModelCodeNamespace(CodeModelContext context, string namespaceName) : base(context, namespaceName) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/NamespaceName.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/NamespaceName.cs new file mode 100644 index 0000000000..8fea477cce --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/NamespaceName.cs @@ -0,0 +1,43 @@ +// 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 ICSharpCode.PackageManagement.EnvDTE +{ + public class NamespaceName + { + public NamespaceName(string parentNamespace, string name) + : this(GetQualifiedNamespaceName(parentNamespace, name)) + { + } + + static string GetQualifiedNamespaceName(string parentNamespace, string name) + { + if (String.IsNullOrEmpty(parentNamespace)) { + return name; + } + return String.Format("{0}.{1}", parentNamespace, name); + } + + public NamespaceName(string qualifiedName) + { + this.QualifiedName = qualifiedName; + LastPart = GetLastPartOfNamespace(); + } + + string GetLastPartOfNamespace() + { + int index = QualifiedName.LastIndexOf('.'); + return QualifiedName.Substring(index + 1); + } + + public string LastPart { get; private set; } + public string QualifiedName { get; private set; } + + public NamespaceName CreateChildNamespaceName(string name) + { + return new NamespaceName(QualifiedName, name); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs index 33254073d7..5f9f27a323 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs @@ -22,6 +22,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE IPackageManagementProjectService projectService; IPackageManagementFileService fileService; DTE dte; + CodeModelContext context; public Project(MSBuildBasedProject project) : this( @@ -40,6 +41,11 @@ namespace ICSharpCode.PackageManagement.EnvDTE this.projectService = projectService; this.fileService = fileService; + context = new CodeModelContext { + CurrentProject = project, + DteProject = this + }; + CreateProperties(); Object = new ProjectObject(this); ProjectItems = new ProjectItems(this, this); @@ -228,8 +234,7 @@ namespace ICSharpCode.PackageManagement.EnvDTE } public virtual global::EnvDTE.CodeModel CodeModel { - get { throw new NotImplementedException(); } - //get { return new CodeModel(projectService.GetProjectContent(MSBuildProject) ); } + get { return new CodeModel(context, this); } } public virtual global::EnvDTE.ConfigurationManager ConfigurationManager { @@ -297,6 +302,11 @@ namespace ICSharpCode.PackageManagement.EnvDTE return fileService.GetCompilationUnit(fileName); } + internal ICompilation GetCompilationUnit() + { + return fileService.GetCompilationUnit(MSBuildProject); + } + internal void RemoveProjectItem(ProjectItem projectItem) { projectService.RemoveProjectItem(MSBuildProject, projectItem.MSBuildProjectItem); diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs index 86277bc468..9fa8c78ec8 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/ProjectItem.cs @@ -155,14 +155,20 @@ namespace ICSharpCode.PackageManagement.EnvDTE public global::EnvDTE.FileCodeModel2 FileCodeModel { get { -// if (!IsDirectory) { -// return new FileCodeModel2(containingProject, projectItem); -// } -// return null; - throw new NotImplementedException(); + if (!IsDirectory) { + return new FileCodeModel2(CreateModelContext(), containingProject); + } + return null; } } + CodeModelContext CreateModelContext() + { + return new CodeModelContext { + FilteredFileName = projectItem.FileName + }; + } + internal string GetIncludePath(string fileName) { string relativeDirectory = GetProjectItemRelativePathToProject(); diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementFileService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementFileService.cs index 59019966aa..8719f87586 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementFileService.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementFileService.cs @@ -6,6 +6,7 @@ using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.PackageManagement { @@ -23,5 +24,6 @@ namespace ICSharpCode.PackageManagement void ParseFile(string fileName); ICompilation GetCompilationUnit(string fileName); + ICompilation GetCompilationUnit(IProject project); } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/IProjectContentExtensions.cs b/src/AddIns/Misc/PackageManagement/Project/Src/IProjectContentExtensions.cs index ad898061a2..ca57acdcc1 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/IProjectContentExtensions.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/IProjectContentExtensions.cs @@ -22,10 +22,10 @@ namespace ICSharpCode.PackageManagement public static global::EnvDTE.vsCMAccess ToAccess(this Accessibility accessiblity) { - if (accessiblity == Accessibility.Public) + if (accessiblity == Accessibility.Public) { return global::EnvDTE.vsCMAccess.vsCMAccessPublic; - else - return global::EnvDTE.vsCMAccess.vsCMAccessPrivate; + } + return global::EnvDTE.vsCMAccess.vsCMAccessPrivate; } public static Accessibility ToAccessibility(this global::EnvDTE.vsCMAccess access) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementFileService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementFileService.cs index a25dd12af6..c0ac5ab667 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementFileService.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementFileService.cs @@ -8,6 +8,7 @@ using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.PackageManagement { @@ -83,5 +84,10 @@ namespace ICSharpCode.PackageManagement { return SD.ParserService.GetCompilationForFile(new FileName(fileName)); } + + public ICompilation GetCompilationUnit(IProject project) + { + return SD.ParserService.GetCompilation(project); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj index b897dc544e..b950f9bf6a 100644 --- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj +++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj @@ -141,6 +141,7 @@ + diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeClass2Tests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeClass2Tests.cs index 26855c8f04..f9f1147cad 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeClass2Tests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeClass2Tests.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.PackageManagement; using ICSharpCode.PackageManagement.EnvDTE; using ICSharpCode.SharpDevelop.Dom; @@ -57,7 +58,7 @@ namespace PackageManagement.Tests.EnvDTE } [Test] - public void Access_InternalClass_ReturnsPrivate() + public void Access_PrivateClass_ReturnsPrivate() { CreateClass("class MyClass {}"); @@ -69,8 +70,9 @@ namespace PackageManagement.Tests.EnvDTE // [Test] // public void ImplementedInterfaces_ClassImplementsGenericICollectionOfString_ReturnsCodeInterfaceForICollection() // { -// CreateClass("using System.Collection.Generic;" + -// "class MyClass : ICollection {}"); +// CreateClass( +// "using System.Collection.Generic;" + +// "class MyClass : ICollection {}"); // // global::EnvDTE.CodeElements codeElements = codeClass.ImplementedInterfaces; // CodeInterface codeInterface = codeElements.FirstCodeInterfaceOrDefault(); diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeInterfaceTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeInterfaceTests.cs index b12a6a1b0e..379b139885 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeInterfaceTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeInterfaceTests.cs @@ -10,27 +10,21 @@ //namespace PackageManagement.Tests.EnvDTE //{ // [TestFixture] -// public class CodeInterfaceTests +// public class CodeInterfaceTests : CodeModelTestBase // { -// ProjectContentHelper helper; // CodeInterface codeInterface; // -// [SetUp] -// public void Init() +// void CreateInterface(string code) // { -// helper = new ProjectContentHelper(); -// } -// -// void CreateInterface() -// { -// IClass c = helper.AddInterfaceToProjectContent("MyInterface"); -// codeInterface = new CodeInterface(helper.ProjectContent, c); +// AddCodeFile("interface.cs", code); +// ITypeDefinitionModel typeModel = assemblyModel.TopLevelTypeDefinitions.Single(); +// codeInterface = new CodeInterface(codeModelContext, typeModel); // } // // [Test] // public void Kind_Interface_ReturnsInterface() // { -// CreateInterface(); +// CreateInterface("interface MyInterface {}"); // // global::EnvDTE.vsCMElement kind = codeInterface.Kind; // diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeModelTests.cs index 3dea3ecec1..d132291913 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/CodeModelTests.cs @@ -1,66 +1,76 @@ -//// 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.Collections.Generic; -//using System.Linq; -//using ICSharpCode.PackageManagement.EnvDTE; -//using ICSharpCode.SharpDevelop.Dom; -//using NUnit.Framework; -//using PackageManagement.Tests.Helpers; -//using Rhino.Mocks; -// -//namespace PackageManagement.Tests.EnvDTE -//{ -// [TestFixture] -// public class CodeModelTests -// { -// CodeModel codeModel; -// ProjectContentHelper helper; -// TestableProject msbuildProject; -// -// void CreateCodeModel() -// { -// CreateProjectContentHelper(); -// CreateProjectForProjectContent(); -// CreateCodeModel(helper.ProjectContent); -// } -// -// void CreateProjectForProjectContent() -// { -// msbuildProject = ProjectHelper.CreateTestProject(); -// helper.SetProjectForProjectContent(msbuildProject); -// } -// -// void CreateProjectContentHelper() -// { -// helper = new ProjectContentHelper(); -// } -// -// void CreateCodeModel(IProjectContent projectContent) -// { -// codeModel = new CodeModel(projectContent); -// } -// -// void CreateCodeModelWithCSharpProject() -// { -// CreateProjectContentHelper(); -// helper.ProjectContentIsForCSharpProject(); -// CreateCodeModel(helper.ProjectContent); -// } -// -// void CreateCodeModelWithVisualBasicProject() -// { -// CreateProjectContentHelper(); -// helper.ProjectContentIsForVisualBasicProject(); -// CreateCodeModel(helper.ProjectContent); -// } -// -// void AddClassToProjectContent(string className) -// { -// helper.AddClassToProjectContent(className); -// } -// +// 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.Collections.Generic; +using System.Linq; + +using ICSharpCode.Core; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; +using ICSharpCode.PackageManagement; +using ICSharpCode.PackageManagement.EnvDTE; +using ICSharpCode.SharpDevelop.Dom; +using NUnit.Framework; +using PackageManagement.Tests.Helpers; +using Rhino.Mocks; + +namespace PackageManagement.Tests.EnvDTE +{ + [TestFixture] + public class CodeModelTests : CodeModelTestBase + { + CodeModel codeModel; + Project dteProject; + IPackageManagementProjectService fakeProjectService; + IPackageManagementFileService fakeFileService; + TestableProject msbuildProject; + + void CreateCodeModel() + { + msbuildProject = ProjectHelper.CreateTestProject(); + + fakeProjectService = MockRepository.GenerateStub(); + fakeFileService = MockRepository.GenerateStub(); + dteProject = new Project(msbuildProject, fakeProjectService, fakeFileService); + codeModelContext.DteProject = dteProject; + + codeModel = new CodeModel(codeModelContext, dteProject); + + msbuildProject.SetAssemblyModel(assemblyModel); + project.Stub(p => p.AssemblyModel).Return(assemblyModel); + + fakeFileService + .Stub(fileService => fileService.GetCompilationUnit(msbuildProject)) + .WhenCalled(compilation => compilation.ReturnValue = CreateCompilation()); + } + + ICompilation CreateCompilation() + { + var solutionSnapshot = new TestableSolutionSnapshot(msbuildProject); + msbuildProject.SetProjectContent(projectContent); + ICompilation compilation = new SimpleCompilation(solutionSnapshot, projectContent, projectContent.AssemblyReferences); + solutionSnapshot.AddCompilation(projectContent, compilation); + return compilation; + } + + void CreateCodeModelWithCSharpProject() + { + CreateCodeModel(); + msbuildProject.FileName = new FileName(@"c:\projects\MyProject.csproj"); + } + + void CreateCodeModelWithVisualBasicProject() + { + CreateCodeModel(); + msbuildProject.FileName = new FileName(@"c:\projects\MyProject.vbproj"); + } + + void AddClassToProject(string code) + { + AddCodeFile("class.cs", code); + } + // void AddClassToDifferentProjectContent(string className) // { // helper.AddClassToDifferentProjectContent(className); @@ -81,148 +91,132 @@ // helper.AddInterfaceToDifferentProjectContent(interfaceName); // } // -// void ProjectIsCSharpProject() -// { -// helper.ProjectContentIsForCSharpProject(); -// } -// -// void ProjectIsVisualBasicProject() -// { -// helper.ProjectContentIsForVisualBasicProject(); -// } -// -// [Test] -// public void CodeTypeFromFullName_NoSuchTypeInProject_ReturnsNull() -// { -// CreateCodeModel(); -// -// global::EnvDTE.CodeType codeType = codeModel.CodeTypeFromFullName("UnknownType"); -// -// Assert.IsNull(codeType); -// } -// -// [Test] -// public void CodeTypeFromFullName_ClassExistsInProject_ReturnsCodeClass2() -// { -// CreateCodeModel(); -// AddClassToProjectContent("Tests.TestClass"); -// -// var codeClass = codeModel.CodeTypeFromFullName("Tests.TestClass") as CodeClass2; -// -// Assert.AreEqual("Tests.TestClass", codeClass.FullName); -// Assert.AreEqual("TestClass", codeClass.Name); -// } -// -// [Test] -// public void CodeTypeFromFullName_ClassWithoutNamespaceExistsInProject_ReturnsCodeClass2() -// { -// CreateCodeModel(); -// AddClassToProjectContent("TestClass"); -// -// var codeClass = codeModel.CodeTypeFromFullName("TestClass") as CodeClass2; -// -// Assert.AreEqual("TestClass", codeClass.FullName); -// } -// -// [Test] -// public void CodeTypeFromFullName_InterfaceExistsInProject_ReturnsCodeInterface() -// { -// CreateCodeModel(); -// AddInterfaceToProjectContent("Interface1"); -// -// var codeInterface = codeModel.CodeTypeFromFullName("Interface1") as CodeInterface; -// -// Assert.AreEqual("Interface1", codeInterface.FullName); -// } -// -// [Test] -// public void CodeElements_OneNamespaceInProject_ReturnsOneCodeNamespaceItem() -// { -// CreateCodeModel(); -// helper.AddNamespaceCompletionEntryInNamespace(String.Empty, "Test"); -// -// global::EnvDTE.CodeElements codeElements = codeModel.CodeElements; -// global::EnvDTE.CodeNamespace codeNamespace = codeElements.FirstCodeNamespaceOrDefault(); -// -// Assert.AreEqual(1, codeElements.Count); -// Assert.AreEqual("Test", codeNamespace.FullName); -// Assert.AreEqual("Test", codeNamespace.Name); -// } -// -// [Test] -// public void CodeElements_OneNamespaceInProjectWithTwoPartsToName_ReturnsOneCodeNamespaceItemWithFirstPartOfNamespaceAsName() -// { -// CreateCodeModel(); -// helper.AddNamespaceCompletionEntryInNamespace(String.Empty, "First"); -// helper.AddNamespaceCompletionEntryInNamespace("First", "Second"); -// -// global::EnvDTE.CodeElements codeElements = codeModel.CodeElements; -// global::EnvDTE.CodeNamespace codeNamespace = codeElements.FirstCodeNamespaceOrDefault(); -// -// Assert.AreEqual(1, codeElements.Count); -// Assert.AreEqual("First", codeNamespace.FullName); -// Assert.AreEqual("First", codeNamespace.Name); -// } -// -// [Test] -// public void CodeElements_OneClassWithNoNamespaceInProject_ReturnsOneCodeClassItem() -// { -// CreateCodeModel(); -// AddClassToProjectContent(String.Empty, "TestClass"); -// -// global::EnvDTE.CodeElements codeElements = codeModel.CodeElements; -// CodeClass2 codeClass = codeElements.FirstCodeClass2OrDefault(); -// -// Assert.AreEqual(1, codeElements.Count); -// Assert.AreEqual("TestClass", codeClass.FullName); -// } -// -// [Test] -// public void CodeElements_TwoNamespacesInProjectWithFirstPartsTheName_ReturnsOneParentNamespaceWithTwoChildNamespaces() -// { -// CreateCodeModel(); -// helper.AddNamespaceCompletionEntryInNamespace(String.Empty, "First"); -// helper.AddNamespaceCompletionEntriesInNamespace("First", "A", "B"); -// helper.NoCompletionItemsInNamespace("First.A"); -// helper.NoCompletionItemsInNamespace("First.B"); -// -// global::EnvDTE.CodeElements codeElements = codeModel.CodeElements; -// CodeNamespace codeNamespace = codeElements.FirstCodeNamespaceOrDefault(); -// -// global::EnvDTE.CodeElements members = codeNamespace.Members; -// CodeNamespace firstChildNamespace = members.FirstCodeNamespaceOrDefault(); -// CodeNamespace secondChildNamespace = members.LastCodeNamespaceOrDefault(); -// -// Assert.AreEqual(1, codeElements.Count); -// Assert.AreEqual("First", codeNamespace.FullName); -// Assert.AreEqual(2, codeNamespace.Members.Count); -// Assert.AreEqual("A", firstChildNamespace.Name); -// Assert.AreEqual("B", secondChildNamespace.Name); -// } -// -// [Test] -// public void CodeElements_ProjectHasEmptyNamespaceName_EmptyNamespaceNameNotIncludedInMembers() -// { -// CreateCodeModel(); -// helper.AddNamespaceCompletionEntriesInNamespace(String.Empty, String.Empty, "Tests"); -// -// global::EnvDTE.CodeElements members = codeModel.CodeElements; -// CodeNamespace codeNamespace = members.FirstCodeNamespaceOrDefault(); -// -// Assert.AreEqual(1, members.Count); -// Assert.AreEqual("Tests", codeNamespace.Name); -// } -// -// [Test] -// public void CodeTypeFromFullName_ClassExistsInProject_InfoLocationIsLocalProject() -// { -// CreateCodeModel(); -// AddClassToProjectContent("Tests.TestClass"); -// -// var codeClass = codeModel.CodeTypeFromFullName("Tests.TestClass") as CodeClass2; -// -// Assert.AreEqual(global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationProject, codeClass.InfoLocation); -// } + [Test] + public void CodeTypeFromFullName_NoSuchTypeInProject_ReturnsNull() + { + CreateCodeModel(); + + global::EnvDTE.CodeType codeType = codeModel.CodeTypeFromFullName("UnknownType"); + + Assert.IsNull(codeType); + } + + [Test] + public void CodeTypeFromFullName_ClassExistsInProject_ReturnsCodeClass2() + { + CreateCodeModel(); + AddClassToProject( + "namespace Tests {\r\n" + + " public class TestClass {} \r\n" + + "}"); + + var codeClass = codeModel.CodeTypeFromFullName("Tests.TestClass") as CodeClass2; + + Assert.AreEqual("Tests.TestClass", codeClass.FullName); + Assert.AreEqual("TestClass", codeClass.Name); + } + + [Test] + public void CodeTypeFromFullName_ClassWithoutNamespaceExistsInProject_ReturnsCodeClass2() + { + CreateCodeModel(); + AddClassToProject("public class TestClass {}"); + + var codeClass = codeModel.CodeTypeFromFullName("TestClass") as CodeClass2; + + Assert.AreEqual("TestClass", codeClass.FullName); + } + + [Test] + public void CodeTypeFromFullName_InterfaceExistsInProject_ReturnsCodeInterface() + { + CreateCodeModel(); + AddClassToProject("public interface Interface1 {}"); + + var codeInterface = codeModel.CodeTypeFromFullName("Interface1") as CodeInterface; + + Assert.AreEqual("Interface1", codeInterface.FullName); + } + + [Test] + public void CodeElements_OneNamespaceInProject_ReturnsOneCodeNamespaceItem() + { + CreateCodeModel(); + AddClassToProject("namespace Test {}"); + + global::EnvDTE.CodeElements codeElements = codeModel.CodeElements; + global::EnvDTE.CodeNamespace codeNamespace = codeElements + .FindFirstCodeNamespaceOrDefault(e => e.Name == "Test"); + + Assert.AreEqual("Test", codeNamespace.FullName); + Assert.AreEqual("Test", codeNamespace.Name); + } + + [Test] + public void CodeElements_OneNamespaceInProjectWithTwoPartsToName_ReturnsOneCodeNamespaceItemWithFirstPartOfNamespaceAsName() + { + CreateCodeModel(); + AddClassToProject("namespace First.Second {}"); + + global::EnvDTE.CodeElements codeElements = codeModel.CodeElements; + global::EnvDTE.CodeNamespace codeNamespace = codeElements + .FindFirstCodeNamespaceOrDefault(e => e.Name == "First"); + + global::EnvDTE.CodeNamespace secondCodeNamespace = codeNamespace.Members.FirstCodeNamespaceOrDefault(); + Assert.AreEqual("First", codeNamespace.FullName); + Assert.AreEqual("First", codeNamespace.Name); + Assert.AreEqual("Second", secondCodeNamespace.Name); + Assert.AreEqual("First.Second", secondCodeNamespace.FullName); + } + + [Test] + public void CodeElements_OneClassWithNoNamespaceInProject_ReturnsOneCodeClassItem() + { + CreateCodeModel(); + AddClassToProject("public class TestClass { }"); + + global::EnvDTE.CodeElements codeElements = codeModel.CodeElements; + CodeClass2 codeClass = codeElements + .FindFirstCodeClass2OrDefault(e => e.FullName == "TestClass"); + + Assert.AreEqual("TestClass", codeClass.Name); + } + + [Test] + public void CodeElements_TwoNamespacesInProjectWithFirstPartsTheName_ReturnsOneParentNamespaceWithTwoChildNamespaces() + { + CreateCodeModel(); + string code = + "namespace First.A { }\r\n" + + "namespace First.B { }\r\n"; + AddClassToProject(code); + + global::EnvDTE.CodeElements codeElements = codeModel.CodeElements; + CodeNamespace codeNamespace = codeElements.FirstCodeNamespaceOrDefault(); + + global::EnvDTE.CodeElements members = codeNamespace.Members; + CodeNamespace firstChildNamespace = members.FirstCodeNamespaceOrDefault(); + CodeNamespace secondChildNamespace = members.LastCodeNamespaceOrDefault(); + + Assert.AreEqual("First", codeNamespace.FullName); + Assert.AreEqual(2, codeNamespace.Members.Count); + Assert.AreEqual("A", firstChildNamespace.Name); + Assert.AreEqual("B", secondChildNamespace.Name); + } + + [Test] + public void CodeTypeFromFullName_ClassExistsInProject_InfoLocationIsLocalProject() + { + CreateCodeModel(); + AddClassToProject( + "namespace Tests {\r\n" + + " public class TestClass {} \r\n" + + "}"); + + var codeClass = codeModel.CodeTypeFromFullName("Tests.TestClass") as CodeClass2; + + Assert.AreEqual(global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationProject, codeClass.InfoLocation); + } // // [Test] // public void CodeTypeFromFullName_ClassExistsInDifferentProject_InfoLocationIsExternal() @@ -256,25 +250,37 @@ // // Assert.AreEqual(global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal, codeInterface.InfoLocation); // } -// -// [Test] -// public void Language_CSharpProject_ReturnsCSharpProjectGuid() -// { -// CreateCodeModelWithCSharpProject(); -// -// string language = codeModel.Language; -// -// Assert.AreEqual(global::EnvDTE.CodeModelLanguageConstants.vsCMLanguageCSharp, language); -// } -// -// [Test] -// public void Language_VisualBasicProject_ReturnsVisualBasicProjectGuid() -// { -// CreateCodeModelWithVisualBasicProject(); -// -// string language = codeModel.Language; -// -// Assert.AreEqual(global::EnvDTE.CodeModelLanguageConstants.vsCMLanguageVB, language); -// } -// } -//} + + [Test] + public void Language_CSharpProject_ReturnsCSharpProjectGuid() + { + CreateCodeModelWithCSharpProject(); + + string language = codeModel.Language; + + Assert.AreEqual(global::EnvDTE.CodeModelLanguageConstants.vsCMLanguageCSharp, language); + } + + [Test] + public void Language_VisualBasicProject_ReturnsVisualBasicProjectGuid() + { + CreateCodeModelWithVisualBasicProject(); + + string language = codeModel.Language; + + Assert.AreEqual(global::EnvDTE.CodeModelLanguageConstants.vsCMLanguageVB, language); + } + + [Test] + [Ignore("TODO - Use NRefactory")] + public void CodeTypeFromFullName_SystemString_ReturnsCodeClass2() + { + CreateCodeModel(); + AddClassToProject("public class TestClass {}"); + + var codeClass = codeModel.CodeTypeFromFullName("System.String") as CodeClass2; + + Assert.AreEqual("System.String", codeClass.FullName); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemTests.cs index 79f5a8c957..7f0d1a946b 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectItemTests.cs @@ -6,8 +6,11 @@ using System.Collections; using System.Collections.Generic; using ICSharpCode.Core; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.PackageManagement.EnvDTE; using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Dom; using NUnit.Framework; using PackageManagement.Tests.Helpers; using Rhino.Mocks; @@ -16,20 +19,20 @@ using DTE = ICSharpCode.PackageManagement.EnvDTE; namespace PackageManagement.Tests.EnvDTE { [TestFixture] - public class ProjectItemTests + public class ProjectItemTests : CodeModelTestBase { - TestableDTEProject project; + TestableDTEProject dteProject; ProjectItems projectItems; TestableProject msbuildProject; FakeFileService fakeFileService; void CreateProjectItems(string fileName = @"d:\projects\MyProject\MyProject.csproj") { - project = new TestableDTEProject(); - msbuildProject = project.TestableProject; + dteProject = new TestableDTEProject(); + msbuildProject = dteProject.TestableProject; msbuildProject.FileName = new FileName(fileName); - projectItems = (ProjectItems)project.ProjectItems; - fakeFileService = project.FakeFileService; + projectItems = (ProjectItems)dteProject.ProjectItems; + fakeFileService = dteProject.FakeFileService; } void OpenSavedFileInSharpDevelop(string fileName) @@ -50,6 +53,11 @@ namespace PackageManagement.Tests.EnvDTE return view; } + void AddCompilationUnit() + { + fakeFileService.CompilationUnitToReturnFromGetCompilationUnit = projectContent.CreateCompilation(); + } + [Test] public void ProjectItems_ProjectHasOneFileInsideSrcDirectory_ReturnsOneFileForSrcDirectory() { @@ -156,7 +164,7 @@ namespace PackageManagement.Tests.EnvDTE fileItem.Delete(); - Assert.AreEqual(@"d:\projects\myproject\src\program.cs", project.FakeFileService.PathPassedToRemoveFile); + Assert.AreEqual(@"d:\projects\myproject\src\program.cs", dteProject.FakeFileService.PathPassedToRemoveFile); } [Test] @@ -173,7 +181,6 @@ namespace PackageManagement.Tests.EnvDTE } [Test] - [Ignore("TODO")] public void FileCodeModel_ProjectDirectory_ReturnsNull() { CreateProjectItems(); @@ -187,10 +194,10 @@ namespace PackageManagement.Tests.EnvDTE } [Test] - [Ignore("TODO")] public void FileCodeModel_ProjectFile_ReturnsFileCodeModel() { CreateProjectItems(); + AddCompilationUnit(); msbuildProject.AddFile(@"src\program.cs"); global::EnvDTE.ProjectItem directoryItem = projectItems.Item("src"); @@ -202,18 +209,18 @@ namespace PackageManagement.Tests.EnvDTE } [Test] - [Ignore("TODO")] public void FileCodeModel_GetCodeElementsFromFileCodeModelForProjectFile_FileServicePassedToFileCodeModel() { CreateProjectItems(@"d:\projects\MyProject\MyProject.csproj"); + AddCompilationUnit(); msbuildProject.AddFile(@"src\program.cs"); - global::EnvDTE.ProjectItem directoryItem = projectItems.Item("src"); global::EnvDTE.ProjectItem fileItem = directoryItem.ProjectItems.Item("program.cs"); global::EnvDTE.CodeElements codeElements = fileItem.FileCodeModel.CodeElements; - Assert.AreEqual(@"d:\projects\MyProject\src\program.cs", fakeFileService.FileNamePassedToGetCompilationUnit); + CodeNamespace codeNamespace = codeElements.FirstCodeNamespaceOrDefault(); + Assert.AreEqual(dteProject.TestableProject, fakeFileService.ProjectPassedToGetCompilationUnit); Assert.AreEqual(0, codeElements.Count); } @@ -329,7 +336,7 @@ namespace PackageManagement.Tests.EnvDTE msbuildProject.AddFile("MainForm.cs"); msbuildProject.AddDependentFile("MainForm.Designer.cs", "MainForm.cs"); - global::EnvDTE.ProjectItems projectItems = project.ProjectItems; + global::EnvDTE.ProjectItems projectItems = dteProject.ProjectItems; string[] expectedFiles = new string[] { "MainForm.cs" @@ -344,7 +351,7 @@ namespace PackageManagement.Tests.EnvDTE msbuildProject.AddFile("MainForm.cs"); msbuildProject.AddDependentFile("MainForm.Designer.cs", "MainForm.cs"); - Assert.Throws(() => project.ProjectItems.Item("MainForm.Designer.cs")); + Assert.Throws(() => dteProject.ProjectItems.Item("MainForm.Designer.cs")); } [Test] @@ -353,7 +360,7 @@ namespace PackageManagement.Tests.EnvDTE CreateProjectItems(); msbuildProject.AddFile("MainForm.cs"); msbuildProject.AddDependentFile("MainForm.Designer.cs", "MainForm.cs"); - global::EnvDTE.ProjectItem mainFormItem = project.ProjectItems.Item("MainForm.cs"); + global::EnvDTE.ProjectItem mainFormItem = dteProject.ProjectItems.Item("MainForm.cs"); global::EnvDTE.ProjectItems mainFormProjectItems = mainFormItem.ProjectItems; @@ -386,7 +393,7 @@ namespace PackageManagement.Tests.EnvDTE global::EnvDTE.ProjectItems collection = projectItem.Collection; - Assert.AreEqual(project.ProjectItems, collection); + Assert.AreEqual(dteProject.ProjectItems, collection); } [Test] @@ -395,7 +402,7 @@ namespace PackageManagement.Tests.EnvDTE CreateProjectItems(); msbuildProject.FileName = new FileName(@"d:\projects\MyProject\MyProject.csproj"); msbuildProject.AddFile(@"src\program.cs"); - global::EnvDTE.ProjectItem srcDirectoryItem = project.ProjectItems.Item("src"); + global::EnvDTE.ProjectItem srcDirectoryItem = dteProject.ProjectItems.Item("src"); global::EnvDTE.ProjectItem fileProjectItem = srcDirectoryItem.ProjectItems.Item("program.cs"); global::EnvDTE.ProjectItems collection = fileProjectItem.Collection; diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectTests.cs index 9ce4e1a081..4e910abf10 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/EnvDTE/ProjectTests.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Linq; using ICSharpCode.Core; using ICSharpCode.PackageManagement; using ICSharpCode.PackageManagement.EnvDTE; @@ -14,11 +15,10 @@ using Rhino.Mocks; namespace PackageManagement.Tests.EnvDTE { [TestFixture] - public class ProjectTests + public class ProjectTests : CodeModelTestBase { - Project project; + Project dteProject; TestableProject msbuildProject; - //ProjectContentHelper helper; IPackageManagementProjectService fakeProjectService; IPackageManagementFileService fakeFileService; @@ -26,18 +26,22 @@ namespace PackageManagement.Tests.EnvDTE { msbuildProject = ProjectHelper.CreateTestProject(); msbuildProject.FileName = new FileName(fileName); - //helper = new ProjectContentHelper(); fakeProjectService = MockRepository.GenerateStub(); - //fakeProjectService.Stub(service => service.GetProjectContent(msbuildProject)).Return(helper.ProjectContent); fakeFileService = MockRepository.GenerateStub(); - project = new Project(msbuildProject, fakeProjectService, fakeFileService); + dteProject = new Project(msbuildProject, fakeProjectService, fakeFileService); + + msbuildProject.SetAssemblyModel(assemblyModel); + + fakeFileService + .Stub(fileService => fileService.GetCompilationUnit(msbuildProject)) + .WhenCalled(compilation => compilation.ReturnValue = projectContent.CreateCompilation()); } - void AddClassToProjectContent(string className) + void AddClassToProject(string code) { -// helper.AddClassToProjectContent(className); + AddCodeFile("class.cs", code); } void SetProjectForProjectContent() @@ -50,13 +54,20 @@ namespace PackageManagement.Tests.EnvDTE // helper.SetProjectForProjectContent(ProjectHelper.CreateTestProject()); } + void SetParentSolutionFileName(string fileName) + { + var solutionFileName = new FileName(fileName); + msbuildProject.ParentSolution.Stub(s => s.FileName).Return(solutionFileName); + msbuildProject.ParentSolution.Stub(s => s.Directory).Return(solutionFileName.GetParentDirectory()); + } + [Test] public void Name_ProjectNameIsMyApp_ReturnsMyApp() { CreateProject(); msbuildProject.Name = "MyApp"; - string name = project.Name; + string name = dteProject.Name; Assert.AreEqual("MyApp", name); } @@ -67,7 +78,7 @@ namespace PackageManagement.Tests.EnvDTE string expectedFullName = @"d:\projects\myproject\myproject.csproj"; CreateProject(expectedFullName); - string fullName = project.FullName; + string fullName = dteProject.FullName; Assert.AreEqual(expectedFullName, fullName); } @@ -78,7 +89,7 @@ namespace PackageManagement.Tests.EnvDTE string expectedFileName = @"d:\projects\myproject\myproject.csproj"; CreateProject(expectedFileName); - string fileName = project.FileName; + string fileName = dteProject.FileName; Assert.AreEqual(expectedFileName, fileName); } @@ -88,7 +99,7 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject(@"c:\projects\myproject\test.csproj", "C#"); - string projectType = project.Type; + string projectType = dteProject.Type; Assert.AreEqual("C#", projectType); } @@ -98,7 +109,7 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject(@"c:\projects\myproject\TEST.CSPROJ"); - string projectType = project.Type; + string projectType = dteProject.Type; Assert.AreEqual("C#", projectType); } @@ -108,7 +119,7 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject(@"c:\projects\myproject\test.vbproj"); - string projectType = project.Type; + string projectType = dteProject.Type; Assert.AreEqual("VB.NET", projectType); } @@ -118,7 +129,7 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject(@"c:\projects\myproject\test.unknown"); - string projectType = project.Type; + string projectType = dteProject.Type; Assert.AreEqual(String.Empty, projectType); } @@ -128,7 +139,7 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject(@"d:\projects\myproject\test.csproj"); - string kind = project.Kind; + string kind = dteProject.Kind; Assert.AreEqual(ProjectTypeGuids.CSharp.ToString(), kind); } @@ -138,7 +149,7 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject( @"d:\projects\myproject\test.vbproj"); - string kind = project.Kind; + string kind = dteProject.Kind; Assert.AreEqual(ProjectTypeGuids.VBNet.ToString(), kind); } @@ -148,7 +159,7 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject(@"d:\projects\myproject\test.unknown"); - string kind = project.Kind; + string kind = dteProject.Kind; Assert.AreEqual(String.Empty, kind); } @@ -159,7 +170,7 @@ namespace PackageManagement.Tests.EnvDTE CreateProject(@"d:\projects\myproject\MyProject.csproj"); SetParentSolutionFileName(@"d:\projects\myproject\MyProject.sln"); - string name = project.UniqueName; + string name = dteProject.UniqueName; Assert.AreEqual("MyProject.csproj", name); } @@ -169,28 +180,20 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject(@"d:\projects\myproject\SubFolder\MyProject.csproj"); SetParentSolutionFileName(@"d:\projects\myproject\MyProject.sln"); - - string name = project.UniqueName; + string name = dteProject.UniqueName; Assert.AreEqual(@"SubFolder\MyProject.csproj", name); } - void SetParentSolutionFileName(string fileName) - { - var solutionFileName = new FileName(fileName); - msbuildProject.ParentSolution.Stub(s => s.FileName).Return(solutionFileName); - msbuildProject.ParentSolution.Stub(s => s.Directory).Return(solutionFileName.GetParentDirectory()); - } - [Test] public void ProjectItemsParent_ParentOfProjectsProjectItems_ReturnsTheProject() { CreateProject(); - object parent = project.ProjectItems.Parent; + object parent = dteProject.ProjectItems.Parent; - Assert.AreEqual(project, parent); + Assert.AreEqual(dteProject, parent); } [Test] @@ -198,7 +201,7 @@ namespace PackageManagement.Tests.EnvDTE { CreateProject(); msbuildProject.SetProperty("OutputPath", @"bin\debug\"); - global::EnvDTE.Configuration activeConfig = project.ConfigurationManager.ActiveConfiguration; + global::EnvDTE.Configuration activeConfig = dteProject.ConfigurationManager.ActiveConfiguration; string outputPath = (string)activeConfig.Properties.Item("OutputPath").Value; @@ -206,24 +209,26 @@ namespace PackageManagement.Tests.EnvDTE } [Test] - [Ignore("TODO")] public void CodeModel_NoTypesInProjectAndCallCodeTypeFromFullName_ReturnsNull() { CreateProject(); + AddClassToProject(""); - global::EnvDTE.CodeType codeType = project.CodeModel.CodeTypeFromFullName("UnknownTypeName"); + global::EnvDTE.CodeType codeType = dteProject.CodeModel.CodeTypeFromFullName("UnknownTypeName"); Assert.IsNull(codeType); } [Test] - [Ignore("TODO")] public void CodeModel_ClassExistsInProjectContentAndCallCodeTypeFromFullName_ReturnsNonCodeType() { CreateProject(); - AddClassToProjectContent("Tests.MyClass"); + AddClassToProject( + "namespace Tests {\r\n" + + " public class MyClass {}\r\n"+ + "}"); - global::EnvDTE.CodeType codeType = project.CodeModel.CodeTypeFromFullName("Tests.MyClass"); + global::EnvDTE.CodeType codeType = dteProject.CodeModel.CodeTypeFromFullName("Tests.MyClass"); Assert.IsNotNull(codeType); } @@ -253,5 +258,19 @@ namespace PackageManagement.Tests.EnvDTE //Assert.AreEqual(global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal, element.InfoLocation); } + + [Test] + public void CodeModel_EmptyNamespaceExistsInProject_CodeElementsReturnsNamespace() + { + CreateProject(); + AddClassToProject("namespace Test {}"); + + global::EnvDTE.CodeElements codeElements = dteProject.CodeModel.CodeElements; + global::EnvDTE.CodeNamespace codeNamespace = codeElements + .FindFirstCodeNamespaceOrDefault(e => e.Name == "Test"); + + Assert.AreEqual("Test", codeNamespace.FullName); + Assert.AreEqual("Test", codeNamespace.Name); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CodeElementsExtensions.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CodeElementsExtensions.cs index 61b4d08f97..d817240a7b 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CodeElementsExtensions.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/CodeElementsExtensions.cs @@ -1,97 +1,107 @@ -//// 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.Collections.Generic; -//using System.Linq; -//using ICSharpCode.PackageManagement.EnvDTE; -// -//namespace PackageManagement.Tests.Helpers -//{ -// public static class CodeElementsExtensions -// { -// public static List ToList(this global::EnvDTE.CodeElements codeElements) -// { -// var list = new List(); -// foreach (CodeElement codeElement in codeElements) { -// list.Add(codeElement); -// } -// return list; -// } -// -// public static CodeElement FirstOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return ToList(codeElements).FirstOrDefault(); -// } -// -// public static CodeFunction2 FirstCodeFunction2OrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeFunction2; -// } -// -// public static CodeClass2 FirstCodeClass2OrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeClass2; -// } -// -// public static CodeInterface FirstCodeInterfaceOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeInterface; -// } -// -// public static CodeAttributeArgument FirstCodeAttributeArgumentOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeAttributeArgument; -// } -// -// public static CodeNamespace FirstCodeNamespaceOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeNamespace; -// } -// -// public static CodeNamespace LastCodeNamespaceOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.LastOrDefault() as CodeNamespace; -// } -// -// public static CodeElement LastOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.ToList().LastOrDefault(); -// } -// -// public static CodeAttribute2 FirstCodeAttribute2OrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeAttribute2; -// } -// +// 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.Collections.Generic; +using System.Linq; +using ICSharpCode.PackageManagement.EnvDTE; + +namespace PackageManagement.Tests.Helpers +{ + public static class CodeElementsExtensions + { + public static List ToList(this global::EnvDTE.CodeElements codeElements) + { + var list = new List(); + foreach (CodeElement codeElement in codeElements) { + list.Add(codeElement); + } + return list; + } + + public static CodeElement FirstOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return ToList(codeElements).FirstOrDefault(); + } + + public static CodeFunction2 FirstCodeFunction2OrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeFunction2; + } + + public static CodeClass2 FirstCodeClass2OrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeClass2; + } + + public static CodeClass2 FindFirstCodeClass2OrDefault(this global::EnvDTE.CodeElements codeElements, Func predicate) + { + return codeElements.OfType().FirstOrDefault(predicate); + } + + public static CodeInterface FirstCodeInterfaceOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeInterface; + } + + public static CodeAttributeArgument FirstCodeAttributeArgumentOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeAttributeArgument; + } + + public static CodeNamespace FirstCodeNamespaceOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeNamespace; + } + + public static CodeNamespace LastCodeNamespaceOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.LastOrDefault() as CodeNamespace; + } + + public static CodeElement LastOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.ToList().LastOrDefault(); + } + + public static CodeAttribute2 FirstCodeAttribute2OrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeAttribute2; + } + // public static CodeProperty2 FirstCodeProperty2OrDefault(this global::EnvDTE.CodeElements codeElements) // { // return codeElements.FirstOrDefault() as CodeProperty2; // } -// -// public static CodeVariable FirstCodeVariableOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeVariable; -// } -// -// public static CodeParameter FirstCodeParameterOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeParameter; -// } -// -// public static CodeParameter2 FirstCodeParameter2OrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeParameter2; -// } -// -// public static CodeImport FirstCodeImportOrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.FirstOrDefault() as CodeImport; -// } -// -// public static CodeClass2 LastCodeClass2OrDefault(this global::EnvDTE.CodeElements codeElements) -// { -// return codeElements.LastOrDefault() as CodeClass2; -// } -// } -//} + + public static CodeVariable FirstCodeVariableOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeVariable; + } + + public static CodeParameter FirstCodeParameterOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeParameter; + } + + public static CodeParameter2 FirstCodeParameter2OrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeParameter2; + } + + public static CodeImport FirstCodeImportOrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.FirstOrDefault() as CodeImport; + } + + public static CodeClass2 LastCodeClass2OrDefault(this global::EnvDTE.CodeElements codeElements) + { + return codeElements.LastOrDefault() as CodeClass2; + } + + public static CodeNamespace FindFirstCodeNamespaceOrDefault(this global::EnvDTE.CodeElements codeElements, Func predicate) + { + return codeElements.OfType().FirstOrDefault(predicate); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeFileService.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeFileService.cs index a69b719845..b049a0f0a1 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeFileService.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeFileService.cs @@ -119,14 +119,20 @@ namespace PackageManagement.Tests.Helpers } public string FileNamePassedToGetCompilationUnit; - //public ICompilation CompilationUnitToReturnFromGetCompilationUnit = - // new DefaultCompilationUnit(new DefaultProjectContent()); + public ICompilation CompilationUnitToReturnFromGetCompilationUnit; public ICompilation GetCompilationUnit(string fileName) { FileNamePassedToGetCompilationUnit = fileName; - // return CompilationUnitToReturnFromGetCompilationUnit; - return null; + return CompilationUnitToReturnFromGetCompilationUnit; + } + + public IProject ProjectPassedToGetCompilationUnit; + + public ICompilation GetCompilationUnit(IProject project) + { + ProjectPassedToGetCompilationUnit = project; + return CompilationUnitToReturnFromGetCompilationUnit; } Dictionary openViews = new Dictionary(); diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableProject.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableProject.cs index fe8d0dd381..12dfecc7d7 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableProject.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableProject.cs @@ -5,6 +5,8 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Project; using Microsoft.Build.Construction; @@ -16,6 +18,8 @@ namespace PackageManagement.Tests.Helpers string assemblyName; string rootNamespace; bool isStartable = true; + IAssemblyModel assemblyModel; + IProjectContent projectContent; public ItemType ItemTypeToReturnFromGetDefaultItemType { get { return TestableProjectBehaviour.ItemTypeToReturnFromGetDefaultItemType; } @@ -130,5 +134,23 @@ namespace PackageManagement.Tests.Helpers return MSBuildProjectFile.Imports; } } + + public override IAssemblyModel AssemblyModel { + get { return assemblyModel; } + } + + public void SetAssemblyModel(IAssemblyModel assemblyModel) + { + this.assemblyModel = assemblyModel; + } + + public override IProjectContent ProjectContent { + get { return projectContent; } + } + + public void SetProjectContent(IProjectContent projectContent) + { + this.projectContent = projectContent; + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableSolutionSnapshot.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableSolutionSnapshot.cs new file mode 100644 index 0000000000..360e4dc15a --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestableSolutionSnapshot.cs @@ -0,0 +1,44 @@ +// 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.Collections.Generic; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop.Parser; +using ICSharpCode.SharpDevelop.Project; + +namespace PackageManagement.Tests.Helpers +{ + public class TestableSolutionSnapshot : DefaultSolutionSnapshot, ISolutionSnapshotWithProjectMapping + { + IProject project; + + public TestableSolutionSnapshot(IProject project) + { + this.project = project; + } + + public IProject GetProject(IAssembly assembly) + { + return GetProject(assembly.UnresolvedAssembly as IProjectContent); + } + + IProject GetProject(IProjectContent projectContent) + { + if (this.project.ProjectContent == projectContent) { + return project; + } + return null; + } + + public IProjectContent GetProjectContent(IProject project) + { + throw new NotImplementedException(); + } + + public ICompilation GetCompilation(IProject project) + { + throw new NotImplementedException(); + } + } +}