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

📄 defaultprojectcontent.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.IO;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Xml;
using System.Text;

using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Dom;

namespace ICSharpCode.Core
{
	public class DefaultProjectContent : IProjectContent
	{
		protected readonly List<IProjectContent> referencedContents = new List<IProjectContent>();
		
		// we use a list of Dictionaries because we need multiple dictionaries:
		// each uses another StringComparer
		// (C#: StringComparer.InvariantCulture, VB: StringComparer.InvariantCultureCaseInsensitive)
		// new dictionaries are added to the list when required
		List<Dictionary<string, IClass>> classLists = new List<Dictionary<string, IClass>>();
		List<Dictionary<string, NamespaceStruct>> namespaces = new List<Dictionary<string, NamespaceStruct>>();
		protected XmlDoc xmlDoc = new XmlDoc();
		IUsing defaultImports;
		
		public IUsing DefaultImports {
			get {
				return defaultImports;
			}
			set {
				defaultImports = value;
			}
		}
		
		public virtual IProject Project {
			get {
				return null;
			}
		}
		
		public List<Dictionary<string, IClass>> ClassLists {
			get {
				if (classLists.Count == 0) {
					classLists.Add(new Dictionary<string, IClass>(language.NameComparer));
				}
				return classLists;
			}
		}
		
		public ICollection<string> NamespaceNames {
			get {
				return Namespaces[0].Keys;
			}
		}
		
		protected List<Dictionary<string, NamespaceStruct>> Namespaces {
			get {
				if (namespaces.Count == 0) {
					namespaces.Add(new Dictionary<string, NamespaceStruct>(language.NameComparer));
				}
				return namespaces;
			}
		}
		
		protected struct NamespaceStruct
		{
			public readonly List<IClass> Classes;
			public readonly List<string> SubNamespaces;
			
			public NamespaceStruct(string name) // struct must have a parameter
			{
				this.Classes = new List<IClass>();
				this.SubNamespaces = new List<string>();
			}
		}
		
		/// <summary>
		/// Gets the class dictionary that uses the name comparison rules of <paramref name="language"/>.
		/// </summary>
		protected Dictionary<string, IClass> GetClasses(LanguageProperties language)
		{
			for (int i = 0; i < classLists.Count; ++i) {
				if (classLists[i].Comparer == language.NameComparer)
					return classLists[i];
			}
			Dictionary<string, IClass> d;
			if (classLists.Count > 0) {
				Dictionary<string, IClass> oldList = classLists[0];
				d = new Dictionary<string, IClass>(oldList.Count, language.NameComparer);
				foreach (KeyValuePair<string, IClass> pair in oldList) {
					d.Add(pair.Key, pair.Value);
				}
			} else {
				d = new Dictionary<string, IClass>(language.NameComparer);
			}
			classLists.Add(d);
			return d;
		}
		
		/// <summary>
		/// Gets the namespace dictionary that uses the name comparison rules of <paramref name="language"/>.
		/// </summary>
		protected Dictionary<string, NamespaceStruct> GetNamespaces(LanguageProperties language)
		{
			for (int i = 0; i < namespaces.Count; ++i) {
				if (namespaces[i].Comparer == language.NameComparer)
					return namespaces[i];
			}
			Dictionary<string, NamespaceStruct> d;
			if (namespaces.Count > 0) {
				Dictionary<string, NamespaceStruct> oldList = namespaces[0];
				d = new Dictionary<string, NamespaceStruct>(oldList.Count, language.NameComparer);
				foreach (KeyValuePair<string, NamespaceStruct> pair in oldList) {
					d.Add(pair.Key, pair.Value);
				}
			} else {
				d = new Dictionary<string, NamespaceStruct>(language.NameComparer);
			}
			namespaces.Add(d);
			return d;
		}
		
		public XmlDoc XmlDoc {
			get {
				return xmlDoc;
			}
		}
		
		public ICollection<IClass> Classes {
			get {
				lock (namespaces) {
					List<IClass> list = new List<IClass>(ClassLists[0].Count + 10);
					foreach (IClass c in ClassLists[0].Values) {
						if (c is GenericClassContainer) {
							GenericClassContainer gcc = (GenericClassContainer)c;
							list.AddRange(gcc.RealClasses);
						} else {
							list.Add(c);
						}
					}
					return list;
				}
			}
		}
		
		public ICollection<IProjectContent> ReferencedContents {
			get {
				return referencedContents;
			}
		}
		
		LanguageProperties language = LanguageProperties.CSharp;
		
		/// <summary>
		/// Gets/Sets the properties of the language this project content was written in.
		/// </summary>
		public LanguageProperties Language {
			[DebuggerStepThrough]
			get {
				return language;
			}
			set {
				if (value == null) throw new ArgumentNullException();
				language = value;
			}
		}
		
		public string GetXmlDocumentation(string memberTag)
		{
			string desc = xmlDoc.GetDocumentation(memberTag);
			if (desc != null) {
				return desc;
			}
			foreach (IProjectContent referencedContent in referencedContents) {
				desc = referencedContent.XmlDoc.GetDocumentation(memberTag);
				if (desc != null) {
					return desc;
				}
			}
			return null;
		}
		
		protected static string LookupLocalizedXmlDoc(string fileName)
		{
			string xmlFileName         = Path.ChangeExtension(fileName, ".xml");
			string localizedXmlDocFile = FileUtility.Combine(System.IO.Path.GetDirectoryName(fileName), Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName, System.IO.Path.GetFileName(xmlFileName));
			if (File.Exists(localizedXmlDocFile)) {
				return localizedXmlDocFile;
			}
			if (File.Exists(xmlFileName)) {
				return xmlFileName;
			}
			return null;
		}
		
		public virtual void Dispose()
		{
			xmlDoc.Dispose();
		}
		
		public void AddClassToNamespaceList(IClass addClass)
		{
			lock (namespaces) {
				AddClassToNamespaceListInternal(addClass);
			}
		}
		
		/// <summary>
		/// Container class that is used when multiple classes with different type parameter
		/// count have the same class name.
		/// </summary>
		private class GenericClassContainer : DefaultClass
		{
			public GenericClassContainer(string fullyQualifiedName) : base(null, fullyQualifiedName) {}
			
			IClass[] realClasses = new IClass[4];
			
			public IEnumerable<IClass> RealClasses {
				get {
					foreach (IClass c in realClasses) {
						if (c != null) yield return c;
					}
				}
			}
			
			public int RealClassCount {
				get {
					int count = 0;
					foreach (IClass c in realClasses) {
						if (c != null) count += 1;
					}
					return count;
				}
			}
			
			public IClass Get(int typeParameterCount)
			{
				if (realClasses.Length > typeParameterCount)
					return realClasses[typeParameterCount];
				else
					return null;
			}
			
			public IClass GetBest(int typeParameterCount)
			{
				IClass c;
				for (int i = typeParameterCount; i < realClasses.Length; i++) {
					c = Get(i);
					if (c != null) return c;
				}
				for (int i = typeParameterCount - 1; i >= 0; i--) {
					c = Get(i);
					if (c != null) return c;
				}
				return null;
			}
			
			public void Set(IClass c)
			{
				int typeParameterCount = c.TypeParameters.Count;
				if (realClasses.Length <= typeParameterCount) {
					IClass[] newArray = new IClass[typeParameterCount + 2];
					realClasses.CopyTo(newArray, 0);
					realClasses = newArray;
				}
				realClasses[typeParameterCount] = c;
			}
			
			public void Remove(int typeParameterCount)
			{
				if (realClasses.Length > typeParameterCount)
					realClasses[typeParameterCount] = null;
			}
		}
		
		protected void AddClassToNamespaceListInternal(IClass addClass)
		{
			string fullyQualifiedName = addClass.FullyQualifiedName;
			if (addClass.IsPartial) {
				LoggingService.Debug("Adding partial class " + addClass.Name + " from " + Path.GetFileName(addClass.CompilationUnit.FileName));
				CompoundClass compound = GetClassInternal(fullyQualifiedName, addClass.TypeParameters.Count, language) as CompoundClass;
				if (compound != null) {
					// possibly replace existing class (look for CU with same filename)
					lock (compound) {
						for (int i = 0; i < compound.Parts.Count; i++) {
							if (compound.Parts[i].CompilationUnit.FileName == addClass.CompilationUnit.FileName) {
								compound.Parts[i] = addClass;
								compound.UpdateInformationFromParts();
								LoggingService.Debug("Replaced old part!");
								return;
							}
						}
						compound.Parts.Add(addClass);
						compound.UpdateInformationFromParts();
					}
					LoggingService.Debug("Added new part!");
					return;
				} else {
					addClass = new CompoundClass(addClass);
					LoggingService.Debug("Compound created!");
				}
			}
			
			IClass oldDictionaryClass;
			if (GetClasses(language).TryGetValue(fullyQualifiedName, out oldDictionaryClass)) {
				GenericClassContainer gcc = oldDictionaryClass as GenericClassContainer;
				if (gcc != null) {
					gcc.Set(addClass);
					return;
				} else if (oldDictionaryClass.TypeParameters.Count != addClass.TypeParameters.Count) {
					gcc = new GenericClassContainer(fullyQualifiedName);
					gcc.Set(addClass);
					gcc.Set(oldDictionaryClass);
					addClass = gcc;
				}
			}
			
			foreach (Dictionary<string, IClass> classes in ClassLists) {
				classes[addClass.FullyQualifiedName] = addClass;
			}
			string nSpace = addClass.Namespace;
			if (nSpace == null) {
				nSpace = String.Empty;
			}
			CreateNamespace(nSpace);
			List<IClass> classList = GetNamespaces(this.language)[nSpace].Classes;
			for (int i = 0; i < classList.Count; i++) {
				if (classList[i].FullyQualifiedName == addClass.FullyQualifiedName) {
					classList[i] = addClass;
					return;
				}
			}
			classList.Add(addClass);
		}
		
		void CreateNamespace(string nSpace)
		{
			Dictionary<string, NamespaceStruct> dict = GetNamespaces(this.language);
			if (dict.ContainsKey(nSpace))
				return;
			NamespaceStruct namespaceStruct = new NamespaceStruct(nSpace);
			dict.Add(nSpace, namespaceStruct);
			// use the same namespaceStruct for all dictionaries
			foreach (Dictionary<string, NamespaceStruct> otherDict in namespaces) {
				if (otherDict == dict) continue;
				otherDict.Add(nSpace, namespaceStruct);
			}
			if (nSpace.Length == 0)
				return;
			// add to parent namespace
			int pos = nSpace.LastIndexOf('.');
			string parent;
			string subNs;
			if (pos < 0) {
				parent = "";
				subNs = nSpace;
			} else {
				parent = nSpace.Substring(0, pos);
				subNs = nSpace.Substring(pos + 1);
			}
			CreateNamespace(parent);
			dict[parent].SubNamespaces.Add(subNs);
		}
		
		/// <summary>
		/// Removes the specified namespace from all namespace lists if the namespace is empty.
		/// </summary>
		void RemoveEmptyNamespace(string nSpace)
		{
			if (nSpace == null || nSpace.Length == 0) return;
			Dictionary<string, NamespaceStruct> dict = GetNamespaces(this.language);
			if (!dict.ContainsKey(nSpace))
				return;
			// remove only if really empty
			if (dict[nSpace].Classes.Count > 0 || dict[nSpace].SubNamespaces.Count > 0)
				return;
			// remove the namespace from all dictionaries
			foreach (Dictionary<string, NamespaceStruct> anyDict in namespaces) {
				anyDict.Remove(nSpace);
			}
			// remove the namespace from parent's SubNamespaces list
			int pos = nSpace.LastIndexOf('.');
			string parent;
			string subNs;
			if (pos < 0) {
				parent = "";
				subNs = nSpace;
			} else {
				parent = nSpace.Substring(0, pos);
				subNs = nSpace.Substring(pos + 1);
			}
			dict[parent].SubNamespaces.Remove(subNs);
			RemoveEmptyNamespace(parent); // remove parent if also empty
		}
		
		public void RemoveCompilationUnit(ICompilationUnit unit)
		{
			lock (namespaces) {
				foreach (IClass c in unit.Classes) {
					RemoveClass(c);
				}
			}
		}
		

⌨️ 快捷键说明

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