/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/CodeType.cs

https://github.com/ajadex/SharpDevelop · C# · 198 lines · 154 code · 23 blank · 21 comment · 21 complexity · f30498f5db47ad6e09c35e69f404f26e MD5 · raw file

  1. // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Linq;
  21. using System.Text;
  22. using ICSharpCode.NRefactory.TypeSystem;
  23. using ICSharpCode.SharpDevelop;
  24. namespace ICSharpCode.PackageManagement.EnvDTE
  25. {
  26. public class CodeType : CodeElement, global::EnvDTE.CodeType
  27. {
  28. protected ITypeDefinition typeDefinition;
  29. IType[] typeArguments;
  30. CodeElementsList<CodeElement> members;
  31. internal static CodeType Create(CodeModelContext context, IType type)
  32. {
  33. ITypeDefinition typeDefinition = type.GetDefinition();
  34. if (typeDefinition != null) {
  35. return Create(context.WithFilteredFileName(null), typeDefinition, type.TypeArguments.ToArray());
  36. }
  37. return null;
  38. }
  39. internal static CodeType Create(
  40. CodeModelContext context,
  41. ITypeDefinition typeDefinition,
  42. params IType[] typeArguments)
  43. {
  44. switch (typeDefinition.Kind) {
  45. case TypeKind.Class:
  46. return new CodeClass2(context, typeDefinition);
  47. case TypeKind.Interface:
  48. return new CodeInterface(context, typeDefinition, typeArguments);
  49. case TypeKind.Module:
  50. case TypeKind.Struct:
  51. case TypeKind.Void:
  52. case TypeKind.Delegate:
  53. case TypeKind.Enum:
  54. default:
  55. return new CodeType(context, typeDefinition, typeArguments);
  56. }
  57. }
  58. public CodeType(CodeModelContext context, ITypeDefinition typeDefinition, params IType[] typeArguments)
  59. : base(context, typeDefinition)
  60. {
  61. this.typeDefinition = typeDefinition;
  62. this.typeArguments = typeArguments;
  63. this.InfoLocation = GetInfoLocation();
  64. }
  65. global::EnvDTE.vsCMInfoLocation GetInfoLocation()
  66. {
  67. if (typeDefinition.ParentAssembly.IsMainAssembly) {
  68. return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationProject;
  69. }
  70. return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal;
  71. }
  72. public CodeType()
  73. {
  74. }
  75. public virtual global::EnvDTE.vsCMAccess Access {
  76. get { return typeDefinition.Accessibility.ToAccess(); }
  77. set { }
  78. }
  79. public virtual string FullName {
  80. get {
  81. FullTypeName fullTypeName = typeDefinition.FullTypeName;
  82. var fullName = new StringBuilder();
  83. if (!string.IsNullOrEmpty(fullTypeName.TopLevelTypeName.Namespace)) {
  84. fullName.Append(fullTypeName.TopLevelTypeName.Namespace);
  85. fullName.Append('.');
  86. }
  87. fullName.Append(fullTypeName.TopLevelTypeName.Name);
  88. for (int i = 0; i < fullTypeName.NestingLevel; i++) {
  89. fullName.Append('.');
  90. fullName.Append(fullTypeName.GetNestedTypeName(i));
  91. }
  92. return fullName.ToString() + GetTypeArguments();
  93. }
  94. }
  95. string GetTypeArguments()
  96. {
  97. if (typeArguments.Length == 0) {
  98. return String.Empty;
  99. }
  100. return String.Format(
  101. "<{0}>",
  102. String.Join(", ", typeArguments.Select(type => type.FullName)));
  103. }
  104. public virtual global::EnvDTE.CodeElements Members {
  105. get {
  106. if (members == null) {
  107. members = new CodeElementsList<CodeElement>();
  108. members.AddRange(typeDefinition.Members
  109. .Where(member => IsInFilter(member.Region))
  110. .Where(member => !member.Region.End.IsEmpty || !typeDefinition.ParentAssembly.IsMainAssembly)
  111. .Select(member => CreateMember(context, member)));
  112. }
  113. return members;
  114. }
  115. }
  116. public virtual global::EnvDTE.CodeElements Bases {
  117. get {
  118. var types = new CodeElementsList<CodeType>();
  119. foreach (IType baseType in GetBaseTypes()) {
  120. CodeType element = Create(context, baseType);
  121. if (element != null) {
  122. types.Add(element);
  123. }
  124. }
  125. return types;
  126. }
  127. }
  128. IEnumerable<IType> GetBaseTypes()
  129. {
  130. if (typeDefinition.Kind == TypeKind.Interface) {
  131. return typeDefinition.DirectBaseTypes;
  132. }
  133. return typeDefinition.DirectBaseTypes.Where(type => type.Kind != TypeKind.Interface);
  134. }
  135. public virtual global::EnvDTE.CodeElements Attributes {
  136. get {
  137. return GetAttributes(typeDefinition);
  138. }
  139. }
  140. public virtual global::EnvDTE.CodeNamespace Namespace {
  141. get { return new FileCodeModelCodeNamespace(context, typeDefinition.Namespace); }
  142. }
  143. public virtual global::EnvDTE.ProjectItem ProjectItem {
  144. get {
  145. if (context.CurrentProject != null) {
  146. return EnvDTE.ProjectItem.FindByEntity(context.CurrentProject, typeDefinition);
  147. }
  148. return null;
  149. }
  150. }
  151. /// <summary>
  152. /// Returns true if the current type matches the fully qualified name or any of its
  153. /// base types are a match.
  154. /// </summary>
  155. protected override bool GetIsDerivedFrom(string fullName)
  156. {
  157. return typeDefinition
  158. .GetAllBaseTypeDefinitions()
  159. .Any(baseType => baseType.FullName == fullName);
  160. }
  161. protected IType FindType(string type)
  162. {
  163. var fieldTypeName = new FullTypeName(type);
  164. return typeDefinition.Compilation.FindType(fieldTypeName);
  165. }
  166. protected void ReloadTypeDefinition()
  167. {
  168. ICompilation compilation = context.DteProject.GetCompilationUnit(typeDefinition.BodyRegion.FileName);
  169. ITypeDefinition matchedTypeDefinition = compilation.MainAssembly.GetTypeDefinition(typeDefinition.FullTypeName);
  170. if (matchedTypeDefinition != null) {
  171. typeDefinition = matchedTypeDefinition;
  172. }
  173. }
  174. }
  175. }