⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resolveresult.cs

📁 SharpDevelop2.0.0 c#开发免费工具
💻 CS
📖 第 1 页 / 共 2 页
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
//     <version>$Revision: 1379 $</version>
// </file>

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;

using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.Core;


namespace ICSharpCode.SharpDevelop.Dom
{
	#region ResolveResult
	/// <summary>
	/// The base class of all resolve results.
	/// This class is used whenever an expression is not one of the special expressions
	/// (having their own ResolveResult class).
	/// The ResolveResult specified the location where Resolve was called (Class+Member)
	/// and the type of the resolved expression.
	/// </summary>
	public class ResolveResult
	{
		IClass callingClass;
		IMember callingMember;
		IReturnType resolvedType;
		
		public ResolveResult(IClass callingClass, IMember callingMember, IReturnType resolvedType)
		{
//			if (callingMember != null && callingMember.DeclaringType != callingClass)
//				throw new ArgumentException("callingMember.DeclaringType must be equal to callingClass");
			this.callingClass = callingClass;
			this.callingMember = callingMember;
			this.resolvedType = resolvedType;
		}
		
		/// <summary>
		/// Gets the class that contained the expression used to get this ResolveResult.
		/// Can be null when the class is unknown.
		/// </summary>
		public IClass CallingClass {
			get {
				return callingClass;
			}
		}
		
		/// <summary>
		/// Gets the member (method or property in <see cref="CallingClass"/>) that contained the
		/// expression used to get this ResolveResult.
		/// Can be null when the expression was not inside a member or the member is unknown.
		/// </summary>
		public IMember CallingMember {
			get {
				return callingMember;
			}
		}
		
		/// <summary>
		/// Gets the type of the resolved expression.
		/// Can be null when the type cannot be represented by a IReturnType (e.g. when the
		/// expression was a namespace name).
		/// </summary>
		public IReturnType ResolvedType {
			get {
				return resolvedType;
			}
			set {
				resolvedType = value;
			}
		}
		
		public virtual ArrayList GetCompletionData(IProjectContent projectContent)
		{
			return GetCompletionData(projectContent.Language, false);
		}
		
		protected ArrayList GetCompletionData(LanguageProperties language, bool showStatic)
		{
			if (resolvedType == null) return null;
			ArrayList res = new ArrayList();
			bool isClassInInheritanceTree = false;
			if (callingClass != null)
				isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(resolvedType.GetUnderlyingClass());
			foreach (IMethod m in resolvedType.GetMethods()) {
				if (language.ShowMember(m, showStatic) && m.IsAccessible(callingClass, isClassInInheritanceTree))
					res.Add(m);
			}
			foreach (IEvent e in resolvedType.GetEvents()) {
				if (language.ShowMember(e, showStatic) && e.IsAccessible(callingClass, isClassInInheritanceTree))
					res.Add(e);
			}
			foreach (IField f in resolvedType.GetFields()) {
				if (language.ShowMember(f, showStatic) && f.IsAccessible(callingClass, isClassInInheritanceTree))
					res.Add(f);
			}
			foreach (IProperty p in resolvedType.GetProperties()) {
				if (language.ShowMember(p, showStatic) && p.IsAccessible(callingClass, isClassInInheritanceTree))
					res.Add(p);
			}
			
			if (!showStatic && callingClass != null) {
				AddExtensions(language, res, callingClass, resolvedType);
			}
			
			return res;
		}
		
		/// <summary>
		/// Adds extension methods to <paramref name="res"/>.
		/// </summary>
		public static void AddExtensions(LanguageProperties language, ArrayList res, IClass callingClass, IReturnType resolvedType)
		{
			if (language == null)
				throw new ArgumentNullException("language");
			if (res == null)
				throw new ArgumentNullException("res");
			if (callingClass == null)
				throw new ArgumentNullException("callingClass");
			if (resolvedType == null)
				throw new ArgumentNullException("resolvedType");
			
			bool supportsExtensionMethods = language.SupportsExtensionMethods;
			bool supportsExtensionProperties = language.SupportsExtensionProperties;
			if (supportsExtensionMethods || supportsExtensionProperties) {
				ArrayList list = new ArrayList();
				IMethod dummyMethod = new DefaultMethod("dummy", ReflectionReturnType.Void, ModifierEnum.Static, DomRegion.Empty, DomRegion.Empty, callingClass);
				NRefactoryResolver.NRefactoryResolver.AddContentsFromCalling(list, callingClass, dummyMethod);
				NRefactoryResolver.NRefactoryResolver.AddImportedNamespaceContents(list, callingClass.CompilationUnit, callingClass);
				
				bool searchExtensionsInClasses = language.SearchExtensionsInClasses;
				foreach (object o in list) {
					if (supportsExtensionMethods && o is IMethod || supportsExtensionProperties && o is IProperty) {
						TryAddExtension(language, res, o as IMethodOrProperty, resolvedType);
					} else if (searchExtensionsInClasses && o is IClass) {
						IClass c = o as IClass;
						if (c.HasExtensionMethods) {
							if (supportsExtensionProperties) {
								foreach (IProperty p in c.Properties) {
									TryAddExtension(language, res, p, resolvedType);
								}
							}
							if (supportsExtensionMethods) {
								foreach (IMethod m in c.Methods) {
									TryAddExtension(language, res, m, resolvedType);
								}
							}
						}
					}
				}
			}
		}
		
