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

📄 sharpassemblyclass.cs

📁 全功能c#编译器
💻 CS
📖 第 1 页 / 共 2 页
字号:
// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
//     <version value="$version"/>
// </file>
using System;
using System.Diagnostics;
using System.Collections;
using System.Text;
using System.Xml;
using System.Collections.Specialized;
using System.Collections.Utility;

using ICSharpCode.SharpAssembly.Metadata.Rows;
using ICSharpCode.SharpAssembly.Metadata;
using ICSharpCode.SharpAssembly.PE;
using ICSharpCode.SharpAssembly.Assembly;

namespace SharpDevelop.Internal.Parser {
	
	[Serializable]
	public class SharpAssemblyClass : AbstractNamedEntity, IClass
	{
		ClassCollection baseTypeCollection = new ClassCollection();
		StringCollection baseTypes         = null;
		
		protected ClassType        classType;
		protected object           declaredIn;

		protected ClassCollection    innerClasses = null; //new ClassCollection();
		protected FieldCollection    fields       = null; //new FieldCollection();
		protected PropertyCollection properties   = null; //new PropertyCollection();
		protected MethodCollection   methods      = null; //new MethodCollection();
		protected EventCollection    events       = null; //new EventCollection();
		protected IndexerCollection  indexer      = null; //new IndexerCollection();

		public virtual ClassType ClassType {
			get {
				return classType;
			}
		}

		public virtual IRegion Region {
			get {
				return null;
			}
		}
		
		public virtual IRegion BodyRegion {
			get {
				return null;
			}
		}

		public object DeclaredIn {
			get {
				return declaredIn;
			}
		}

		public virtual StringCollection BaseTypes {
			get {
				if (baseTypes == null) baseTypes = new StringCollection();
				return baseTypes;
			}
		}
		
		public virtual ClassCollection InnerClasses {
			get {
				if (innerClasses == null) innerClasses = new ClassCollection();
				return innerClasses;
			}
		}

		public IndexerCollection Indexer {
			get {
				if (indexer == null) indexer = new IndexerCollection();
				return indexer;
			}
		}

		public IEnumerable ClassInheritanceTree {
			get {
				return new AbstractClass.ClassInheritanceEnumerator(this);
			}
		}
		
		protected override bool CanBeSubclass {
			get {
				return true;
			}
		}

		public ClassCollection BaseTypeCollection {
			get {
				if (baseTypeCollection == null) baseTypeCollection = new ClassCollection();
				return baseTypeCollection;
			}
		}
		
		public virtual ICompilationUnit CompilationUnit {
			get {
				return null;
			}
		}
		
		public static string GetNestedName(SharpAssembly asm, TypeRef[] typeRefTable, uint index)
		{
			uint val = typeRefTable[index].ResolutionScope;
			int table = asm.Reader.GetCodedIndexTable(CodedIndex.ResolutionScope, ref val);
			
			switch (table) {
				case 2: // AssemblyRef
					return asm.Reader.GetStringFromHeap(typeRefTable[index].Nspace) + "." + asm.Reader.GetStringFromHeap(typeRefTable[index].Name);
				case 3: // TypeRef -- nested type
					return GetNestedName(asm, typeRefTable, val) + "+" + asm.Reader.GetStringFromHeap(typeRefTable[index].Name);
				default: // other token - not supported
					Console.WriteLine("GetNestedName: Unsupported resolution scope!");
					goto case 3;
			}
		}
		
		public static string GetNestedName(SharpAssembly asm, TypeDef[] typeDefTable, uint index)
		{
			uint nestedParent = asm.GetNestedTypeParent(index);
			
			if (nestedParent == 0) {
				return asm.Reader.GetStringFromHeap(typeDefTable[index].NSpace) + "." + asm.Reader.GetStringFromHeap(typeDefTable[index].Name);
			}
			
			return GetNestedName(asm, typeDefTable, nestedParent) + "+" + asm.Reader.GetStringFromHeap(typeDefTable[index].Name);
		}
		
