Browse Source

Use static typing of expression to get rid of some casts

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5178 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
4225594582
  1. 4
      src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/StackFrameNode.cs
  2. 103
      src/AddIns/Misc/Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs
  3. 21
      src/AddIns/Misc/Debugger/Debugger.Tests/Tests/ExpressionEvaluator_Tests.cs

4
src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/StackFrameNode.cs

@ -29,10 +29,10 @@ namespace Debugger.AddIn.TreeModel
IEnumerable<TreeNode> LazyGetChildNodes() IEnumerable<TreeNode> LazyGetChildNodes()
{ {
foreach(DebugParameterInfo par in stackFrame.MethodInfo.GetParameters()) { foreach(DebugParameterInfo par in stackFrame.MethodInfo.GetParameters()) {
yield return new ExpressionNode(ExpressionNode.GetImageForParameter(), par.Name, new IdentifierExpression(par.Name)); yield return new ExpressionNode(ExpressionNode.GetImageForParameter(), par.Name, par.GetExpression());
} }
foreach(DebugLocalVariableInfo locVar in stackFrame.MethodInfo.GetLocalVariables()) { foreach(DebugLocalVariableInfo locVar in stackFrame.MethodInfo.GetLocalVariables()) {
yield return new ExpressionNode(ExpressionNode.GetImageForLocalVariable(), locVar.Name, new IdentifierExpression(locVar.Name)); yield return new ExpressionNode(ExpressionNode.GetImageForLocalVariable(), locVar.Name, locVar.GetExpression());
} }
if (stackFrame.Thread.CurrentException != null) { if (stackFrame.Thread.CurrentException != null) {
yield return new ExpressionNode(null, "__exception", new IdentifierExpression("__exception")); yield return new ExpressionNode(null, "__exception", new IdentifierExpression("__exception"));

103
src/AddIns/Misc/Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs

@ -23,6 +23,51 @@ namespace ICSharpCode.NRefactory.Ast
return ExpressionEvaluator.Evaluate(expression, process); return ExpressionEvaluator.Evaluate(expression, process);
} }
static M SetStaticType<M>(this M expr, DebugType type) where M: INode
{
expr.UserData = type;
return expr;
}
public static DebugType GetStaticType(this INode expr)
{
return expr.UserData as DebugType;
}
public static Expression Parenthesize(this Expression expr)
{
if (expr is IdentifierExpression ||
expr is MemberReferenceExpression ||
expr is IndexerExpression ||
expr is ParenthesizedExpression ||
expr is PrimitiveExpression)
return expr;
return new ParenthesizedExpression(expr);
}
public static Expression CastTo(this Expression expresion, DebugType castTo)
{
// No need to cast
if (expresion.GetStaticType() == castTo)
return expresion;
if (expresion is PrimitiveExpression) {
object val = ((PrimitiveExpression)expresion).Value;
if (val != null && val.GetType().FullName == castTo.FullName)
return expresion;
}
return new CastExpression(castTo.GetTypeReference(), expresion.Parenthesize(), CastType.Cast);
}
public static Expression GetExpression(this DebugLocalVariableInfo locVar)
{
return new IdentifierExpression(locVar.Name).SetStaticType((DebugType)locVar.LocalType);
}
public static Expression GetExpression(this DebugParameterInfo par)
{
return new IdentifierExpression(par.Name).SetStaticType((DebugType)par.ParameterType);
}
public static UnaryOperatorExpression AppendDereference(this Expression expression) public static UnaryOperatorExpression AppendDereference(this Expression expression)
{ {
return new UnaryOperatorExpression(new ParenthesizedExpression(expression), UnaryOperatorType.Dereference); return new UnaryOperatorExpression(new ParenthesizedExpression(expression), UnaryOperatorType.Dereference);
@ -32,14 +77,13 @@ namespace ICSharpCode.NRefactory.Ast
{ {
IndexerExpression indexerExpr = new IndexerExpression(Parenthesize(expression), new List<Expression>()); IndexerExpression indexerExpr = new IndexerExpression(Parenthesize(expression), new List<Expression>());
foreach(int index in indices) { foreach(int index in indices) {
indexerExpr.Indexes.Add( indexerExpr.Indexes.Add(new PrimitiveExpression(index));
new CastExpression(
new TypeReference(typeof(int).FullName),
new PrimitiveExpression(index),
CastType.Cast
)
);
} }
DebugType staticType = expression.GetStaticType();
if (staticType != null && staticType.IsArray)
indexerExpr.SetStaticType((DebugType)staticType.GetElementType());
if (staticType != null && staticType.FullNameWithoutGenericArguments == typeof(List<>).FullName)
indexerExpr.SetStaticType((DebugType)staticType.GetGenericArguments()[0]);
return indexerExpr; return indexerExpr;
} }
@ -51,26 +95,20 @@ namespace ICSharpCode.NRefactory.Ast
memberInfo.DeclaringType.GetTypeReference() memberInfo.DeclaringType.GetTypeReference()
); );
} else { } else {
target = new ParenthesizedExpression( target = expresion.CastTo((DebugType)memberInfo.DeclaringType);
new CastExpression(
memberInfo.DeclaringType.GetTypeReference(),
Parenthesize(expresion),
CastType.Cast
)
);
} }
if (memberInfo is DebugFieldInfo) { if (memberInfo is DebugFieldInfo) {
if (args.Length > 0) if (args.Length > 0)
throw new DebuggerException("No arguments expected for a field"); throw new DebuggerException("No arguments expected for a field");
return new MemberReferenceExpression(target, memberInfo.Name); return new MemberReferenceExpression(target, memberInfo.Name).SetStaticType(memberInfo.MemberType);
} }
if (memberInfo is MethodInfo) { if (memberInfo is MethodInfo) {
return new InvocationExpression( return new InvocationExpression(
new MemberReferenceExpression(target, memberInfo.Name), new MemberReferenceExpression(target, memberInfo.Name),
AddExplicitTypes((MethodInfo)memberInfo, args) AddExplicitTypes((MethodInfo)memberInfo, args)
); ).SetStaticType(memberInfo.MemberType);
} }
if (memberInfo is PropertyInfo) { if (memberInfo is PropertyInfo) {
@ -81,38 +119,22 @@ namespace ICSharpCode.NRefactory.Ast
return new IndexerExpression( return new IndexerExpression(
target, target,
AddExplicitTypes(propInfo.GetGetMethod() ?? propInfo.GetSetMethod(), args) AddExplicitTypes(propInfo.GetGetMethod() ?? propInfo.GetSetMethod(), args)
); ).SetStaticType(memberInfo.MemberType);
} else { } else {
return new MemberReferenceExpression(target, memberInfo.Name); return new MemberReferenceExpression(target, memberInfo.Name).SetStaticType(memberInfo.MemberType);
} }
} }
throw new DebuggerException("Unknown member type " + memberInfo.GetType().FullName); 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) static List<Expression> AddExplicitTypes(MethodInfo method, Expression[] args)
{ {
if (args.Length != method.GetParameters().Length) if (args.Length != method.GetParameters().Length)
throw new DebuggerException("Incorrect number of arguments"); throw new DebuggerException("Incorrect number of arguments");
List<Expression> typedArgs = new List<Expression>(args.Length); List<Expression> typedArgs = new List<Expression>(args.Length);
for(int i = 0; i < args.Length; i++) { for(int i = 0; i < args.Length; i++) {
typedArgs.Add( typedArgs.Add(args[i].CastTo((DebugType)method.GetParameters()[i].ParameterType));
new CastExpression(
method.GetParameters()[i].ParameterType.GetTypeReference(),
Parenthesize(args[i]),
CastType.Cast
)
);
} }
return typedArgs; return typedArgs;
} }
@ -174,9 +196,9 @@ namespace ICSharpCode.NRefactory.Ast
InnerClassTypeReference innerRef = new InnerClassTypeReference(outterRef, name, genTypeRefs); InnerClassTypeReference innerRef = new InnerClassTypeReference(outterRef, name, genTypeRefs);
innerRef.PointerNestingLevel = pointerNest; innerRef.PointerNestingLevel = pointerNest;
innerRef.RankSpecifier = arrayRanks.ToArray(); innerRef.RankSpecifier = arrayRanks.ToArray();
return innerRef; return innerRef.SetStaticType((DebugType)type);
} else { } else {
return new TypeReference(name, pointerNest, arrayRanks.ToArray(), genTypeRefs); return new TypeReference(name, pointerNest, arrayRanks.ToArray(), genTypeRefs).SetStaticType((DebugType)type);
} }
} }
@ -248,6 +270,11 @@ namespace ICSharpCode.NRefactory.Ast
public static DebugType ResolveType(this INode expr, Debugger.AppDomain appDomain) public static DebugType ResolveType(this INode expr, Debugger.AppDomain appDomain)
{ {
if (expr is TypeReference && expr.GetStaticType() != null)
return expr.GetStaticType();
if (expr is TypeReferenceExpression && ((TypeReferenceExpression)expr).TypeReference.GetStaticType() != null)
return ((TypeReferenceExpression)expr).TypeReference.GetStaticType();
TypeReference typeRef = NormalizeTypeReference(expr); TypeReference typeRef = NormalizeTypeReference(expr);
List<TypeReference> genTypeRefs; List<TypeReference> genTypeRefs;

21
src/AddIns/Misc/Debugger/Debugger.Tests/Tests/ExpressionEvaluator_Tests.cs

@ -209,15 +209,16 @@ namespace Debugger.Tests {
// Test member hiding / overloading // Test member hiding / overloading
Value myClass = process.SelectedStackFrame.GetLocalVariableValue("myClass").GetPermanentReference(); Value myClass = process.SelectedStackFrame.GetLocalVariableValue("myClass").GetPermanentReference();
Expression myClassExpr = process.SelectedStackFrame.MethodInfo.GetLocalVariable("myClass").GetExpression();
List<Expression> expressions = new List<Expression>(); List<Expression> expressions = new List<Expression>();
foreach(MemberInfo memberInfo in myClass.Type.GetFieldsAndNonIndexedProperties(DebugType.BindingFlagsAll)) { foreach(MemberInfo memberInfo in myClass.Type.GetFieldsAndNonIndexedProperties(DebugType.BindingFlagsAll)) {
expressions.Add(new IdentifierExpression("myClass").AppendMemberReference((IDebugMemberInfo)memberInfo)); expressions.Add(myClassExpr.AppendMemberReference((IDebugMemberInfo)memberInfo));
} }
expressions.Add(new IdentifierExpression("myClass").AppendMemberReference((DebugMethodInfo)myClass.Type.GetMethod("StaticMethod"))); expressions.Add(myClassExpr.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(myClassExpr.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(myClassExpr.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"))); expressions.Add(myClassExpr.AppendMemberReference((DebugMethodInfo)myClass.Type.GetMethod("Foo", new string[] { "s" }), new PrimitiveExpression("a")));
foreach(Expression expr in expressions) { foreach(Expression expr in expressions) {
Eval(expr.PrettyPrint()); Eval(expr.PrettyPrint());
@ -409,17 +410,17 @@ namespace Debugger.Tests {
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstString = "const string" </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstString = "const string" </Eval>
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstNull = null </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstNull = null </Eval>
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstEnum = B </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstEnum = B </Eval>
<Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass)myClass).name = "derived name" </Eval> <Eval> myClass.name = "derived name" </Eval>
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.StaticField = "derived static field" </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.StaticField = "derived static field" </Eval>
<Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass)myClass).Name = "derived name" </Eval> <Eval> myClass.Name = "derived name" </Eval>
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.StaticProperty = "static property" </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.StaticProperty = "static property" </Eval>
<Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.BaseClass)myClass).name = "base name" </Eval> <Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.BaseClass)myClass).name = "base name" </Eval>
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.BaseClass.StaticField = "base static field" </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.BaseClass.StaticField = "base static field" </Eval>
<Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.BaseClass)myClass).Name = "base name" </Eval> <Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.BaseClass)myClass).Name = "base name" </Eval>
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.StaticMethod() = "static method" </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.StaticMethod() = "static method" </Eval>
<Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.BaseClass)myClass).Foo((System.Int32)1) = "base Foo - int" </Eval> <Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.BaseClass)myClass).Foo(1) = "base Foo - int" </Eval>
<Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass)myClass).Foo((System.Int32)1) = "derived Foo - int" </Eval> <Eval> myClass.Foo(1) = "derived Foo - int" </Eval>
<Eval> ((Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass)myClass).Foo((System.String)"a") = "derived Foo - string" </Eval> <Eval> myClass.Foo("a") = "derived Foo - string" </Eval>
<Eval> </Eval> <Eval> </Eval>
<Eval> myClass.Foo(1.0) = "base Foo - double" </Eval> <Eval> myClass.Foo(1.0) = "base Foo - double" </Eval>
<Eval> myClass.Foo(myClass) = "derived Foo - object" </Eval> <Eval> myClass.Foo(myClass) = "derived Foo - object" </Eval>

Loading…
Cancel
Save