		static void TryAddExtension(LanguageProperties language, ArrayList res, IMethodOrProperty ext, IReturnType resolvedType)
		{
			// accept only extension methods
			if (!ext.IsExtensionMethod)
				return;
			// don't add extension if method with that name already exists
			// but allow overloading extension methods
			foreach (IMember member in res) {
				IMethodOrProperty p = member as IMethodOrProperty;
				if (p != null && p.IsExtensionMethod)
					continue;
				if (language.NameComparer.Equals(member.Name, ext.Name)) {
					return;
				}
			}
			// now add the extension method if it fits the type
			if (MemberLookupHelper.ConversionExists(resolvedType, ext.Parameters[0].ReturnType)) {
				IMethod method = ext as IMethod;
				if (method != null && method.TypeParameters.Count > 0) {
					IReturnType[] typeArguments = new IReturnType[method.TypeParameters.Count];
					MemberLookupHelper.InferTypeArgument(method.Parameters[0].ReturnType, resolvedType, typeArguments);
					for (int i = 0; i < typeArguments.Length; i++) {
						if (typeArguments[i] != null) {
							ext = (IMethod)ext.Clone();
							ext.ReturnType = ConstructedReturnType.TranslateType(ext.ReturnType, typeArguments, true);
							for (int j = 0; j < ext.Parameters.Count; ++j) {
								ext.Parameters[j].ReturnType = ConstructedReturnType.TranslateType(ext.Parameters[j].ReturnType, typeArguments, true);
							}
							break;
						}
					}
				}
				res.Add(ext);
			}
		}
		
		public virtual FilePosition GetDefinitionPosition()
		{
			// this is only possible on some subclasses of ResolveResult
			return null;
		}
	}
	#endregion
	
	#region MixedResolveResult
	/// <summary>
	/// The MixedResolveResult is used when an expression can have multiple meanings, for example
	/// "Size" in a class deriving from "Control".
	/// </summary>
	public class MixedResolveResult : ResolveResult
	{
		ResolveResult primaryResult, secondaryResult;

		public ResolveResult PrimaryResult {
			get {
				return primaryResult;
			}
		}
		
		public IEnumerable<ResolveResult> Results {
			get {
				yield return primaryResult;
				yield return secondaryResult;
			}
		}
		
		public TypeResolveResult TypeResult {
			get {
				if (primaryResult is TypeResolveResult)
					return (TypeResolveResult)primaryResult;
				if (secondaryResult is TypeResolveResult)
					return (TypeResolveResult)secondaryResult;
				return null;
			}
		}
		
		public MixedResolveResult(ResolveResult primaryResult, ResolveResult secondaryResult)
			: base(primaryResult.CallingClass, primaryResult.CallingMember, primaryResult.ResolvedType)
		{
			this.primaryResult = primaryResult;
			this.secondaryResult = secondaryResult;
		}
		
		public override FilePosition GetDefinitionPosition()
		{
			return primaryResult.GetDefinitionPosition();
		}
		
		public override ArrayList GetCompletionData(IProjectContent projectContent)
		{
			ArrayList result = primaryResult.GetCompletionData(projectContent);
			ArrayList result2 = secondaryResult.GetCompletionData(projectContent);
			if (result == null)  return result2;
			if (result2 == null) return result;
			foreach (object o in result2) {
				if (!result.Contains(o))
					result.Add(o);
			}
			return result;
		}
	}
	#endregion
	
	#region LocalResolveResult
	/// <summary>
	/// The LocalResolveResult is used when an expression was a simple local variable
	/// or parameter.
	/// </summary>
	/// <remarks>
	/// For fields in the current class, a MemberResolveResult is used, so "e" is not always
	/// a LocalResolveResult.
	/// </remarks>
	public class LocalResolveResult : ResolveResult
	{
		IField field;
		bool isParameter;
		
		public LocalResolveResult(IMember callingMember, IField field)
			: base(callingMember.DeclaringType, callingMember, field.ReturnType)
		{
			if (callingMember == null)
				throw new ArgumentNullException("callingMember");
			if (field == null)
				throw new ArgumentNullException("field");
			this.field = field;
			this.isParameter = field.IsParameter;
			if (!isParameter && !field.IsLocalVariable) {
				throw new ArgumentException("the field must either be a local variable-field or a parameter-field");
			}
		}
		
		/// <summary>
		/// Gets the field representing the local variable.
		/// </summary>
		public IField Field {
			get {
				return field;
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -