Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@629 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
29 changed files with 2191 additions and 338 deletions
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00 |
||||
# SharpDevelop 2.0.0.612 |
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyScout", "Project\AssemblyScout.csproj", "{DDD402CD-1D04-4E3F-B563-A4CACC500188}" |
||||
EndProject |
||||
Global |
||||
EndGlobal |
@ -0,0 +1,262 @@
@@ -0,0 +1,262 @@
|
||||
// <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.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.Xml; |
||||
using System.IO; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpAssembly.Metadata.Rows; |
||||
using ICSharpCode.SharpAssembly.Metadata; |
||||
using ICSharpCode.SharpAssembly.PE; |
||||
using SA = ICSharpCode.SharpAssembly.Assembly; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.AddIns.AssemblyScout |
||||
{ |
||||
[Serializable] |
||||
public class SharpAssemblyAttribute : DefaultAttribute |
||||
{ |
||||
SharpAssemblyClass attributeType; |
||||
|
||||
public SharpAssemblyClass AttributeType { |
||||
get { |
||||
return attributeType; |
||||
} |
||||
} |
||||
|
||||
public SharpAssemblyAttribute(SA.SharpAssembly assembly, SA.SharpCustomAttribute attribute) : base(null) |
||||
{ |
||||
uint sigOffset = 0; |
||||
|
||||
if (attribute.IsMemberRef) { |
||||
MemberRef[] memberTable = assembly.Tables.MemberRef; |
||||
TypeRef[] typeRefTable = assembly.Tables.TypeRef; |
||||
|
||||
sigOffset = memberTable[attribute.MemberIndex].Signature; |
||||
uint trIndex = memberTable[attribute.MemberIndex].Class; |
||||
|
||||
int table = assembly.Reader.GetCodedIndexTable(CodedIndex.MemberRefParent, ref trIndex); |
||||
if (table != 1) { |
||||
Console.WriteLine("SharpAssemblyAttribute: unsupported MemberRefParent coded index"); |
||||
return; // unsupported
|
||||
} |
||||
|
||||
attributeType = SharpAssemblyClass.FromTypeRef(assembly, trIndex); |
||||
|
||||
} else { |
||||
TypeDef[] typeDefTable = assembly.Tables.TypeDef; |
||||
|
||||
sigOffset = assembly.Tables.Method[attribute.MemberIndex].Signature; |
||||
uint tdIndex = 0; |
||||
|
||||
for (uint i = 1; i <= typeDefTable.GetUpperBound(0); ++i) { |
||||
if (typeDefTable[i].MethodList <= attribute.MemberIndex && i == typeDefTable.GetUpperBound(0)) { |
||||
tdIndex = i; |
||||
break; |
||||
} |
||||
if (typeDefTable[i].MethodList <= attribute.MemberIndex && typeDefTable[i+1].MethodList > attribute.MemberIndex) { |
||||
tdIndex = i; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
attributeType = SharpAssemblyClass.FromTypeDef(assembly, tdIndex); |
||||
} |
||||
if (attributeType != null) Name = attributeType.FullyQualifiedName; |
||||
|
||||
if (attribute.ValueIndex == 0) return; |
||||
|
||||
try { |
||||
|
||||
// Get return types of positional arguments by inspecting the method signature
|
||||
int size = assembly.Reader.LoadBlob(ref sigOffset); |
||||
sigOffset += 1; // skip calling convention
|
||||
int numReturnTypes = assembly.Reader.LoadBlob(ref sigOffset); |
||||
|
||||
SharpAssemblyReturnType dummy = SharpAssemblyReturnType.Create(assembly, ref sigOffset); |
||||
|
||||
SharpAssemblyReturnType[] returnTypes = new SharpAssemblyReturnType[numReturnTypes]; |
||||
for (int i = 0; i < returnTypes.Length; ++i) { |
||||
returnTypes[i] = SharpAssemblyReturnType.Create(assembly, ref sigOffset); |
||||
} |
||||
|
||||
// Get the return type values and the named arguments
|
||||
byte[] argBlob = assembly.Reader.GetBlobFromHeap(attribute.ValueIndex); |
||||
Stream str = new MemoryStream(argBlob); |
||||
BinaryReader binaryReader = new BinaryReader(str); |
||||
|
||||
ushort prolog = binaryReader.ReadUInt16(); |
||||
if (prolog != 1) { |
||||
Console.WriteLine("SharpAssemblyAttribute: Wrong prolog in argument list"); |
||||
return; |
||||
} |
||||
|
||||
// read positional arguments
|
||||
for (int i = 0; i < returnTypes.Length; ++i) { |
||||
string rettypename = returnTypes[i].Name; |
||||
|
||||
SharpAssemblyClass underlyingClass = returnTypes[i].UnderlyingClass; |
||||
|
||||
// enum -> determine base integer size and try to display the user-friendly name of the value
|
||||
if (underlyingClass != null && underlyingClass.IsSubclassOf("System.Enum")) { |
||||
//underlyingClass.LoadMembers();
|
||||
foreach (IField field in underlyingClass.Fields) { |
||||
if (field.Name.EndsWith("value__")) { |
||||
rettypename = field.ReturnType.Name; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
object argValue = GetFixedArg(argBlob, binaryReader, rettypename); |
||||
|
||||
foreach (IField field in underlyingClass.Fields) { |
||||
if (field is SharpAssemblyField) { |
||||
try { |
||||
if (((field as SharpAssemblyField).InitialValue as IComparable).CompareTo(argValue) == 0) { |
||||
// TODO PositionArguments
|
||||
//PositionalArguments.Add(underlyingClass.Name + "." + field.Name);
|
||||
goto namefound; |
||||
} |
||||
} catch {} |
||||
} |
||||
} |
||||
// if the value cannot be found
|
||||
// TODO PositionArguments
|
||||
//PositionalArguments.Add(argValue.ToString());
|
||||
|
||||
namefound: ; |
||||
|
||||
} else { |
||||
// TODO PositionArguments
|
||||
//PositionalArguments.Add(GetFixedArg(argBlob, binaryReader, rettypename).ToString());
|
||||
} |
||||
} |
||||
|
||||
ushort numnamed = binaryReader.ReadUInt16(); |
||||
|
||||
for (int i = 0; i < numnamed; ++i) { |
||||
byte field_or_prop = binaryReader.ReadByte(); |
||||
byte type = binaryReader.ReadByte(); |
||||
|
||||
string typename = ""; |
||||
if (type == 0x50) { |
||||
typename = "Type"; |
||||
} else { |
||||
DataType dt = (DataType)type; |
||||
typename = dt.ToString(); |
||||
} |
||||
|
||||
string argname = GetSerString(argBlob, binaryReader.BaseStream); |
||||
|
||||
// TODO NamedArgs
|
||||
//NamedArguments.Add(argname, GetFixedArg(argBlob, binaryReader, typename).ToString());
|
||||
} |
||||
|
||||
binaryReader.Close(); |
||||
} catch (Exception ex) { |
||||
LoggingService.Error("SharpAssemblyAttribute: Error loading arguments. " + ex.ToString()); |
||||
} |
||||
} |
||||
|
||||
object GetFixedArg(byte[] argBlob, BinaryReader binaryReader, string name) |
||||
{ |
||||
switch (name) { |
||||
case "Boolean": |
||||
return binaryReader.ReadBoolean(); |
||||
case "Char": |
||||
return binaryReader.ReadChar(); |
||||
case "SByte": |
||||
return binaryReader.ReadSByte(); |
||||
case "Byte": |
||||
return binaryReader.ReadByte(); |
||||
case "Int16": |
||||
return binaryReader.ReadInt16(); |
||||
case "UInt16": |
||||
return binaryReader.ReadUInt16(); |
||||
case "Int32": |
||||
return binaryReader.ReadInt32(); |
||||
case "UInt32": |
||||
return binaryReader.ReadUInt32(); |
||||
case "Int64": |
||||
return binaryReader.ReadInt64(); |
||||
case "UInt64": |
||||
return binaryReader.ReadUInt64(); |
||||
case "Single": |
||||
return binaryReader.ReadSingle(); |
||||
case "Double": |
||||
return binaryReader.ReadDouble(); |
||||
case "String": |
||||
case "Type": |
||||
return '"' + GetSerString(argBlob, binaryReader.BaseStream) + '"'; |
||||
default: |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
string GetSerString(byte[] blob, Stream stream) |
||||
{ |
||||
uint pos2 = (uint)stream.Position; |
||||
int size = SA.AssemblyReader.GetCompressedInt(blob, ref pos2); |
||||
|
||||
string str; |
||||
try { |
||||
str = System.Text.Encoding.UTF8.GetString(blob, (int)pos2, size); |
||||
} catch { |
||||
str = "<error with string>"; |
||||
} |
||||
|
||||
stream.Position = pos2 + size; |
||||
|
||||
return str; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
string ret = Name + " ("; |
||||
|
||||
foreach (AttributeArgument arg in PositionalArguments) { |
||||
ret += arg.Type.FullyQualifiedName + ", "; |
||||
} |
||||
|
||||
// TODO NamedArguments
|
||||
|
||||
foreach (KeyValuePair<string, AttributeArgument> item in NamedArguments) { |
||||
try { |
||||
ret += item.Key + " = " + item.Value.Type.FullyQualifiedName + ", "; |
||||
} catch { |
||||
LoggingService.Error("Error in NamedArguments."); |
||||
} |
||||
} |
||||
|
||||
|
||||
// delete last bracket
|
||||
if (ret.EndsWith(", ")) ret = ret.Substring(0, ret.Length - 2); |
||||
|
||||
return ret + ")"; |
||||
} |
||||
|
||||
public static List<IAttribute> GetAssemblyAttributes(SA.SharpAssembly assembly) |
||||
{ |
||||
List<IAttribute> attributes = new List<IAttribute>(); |
||||
|
||||
foreach (ArrayList al in assembly.Attributes.Assembly.Values) { |
||||
foreach (SA.SharpCustomAttribute attr in al) { |
||||
attributes.Add(new SharpAssemblyAttribute(assembly, attr)); |
||||
} |
||||
} |
||||
|
||||
return attributes; |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,484 @@
@@ -0,0 +1,484 @@
|
||||
// <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.Collections.Generic; |
||||
using System.Text; |
||||
using System.Xml; |
||||
using System.Collections.Specialized; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpAssembly.Metadata.Rows; |
||||
using ICSharpCode.SharpAssembly.Metadata; |
||||
using ICSharpCode.SharpAssembly.PE; |
||||
using ICSharpCode.SharpAssembly.Assembly; |
||||
using SA = ICSharpCode.SharpAssembly.Assembly; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.AddIns.AssemblyScout |
||||
{ |
||||
[Serializable] |
||||
public class SharpAssemblyClass : DefaultClass |
||||
{ |
||||
List<IClass> baseTypeCollection = new List<IClass>(); |
||||
|
||||
object declaredIn; |
||||
|
||||
public object DeclaredIn { |
||||
get { |
||||
return declaredIn; |
||||
} |
||||
} |
||||
|
||||
public override string DocumentationTag { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public List<IClass> BaseTypeCollection { |
||||
get { |
||||
if (baseTypeCollection == null) baseTypeCollection = new List<IClass>(); |
||||
return baseTypeCollection; |
||||
} |
||||
} |
||||
|
||||
public static string GetNestedName(SA.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(SA.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(SA.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); |
||||
|
||||
SA.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(SA.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>
|
||||
SharpAssemblyClass(SA.SharpAssembly assembly, TypeDef[] typeDefTable, uint index) : base(null, String.Empty) |
||||
{ |
||||
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); |
||||
InnerClasses.Add(newclass); |
||||
} |
||||
} |
||||
|
||||
nonested: |
||||
|
||||
// Attributes
|
||||
ArrayList attrib = assembly.Attributes.TypeDef[index] as ArrayList; |
||||
if (attrib == null) goto modifiers; |
||||
|
||||
foreach(SharpCustomAttribute customattribute in attrib) { |
||||
Attributes.Add(new SharpAssemblyAttribute(assembly, customattribute)); |
||||
} |
||||
|
||||
modifiers: |
||||
|
||||
Modifiers = ModifierEnum.None; |
||||
|
||||
if (typeDef.IsFlagSet(TypeDef.FLAG_SEALED)) { |
||||
Modifiers |= ModifierEnum.Sealed; |
||||
} |
||||
|
||||
if (typeDef.IsFlagSet(TypeDef.FLAG_ABSTRACT)) { |
||||
Modifiers |= ModifierEnum.Abstract; |
||||
} |
||||
|
||||
if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDPRIVATE, TypeDef.FLAG_VISIBILITYMASK)) { |
||||
Modifiers |= ModifierEnum.Private; |
||||
} else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDPUBLIC, TypeDef.FLAG_VISIBILITYMASK) || typeDef.IsMaskedFlagSet(TypeDef.FLAG_PUBLIC, TypeDef.FLAG_VISIBILITYMASK)) { |
||||
Modifiers |= ModifierEnum.Public; |
||||
} else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDASSEMBLY, TypeDef.FLAG_VISIBILITYMASK) || |
||||
typeDef.IsMaskedFlagSet(TypeDef.FLAG_NOTPUBLIC, TypeDef.FLAG_VISIBILITYMASK)) { |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDFAMILY, TypeDef.FLAG_VISIBILITYMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
} else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDFAMORASSEM, TypeDef.FLAG_VISIBILITYMASK)) { |
||||
Modifiers |= ModifierEnum.ProtectedOrInternal; |
||||
} else if (typeDef.IsMaskedFlagSet(TypeDef.FLAG_NESTEDFAMANDASSEM, TypeDef.FLAG_VISIBILITYMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} |
||||
|
||||
if (typeDef.IsFlagSet(TypeDef.FLAG_SPECIALNAME)) { |
||||
Modifiers |= ModifierEnum.Volatile | ModifierEnum.Unsafe | ModifierEnum.Extern; |
||||
} |
||||
|
||||
/* members are loaded on demand now |
||||
if (classType != ClassType.Delegate && loadMembers) { |
||||
AddMethods(assembly, typeDefTable, index); |
||||
AddFields(assembly, typeDefTable, index); |
||||
AddProperties(assembly, typeDefTable, index); |
||||
AddEvents(assembly, typeDefTable, index); |
||||
|
||||
membersLoaded = true; |
||||
} |
||||
*/ |
||||
} |
||||
|
||||
uint typeDefIndex = 0; |
||||
|
||||
bool membersLoaded = false; |
||||
|
||||
void LoadMembers() |
||||
{ |
||||
if (membersLoaded) return; |
||||
|
||||
membersLoaded = true; |
||||
|
||||
SA.SharpAssembly assembly = (SA.SharpAssembly)declaredIn; |
||||
TypeDef[] typeDefTable = assembly.Tables.TypeDef; |
||||
|
||||
AddMethods(assembly, typeDefTable, typeDefIndex); |
||||
AddFields(assembly, typeDefTable, typeDefIndex); |
||||
AddProperties(assembly, typeDefTable, typeDefIndex); |
||||
AddEvents(assembly, typeDefTable, typeDefIndex); |
||||
} |
||||
|
||||
public bool IsSubclassOf(string FullName) |
||||
{ |
||||
foreach (SharpAssemblyClass basetype in baseTypeCollection) { |
||||
if (basetype.FullyQualifiedName == FullName) return true; |
||||
|
||||
if (basetype.IsSubclassOf(FullName)) return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
private static SharpAssemblyClass GetTypeRefOrDefClass(SA.SharpAssembly assembly, uint cind) { |
||||
uint nTable = cind & 0x03; |
||||
uint nIndex = cind >> 2; |
||||
|
||||
switch (nTable) { |
||||
case 0: // TypeDef
|
||||
return FromTypeDef(assembly, nIndex); |
||||
case 1: // TypeRef
|
||||
return FromTypeRef(assembly, nIndex); |
||||
default: |
||||
Console.WriteLine("GetTypeRefOrDefClass: Wrong TypeDefOrRef coded index!"); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
void AddEvents(SA.SharpAssembly asm, TypeDef[] typeDefTable, uint index) |
||||
{ |
||||
EventMap[] eventMapTable = asm.Tables.EventMap; |
||||
Event[] eventTable = asm.Tables.Event; |
||||
if (eventMapTable == null || eventTable == null) { |
||||
return; |
||||
} |
||||
|
||||
for (int i = 1; i <= eventMapTable.GetUpperBound(0); ++i) { |
||||
EventMap eventMap = eventMapTable[i]; |
||||
|
||||
if (eventMap.Parent == index) { |
||||
uint eventIndexStart = eventMap.EventList; |
||||
|
||||
// 0 means no events
|
||||
if (eventIndexStart == 0) { |
||||
return; |
||||
} |
||||
|
||||
uint eventIndexEnd = (uint)eventTable.GetUpperBound(0) + 1; |
||||
if (i < eventMapTable.GetUpperBound(0)) { |
||||
eventIndexEnd = eventMapTable[i + 1].EventList; |
||||
} |
||||
|
||||
for (uint j = eventIndexStart; j < eventIndexEnd; ++j) { |
||||
IEvent newEvent = new SharpAssemblyEvent(asm, eventTable, this, j); |
||||
Events.Add(newEvent); |
||||
} |
||||
|
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void AddProperties(SA.SharpAssembly asm, TypeDef[] typeDefTable, uint index) |
||||
{ |
||||
PropertyMap[] propertyMapTable = asm.Tables.PropertyMap; |
||||
Property[] propertyTable = asm.Tables.Property; |
||||
if (propertyMapTable == null || propertyTable == null) { |
||||
return; |
||||
} |
||||
|
||||
for (int i = 1; i <= propertyMapTable.GetUpperBound(0); ++i) { |
||||
PropertyMap propertyMap = propertyMapTable[i]; |
||||
|
||||
if (propertyMap.Parent == index) { |
||||
uint propertyIndexStart = propertyMap.PropertyList; |
||||
|
||||
// 0 means no properties
|
||||
if (propertyIndexStart == 0) { |
||||
return; |
||||
} |
||||
|
||||
uint propertyIndexEnd = (uint)propertyTable.GetUpperBound(0) + 1; |
||||
if (i < propertyMapTable.GetUpperBound(0)) { |
||||
propertyIndexEnd = propertyMapTable[i + 1].PropertyList; |
||||
} |
||||
|
||||
for (uint j = propertyIndexStart; j < propertyIndexEnd; ++j) { |
||||
IProperty newProperty = new SharpAssemblyProperty(asm, propertyTable, this, j); |
||||
Properties.Add(newProperty); |
||||
} |
||||
|
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void AddFields(SA.SharpAssembly asm, TypeDef[] typeDefTable, uint index) |
||||
{ |
||||
Field[] fieldTable = asm.Tables.Field; |
||||
if (fieldTable == null) { |
||||
return; |
||||
} |
||||
|
||||
uint fieldIndexStart = typeDefTable[index].FieldList; |
||||
|
||||
// 0 means no fields
|
||||
if (fieldIndexStart == 0) { |
||||
return; |
||||
} |
||||
|
||||
uint fieldIndexEnd = (uint)fieldTable.GetUpperBound(0) + 1; |
||||
if (index < typeDefTable.GetUpperBound(0)) { |
||||
fieldIndexEnd = typeDefTable[index + 1].FieldList; |
||||
} |
||||
|
||||
for (uint i = fieldIndexStart; i < fieldIndexEnd; ++i) { |
||||
IField newField = new SharpAssemblyField(asm, fieldTable, this, i); |
||||
Fields.Add(newField); |
||||
} |
||||
} |
||||
|
||||
void AddMethods(SA.SharpAssembly asm, TypeDef[] typeDefTable, uint index) |
||||
{ |
||||
Method[] methodDefTable = asm.Tables.Method; |
||||
if (methodDefTable == null) { |
||||
return; |
||||
} |
||||
|
||||
uint methodIndexStart = typeDefTable[index].MethodList; |
||||
|
||||
// 0 means no methods
|
||||
if (methodIndexStart == 0) { |
||||
return; |
||||
} |
||||
|
||||
uint methodIndexEnd = (uint)methodDefTable.GetUpperBound(0) + 1; |
||||
if (index < typeDefTable.GetUpperBound(0)) { |
||||
methodIndexEnd = typeDefTable[index + 1].MethodList; |
||||
} |
||||
|
||||
for (uint i = methodIndexStart; i < methodIndexEnd; ++i) { |
||||
IMethod newMethod = new SharpAssemblyMethod(asm, methodDefTable, this, i); |
||||
Methods.Add(newMethod); |
||||
} |
||||
} |
||||
|
||||
public static SharpAssemblyClass[] GetAssemblyTypes(SA.SharpAssembly assembly) |
||||
{ |
||||
|
||||
TypeDef[] typeDefTable = assembly.Tables.TypeDef; |
||||
if (typeDefTable == null) return new SharpAssemblyClass[0]; |
||||
|
||||
ArrayList classes = new ArrayList(); |
||||
|
||||
for (uint i = 1; i <= typeDefTable.GetUpperBound(0); ++i) { |
||||
try { |
||||
IClass newclass = new SharpAssemblyClass(assembly, typeDefTable, i); |
||||
classes.Add(newclass); |
||||
} catch { |
||||
Console.WriteLine("GetAssemblyTypes: Error loading class " + i); |
||||
} |
||||
} |
||||
|
||||
return (SharpAssemblyClass[])classes.ToArray(typeof(SharpAssemblyClass)); |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return FullyQualifiedName; |
||||
} |
||||
|
||||
public override List<IField> Fields { |
||||
get { |
||||
if (!membersLoaded) LoadMembers(); |
||||
return base.Fields; |
||||
} |
||||
} |
||||
|
||||
public override List<IProperty> Properties { |
||||
get { |
||||
if (!membersLoaded) LoadMembers(); |
||||
return base.Properties; |
||||
} |
||||
} |
||||
|
||||
public override List<IMethod> Methods { |
||||
get { |
||||
if (!membersLoaded) LoadMembers(); |
||||
return base.Methods; |
||||
} |
||||
} |
||||
|
||||
public override List<IEvent> Events { |
||||
get { |
||||
if (!membersLoaded) LoadMembers(); |
||||
return base.Events; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,135 @@
@@ -0,0 +1,135 @@
|
||||
// <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.Collections; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.Xml; |
||||
|
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpAssembly.Metadata.Rows; |
||||
using ICSharpCode.SharpAssembly.Metadata; |
||||
using ICSharpCode.SharpAssembly.PE; |
||||
using ICSharpCode.SharpAssembly.Assembly; |
||||
using SA = ICSharpCode.SharpAssembly.Assembly; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.AddIns.AssemblyScout |
||||
{ |
||||
[Serializable] |
||||
public class SharpAssemblyEvent : DefaultEvent |
||||
{ |
||||
public override string DocumentationTag { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public SharpAssemblyEvent(SA.SharpAssembly asm, Event[] eventTable, SharpAssemblyClass declaringType, uint index) : base(declaringType, null) |
||||
{ |
||||
if (asm == null) { |
||||
throw new System.ArgumentNullException("asm"); |
||||
} |
||||
if (eventTable == null) { |
||||
throw new System.ArgumentNullException("eventTable"); |
||||
} |
||||
if (declaringType == null) { |
||||
throw new System.ArgumentNullException("declaringtype"); |
||||
} |
||||
if (index > eventTable.GetUpperBound(0) || index < 1) { |
||||
throw new System.ArgumentOutOfRangeException("index", index, String.Format("must be between 1 and {0}!", eventTable.GetUpperBound(0))); |
||||
} |
||||
|
||||
AssemblyReader assembly = asm.Reader; |
||||
|
||||
Event evt = eventTable[index]; |
||||
string name = assembly.GetStringFromHeap(evt.Name); |
||||
FullyQualifiedName = String.Concat(DeclaringType.FullyQualifiedName, ".", name); |
||||
|
||||
MethodSemantics[] sem = asm.Tables.MethodSemantics; |
||||
Method[] method = asm.Tables.Method; |
||||
if (sem == null) goto nosem; |
||||
|
||||
for (int i = 1; i <= sem.GetUpperBound(0); ++i) { |
||||
uint table = sem[i].Association & 1; |
||||
uint ident = sem[i].Association >> 1; |
||||
|
||||
if (table == 0 && ident == index) { // table: Event
|
||||
Modifiers = ModifierEnum.None; |
||||
Method methodDef = method[sem[i].Method]; |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_STATIC)) { |
||||
Modifiers |= ModifierEnum.Static; |
||||
} |
||||
|
||||
if (methodDef.IsMaskedFlagSet(Method.FLAG_PRIVATE, Method.FLAG_MEMBERACCESSMASK)) { // I assume that private is used most and public last (at least should be)
|
||||
Modifiers |= ModifierEnum.Private; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMILY, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_PUBLIC, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Public; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_ASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMORASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.ProtectedOrInternal; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMANDASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} |
||||
|
||||
if ((sem[i].Semantics & MethodSemantics.SEM_ADDON) == MethodSemantics.SEM_ADDON) { |
||||
addMethod = new SharpAssemblyMethod(asm, method, declaringType, sem[i].Method); |
||||
} |
||||
|
||||
if ((sem[i].Semantics & MethodSemantics.SEM_REMOVEON) == MethodSemantics.SEM_REMOVEON) { |
||||
removeMethod = new SharpAssemblyMethod(asm, method, declaringType, sem[i].Method); |
||||
} |
||||
|
||||
if ((sem[i].Semantics & MethodSemantics.SEM_FIRE) == MethodSemantics.SEM_FIRE) { |
||||
raiseMethod = new SharpAssemblyMethod(asm, method, declaringType, sem[i].Method); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
nosem: |
||||
|
||||
// Attributes
|
||||
ArrayList attrib = asm.Attributes.Event[index] as ArrayList; |
||||
if (attrib == null) goto noatt; |
||||
|
||||
foreach(SharpCustomAttribute customattribute in attrib) { |
||||
Attributes.Add(new SharpAssemblyAttribute(asm, customattribute)); |
||||
} |
||||
|
||||
noatt: |
||||
|
||||
if ((evt.EventFlags & Event.FLAG_SPECIALNAME) == Event.FLAG_SPECIALNAME) Modifiers |= ModifierEnum.Extern | ModifierEnum.Volatile | ModifierEnum.Unsafe; |
||||
|
||||
uint typtab = evt.EventType & 0x03; |
||||
uint typid = evt.EventType >> 2; |
||||
|
||||
if (typtab == 0) { // TypeDef
|
||||
TypeDef[] typedef = (TypeDef[])assembly.MetadataTable.Tables[TypeDef.TABLE_ID]; |
||||
ReturnType = SharpAssemblyReturnType.Create(asm, typedef, typid); |
||||
|
||||
} else if (typtab == 1) { // TypeRef
|
||||
TypeRef[] typeref = (TypeRef[])assembly.MetadataTable.Tables[TypeRef.TABLE_ID]; |
||||
ReturnType = SharpAssemblyReturnType.Create(asm, typeref, typid); |
||||
|
||||
} else { // TypeSpec
|
||||
ReturnType = SharpAssemblyReturnType.Create("NOT_SUPPORTED"); |
||||
Console.WriteLine("SharpAssemblyEvent: TypeSpec -- not supported"); |
||||
} |
||||
|
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return FullyQualifiedName; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,161 @@
@@ -0,0 +1,161 @@
|
||||
// <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.Collections; |
||||
using System.Text; |
||||
using System.IO; |
||||
using System.Xml; |
||||
|
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpAssembly.Metadata.Rows; |
||||
using ICSharpCode.SharpAssembly.Metadata; |
||||
using ICSharpCode.SharpAssembly.PE; |
||||
using ICSharpCode.SharpAssembly.Assembly; |
||||
using SA = ICSharpCode.SharpAssembly.Assembly; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.AddIns.AssemblyScout |
||||
{ |
||||
[Serializable] |
||||
public class SharpAssemblyField : DefaultField |
||||
{ |
||||
public override string DocumentationTag { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public SharpAssemblyField(SA.SharpAssembly assembly, Field[] fieldTable, SharpAssemblyClass declaringType, uint index) : base(declaringType, null) |
||||
{ |
||||
if (assembly == null) { |
||||
throw new System.ArgumentNullException("assembly"); |
||||
} |
||||
if (fieldTable == null) { |
||||
throw new System.ArgumentNullException("fieldTable"); |
||||
} |
||||
if (declaringType == null) { |
||||
throw new System.ArgumentNullException("declaringType"); |
||||
} |
||||
if (index > fieldTable.GetUpperBound(0) || index < 0) { |
||||
throw new System.ArgumentOutOfRangeException("index", index, String.Format("must be between 1 and {0}!", fieldTable.GetUpperBound(0))); |
||||
} |
||||
|
||||
Field field = fieldTable[index]; |
||||
string name = assembly.Reader.GetStringFromHeap(field.Name); |
||||
FullyQualifiedName = String.Concat(DeclaringType.FullyQualifiedName, ".", name); |
||||
|
||||
// Attributes
|
||||
ArrayList attrib = assembly.Attributes.Field[index] as ArrayList; |
||||
if (attrib == null) goto noatt; |
||||
|
||||
foreach(SharpCustomAttribute customattribute in attrib) { |
||||
Attributes.Add(new SharpAssemblyAttribute(assembly, customattribute)); |
||||
} |
||||
|
||||
noatt: |
||||
|
||||
if (field.IsFlagSet(Field.FLAG_INITONLY)) { |
||||
Modifiers |= ModifierEnum.Readonly; |
||||
} |
||||
|
||||
if (field.IsFlagSet(Field.FLAG_STATIC)) { |
||||
Modifiers |= ModifierEnum.Static; |
||||
} |
||||
|
||||
if (field.IsMaskedFlagSet(Field.FLAG_PRIVATE, Field.FLAG_FIELDACCESSMASK)) { // I assume that private is used most and public last (at least should be)
|
||||
Modifiers |= ModifierEnum.Private; |
||||
} else if (field.IsMaskedFlagSet(Field.FLAG_FAMILY, Field.FLAG_FIELDACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
} else if (field.IsMaskedFlagSet(Field.FLAG_PUBLIC, Field.FLAG_FIELDACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Public; |
||||
} else if (field.IsMaskedFlagSet(Field.FLAG_ASSEMBLY, Field.FLAG_FIELDACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} else if (field.IsMaskedFlagSet(Field.FLAG_FAMORASSEM, Field.FLAG_FIELDACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.ProtectedOrInternal; |
||||
} else if (field.IsMaskedFlagSet(Field.FLAG_FAMANDASSEM, Field.FLAG_FIELDACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} |
||||
|
||||
if (field.IsFlagSet(Field.FLAG_LITERAL)) { |
||||
Modifiers |= ModifierEnum.Const; |
||||
} |
||||
|
||||
if (field.IsFlagSet(Field.FLAG_SPECIALNAME)) { |
||||
Modifiers |= ModifierEnum.Extern | ModifierEnum.Unsafe | ModifierEnum.Volatile; |
||||
} |
||||
|
||||
// field return type
|
||||
uint sigOffset = field.Signature; |
||||
int sigSize = assembly.Reader.LoadBlob(ref sigOffset); |
||||
sigOffset++; // skip field id
|
||||
ReturnType = SharpAssemblyReturnType.Create(assembly, ref sigOffset); |
||||
|
||||
// field constant value -- for enums
|
||||
Constant cst = (Constant)assembly.FieldConstantTable[index]; |
||||
if (declaringType.ClassType == ClassType.Enum && cst != null) { |
||||
try { |
||||
DataType dt = (DataType)cst.Type; |
||||
|
||||
byte[] blob = assembly.Reader.GetBlobFromHeap(cst.Val); |
||||
BinaryReader binReader = new BinaryReader(new MemoryStream(blob)); |
||||
|
||||
switch (dt) { |
||||
case DataType.Byte: |
||||
initialValue = binReader.ReadByte(); |
||||
break; |
||||
case DataType.Int16: |
||||
initialValue = binReader.ReadInt16(); |
||||
break; |
||||
case DataType.Int32: |
||||
initialValue = binReader.ReadInt32(); |
||||
break; |
||||
case DataType.Int64: |
||||
initialValue = binReader.ReadInt64(); |
||||
break; |
||||
case DataType.SByte: |
||||
initialValue = binReader.ReadSByte(); |
||||
break; |
||||
case DataType.UInt16: |
||||
initialValue = binReader.ReadUInt16(); |
||||
break; |
||||
case DataType.UInt32: |
||||
initialValue = binReader.ReadUInt32(); |
||||
break; |
||||
case DataType.UInt64: |
||||
initialValue = binReader.ReadUInt64(); |
||||
break; |
||||
default: // not supported
|
||||
break; |
||||
} |
||||
binReader.Close(); |
||||
} catch { |
||||
Console.WriteLine("SharpAssemblyField: Error reading constant value"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return FullyQualifiedName; |
||||
} |
||||
|
||||
object initialValue; |
||||
|
||||
public object InitialValue { |
||||
get { |
||||
return initialValue; |
||||
} |
||||
} |
||||
|
||||
public static bool IsSpecial(IField field) |
||||
{ |
||||
return ((field.Modifiers & ModifierEnum.Extern) == ModifierEnum.Extern) || |
||||
((field.Modifiers & ModifierEnum.Volatile) == ModifierEnum.Volatile) || |
||||
((field.Modifiers & ModifierEnum.Unsafe) == ModifierEnum.Unsafe); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,158 @@
@@ -0,0 +1,158 @@
|
||||
// <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.Reflection; |
||||
using System.Xml; |
||||
|
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpAssembly.Metadata.Rows; |
||||
using ICSharpCode.SharpAssembly.Metadata; |
||||
using ICSharpCode.SharpAssembly.PE; |
||||
using SA = ICSharpCode.SharpAssembly.Assembly; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.AddIns.AssemblyScout |
||||
{ |
||||
[Serializable] |
||||
public class SharpAssemblyMethod : DefaultMethod |
||||
{ |
||||
public override string DocumentationTag { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public SharpAssemblyMethod(SA.SharpAssembly asm, Method[] methodTable, SharpAssemblyClass declaringType, uint index) : base(declaringType, null) |
||||
{ |
||||
if (asm == null) { |
||||
throw new System.ArgumentNullException("asm"); |
||||
} |
||||
if (methodTable == null) { |
||||
throw new System.ArgumentNullException("methodTable"); |
||||
} |
||||
if (declaringType == null) { |
||||
throw new System.ArgumentNullException("declaringType"); |
||||
} |
||||
if (index > methodTable.GetUpperBound(0) || index < 1) { |
||||
throw new System.ArgumentOutOfRangeException("index", index, String.Format("must be between 1 and {0}!", methodTable.GetUpperBound(0))); |
||||
} |
||||
SA.AssemblyReader assembly = asm.Reader; |
||||
|
||||
Method methodDef = methodTable[index]; |
||||
string name = assembly.GetStringFromHeap(methodDef.Name); |
||||
|
||||
FullyQualifiedName = String.Concat(DeclaringType.FullyQualifiedName, ".", name); |
||||
|
||||
// Attributes
|
||||
ArrayList attrib = asm.Attributes.Method[index] as ArrayList; |
||||
if (attrib == null) goto noatt; |
||||
|
||||
foreach(SA.SharpCustomAttribute customattribute in attrib) { |
||||
Attributes.Add(new SharpAssemblyAttribute(asm, customattribute)); |
||||
} |
||||
|
||||
noatt: |
||||
|
||||
Modifiers = ModifierEnum.None; |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_STATIC)) { |
||||
Modifiers |= ModifierEnum.Static; |
||||
} |
||||
|
||||
if (methodDef.IsMaskedFlagSet(Method.FLAG_PRIVATE, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Private; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_PUBLIC, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Public; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMILY, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_ASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMORASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.ProtectedOrInternal; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMANDASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_VIRTUAL)) { |
||||
Modifiers |= ModifierEnum.Virtual; |
||||
} |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_FINAL)) { |
||||
Modifiers |= ModifierEnum.Default; |
||||
} |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_ABSTRACT)) { |
||||
Modifiers |= ModifierEnum.Abstract; |
||||
} |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_SPECIALNAME)) { |
||||
Modifiers |= ModifierEnum.Extern | ModifierEnum.Volatile | ModifierEnum.Unsafe; |
||||
} |
||||
|
||||
uint offset = methodDef.Signature; |
||||
int size = assembly.LoadBlob(ref offset); |
||||
offset += 1; // skip calling convention
|
||||
int numReturnTypes = assembly.LoadBlob(ref offset); |
||||
|
||||
ReturnType = SharpAssemblyReturnType.Create(asm, ref offset); |
||||
|
||||
IReturnType[] returnTypes = new IReturnType[numReturnTypes]; |
||||
for (int i = 0; i < returnTypes.Length; ++i) { |
||||
returnTypes[i] = SharpAssemblyReturnType.Create(asm, ref offset); |
||||
} |
||||
|
||||
AddParameters(asm, methodTable, index, returnTypes); |
||||
} |
||||
|
||||
public static bool IsSpecial(IMethod method) |
||||
{ |
||||
return ((method.Modifiers & ModifierEnum.Extern) == ModifierEnum.Extern) || |
||||
((method.Modifiers & ModifierEnum.Volatile) == ModifierEnum.Volatile) || |
||||
((method.Modifiers & ModifierEnum.Unsafe) == ModifierEnum.Unsafe); |
||||
} |
||||
|
||||
void AddParameters(SA.SharpAssembly asm, Method[] methodDefTable, uint index, IReturnType[] returnTypes) |
||||
{ |
||||
Param[] paramTable = asm.Tables.Param; |
||||
if (paramTable == null) return; |
||||
|
||||
uint paramIndexStart = methodDefTable[index].ParamList; |
||||
|
||||
// 0 means no parameters
|
||||
if (paramIndexStart > paramTable.GetUpperBound(0) || paramIndexStart == 0) { |
||||
return; |
||||
} |
||||
|
||||
uint paramIndexEnd = (uint)paramTable.GetUpperBound(0); |
||||
if (index < methodDefTable.GetUpperBound(0)) { |
||||
paramIndexEnd = methodDefTable[index + 1].ParamList; |
||||
} |
||||
|
||||
if (paramTable[paramIndexStart].Sequence == 0) paramIndexStart++; |
||||
|
||||
for (uint i = paramIndexStart; i < paramIndexEnd; ++i) { |
||||
uint j = (i - paramIndexStart); |
||||
Parameters.Add(new SharpAssemblyParameter(asm, paramTable, i, j < returnTypes.Length ? returnTypes[j] : null)); |
||||
} |
||||
} |
||||
|
||||
public override bool IsConstructor { |
||||
get { |
||||
return FullyQualifiedName.IndexOf("..") != -1; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return FullyQualifiedName; |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
// <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.Collections; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.Xml; |
||||
|
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpAssembly.Metadata.Rows; |
||||
using ICSharpCode.SharpAssembly.Metadata; |
||||
using ICSharpCode.SharpAssembly.PE; |
||||
using ICSharpCode.SharpAssembly.Assembly; |
||||
using SA = ICSharpCode.SharpAssembly.Assembly; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.AddIns.AssemblyScout |
||||
{ |
||||
[Serializable] |
||||
public class SharpAssemblyParameter : DefaultParameter |
||||
{ |
||||
public SharpAssemblyParameter(SA.SharpAssembly asm, Param[] paramTable, uint index, IReturnType type) : base(String.Empty) |
||||
{ |
||||
if (asm == null) { |
||||
throw new System.ArgumentNullException("asm"); |
||||
} |
||||
if (paramTable == null) { |
||||
throw new System.ArgumentNullException("paramTable"); |
||||
} |
||||
if (index > paramTable.GetUpperBound(0) || index < 1) { |
||||
throw new System.ArgumentOutOfRangeException("index", index, String.Format("must be between 1 and {0}!", paramTable.GetUpperBound(0))); |
||||
} |
||||
AssemblyReader assembly = asm.Reader; |
||||
|
||||
Param param = asm.Tables.Param[index]; |
||||
|
||||
Name = assembly.GetStringFromHeap(param.Name); |
||||
|
||||
if (param.IsFlagSet(Param.FLAG_OUT)) { |
||||
Modifiers |= ParameterModifiers.Out; |
||||
} |
||||
|
||||
// Attributes
|
||||
ArrayList attrib = asm.Attributes.Param[index] as ArrayList; |
||||
if (attrib == null) goto noatt; |
||||
|
||||
foreach(SharpCustomAttribute customattribute in attrib) { |
||||
SharpAssemblyAttribute newatt = new SharpAssemblyAttribute(asm, customattribute); |
||||
if (newatt.Name == "System.ParamArrayAttribute") Modifiers |= ParameterModifiers.Params; |
||||
Attributes.Add(newatt); |
||||
} |
||||
|
||||
noatt: |
||||
|
||||
if (type == null) { |
||||
returnType = SharpAssemblyReturnType.Create("PARAMETER_UNKNOWN"); |
||||
} else { |
||||
if (type.Name.EndsWith("&")) { |
||||
Modifiers |= ParameterModifiers.Ref; |
||||
} |
||||
returnType = type; |
||||
} |
||||
|
||||
} |
||||
|
||||
public SharpAssemblyParameter(SA.SharpAssembly asm, string paramName, IReturnType type) : base(String.Empty) |
||||
{ |
||||
Name = paramName; |
||||
if (type.Name.EndsWith("&")) { |
||||
Modifiers |= ParameterModifiers.Ref; |
||||
} |
||||
returnType = type; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return "Parameter : " + returnType.FullyQualifiedName; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,184 @@
@@ -0,0 +1,184 @@
|
||||
// <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.Collections; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.Xml; |
||||
|
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpAssembly.Metadata.Rows; |
||||
using ICSharpCode.SharpAssembly.Metadata; |
||||
using ICSharpCode.SharpAssembly.PE; |
||||
using ICSharpCode.SharpAssembly.Assembly; |
||||
using SA = ICSharpCode.SharpAssembly.Assembly; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.AddIns.AssemblyScout |
||||
{ |
||||
[Serializable] |
||||
public class SharpAssemblyProperty : DefaultProperty |
||||
{ |
||||
public override string DocumentationTag { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public SharpAssemblyProperty(SA.SharpAssembly asm, Property[] propertyTable, SharpAssemblyClass declaringType, uint index) : base(declaringType, String.Empty) |
||||
{ |
||||
if (asm == null) { |
||||
throw new System.ArgumentNullException("asm"); |
||||
} |
||||
if (propertyTable == null) { |
||||
throw new System.ArgumentNullException("propertyTable"); |
||||
} |
||||
if (declaringType == null) { |
||||
throw new System.ArgumentNullException("declaringType"); |
||||
} |
||||
if (index > propertyTable.GetUpperBound(0) || index < 1) { |
||||
throw new System.ArgumentOutOfRangeException("index", index, String.Format("must be between 1 and {0}!", propertyTable.GetUpperBound(0))); |
||||
} |
||||
|
||||
AssemblyReader assembly = asm.Reader; |
||||
|
||||
Property property = asm.Tables.Property[index]; |
||||
string name = assembly.GetStringFromHeap(property.Name); |
||||
FullyQualifiedName = String.Concat(DeclaringType.FullyQualifiedName, ".", name); |
||||
|
||||
MethodSemantics[] sem = (MethodSemantics[])assembly.MetadataTable.Tables[MethodSemantics.TABLE_ID]; |
||||
Method[] method = (Method[])assembly.MetadataTable.Tables[Method.TABLE_ID]; |
||||
|
||||
uint getterMethodIndex = 0; // used later for parameters
|
||||
|
||||
if (sem == null) goto nosem; |
||||
|
||||
for (int i = 1; i <= sem.GetUpperBound(0); ++i) { |
||||
uint table = sem[i].Association & 1; |
||||
uint ident = sem[i].Association >> 1; |
||||
|
||||
if (table == 1 && ident == index) { // table: Property
|
||||
Modifiers = ModifierEnum.None; |
||||
Method methodDef = method[sem[i].Method]; |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_STATIC)) { |
||||
Modifiers |= ModifierEnum.Static; |
||||
} |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_ABSTRACT)) { |
||||
Modifiers |= ModifierEnum.Abstract; |
||||
} |
||||
|
||||
if (methodDef.IsFlagSet(Method.FLAG_VIRTUAL)) { |
||||
Modifiers |= ModifierEnum.Virtual; |
||||
} |
||||
if (methodDef.IsFlagSet(Method.FLAG_FINAL)) { |
||||
Modifiers |= ModifierEnum.Default; |
||||
} |
||||
|
||||
if (methodDef.IsMaskedFlagSet(Method.FLAG_PRIVATE, Method.FLAG_MEMBERACCESSMASK)) { // I assume that private is used most and public last (at least should be)
|
||||
Modifiers |= ModifierEnum.Private; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMILY, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_PUBLIC, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Public; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_ASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMORASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.ProtectedOrInternal; |
||||
} else if (methodDef.IsMaskedFlagSet(Method.FLAG_FAMANDASSEM, Method.FLAG_MEMBERACCESSMASK)) { |
||||
Modifiers |= ModifierEnum.Protected; |
||||
Modifiers |= ModifierEnum.Internal; |
||||
} |
||||
|
||||
|
||||
if ((sem[i].Semantics & MethodSemantics.SEM_GETTER) == MethodSemantics.SEM_GETTER) { |
||||
GetterRegion = new DomRegion(0, 0, 0, 0); |
||||
// TODO GetterMethod missing.
|
||||
// GetterMethod = new SharpAssemblyMethod(asm, method, declaringtype, sem[i].Method);
|
||||
// GetterMethodIndex = sem[i].Method;
|
||||
} |
||||
|
||||
if ((sem[i].Semantics & MethodSemantics.SEM_SETTER) == MethodSemantics.SEM_SETTER) { |
||||
SetterRegion = new DomRegion(0, 0, 0, 0); |
||||
// TODO SetterMethod missing.
|
||||
// SetterMethod = new SharpAssemblyMethod(asm, method, declaringtype, sem[i].Method);
|
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
nosem: |
||||
|
||||
// Attributes
|
||||
ArrayList attrib = asm.Attributes.Property[index] as ArrayList; |
||||
if (attrib == null) goto noatt; |
||||
|
||||
foreach(SA.SharpCustomAttribute customattribute in attrib) { |
||||
Attributes.Add(new SharpAssemblyAttribute(asm, customattribute)); |
||||
} |
||||
|
||||
noatt: |
||||
|
||||
if ((property.Flags & Property.FLAG_SPECIALNAME) == Property.FLAG_SPECIALNAME) Modifiers |= ModifierEnum.Extern | ModifierEnum.Volatile | ModifierEnum.Unsafe; |
||||
|
||||
uint offset = property.Type; |
||||
int sigSize = assembly.LoadBlob(ref offset); |
||||
offset += 1; // skip calling convention
|
||||
int paramCount = assembly.LoadBlob(ref offset); |
||||
|
||||
ReturnType = SharpAssemblyReturnType.Create(asm, ref offset); |
||||
|
||||
IReturnType[] returnTypes = new IReturnType[paramCount]; |
||||
for (int i = 0; i < returnTypes.Length; ++i) { |
||||
returnTypes[i] = SharpAssemblyReturnType.Create(asm, ref offset); |
||||
} |
||||
|
||||
if (getterMethodIndex != 0) { |
||||
AddParameters(asm, asm.Tables.Method, getterMethodIndex, returnTypes); |
||||
} else { |
||||
AddParameters(asm, returnTypes); |
||||
} |
||||
} |
||||
|
||||
void AddParameters(SA.SharpAssembly asm, Method[] methodTable, uint index, IReturnType[] returnTypes) |
||||
{ |
||||
Param[] paramTable = asm.Tables.Param; |
||||
if (paramTable == null) return; |
||||
|
||||
uint paramIndexStart = methodTable[index].ParamList; |
||||
|
||||
// 0 means no parameters
|
||||
if (paramIndexStart > paramTable.GetUpperBound(0) || paramIndexStart == 0) { |
||||
return; |
||||
} |
||||
|
||||
uint paramIndexEnd = (uint)paramTable.GetUpperBound(0); |
||||
if (index < methodTable.GetUpperBound(0)) { |
||||
paramIndexEnd = methodTable[index + 1].ParamList; |
||||
} |
||||
|
||||
if (paramTable[paramIndexStart].Sequence == 0) paramIndexStart++; |
||||
|
||||
for (uint i = paramIndexStart; i < paramIndexEnd; ++i) { |
||||
uint j = (i - paramIndexStart); |
||||
Parameters.Add(new SharpAssemblyParameter(asm, paramTable, i, j < returnTypes.Length ? returnTypes[j] : null)); |
||||
} |
||||
} |
||||
|
||||
void AddParameters(SA.SharpAssembly asm, IReturnType[] returnTypes) |
||||
{ |
||||
for (uint i = 0; i < returnTypes.GetUpperBound(0); ++i) { |
||||
Parameters.Add(new SharpAssemblyParameter(asm, "param_" + i, returnTypes[i])); |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return FullyQualifiedName; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,225 @@
@@ -0,0 +1,225 @@
|
||||
// <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.Collections; |
||||
using System.Text; |
||||
using System.Reflection; |
||||
using System.Xml; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpAssembly.Metadata.Rows; |
||||
using ICSharpCode.SharpAssembly.Metadata; |
||||
using ICSharpCode.SharpAssembly.PE; |
||||
using ICSharpCode.SharpAssembly.Assembly; |
||||
using SA = ICSharpCode.SharpAssembly.Assembly; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.AddIns.AssemblyScout |
||||
{ |
||||
[Serializable] |
||||
public class SharpAssemblyReturnType : DefaultReturnType |
||||
{ |
||||
object declaredIn; |
||||
|
||||
SharpAssemblyClass underlyingClass; |
||||
|
||||
public SharpAssemblyClass UnderlyingClass { |
||||
get { |
||||
return underlyingClass; |
||||
} |
||||
} |
||||
|
||||
public object DeclaredIn { |
||||
get { |
||||
return declaredIn; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return FullyQualifiedName; |
||||
} |
||||
|
||||
public static SharpAssemblyReturnType Create(string name) |
||||
{ |
||||
return new SharpAssemblyReturnType(name); |
||||
} |
||||
|
||||
public static SharpAssemblyReturnType Create(SA.SharpAssembly assembly, TypeRef[] typeRefTable, uint index) |
||||
{ |
||||
string fullyQualifiedName = String.Empty; |
||||
SharpAssemblyClass underlyingClass = SharpAssemblyClass.FromTypeRef(assembly, index); |
||||
if (underlyingClass != null) { |
||||
fullyQualifiedName = underlyingClass.FullyQualifiedName; |
||||
} else { |
||||
fullyQualifiedName = assembly.Reader.GetStringFromHeap(typeRefTable[index].Nspace) + "." + |
||||
assembly.Reader.GetStringFromHeap(typeRefTable[index].Name); |
||||
LoggingService.Warn("SharpAssemblyReturnType from TypeRef: TypeRef not resolved!"); |
||||
} |
||||
|
||||
return new SharpAssemblyReturnType(fullyQualifiedName, underlyingClass, assembly.GetRefAssemblyFor(index)); |
||||
} |
||||
|
||||
public static SharpAssemblyReturnType Create(SA.SharpAssembly assembly, TypeDef[] typeDefTable, uint index) |
||||
{ |
||||
string fullyQualifiedName = String.Empty; |
||||
SharpAssemblyClass underlyingClass = SharpAssemblyClass.FromTypeDef(assembly, index); |
||||
if (underlyingClass != null) { |
||||
fullyQualifiedName = underlyingClass.FullyQualifiedName; |
||||
} else { |
||||
fullyQualifiedName = assembly.Reader.GetStringFromHeap(typeDefTable[index].NSpace) + "." + |
||||
assembly.Reader.GetStringFromHeap(typeDefTable[index].Name); |
||||
} |
||||
|
||||
return new SharpAssemblyReturnType(fullyQualifiedName, underlyingClass, assembly); |
||||
} |
||||
|
||||
public static SharpAssemblyReturnType Create(SA.SharpAssembly assembly, ref uint blobSignatureIndex) |
||||
{ |
||||
ArrayList arrayRanks = new ArrayList(); |
||||
string fullyQualifiedName = String.Empty; |
||||
SA.SharpAssembly declaredIn = null; |
||||
SharpAssemblyClass underlyingClass = null; |
||||
|
||||
try { |
||||
GetDataType(assembly, ref blobSignatureIndex, ref arrayRanks, ref fullyQualifiedName, ref underlyingClass, ref declaredIn); |
||||
} catch (Exception e) { |
||||
LoggingService.Error("Got exception in ReturnType creation: " + e.ToString()); |
||||
fullyQualifiedName = "GOT_EXCEPTION"; |
||||
} |
||||
|
||||
// if (this.arrayRanks.Count > 0) {
|
||||
// arrayDimensions = new int[arrayRanks.Count];
|
||||
// arrayRanks.CopyTo(arrayDimensions, 0);
|
||||
// } else {
|
||||
// arrayRanks = null;
|
||||
// }
|
||||
|
||||
return new SharpAssemblyReturnType(fullyQualifiedName, underlyingClass, declaredIn); |
||||
} |
||||
|
||||
SharpAssemblyReturnType(string name) : base(new DefaultClass(null, name)) |
||||
{ |
||||
} |
||||
|
||||
SharpAssemblyReturnType(string name, SharpAssemblyClass underlyingClass, SA.SharpAssembly declaredIn) : this(name) |
||||
{ |
||||
this.declaredIn = declaredIn; |
||||
this.underlyingClass = underlyingClass; |
||||
} |
||||
|
||||
static void GetDataType(SA.SharpAssembly asm, ref uint offset, ref ArrayList arrayRanks, ref string fullyQualifiedName, ref SharpAssemblyClass underlyingClass, ref SA.SharpAssembly declaredIn) |
||||
{ |
||||
AssemblyReader assembly = asm.Reader; |
||||
DataType dt = (DataType)assembly.LoadBlob(ref offset); |
||||
switch (dt) { |
||||
case DataType.Void: |
||||
case DataType.Boolean: |
||||
case DataType.Char: |
||||
case DataType.SByte: |
||||
case DataType.Byte: |
||||
case DataType.Int16: |
||||
case DataType.UInt16: |
||||
case DataType.Int32: |
||||
case DataType.UInt32: |
||||
case DataType.Int64: |
||||
case DataType.UInt64: |
||||
case DataType.Single: |
||||
case DataType.Double: |
||||
case DataType.String: |
||||
case DataType.Object: |
||||
case DataType.IntPtr: |
||||
case DataType.UIntPtr: |
||||
fullyQualifiedName = "System." + dt.ToString(); |
||||
|
||||
declaredIn = asm.GetReference("mscorlib"); |
||||
break; |
||||
|
||||
case DataType.SZArray: |
||||
GetDataType(asm, ref offset, ref arrayRanks, ref fullyQualifiedName, ref underlyingClass, ref declaredIn); |
||||
arrayRanks.Add(0); |
||||
break; |
||||
|
||||
case DataType.Array: |
||||
GetDataType(asm, ref offset, ref arrayRanks, ref fullyQualifiedName, ref underlyingClass, ref declaredIn); |
||||
int rank = assembly.LoadBlob(ref offset); |
||||
int num_sizes = assembly.LoadBlob(ref offset); |
||||
int[] sizes = new int[num_sizes]; |
||||
for (int i = 0; i < num_sizes; ++i) { |
||||
sizes[i] = assembly.LoadBlob(ref offset); |
||||
} |
||||
int num_lowerBounds = assembly.LoadBlob(ref offset); |
||||
int[] lowerBounds = new int[num_lowerBounds]; |
||||
for (int i = 0; i < num_lowerBounds; ++i) { |
||||
lowerBounds[i] = assembly.LoadBlob(ref offset); |
||||
} |
||||
arrayRanks.Add(rank - 1); |
||||
break; |
||||
|
||||
case DataType.ValueType: |
||||
case DataType.Class: |
||||
uint idx = (uint)assembly.LoadBlob(ref offset); |
||||
bool isTypeRef = (idx & 1) == 1; |
||||
uint index = (idx >> 2); |
||||
|
||||
TypeDef[] typeDefTable = asm.Tables.TypeDef; |
||||
TypeRef[] typeRefTable = asm.Tables.TypeRef; |
||||
|
||||
if (isTypeRef) { |
||||
underlyingClass = SharpAssemblyClass.FromTypeRef(asm, index); |
||||
if (underlyingClass != null) { |
||||
fullyQualifiedName = underlyingClass.FullyQualifiedName; |
||||
} else { |
||||
fullyQualifiedName = assembly.GetStringFromHeap(typeRefTable[index].Nspace) + "." + |
||||
assembly.GetStringFromHeap(typeRefTable[index].Name); |
||||
LoggingService.Warn("GetDataType: TypeRef not resolved!"); |
||||
} |
||||
declaredIn = asm.GetRefAssemblyFor(index); |
||||
} else { |
||||
underlyingClass = SharpAssemblyClass.FromTypeDef(asm, index); |
||||
if (underlyingClass != null) { |
||||
fullyQualifiedName = underlyingClass.FullyQualifiedName; |
||||
} else { |
||||
fullyQualifiedName = assembly.GetStringFromHeap(typeDefTable[index].NSpace) + "." + |
||||
assembly.GetStringFromHeap(typeDefTable[index].Name); |
||||
} |
||||
declaredIn = asm; |
||||
} |
||||
|
||||
break; |
||||
|
||||
case DataType.Ptr: |
||||
GetDataType(asm, ref offset, ref arrayRanks, ref fullyQualifiedName, ref underlyingClass, ref declaredIn); |
||||
break; |
||||
case DataType.ByRef: |
||||
GetDataType(asm, ref offset, ref arrayRanks, ref fullyQualifiedName, ref underlyingClass, ref declaredIn); |
||||
fullyQualifiedName += "&"; |
||||
break; |
||||
|
||||
case DataType.TypeReference: |
||||
fullyQualifiedName = "typedref"; |
||||
break; |
||||
|
||||
case DataType.Pinned: |
||||
GetDataType(asm, ref offset, ref arrayRanks, ref fullyQualifiedName, ref underlyingClass, ref declaredIn); |
||||
//fullyQualifiedName += " pinned";
|
||||
break; |
||||
|
||||
case DataType.CModOpt: |
||||
case DataType.CModReq: |
||||
GetDataType(asm, ref offset, ref arrayRanks, ref fullyQualifiedName, ref underlyingClass, ref declaredIn); |
||||
break; |
||||
|
||||
default: |
||||
//Console.WriteLine("NOT supported: " + dt.ToString());
|
||||
fullyQualifiedName += " NOT_SUPPORTED [" + dt.ToString() + "]"; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue