Browse Source

Add support for multidimensional arrays.

pull/70/head
Daniel Grunwald 15 years ago
parent
commit
1607321a64
  1. 33
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

33
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -273,7 +273,7 @@ namespace Decompiler
// Do branches first because TransformExpressionArguments does not work on arguments that are branches themselfs // Do branches first because TransformExpressionArguments does not work on arguments that are branches themselfs
// TODO: We should probably have virtual instructions for these and not abuse branch codes as expressions // TODO: We should probably have virtual instructions for these and not abuse branch codes as expressions
switch(opCode) { switch(opCode) {
case ILCode.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name); case ILCode.Br: return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
case ILCode.Brfalse: case ILCode.Brfalse:
case ILCode.Brtrue: case ILCode.Brtrue:
case ILCode.Beq: case ILCode.Beq:
@ -293,7 +293,7 @@ namespace Decompiler
TrueStatement = new BlockStatement() { TrueStatement = new BlockStatement() {
new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name) new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
} }
}; };
} }
List<Ast.Expression> args = TransformExpressionArguments(byteCode); List<Ast.Expression> args = TransformExpressionArguments(byteCode);
@ -361,14 +361,13 @@ namespace Decompiler
case Code.Stelem_R4: case Code.Stelem_R4:
case Code.Stelem_R8: case Code.Stelem_R8:
case Code.Stelem_Ref: case Code.Stelem_Ref:
return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
case Code.Stelem_Any: case Code.Stelem_Any:
return InlineAssembly(byteCode, args); return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
#endregion #endregion
#region Comparison #region Comparison
case Code.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2); case Code.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
case Code.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2); case Code.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
case Code.Cgt_Un: case Code.Cgt_Un:
// can also mean Inequality, when used with object references // can also mean Inequality, when used with object references
{ {
TypeReference arg1Type = byteCode.Arguments[0].InferredType; TypeReference arg1Type = byteCode.Arguments[0].InferredType;
@ -568,14 +567,18 @@ namespace Decompiler
case Code.Newobj: case Code.Newobj:
{ {
Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType; Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
// TODO: Ensure that the corrent overloaded constructor is called
/*if (declaringType is ArrayType) { shouldn't this be newarr? if (declaringType is ArrayType) {
return new Ast.ArrayCreateExpression { ComposedType ct = AstBuilder.ConvertType((ArrayType)declaringType) as ComposedType;
Type = AstBuilder.ConvertType((ArrayType)declaringType), if (ct != null && ct.ArraySpecifiers.Count >= 1) {
Arguments = args var ace = new Ast.ArrayCreateExpression();
}; ct.ArraySpecifiers.First().Remove();
}*/ ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
ace.Type = ct;
ace.Arguments.AddRange(args);
return ace;
}
}
var oce = new Ast.ObjectCreateExpression(); var oce = new Ast.ObjectCreateExpression();
oce.Type = AstBuilder.ConvertType(declaringType); oce.Type = AstBuilder.ConvertType(declaringType);
oce.Arguments.AddRange(args); oce.Arguments.AddRange(args);
@ -639,6 +642,12 @@ namespace Decompiler
} }
} }
if (cecilMethod.Name == "Get" && cecilMethod.DeclaringType is ArrayType && methodArgs.Count > 1) {
return target.Indexer(methodArgs);
} else if (cecilMethod.Name == "Set" && cecilMethod.DeclaringType is ArrayType && methodArgs.Count > 2) {
return new AssignmentExpression(target.Indexer(methodArgs.GetRange(0, methodArgs.Count - 1)), methodArgs.Last());
}
// Resolve the method to figure out whether it is an accessor: // Resolve the method to figure out whether it is an accessor:
Cecil.MethodDefinition cecilMethodDef = cecilMethod.Resolve(); Cecil.MethodDefinition cecilMethodDef = cecilMethod.Resolve();
if (cecilMethodDef != null) { if (cecilMethodDef != null) {

Loading…
Cancel
Save