Browse Source

Replace ctors of anonymous types with AnonymousTypeCreateExpression

pull/728/merge
Siegfried Pammer 9 years ago
parent
commit
2a6d359e71
  1. 39
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 10
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

39
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1014,9 +1014,28 @@ namespace ICSharpCode.Decompiler.CSharp
rr = new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults); rr = new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults);
if (inst.OpCode == OpCode.NewObj) { if (inst.OpCode == OpCode.NewObj) {
var argumentExpressions = arguments.Select(arg => arg.Expression); var argumentExpressions = arguments.SelectArray(arg => arg.Expression);
if (method.DeclaringType.IsAnonymousType()) {
AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression();
var parameters = inst.Method.Parameters;
if (CanInferAnonymousTypePropertyNamesFromArguments(argumentExpressions, parameters)) {
atce.Initializers.AddRange(argumentExpressions);
} else {
for (int i = 0; i < argumentExpressions.Length; i++) {
atce.Initializers.Add(
new NamedExpression {
Name = parameters[i].Name,
Expression = argumentExpressions[i]
});
}
}
return atce
.WithILInstruction(inst)
.WithRR(rr);
} else {
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;
int allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0); int allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0);
@ -1051,6 +1070,24 @@ namespace ICSharpCode.Decompiler.CSharp
} }
} }
static bool CanInferAnonymousTypePropertyNamesFromArguments(IList<Expression> args, IList<IParameter> parameters)
{
for (int i = 0; i < args.Count; i++) {
string inferredName;
if (args[i] is IdentifierExpression)
inferredName = ((IdentifierExpression)args[i]).Identifier;
else if (args[i] is MemberReferenceExpression)
inferredName = ((MemberReferenceExpression)args[i]).MemberName;
else
inferredName = null;
if (inferredName != parameters[i].Name) {
return false;
}
}
return true;
}
Expression HandleAccessorCall(ILInstruction inst, TranslatedExpression target, IMethod method, IList<TranslatedExpression> arguments) Expression HandleAccessorCall(ILInstruction inst, TranslatedExpression target, IMethod method, IList<TranslatedExpression> arguments)
{ {
var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly); var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly);

10
ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

@ -255,11 +255,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (v.RemovedDueToCollision) if (v.RemovedDueToCollision)
continue; continue;
AstType type = context.TypeSystemAstBuilder.ConvertType(v.Type);
var boe = (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression; var boe = (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression;
if (boe != null && boe.Left.IsMatch(new IdentifierExpression(v.Name))) { if (boe != null && boe.Left.IsMatch(new IdentifierExpression(v.Name))) {
AstType type;
if (v.Type.ContainsAnonymousType()) {
type = new SimpleType("var");
} else {
type = context.TypeSystemAstBuilder.ConvertType(v.Type);
}
var vds = new VariableDeclarationStatement(type, v.Name, boe.Right.Detach()); var vds = new VariableDeclarationStatement(type, v.Name, boe.Right.Detach());
var init = vds.Variables.Single(); var init = vds.Variables.Single();
init.AddAnnotation(boe.Left.GetResolveResult()); init.AddAnnotation(boe.Left.GetResolveResult());
@ -271,6 +274,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
replacements.Add(new KeyValuePair<AstNode, AstNode>(v.InsertionPoint.nextNode, vds)); replacements.Add(new KeyValuePair<AstNode, AstNode>(v.InsertionPoint.nextNode, vds));
} else { } else {
Expression initializer = null; Expression initializer = null;
AstType type = context.TypeSystemAstBuilder.ConvertType(v.Type);
if (v.DefaultInitialization) { if (v.DefaultInitialization) {
initializer = new DefaultValueExpression(type.Clone()); initializer = new DefaultValueExpression(type.Clone());
} }

Loading…
Cancel
Save