|
|
|
@ -291,32 +291,52 @@ namespace ICSharpCode.Decompiler.ILAst
@@ -291,32 +291,52 @@ namespace ICSharpCode.Decompiler.ILAst
|
|
|
|
|
///
|
|
|
|
|
/// CallGetter/CallSetter is used to allow the ILAst to represent "while ((SomeProperty = value) != null)".
|
|
|
|
|
/// </summary>
|
|
|
|
|
void IntroducePropertyAccessInstructions(ILBlock method) |
|
|
|
|
void IntroducePropertyAccessInstructions(ILNode node) |
|
|
|
|
{ |
|
|
|
|
foreach (ILExpression expr in method.GetSelfAndChildrenRecursive<ILExpression>()) { |
|
|
|
|
if (expr.Code == ILCode.Call || expr.Code == ILCode.Callvirt) { |
|
|
|
|
MethodReference cecilMethod = (MethodReference)expr.Operand; |
|
|
|
|
if (cecilMethod.DeclaringType is ArrayType) { |
|
|
|
|
switch (cecilMethod.Name) { |
|
|
|
|
case "Get": |
|
|
|
|
expr.Code = ILCode.CallGetter; |
|
|
|
|
break; |
|
|
|
|
case "Set": |
|
|
|
|
expr.Code = ILCode.CallSetter; |
|
|
|
|
break; |
|
|
|
|
case "Address": |
|
|
|
|
expr.Code = ILCode.CallGetter; |
|
|
|
|
expr.AddPrefix(new ILExpressionPrefix(ILCode.PropertyAddress)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
MethodDefinition cecilMethodDef = cecilMethod.Resolve(); |
|
|
|
|
if (cecilMethodDef != null) { |
|
|
|
|
if (cecilMethodDef.IsGetter) |
|
|
|
|
expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallGetter : ILCode.CallvirtGetter; |
|
|
|
|
else if (cecilMethodDef.IsSetter) |
|
|
|
|
expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallSetter : ILCode.CallvirtSetter; |
|
|
|
|
} |
|
|
|
|
ILExpression parentExpr = node as ILExpression; |
|
|
|
|
if (parentExpr != null) { |
|
|
|
|
for (int i = 0; i < parentExpr.Arguments.Count; i++) { |
|
|
|
|
ILExpression expr = parentExpr.Arguments[i]; |
|
|
|
|
IntroducePropertyAccessInstructions(expr); |
|
|
|
|
IntroducePropertyAccessInstructions(expr, parentExpr, i); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
foreach (ILNode child in node.GetChildren()) { |
|
|
|
|
IntroducePropertyAccessInstructions(child); |
|
|
|
|
ILExpression expr = child as ILExpression; |
|
|
|
|
if (expr != null) { |
|
|
|
|
IntroducePropertyAccessInstructions(expr, null, -1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void IntroducePropertyAccessInstructions(ILExpression expr, ILExpression parentExpr, int posInParent) |
|
|
|
|
{ |
|
|
|
|
if (expr.Code == ILCode.Call || expr.Code == ILCode.Callvirt) { |
|
|
|
|
MethodReference cecilMethod = (MethodReference)expr.Operand; |
|
|
|
|
if (cecilMethod.DeclaringType is ArrayType) { |
|
|
|
|
switch (cecilMethod.Name) { |
|
|
|
|
case "Get": |
|
|
|
|
expr.Code = ILCode.CallGetter; |
|
|
|
|
break; |
|
|
|
|
case "Set": |
|
|
|
|
expr.Code = ILCode.CallSetter; |
|
|
|
|
break; |
|
|
|
|
case "Address": |
|
|
|
|
expr.Code = ILCode.CallGetter; |
|
|
|
|
if (parentExpr != null) { |
|
|
|
|
parentExpr.Arguments[posInParent] = new ILExpression(ILCode.AddressOf, null, expr); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
MethodDefinition cecilMethodDef = cecilMethod.Resolve(); |
|
|
|
|
if (cecilMethodDef != null) { |
|
|
|
|
if (cecilMethodDef.IsGetter) |
|
|
|
|
expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallGetter : ILCode.CallvirtGetter; |
|
|
|
|
else if (cecilMethodDef.IsSetter) |
|
|
|
|
expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallSetter : ILCode.CallvirtSetter; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|