Browse Source

Improved type resolution by name

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5117 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
19decb3dc6
  1. 25
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/AppDomain.cs
  2. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs
  3. 22
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionExtensionMethods.cs
  4. 130
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
  5. 15
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs
  6. 30
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/ExpressionEvaluator.cs

25
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/AppDomain.cs

@ -43,17 +43,36 @@ namespace Debugger @@ -43,17 +43,36 @@ namespace Debugger
}
}
DebugType objectType;
public DebugType ObjectType {
get {
if (objectType == null)
objectType = DebugType.CreateFromType(this.Mscorlib, typeof(object));
return objectType;
}
}
DebugType valueType;
internal DebugType ValueType {
public DebugType ValueType {
get {
// TODO: Search only mscorlib module
if (valueType == null)
valueType = DebugType.CreateFromType(this, typeof(ValueType));
valueType = DebugType.CreateFromType(this.Mscorlib, typeof(ValueType));
return valueType;
}
}
DebugType voidType;
public DebugType VoidType {
get {
if (voidType == null)
voidType = DebugType.CreateFromType(this.Mscorlib, typeof(void));
return voidType;
}
}
internal ICorDebugAppDomain CorAppDomain {
get {
return corAppDomain;

4
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs

@ -252,7 +252,7 @@ namespace Debugger @@ -252,7 +252,7 @@ namespace Debugger
public static Value CreateValue(AppDomain appDomain, object value)
{
if (value == null) {
ICorDebugClass corClass = DebugType.CreateFromType(appDomain, typeof(object)).CorType.Class;
ICorDebugClass corClass = appDomain.ObjectType.CorType.Class;
ICorDebugEval corEval = CreateCorEval(appDomain);
ICorDebugValue corValue = corEval.CreateValue((uint)CorElementType.CLASS, corClass);
return new Value(appDomain, corValue);
@ -260,7 +260,7 @@ namespace Debugger @@ -260,7 +260,7 @@ namespace Debugger
return Eval.NewString(appDomain, (string)value);
} else {
// TODO: Check if it is primitive type
Value val = Eval.NewObjectNoConstructor(DebugType.CreateFromType(appDomain, value.GetType()));
Value val = Eval.NewObjectNoConstructor(DebugType.CreateFromType(appDomain.Mscorlib, value.GetType()));
val.PrimitiveValue = value;
return val;
}

22
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionExtensionMethods.cs

@ -103,6 +103,24 @@ namespace Debugger @@ -103,6 +103,24 @@ namespace Debugger
return typedArgs;
}
public static string GetDottedName(this Type type)
{
string fullName = null;
for(Type currentType = type; currentType != null; currentType = currentType.DeclaringType) {
string name = currentType.Name;
if (name.IndexOf('`') != -1)
name = name.Substring(0, name.IndexOf('`'));
if (currentType.Namespace != string.Empty)
name = currentType.Namespace + "." + name;
if (fullName == null) {
fullName = name;
} else {
fullName = name + "." + fullName;
}
}
return fullName;
}
public static TypeReference ToTypeReference(this Type type)
{
List<int> arrayRanks = new List<int>();
@ -120,9 +138,7 @@ namespace Debugger @@ -120,9 +138,7 @@ namespace Debugger
break;
}
}
string name = type.FullName;
if (name.IndexOf('<') != -1)
name = name.Substring(0, name.IndexOf('<'));
string name = type.GetDottedName();
List<TypeReference> genArgs = new List<TypeReference>();
foreach(DebugType genArg in type.GetGenericArguments()) {
genArgs.Add(genArg.ToTypeReference());

130
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs

@ -158,7 +158,7 @@ namespace Debugger.MetaData @@ -158,7 +158,7 @@ namespace Debugger.MetaData
}
// corType.Base does not work for arrays
if (this.IsArray) {
return DebugType.CreateFromType(this.AppDomain, typeof(Array));
return DebugType.CreateFromType(this.AppDomain.Mscorlib, typeof(Array));
}
// corType.Base does not work for primitive types
// if (this.IsPrimitive) {
@ -656,46 +656,102 @@ namespace Debugger.MetaData @@ -656,46 +656,102 @@ namespace Debugger.MetaData
}
}
public static DebugType CreateFromType(AppDomain appDomain, System.Type type, params DebugType[] genericArguments)
public static DebugType CreateFromDottedName(AppDomain appDomain, string dottedName, params DebugType[] genericArguments)
{
return CreateFromName(appDomain, type.FullName, genericArguments);
// The most common case
DebugType result = CreateFromName(appDomain, dottedName, null, genericArguments);
if (result != null)
return result;
string[] names = dottedName.Split('.');
for(int take = names.Length - 1; take > 0; take--) {
string enclosingName = string.Join(".", names, 0, take);
DebugType enclosingType = CreateFromName(appDomain, enclosingName, null, genericArguments);
if (enclosingType != null) {
for(int nested = take; nested < names.Length; nested++) {
string nestedName = names[nested];
enclosingType = CreateFromName(appDomain, nestedName, enclosingType, genericArguments);
if (enclosingType == null)
return null;
}
return enclosingType;
}
}
return null;
}
public static DebugType CreateFromName(AppDomain appDomain, string typeName, params DebugType[] genericArguments)
public static DebugType CreateFromType(Module module, System.Type type)
{
return CreateFromName(appDomain, typeName, null, genericArguments);
if (type is DebugType)
throw new DebuggerException("You already have DebugType, no need to create it.");
if (type.GetGenericArguments().Length > 0)
throw new DebuggerException("Generic arguments not allowed in this overload");
DebugType declaringType = null;
if (type.DeclaringType != null)
declaringType = CreateFromType(module, type.DeclaringType);
DebugType result = CreateFromName(module, type.FullName, declaringType);
if (result == null)
throw new DebuggerException("Type not found: " + type);
return result;
}
public static DebugType CreateFromName(AppDomain appDomain, string typeName, DebugType enclosingType, params DebugType[] genericArguments)
public static DebugType CreateFromType(AppDomain appDomain, System.Type type, params DebugType[] genericArgumentsOverride)
{
if (genericArguments != null) {
if (enclosingType != null)
typeName = GetQualifiedName(typeName, genericArguments.Length - enclosingType.GetGenericArguments().Length);
else
typeName = GetQualifiedName(typeName, genericArguments.Length);
if (type is DebugType)
throw new DebuggerException("You already have DebugType, no need to create it.");
// Get generic arguments for the type if they are not explicitely defined
if (genericArgumentsOverride == null) {
List<DebugType> genArgs = new List<DebugType>();
foreach(System.Type arg in type.GetGenericArguments()) {
genArgs.Add(CreateFromType(appDomain, arg, null /* implicit */));
}
genericArgumentsOverride = genArgs.ToArray();
}
string name;
DebugType declaringType;
if (type.DeclaringType != null) {
name = type.Name;
declaringType = CreateFromType(appDomain, type.DeclaringType, genericArgumentsOverride);
} else {
name = string.IsNullOrEmpty(type.Namespace) ? type.Name : type.Namespace + "." + type.Name;
declaringType = null;
}
DebugType result = CreateFromName(appDomain, name, declaringType, genericArgumentsOverride);
if (result == null)
throw new DebuggerException("Type not found: " + type);
return result;
}
public static DebugType CreateFromName(AppDomain appDomain, string name, DebugType declaringType, params DebugType[] genericArguments)
{
if (declaringType != null)
return CreateFromName(declaringType.DebugModule, name, declaringType, genericArguments);
foreach(Module module in appDomain.Process.Modules) {
if (module.AppDomain == appDomain) {
uint token;
try {
token = module.MetaData.FindTypeDefPropsByName(typeName, enclosingType == null ? 0 : (uint)enclosingType.MetadataToken).Token;
} catch {
continue;
}
return CreateFromTypeDefOrRef(module, null, token, genericArguments);
}
if (module.AppDomain != appDomain) continue;
DebugType result = CreateFromName(module, name, declaringType, genericArguments);
if (result != null)
return result;
}
throw new DebuggerException("Can not find type " + typeName);
return null;
}
/// <summary> Converts type name to the form suitable for COM API. </summary>
static string GetQualifiedName(string typeName, int genericArgumentsCount)
public static DebugType CreateFromName(Module module, string name, DebugType declaringType, params DebugType[] genericArguments)
{
if (genericArgumentsCount > 0 && !typeName.Contains("`")) {
return typeName + "`" + genericArgumentsCount;
} else {
return typeName;
if (declaringType != null && declaringType.DebugModule != module)
throw new DebuggerException("Declaring type must be in the same module");
uint token;
try {
token = module.MetaData.FindTypeDefPropsByName(name, declaringType == null ? 0 : (uint)declaringType.MetadataToken).Token;
} catch {
return null;
}
return CreateFromTypeDefOrRef(module, null, token, genericArguments);
}
public static DebugType CreateFromTypeSpec(Module module, uint token, DebugType declaringType)
@ -715,7 +771,11 @@ namespace Debugger.MetaData @@ -715,7 +771,11 @@ namespace Debugger.MetaData
foreach(TypeReference argRef in typeRef.GenericTypes) {
genArgs.Add(CreateFromTypeReference(appDomain, argRef));
}
DebugType type = CreateFromName(appDomain, typeRef.Type, genArgs.ToArray());
// TODO: A<T>.C<U>
string name = typeRef.Type;
if (genArgs.Count > 0)
name += '`' + genArgs.Count;
DebugType type = CreateFromDottedName(appDomain, name, genArgs.ToArray());
for(int i = 0; i < typeRef.PointerNestingLevel; i++) {
type = (DebugType)type.MakePointerType();
}
@ -737,11 +797,11 @@ namespace Debugger.MetaData @@ -737,11 +797,11 @@ namespace Debugger.MetaData
{
System.Type sysType = CorElementTypeToManagedType((CorElementType)(uint)sigType.ElementType);
if (sysType != null) {
return CreateFromType(module.AppDomain, sysType);
return CreateFromType(module.AppDomain.Mscorlib, sysType);
}
if (sigType.ElementType == Mono.Cecil.Metadata.ElementType.Object) {
return CreateFromType(module.AppDomain, typeof(object));
return module.AppDomain.ObjectType;
}
if (sigType is CLASS) {
@ -760,7 +820,7 @@ namespace Debugger.MetaData @@ -760,7 +820,7 @@ namespace Debugger.MetaData
// Numbered generic reference
if (sigType is MVAR) {
return CreateFromType(module.AppDomain, typeof(object));
return module.AppDomain.ObjectType;
}
if (sigType is GENERICINST) {
@ -790,7 +850,7 @@ namespace Debugger.MetaData @@ -790,7 +850,7 @@ namespace Debugger.MetaData
PTR ptrSig = (PTR)sigType;
DebugType elementType;
if (ptrSig.Void) {
elementType = CreateFromType(module.AppDomain, typeof(void));
elementType = module.AppDomain.VoidType;
} else {
elementType = CreateFromSignature(module, ptrSig.PtrType, declaringType);
}
@ -875,12 +935,10 @@ namespace Debugger.MetaData @@ -875,12 +935,10 @@ namespace Debugger.MetaData
CorElementType corElemType = (CorElementType)(corType.Type);
Type primitiveType = CorElementTypeToManagedType(corElemType);
if (primitiveType != null) {
// TODO: Look only in mscorlib
corType = CreateFromType(appDomain, primitiveType).CorType;
corType = CreateFromType(appDomain.Mscorlib, primitiveType).CorType;
}
if (corElemType == CorElementType.VOID) {
// TODO: Look only in mscorlib
corType = CreateFromType(appDomain, typeof(void)).CorType;
corType = appDomain.VoidType.CorType;
}
if (loadedTypes.ContainsKey(corType)) return loadedTypes[corType];

15
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs

@ -165,24 +165,19 @@ namespace Debugger @@ -165,24 +165,19 @@ namespace Debugger
{
// We were passed null reference and no metadata description
// (happens during CreateThread callback for the thread object)
this.type = DebugType.CreateFromType(appDomain, typeof(object));
this.type = appDomain.ObjectType;
} else {
ICorDebugType exactType = this.CorValue.CastTo<ICorDebugValue2>().ExactType;
this.type = DebugType.CreateFromCorType(appDomain, exactType);
}
}
// Box value type
public Value Box()
{
byte[] rawValue = this.CorGenericValue.RawValue;
// Box the value type
ICorDebugValue corValue;
if (this.Type.IsPrimitive) {
// Get value type for the primive type
corValue = Eval.NewObjectNoConstructor(DebugType.CreateFromName(appDomain, this.Type.FullName)).CorValue;
} else {
corValue = Eval.NewObjectNoConstructor(this.Type).CorValue;
}
// The type must not be a primive type (always true in current design)
ICorDebugValue corValue = Eval.NewObjectNoConstructor(this.Type).CorValue;
// Make the reference to box permanent
corValue = corValue.CastTo<ICorDebugReferenceValue>().Dereference().CastTo<ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_STRONG).CastTo<ICorDebugValue>();
// Create new value
@ -540,7 +535,7 @@ namespace Debugger @@ -540,7 +535,7 @@ namespace Debugger
if (this.Type.IsPrimitive) return AsString;
if (this.Type.IsPointer) return "0x" + this.PointerAddress.ToString("X");
// if (!IsObject) // Can invoke on primitives
DebugMethodInfo methodInfo = (DebugMethodInfo)DebugType.CreateFromType(this.AppDomain, typeof(object)).GetMethod("ToString", new DebugType[] {});
DebugMethodInfo methodInfo = (DebugMethodInfo)this.AppDomain.ObjectType.GetMethod("ToString", new DebugType[] {});
return Eval.InvokeMethod(methodInfo, this, new Value[] {}).AsString;
}

30
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/ExpressionEvaluator.cs

@ -10,8 +10,8 @@ using System.Collections.Generic; @@ -10,8 +10,8 @@ using System.Collections.Generic;
namespace Debugger.Tests.TestPrograms
{
// TODO: Make nested
public class ExpressionEvaluator
{
public class BaseClass
{
string name = "base name";
@ -57,8 +57,6 @@ namespace Debugger.Tests.TestPrograms @@ -57,8 +57,6 @@ namespace Debugger.Tests.TestPrograms
}
}
public class ExpressionEvaluator
{
public static void Main()
{
bool flag = true;
@ -199,7 +197,7 @@ namespace Debugger.Tests { @@ -199,7 +197,7 @@ namespace Debugger.Tests {
<ProcessStarted />
<ModuleLoaded>mscorlib.dll (No symbols)</ModuleLoaded>
<ModuleLoaded>ExpressionEvaluator.exe (Has symbols)</ModuleLoaded>
<DebuggingPaused>Break ExpressionEvaluator.cs:77,4-77,40</DebuggingPaused>
<DebuggingPaused>Break ExpressionEvaluator.cs:75,4-75,40</DebuggingPaused>
<Eval> </Eval>
<Eval> b = 1 </Eval>
<Eval> i = 4 </Eval>
@ -247,17 +245,17 @@ namespace Debugger.Tests { @@ -247,17 +245,17 @@ namespace Debugger.Tests {
<Eval> flag = True </Eval>
<Eval> !flag = False </Eval>
<Eval> </Eval>
<Eval> ((Debugger.Tests.TestPrograms.DerivedClass)(myClass)).name = "derived name" </Eval>
<Eval> Debugger.Tests.TestPrograms.DerivedClass.StaticField = Error evaluating "Debugger.Tests.TestPrograms.DerivedClass.StaticField": Identifier "Debugger" not found in this context </Eval>
<Eval> ((Debugger.Tests.TestPrograms.DerivedClass)(myClass)).Name = "derived name" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.DerivedClass)(myClass)).SetterOnlyProperty = Error evaluating "((Debugger.Tests.TestPrograms.DerivedClass)(myClass)).SetterOnlyProperty": Property does not have a get method </Eval>
<Eval> Debugger.Tests.TestPrograms.DerivedClass.StaticProperty = Error evaluating "Debugger.Tests.TestPrograms.DerivedClass.StaticProperty": Identifier "Debugger" not found in this context </Eval>
<Eval> ((Debugger.Tests.TestPrograms.BaseClass)(myClass)).name = "base name" </Eval>
<Eval> Debugger.Tests.TestPrograms.BaseClass.StaticField = Error evaluating "Debugger.Tests.TestPrograms.BaseClass.StaticField": Identifier "Debugger" not found in this context </Eval>
<Eval> ((Debugger.Tests.TestPrograms.BaseClass)(myClass)).Name = "base name" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.BaseClass)(myClass)).Foo((System.Int32)(1)) = "base Foo - int" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.DerivedClass)(myClass)).Foo((System.Int32)(1)) = "derived Foo - int" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.DerivedClass)(myClass)).Foo((System.String)("a")) = "derived Foo - string" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass)(myClass)).name = "derived name" </Eval>
<Eval> Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass.StaticField = Error evaluating "Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass.StaticField": Identifier "Debugger" not found in this context </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass)(myClass)).Name = "derived name" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass)(myClass)).SetterOnlyProperty = Error evaluating "((Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass)(myClass)).SetterOnlyProperty": Property does not have a get method </Eval>
<Eval> Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass.StaticProperty = Error evaluating "Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass.StaticProperty": Identifier "Debugger" not found in this context </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.BaseClass)(myClass)).name = "base name" </Eval>
<Eval> Debugger.Tests.TestPrograms.ExpressionEvaluator.BaseClass.StaticField = Error evaluating "Debugger.Tests.TestPrograms.ExpressionEvaluator.BaseClass.StaticField": Identifier "Debugger" not found in this context </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.BaseClass)(myClass)).Name = "base name" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.BaseClass)(myClass)).Foo((System.Int32)(1)) = "base Foo - int" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass)(myClass)).Foo((System.Int32)(1)) = "derived Foo - int" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass)(myClass)).Foo((System.String)("a")) = "derived Foo - string" </Eval>
<ProcessExited />
</Test>
</DebuggerTests>

Loading…
Cancel
Save