PageRenderTime 18ms CodeModel.GetById 10ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 19using System;
 20using System.Collections.Generic;
 21using System.Linq;
 22using System.Text;
 23
 24using ICSharpCode.NRefactory.TypeSystem;
 25using ICSharpCode.SharpDevelop;
 26
 27namespace ICSharpCode.PackageManagement.EnvDTE
 28{
 29	public class CodeType : CodeElement, global::EnvDTE.CodeType
 30	{
 31		protected ITypeDefinition typeDefinition;
 32		IType[] typeArguments;
 33		
 34		CodeElementsList<CodeElement> members;
 35		
 36		internal static CodeType Create(CodeModelContext context, IType type)
 37		{
 38			ITypeDefinition typeDefinition = type.GetDefinition();
 39			if (typeDefinition != null) {
 40				return Create(context.WithFilteredFileName(null), typeDefinition, type.TypeArguments.ToArray());
 41			}
 42			return null;
 43		}
 44		
 45		internal static CodeType Create(
 46			CodeModelContext context,
 47			ITypeDefinition typeDefinition,
 48			params IType[] typeArguments)
 49		{
 50			switch (typeDefinition.Kind) {
 51				case TypeKind.Class:
 52					return new CodeClass2(context, typeDefinition);
 53				case TypeKind.Interface:
 54					return new CodeInterface(context, typeDefinition, typeArguments);
 55				case TypeKind.Module:
 56				case TypeKind.Struct:
 57				case TypeKind.Void:
 58				case TypeKind.Delegate:
 59				case TypeKind.Enum:
 60				default:
 61					return new CodeType(context, typeDefinition, typeArguments);
 62			}
 63		}
 64		
 65		public CodeType(CodeModelContext context, ITypeDefinition typeDefinition, params IType[] typeArguments)
 66			: base(context, typeDefinition)
 67		{
 68			this.typeDefinition = typeDefinition;
 69			this.typeArguments = typeArguments;
 70			this.InfoLocation = GetInfoLocation();
 71		}
 72		
 73		global::EnvDTE.vsCMInfoLocation GetInfoLocation()
 74		{
 75			if (typeDefinition.ParentAssembly.IsMainAssembly) {
 76				return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationProject;
 77			}
 78			return global::EnvDTE.vsCMInfoLocation.vsCMInfoLocationExternal;
 79		}
 80		
 81		public CodeType()
 82		{
 83		}
 84		
 85		public virtual global::EnvDTE.vsCMAccess Access {
 86			get { return typeDefinition.Accessibility.ToAccess(); }
 87			set { }
 88		}
 89		
 90		public virtual string FullName {
 91			get {
 92				FullTypeName fullTypeName = typeDefinition.FullTypeName;
 93				var fullName = new StringBuilder();
 94				if (!string.IsNullOrEmpty(fullTypeName.TopLevelTypeName.Namespace)) {
 95					fullName.Append(fullTypeName.TopLevelTypeName.Namespace);
 96					fullName.Append('.');
 97				}
 98				fullName.Append(fullTypeName.TopLevelTypeName.Name);
 99				for (int i = 0; i < fullTypeName.NestingLevel; i++) {
100					fullName.Append('.');
101					fullName.Append(fullTypeName.GetNestedTypeName(i));
102				}
103				return fullName.ToString() + GetTypeArguments();
104			}
105		}
106		
107		string GetTypeArguments()
108		{
109			if (typeArguments.Length == 0) {
110				return String.Empty;
111			}
112			
113			return String.Format(
114				"<{0}>",
115				String.Join(", ", typeArguments.Select(type => type.FullName)));
116		}
117		
118		public virtual global::EnvDTE.CodeElements Members {
119			get {
120				if (members == null) {
121					members = new CodeElementsList<CodeElement>();
122					members.AddRange(typeDefinition.Members
123						.Where(member => IsInFilter(member.Region))
124						.Where(member => !member.Region.End.IsEmpty || !typeDefinition.ParentAssembly.IsMainAssembly)
125						.Select(member => CreateMember(context, member)));
126				}
127				return members;
128			}
129		}
130		
131		public virtual global::EnvDTE.CodeElements Bases {
132			get {
133				var types = new CodeElementsList<CodeType>();
134				foreach (IType baseType in GetBaseTypes()) {
135					CodeType element = Create(context, baseType);
136					if (element != null) {
137						types.Add(element);
138					}
139				}
140				return types;
141			}
142		}
143		
144		IEnumerable<IType> GetBaseTypes()
145		{
146			if (typeDefinition.Kind == TypeKind.Interface) {
147				return typeDefinition.DirectBaseTypes;
148			}
149			return typeDefinition.DirectBaseTypes.Where(type => type.Kind != TypeKind.Interface);
150		}
151		
152		public virtual global::EnvDTE.CodeElements Attributes {
153			get {
154				return GetAttributes(typeDefinition);
155			}
156		}
157		
158		public virtual global::EnvDTE.CodeNamespace Namespace {
159			get { return new FileCodeModelCodeNamespace(context, typeDefinition.Namespace); }
160		}
161		
162		public virtual global::EnvDTE.ProjectItem ProjectItem {
163			get {
164				if (context.CurrentProject != null) {
165					return EnvDTE.ProjectItem.FindByEntity(context.CurrentProject, typeDefinition);
166				}
167				return null;
168			}
169		}
170		
171		/// <summary>
172		/// Returns true if the current type matches the fully qualified name or any of its
173		/// base types are a match.
174		/// </summary>
175		protected override bool GetIsDerivedFrom(string fullName)
176		{
177			return typeDefinition
178				.GetAllBaseTypeDefinitions()
179				.Any(baseType => baseType.FullName == fullName);
180		}
181		
182		protected IType FindType(string type)
183		{
184			var fieldTypeName = new FullTypeName(type);
185			return typeDefinition.Compilation.FindType(fieldTypeName);
186		}
187		
188		protected void ReloadTypeDefinition()
189		{
190			ICompilation compilation = context.DteProject.GetCompilationUnit(typeDefinition.BodyRegion.FileName);
191			
192			ITypeDefinition matchedTypeDefinition = compilation.MainAssembly.GetTypeDefinition(typeDefinition.FullTypeName);
193			if (matchedTypeDefinition != null) {
194				typeDefinition = matchedTypeDefinition;
195			}
196		}
197	}
198}