Browse Source

add missing casts to property- and event-uses

pull/728/head
Siegfried Pammer 9 years ago
parent
commit
c940b7b767
  1. 30
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 25
      ICSharpCode.Decompiler/Tests/TestCases/MemberLookup.cs

30
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -719,14 +719,15 @@ namespace ICSharpCode.Decompiler.CSharp
else else
rr = new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults); rr = new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults);
var argumentExpressions = arguments.Skip(firstParamIndex).Select(arg => arg.Expression).ToList();
if (inst.OpCode == OpCode.NewObj) { if (inst.OpCode == OpCode.NewObj) {
var argumentExpressions = arguments.Skip(firstParamIndex).Select(arg => arg.Expression).ToList();
return new ObjectCreateExpression(ConvertType(inst.Method.DeclaringType), argumentExpressions) return new ObjectCreateExpression(ConvertType(inst.Method.DeclaringType), argumentExpressions)
.WithILInstruction(inst).WithRR(rr); .WithILInstruction(inst).WithRR(rr);
} else { } else {
Expression expr; Expression expr;
if (method.IsAccessor) { int allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0);
expr = HandleAccessorCall(target, method, argumentExpressions); if (method.IsAccessor && (method.AccessorOwner.SymbolKind == SymbolKind.Indexer || method.Parameters.Count == allowedParamCount)) {
expr = HandleAccessorCall(inst, target, method, arguments.Skip(firstParamIndex).ToList());
} else { } else {
var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly); var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
var or = new OverloadResolution(resolver.Compilation, arguments.Skip(firstParamIndex).Select(a => a.ResolveResult).ToArray()); var or = new OverloadResolution(resolver.Compilation, arguments.Skip(firstParamIndex).Select(a => a.ResolveResult).ToArray());
@ -749,22 +750,29 @@ namespace ICSharpCode.Decompiler.CSharp
} }
var mre = new MemberReferenceExpression(targetExpr, methodName); var mre = new MemberReferenceExpression(targetExpr, methodName);
mre.TypeArguments.AddRange(method.TypeArguments.Select(a => ConvertType(a))); mre.TypeArguments.AddRange(method.TypeArguments.Select(a => ConvertType(a)));
var argumentExpressions = arguments.Skip(firstParamIndex).Select(arg => arg.Expression).ToList();
expr = new InvocationExpression(mre, argumentExpressions); expr = new InvocationExpression(mre, argumentExpressions);
} }
return expr.WithILInstruction(inst).WithRR(rr); return expr.WithILInstruction(inst).WithRR(rr);
} }
} }
Expression HandleAccessorCall(TranslatedExpression target, IMethod method, IList<Expression> argumentExpressions) Expression HandleAccessorCall(ILInstruction inst, TranslatedExpression target, IMethod method, IList<TranslatedExpression> arguments)
{ {
var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);
var result = lookup.Lookup(target.ResolveResult, method.AccessorOwner.Name, EmptyList<IType>.Instance, isInvocation:false);
if (result.IsError || (result is MemberResolveResult && !IsAppropriateCallTarget(method.AccessorOwner, ((MemberResolveResult)result).Member, inst.OpCode == OpCode.CallVirt)))
target = target.ConvertTo(method.AccessorOwner.DeclaringType, this);
if (method.ReturnType.IsKnownType(KnownTypeCode.Void)) { if (method.ReturnType.IsKnownType(KnownTypeCode.Void)) {
var value = argumentExpressions.Last(); var value = arguments.Last();
argumentExpressions.Remove(value); arguments.Remove(value);
Expression expr; Expression expr;
if (argumentExpressions.Count == 0) if (arguments.Count == 0)
expr = new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name); expr = new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name);
else else
expr = new IndexerExpression(target.Expression, argumentExpressions); expr = new IndexerExpression(target.Expression, arguments.Select(a => a.Expression));
var op = AssignmentOperatorType.Assign; var op = AssignmentOperatorType.Assign;
var parentEvent = method.AccessorOwner as IEvent; var parentEvent = method.AccessorOwner as IEvent;
if (parentEvent != null) { if (parentEvent != null) {
@ -775,12 +783,12 @@ namespace ICSharpCode.Decompiler.CSharp
op = AssignmentOperatorType.Subtract; op = AssignmentOperatorType.Subtract;
} }
} }
return new AssignmentExpression(expr, op, value); return new AssignmentExpression(expr, op, value.Expression);
} else { } else {
if (argumentExpressions.Count == 0) if (arguments.Count == 0)
return new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name); return new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name);
else else
return new IndexerExpression(target.Expression, argumentExpressions); return new IndexerExpression(target.Expression, arguments.Select(a => a.Expression));
} }
} }

25
ICSharpCode.Decompiler/Tests/TestCases/MemberLookup.cs

@ -38,13 +38,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases
protected virtual void TestMethod() protected virtual void TestMethod()
{ {
Property = 5;
Console.WriteLine("Base1.TestMethod()"); Console.WriteLine("Base1.TestMethod()");
Console.WriteLine(Property);
} }
public void TestAction() public void TestAction()
{ {
Console.WriteLine("Base1.TestAction()"); Console.WriteLine("Base1.TestAction()");
} }
public int Property { get; set; }
public virtual int VirtProp {
get {
return 3;
}
}
} }
class Child1 : Base1 class Child1 : Base1
@ -57,20 +67,35 @@ namespace ICSharpCode.Decompiler.Tests.TestCases
var o = new Child1(); var o = new Child1();
o.child = new Child1(); o.child = new Child1();
o.TestMethod(); o.TestMethod();
Console.WriteLine(((Base1)o).Property);
Console.WriteLine(o.Property);
Console.WriteLine(((Base1)o).VirtProp);
Console.WriteLine(o.VirtProp);
} }
protected override void TestMethod() protected override void TestMethod()
{ {
Property = 10;
base.TestMethod(); base.TestMethod();
if (child != null) if (child != null)
child.TestMethod(); child.TestMethod();
Console.WriteLine("Child1.TestMethod()"); Console.WriteLine("Child1.TestMethod()");
Console.WriteLine("Property = " + Property + " " + base.Property);
} }
new public void TestAction() new public void TestAction()
{ {
Console.WriteLine("Child1.TestAction()"); Console.WriteLine("Child1.TestAction()");
} }
new public int Property { get; set; }
public override int VirtProp {
get {
return base.VirtProp * 2;
}
}
} }
} }
} }

Loading…
Cancel
Save