		/// <summary>
		/// Constructs a SharpAssemblyClass from an entry in the assembly's TypeRef table
		/// by looking in the referencing assembly's TypeDef table
		/// </summary>
		public static SharpAssemblyClass FromTypeRef(SharpAssembly referencingAssembly, uint index)
		{
			if (referencingAssembly.TypeRefObjects[index] as SharpAssemblyClass != null) {
				return (SharpAssemblyClass)referencingAssembly.TypeRefObjects[index];
			}
			
			TypeRef[] typeRefTable = referencingAssembly.Tables.TypeRef;
			
			string name = referencingAssembly.Reader.GetStringFromHeap(typeRefTable[index].Name);
			
			SharpAssembly declaringAssembly = referencingAssembly.GetRefAssemblyFor(index);
			if (declaringAssembly == null) {
				Console.Write("FromTypeRef failed for: " + name + " declared in assembly " + referencingAssembly.Name);
				Console.WriteLine(": Declaring assembly not found.");
				return null;
			}
			
			
			TypeDef[] typeDefTable = declaringAssembly.Tables.TypeDef;
			if (typeDefTable == null) {
				return null;
			}
			
			string nestedName = GetNestedName(referencingAssembly, typeRefTable, index);
			
			for (uint i = 1; i <= typeDefTable.GetUpperBound(0); ++i) {
				if (declaringAssembly.Reader.GetStringFromHeap(typeDefTable[i].Name) == name) {
					if (GetNestedName(declaringAssembly, typeDefTable, i) == nestedName) {
						SharpAssemblyClass newclass = FromTypeDef(declaringAssembly, i);
						
						// store new class object in assembly's cache
						if (newclass != null) referencingAssembly.TypeRefObjects[index] = newclass;
						return newclass;
					}
				}
			}
			
			Console.Write("FromTypeRef failed for: " + name + " declared in assembly " + referencingAssembly.Name);
			Console.WriteLine(": Matching type not found for nested name: " + nestedName);
			return null;
		}
		
		/// <summary>
		/// Constructs a SharpAssemblyClass from an entry in the assembly's TypeDef table
		/// Looks in the class cache for the assembly first
		/// </summary>
		public static SharpAssemblyClass FromTypeDef(SharpAssembly assembly, uint index)
		{
			if (assembly.TypeDefObjects[index] as SharpAssemblyClass != null) {
				SharpAssemblyClass exclass = (SharpAssemblyClass)assembly.TypeDefObjects[index];
				
				return exclass;
			}
			
			return new SharpAssemblyClass(assembly, assembly.Tables.TypeDef, index);
		}
		
		/// <summary>
		/// The constructor is private because the only way to construct SharpAssemblyClass objects
		/// is to call FromTypeRef/Def to make us of the cache
		/// </summary>
		private SharpAssemblyClass(SharpAssembly assembly, TypeDef[] typeDefTable, uint index)
		{
			if (assembly == null) {
				throw new System.ArgumentNullException("assembly");
			}
			if (typeDefTable == null) {
				throw new System.ArgumentNullException("typeDefTable");
			}
			if (index > typeDefTable.GetUpperBound(0) || index < 1) {
				throw new System.ArgumentOutOfRangeException("index", index, String.Format("must be between 1 and {0}!", typeDefTable.GetUpperBound(0)));
			}
			
			TypeDef typeDef = typeDefTable[index];
			typeDefIndex = index;  // store index for use in LoadMembers()
			
			declaredIn = assembly;
			
			FullyQualifiedName = GetNestedName(assembly, typeDefTable, index);
			
			// store in assembly's cache
			assembly.TypeDefObjects[index] = this;
			
			if (typeDef.IsFlagSet(TypeDef.FLAG_INTERFACE)) {
				classType = ClassType.Interface;
			} else if (typeDef.IsFlagSet(TypeDef.FLAG_CLASS)) {
				classType = ClassType.Class;
			}
			
			if (typeDef.Extends == 0) goto noext;
			
			SharpAssemblyClass extend = GetTypeRefOrDefClass(assembly, typeDef.Extends);
			
			if (extend == null) goto noext;
			
			if (extend.FullyQualifiedName == "System.Enum") {
				classType = ClassType.Enum;
			} else if (extend.FullyQualifiedName == "System.ValueType") {
				classType = ClassType.Struct;
			}
			
			baseTypeCollection.Add(extend);
			
			if (IsSubclassOf("System.Delegate")) classType = ClassType.Delegate;
			
		noext:
		
			InterfaceImpl[] ifaces = assembly.Tables.InterfaceImpl;
			if (ifaces == null) goto nointerfaces;
			
			for (int i = 1; i <= ifaces.GetUpperBound(0); ++i) {
				if (ifaces[i].Class == index) {
					SharpAssemblyClass impl = GetTypeRefOrDefClass(assembly, ifaces[i].Interface);
					if (impl != null) {
						baseTypeCollection.Add(impl);
					}
				}
			}
			
		nointerfaces:
		
			NestedClass[] nestedClasses = assembly.Tables.NestedClass;
			if (nestedClasses == null) goto nonested;

			for (int i = 1; i <= nestedClasses.GetUpperBound(0); ++i) {
				if (nestedClasses[i].EnclosingClass == index) {
					IClass newclass = FromTypeDef(assembly, nestedClasses[i].NestedClassIndex);
					if (innerClasses == null) innerClasses = new ClassCollection();
					innerClasses.Add(newclass);
				}
			}
		
		nonested:
			
			// Attributes
			ArrayList attrib = assembly.Attributes.TypeDef[index] as ArrayList;
			if (attrib == null) goto modifiers;
			

⌨️ 快捷键说明

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