📄 sharpassemblyclass.cs
字号:
// <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 + -