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 @@ -29,10 +29,10 @@ namespace Debugger.AddIn.TreeModel
IEnumerable<TreeNode> LazyGetChildNodes()
{
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()) {
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) {
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 @@ -23,6 +23,51 @@ namespace ICSharpCode.NRefactory.Ast
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)
{
return new UnaryOperatorExpression(new ParenthesizedExpression(expression), UnaryOperatorType.Dereference);
@ -32,14 +77,13 @@ namespace ICSharpCode.NRefactory.Ast @@ -32,14 +77,13 @@ namespace ICSharpCode.NRefactory.Ast
{
IndexerExpression indexerExpr = new IndexerExpression(Parenthesize(expression), new List<Expression>());
foreach(int index in indices) {
indexerExpr.Indexes.Add(
new CastExpression(
new TypeReference(typeof(int).FullName),
new PrimitiveExpression(index),
CastType.Cast
)
);
indexerExpr.Indexes.Add(new PrimitiveExpression(index));
}
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;
}
@ -51,26 +95,20 @@ namespace ICSharpCode.NRefactory.Ast @@ -51,26 +95,20 @@ namespace ICSharpCode.NRefactory.Ast
memberInfo.DeclaringType.GetTypeReference()
);
} else {
target = new ParenthesizedExpression(
new CastExpression(
memberInfo.DeclaringType.GetTypeReference(),
Parenthesize(expresion),
CastType.Cast
)
);
target = expresion.CastTo((DebugType)memberInfo.DeclaringType);
}
if (memberInfo is DebugFieldInfo) {
if (args.Length > 0)
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) {
return new InvocationExpression(
new MemberReferenceExpression(target, memberInfo.Name),
AddExplicitTypes((MethodInfo)memberInfo, args)
);
).SetStaticType(memberInfo.MemberType);
}
if (memberInfo is PropertyInfo) {
@ -81,38 +119,22 @@ namespace ICSharpCode.NRefactory.Ast @@ -81,38 +119,22 @@ namespace ICSharpCode.NRefactory.Ast
return new IndexerExpression(
target,
AddExplicitTypes(propInfo.GetGetMethod() ?? propInfo.GetSetMethod(), args)
);
).SetStaticType(memberInfo.MemberType);
} 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);
}
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)
throw new DebuggerException("Incorrect number of arguments");
List<Expression> typedArgs = new List<Expression>(args.Length);
for(int i = 0; i < args.Length; i++) {
typedArgs.Add(
new CastExpression(
method.GetParameters()[i].ParameterType.GetTypeReference(),
Parenthesize(args[i]),
CastType.Cast
)
);
typedArgs.Add(args[i].CastTo((DebugType)method.GetParameters()[i].ParameterType));
}
return typedArgs;
}
@ -174,9 +196,9 @@ namespace ICSharpCode.NRefactory.Ast @@ -174,9 +196,9 @@ namespace ICSharpCode.NRefactory.Ast
InnerClassTypeReference innerRef = new InnerClassTypeReference(outterRef, name, genTypeRefs);
innerRef.PointerNestingLevel = pointerNest;
innerRef.RankSpecifier = arrayRanks.ToArray();
return innerRef;
return innerRef.SetStaticType((DebugType)type);
} 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 @@ -248,6 +270,11 @@ namespace ICSharpCode.NRefactory.Ast
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);
List<TypeReference> genTypeRefs;

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

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

Loading…
Cancel
Save