Browse Source

Basic support for static expressions.

Removed some extra parenthesis.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5121 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 17 years ago
parent
commit
dd73b1fb64
  1. 56
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs
  2. 17
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionExtensionMethods.cs
  3. 33
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/ExpressionEvaluator.cs

56
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs

@ -323,6 +323,30 @@ namespace Debugger @@ -323,6 +323,30 @@ namespace Debugger
return target.GetPropertyValue(pi, indexes.ToArray());
}
DebugType ResoleType(Expression expr)
{
string name = GetTypeName(expr);
if (name == null)
return null;
// TODO: Generic arguments
return DebugType.CreateFromDottedName(context.AppDomain, name);
}
string GetTypeName(Expression expr)
{
if (expr is IdentifierExpression) {
return ((IdentifierExpression)expr).Identifier;
} else if (expr is MemberReferenceExpression) {
return GetTypeName(((MemberReferenceExpression)expr).TargetObject) + "." + ((MemberReferenceExpression)expr).MemberName;
} else if (expr is TypeReferenceExpression) {
TypeReference typeRef = ((TypeReferenceExpression)expr).TypeReference;
string genArity = typeRef.GenericTypes.Count > 0 ? "`" + typeRef.GenericTypes.Count : string.Empty;
return typeRef.Type + genArity;
} else {
return null;
}
}
public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
{
Value target;
@ -330,8 +354,17 @@ namespace Debugger @@ -330,8 +354,17 @@ namespace Debugger
string methodName;
MemberReferenceExpression memberRef = invocationExpression.TargetObject as MemberReferenceExpression;
if (memberRef != null) {
try {
// Instance
target = Evaluate(memberRef.TargetObject);
targetType = GetDebugType(memberRef.TargetObject) ?? target.Type;
} catch (GetValueException) {
// Static
target = null;
targetType = ResoleType(memberRef.TargetObject);
if (targetType == null)
throw;
}
methodName = memberRef.MemberName;
} else {
IdentifierExpression ident = invocationExpression.TargetObject as IdentifierExpression;
@ -356,10 +389,10 @@ namespace Debugger @@ -356,10 +389,10 @@ namespace Debugger
foreach(Expression expr in invocationExpression.Arguments) {
DebugType argType = GetDebugType(expr);
if (argType == null)
throw new GetValueException("Multiple methods with name " + methodName + " found. Use explicit casts for arguments to select method overload.");
argType = Evaluate(expr).Type;
argTypes.Add(argType);
}
method = target.Type.GetMethod(methodName, argTypes.ToArray());
method = targetType.GetMethod(methodName, argTypes.ToArray());
if (method == null)
throw new GetValueException("Can not find overload with given types");
}
@ -367,7 +400,7 @@ namespace Debugger @@ -367,7 +400,7 @@ namespace Debugger
foreach(Expression expr in invocationExpression.Arguments) {
args.Add(Evaluate(expr));
}
return target.InvokeMethod((DebugMethodInfo)method, args.ToArray());
return Value.InvokeMethod(target, method, args.ToArray());
}
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
@ -387,14 +420,25 @@ namespace Debugger @@ -387,14 +420,25 @@ namespace Debugger
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{
Value target = Evaluate(memberReferenceExpression.TargetObject);
DebugType targetType = GetDebugType(memberReferenceExpression.TargetObject) ?? target.Type;
Value target;
DebugType targetType;
try {
// Instance
target = Evaluate(memberReferenceExpression.TargetObject);
targetType = GetDebugType(memberReferenceExpression.TargetObject) ?? target.Type;
} catch (GetValueException) {
// Static
target = null;
targetType = ResoleType(memberReferenceExpression.TargetObject);
if (targetType == null)
throw;
}
MemberInfo[] memberInfos = targetType.GetMember(memberReferenceExpression.MemberName, BindingFlagsAllDeclared);
if (memberInfos.Length == 0)
memberInfos = targetType.GetMember(memberReferenceExpression.MemberName, BindingFlagsAll);
if (memberInfos.Length == 0)
throw new GetValueException("Member \"" + memberReferenceExpression.MemberName + "\" not found");
Value member = target.GetMemberValue(memberInfos[0]);
Value member = Value.GetMemberValue(target, memberInfos[0]);
return member;
}

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

