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

📄 searchclassreturntype.cs

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

using System;
using System.Collections.Generic;
using ICSharpCode.Core;

namespace ICSharpCode.SharpDevelop.Dom
{
	/// <summary>
	/// The SearchClassReturnType is used when only a part of the class name is known and the
	/// type can only be resolved on demand (the ConvertVisitor uses SearchClassReturnType's).
	/// </summary>
	public sealed class SearchClassReturnType : ProxyReturnType
	{
		IClass declaringClass;
		IProjectContent pc;
		int caretLine;
		int caretColumn;
		string name;
		string shortName;
		int typeParameterCount;
		
		public SearchClassReturnType(IProjectContent projectContent, IClass declaringClass, int caretLine, int caretColumn, string name, int typeParameterCount)
		{
			if (declaringClass == null)
				throw new ArgumentNullException("declaringClass");
			this.declaringClass = declaringClass;
			this.pc = projectContent;
			this.caretLine = caretLine;
			this.caretColumn = caretColumn;
			this.typeParameterCount = typeParameterCount;
			this.name = name;
			int pos = name.LastIndexOf('.');
			if (pos < 0)
				shortName = name;
			else
				shortName = name.Substring(pos + 1);
		}
		
		public override int TypeParameterCount {
			get {
				return typeParameterCount;
			}
		}
		
		public override bool Equals(object o)
		{
			SearchClassReturnType rt = o as SearchClassReturnType;
			if (rt != null) {
				if (name != rt.name)
					return false;
				if (declaringClass.FullyQualifiedName == rt.declaringClass.FullyQualifiedName
				    && typeParameterCount == rt.typeParameterCount
				    && caretLine == rt.caretLine
				    && caretColumn == rt.caretColumn)
				{
					return true;
				}
			}
			IReturnType rt2 = o as IReturnType;
			if (rt2 != null && rt2.IsDefaultReturnType)
				return rt2.FullyQualifiedName == this.FullyQualifiedName && rt2.TypeParameterCount == this.TypeParameterCount;
			else
				return false;
		}
		
		public override int GetHashCode()
		{
			unchecked {
				return declaringClass.GetHashCode() ^ name.GetHashCode()
					^ (typeParameterCount << 16 + caretLine << 8 + caretColumn);
			}
		}
		
		// we need to use a static Dictionary as cache to provide a easy was to clear all cached
		// BaseTypes.
		// When the cached BaseTypes could not be cleared as soon as the parse information is updated
		// (in contrast to a check if the parse information was updated when the base type is needed
		// the next time), we can get a memory leak:
		// The cached type of a property in Class1 is Class2. Then Class2 is updated, but the property
		// in Class1 is not needed again -> the reference causes the GC to keep the old version
		// of Class2 in memory.
		// The solution is this static cache which is cleared when some parse information updates.
		// That way, there can never be any reference to an out-of-date class.
		static Dictionary<SearchClassReturnType, IReturnType> cache;
		
		static SearchClassReturnType()
		{
			cache = new Dictionary<SearchClassReturnType, IReturnType>(new ReferenceComparer());
			ParserService.ParserUpdateStepFinished += OnParserUpdateStepFinished;
		}
		
		class ReferenceComparer : IEqualityComparer<SearchClassReturnType>
		{
			public bool Equals(SearchClassReturnType x, SearchClassReturnType y)
			{
				return x == y; // don't use x.Equals(y) - Equals might cause a FullyQualifiedName lookup on its own
			}
			
			public int GetHashCode(SearchClassReturnType obj)
			{
				return obj.GetHashCode();
			}
		}
		
		static void OnParserUpdateStepFinished(object sender, ParserUpdateStepEventArgs e)
		{
			if (e.Updated) {
				// clear the cache completely when the information was updated
				lock (cache) {
					cache.Clear();
				}
			}
		}
		
		bool isSearching;
		
		public override IReturnType BaseType {
			get {
				if (isSearching)
					return null;
				IReturnType type;
				lock (cache) {
					if (cache.TryGetValue(this, out type))
						return type;
					try {
						isSearching = true;
						type = pc.SearchType(name, typeParameterCount, declaringClass, caretLine, caretColumn);
						cache[this] = type;
						return type;
					} finally {
						isSearching = false;
					}
				}
			}
		}
		
		public override string FullyQualifiedName {
			get {
				string tmp = base.FullyQualifiedName;
				if (tmp == "?") {
					return name;
				}
				return tmp;
			}
		}
		
		public override string Name {
			get {
				return shortName;
			}
		}
		
		public override string DotNetName {
			get {
				string tmp = base.DotNetName;
				if (tmp == "?") {
					return name;
				}
				return tmp;
			}
		}
		
		public override bool IsDefaultReturnType {
			get {
				return true;
			}
		}
		
		public override string ToString()
		{
			return String.Format("[SearchClassReturnType: {0}]", name);
		}
	}
}

⌨️ 快捷键说明

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