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 @@ |
|||||||
|
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 @@ |
|||||||
|
// <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 @@ |
|||||||
|
// <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 @@ |
|||||||
|
// <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 @@ |
|||||||
|
// <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 @@ |
|||||||
|
// <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 @@ |
|||||||
|
// <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 @@ |
|||||||
|
// <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 @@ |
|||||||
|
// <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