@ -27,7 +27,7 @@ namespace Debugger @@ -27,7 +27,7 @@ namespace Debugger
public static IndexerExpression AppendIndexer(this Expression expression, params int[] indices)
{
IndexerExpression indexerExpr = new IndexerExpression(new ParenthesizedExpression(expression), new List<Expression>());
IndexerExpression indexerExpr = new IndexerExpression(Parenthesize(expression), new List<Expression>());
foreach(int index in indices) {
indexerExpr.Indexes.Add(
new CastExpression(
@ -51,7 +51,7 @@ namespace Debugger @@ -51,7 +51,7 @@ namespace Debugger
target = new ParenthesizedExpression(
new CastExpression(
memberInfo.DeclaringType.ToTypeReference(),
new ParenthesizedExpression(expresion),
Parenthesize(expresion),
CastType.Cast
)
);
@ -86,6 +86,17 @@ namespace Debugger @@ -86,6 +86,17 @@ namespace Debugger
throw new DebuggerException("Unknown member type " + memberInfo.GetType().FullName);
}
static Expression Parenthesize(Expression expr)
{
if (expr is IdentifierExpression ||
expr is MemberReferenceExpression ||
expr is IndexerExpression ||
expr is ParenthesizedExpression ||
expr is PrimitiveExpression)
return expr;
return new ParenthesizedExpression(expr);
}
static List<Expression> AddExplicitTypes(MethodInfo method, Expression[] args)
{
if (args.Length != method.GetParameters().Length)
@ -95,7 +106,7 @@ namespace Debugger @@ -95,7 +106,7 @@ namespace Debugger
typedArgs.Add(
new CastExpression(
method.GetParameters()[i].ParameterType.ToTypeReference(),
new ParenthesizedExpression(args[i]),
Parenthesize(args[i]),
CastType.Cast
)
);

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

@ -42,10 +42,15 @@ namespace Debugger.Tests.TestPrograms @@ -42,10 +42,15 @@ namespace Debugger.Tests.TestPrograms
public static string StaticProperty {
get {
return "static";
return "static property";
}
}
public static string StaticMethod()
{
return "static method";
}
new public string Foo(int i)
{
return "derived Foo - int";
@ -155,6 +160,7 @@ namespace Debugger.Tests { @@ -155,6 +160,7 @@ namespace Debugger.Tests {
if (memberInfo.MemberType == MemberTypes.Field || memberInfo.MemberType == MemberTypes.Property)
expressions.Add(new IdentifierExpression("myClass").AppendMemberReference((IDebugMemberInfo)memberInfo));
}
expressions.Add(new IdentifierExpression("myClass").AppendMemberReference((DebugMethodInfo)myClass.Type.GetMethod("StaticMethod")));
expressions.Add(new IdentifierExpression("myClass").AppendMemberReference((DebugMethodInfo)((DebugType)myClass.Type.BaseType).GetMethod("Foo", new string[] { "i" }), new PrimitiveExpression(1)));
expressions.Add(new IdentifierExpression("myClass").AppendMemberReference((DebugMethodInfo)myClass.Type.GetMethod("Foo", new string[] { "i" }), new PrimitiveExpression(1)));
expressions.Add(new IdentifierExpression("myClass").AppendMemberReference((DebugMethodInfo)myClass.Type.GetMethod("Foo", new string[] { "s" }), new PrimitiveExpression("a")));
@ -197,7 +203,7 @@ namespace Debugger.Tests { @@ -197,7 +203,7 @@ namespace Debugger.Tests {
<ProcessStarted />
<ModuleLoaded>mscorlib.dll (No symbols)</ModuleLoaded>
<ModuleLoaded>ExpressionEvaluator.exe (Has symbols)</ModuleLoaded>
<DebuggingPaused>Break ExpressionEvaluator.cs:75,4-75,40</DebuggingPaused>
<DebuggingPaused>Break ExpressionEvaluator.cs:80,4-80,40</DebuggingPaused>
<Eval> </Eval>
<Eval> b = 1 </Eval>
<Eval> i = 4 </Eval>
@ -245,17 +251,18 @@ namespace Debugger.Tests { @@ -245,17 +251,18 @@ namespace Debugger.Tests {
<Eval> flag = True </Eval>
<Eval> !flag = False </Eval>
<Eval> </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>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass)myClass).name = "derived name" </Eval>
<Eval> Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass.StaticField = "derived static field" </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 = "static property" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.BaseClass)myClass).name = "base name" </Eval>
<Eval> Debugger.Tests.TestPrograms.ExpressionEvaluator.BaseClass.StaticField = "base static field" </Eval>
<Eval> ((Debugger.Tests.TestPrograms.ExpressionEvaluator.BaseClass)myClass).Name = "base name" </Eval>
<Eval> Debugger.Tests.TestPrograms.ExpressionEvaluator.DerivedClass.StaticMethod() = "static method" </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