diff --git a/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md b/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md index 452a06e1..8cb26d6e 100644 --- a/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md +++ b/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md @@ -1,6 +1,6 @@ Detail of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:02 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:03 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework v6.1](http://msdn.microsoft.com/en-us/data/aa937723) (EF). diff --git a/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md b/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md index 649a2bb7..93ea1c41 100644 --- a/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md +++ b/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md @@ -1,6 +1,6 @@ Detail With Sql of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:02 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:03 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework v6.1](http://msdn.microsoft.com/en-us/data/aa937723) (EF). diff --git a/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md b/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md index b630ced2..8e91a723 100644 --- a/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md +++ b/src/DelegateDecompiler.EntityFramework.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md @@ -1,6 +1,6 @@ Summary of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:02 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:03 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework v6.1](http://msdn.microsoft.com/en-us/data/aa937723) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md b/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md index 6cbc7aa3..d8176b1d 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md +++ b/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md @@ -1,6 +1,6 @@ Detail of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:04 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md b/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md index 81cce82c..4aa3fe90 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md +++ b/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md @@ -1,6 +1,6 @@ Detail With Sql of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:04 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md b/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md index 4df7bd62..d59ef471 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md +++ b/src/DelegateDecompiler.EntityFrameworkCore.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md @@ -1,6 +1,6 @@ Summary of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:04 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md b/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md index ef2acc3a..2dfd5ca4 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md +++ b/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md @@ -1,6 +1,6 @@ Detail of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:05 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md b/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md index 8e25d783..01fc6b28 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md +++ b/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md @@ -1,6 +1,6 @@ Detail With Sql of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:05 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md b/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md index faed918c..9684305c 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md +++ b/src/DelegateDecompiler.EntityFrameworkCore3.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md @@ -1,6 +1,6 @@ Summary of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:05 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md b/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md index ef2acc3a..2dfd5ca4 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md +++ b/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/DetailedListOfSupportedCommands.md @@ -1,6 +1,6 @@ Detail of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:05 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md b/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md index 8e25d783..01fc6b28 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md +++ b/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/DetailedListOfSupportedCommandsWithSQL.md @@ -1,6 +1,6 @@ Detail With Sql of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:05 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md b/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md index faed918c..9684305c 100644 --- a/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md +++ b/src/DelegateDecompiler.EntityFrameworkCore5.Tests/GeneratedDocumentation/SummaryOfSupportedCommands.md @@ -1,6 +1,6 @@ Summary of supported commands ============ -## Documentation produced for DelegateDecompiler, version 0.28.0 on Friday, 23 October 2020 15:03 +## Documentation produced for DelegateDecompiler, version 0.29.0 on Thursday, 04 February 2021 16:05 This file documents what linq commands **DelegateDecompiler** supports when working with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF). diff --git a/src/DelegateDecompiler.Tests/EnumTests.cs b/src/DelegateDecompiler.Tests/EnumTests.cs index 4b4bb60c..1f39d48b 100644 --- a/src/DelegateDecompiler.Tests/EnumTests.cs +++ b/src/DelegateDecompiler.Tests/EnumTests.cs @@ -285,6 +285,15 @@ public void Issue98B() Test(expected, compiled); } + [Test, Ignore("Not fixed yet")] + public void Issue160() + { + Expression> expected1 = x => (TestEnum?) x == TestEnum.Bar; + Expression> expected2 = x => (int?) x == (int?) TestEnum.Bar; + Func compiled = x => (TestEnum?) x == TestEnum.Bar; + Test(expected1, expected2, compiled); + } + private static bool TestEnumMethod(TestEnum p0) { throw new NotImplementedException(); diff --git a/src/DelegateDecompiler.Tests/Issue166.cs b/src/DelegateDecompiler.Tests/Issue166.cs new file mode 100644 index 00000000..b3f37b8d --- /dev/null +++ b/src/DelegateDecompiler.Tests/Issue166.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace DelegateDecompiler.Tests +{ + [TestFixture] + public class Issue166 : DecompilerTestsBase + { + [Test] + public void ShouldSupportInstanceClosures() + { + var comments = new Comment[0]; + var expected = comments.AsQueryable().Select(c => new CommentDto + { + HasUserPurchasedTheCourse = c.User.Purchases.Any(p => p.Items.Any(i => i.CourseId == c.CourseId)), + }); + var actual = comments.AsQueryable().Select(c => ToCommentDto(c)).Decompile(); + AssertAreEqual(expected.Expression, actual.Expression); + } + + [Decompile] + static CommentDto ToCommentDto(Comment comment) + { + return new CommentDto + { + HasUserPurchasedTheCourse = comment.User.Purchases.Any(p => p.Items.Any(i => i.CourseId == comment.CourseId)), + }; + } + + class Comment + { + public User User { get; set; } + + public int CourseId { get; set; } + } + + class User + { + public IEnumerable Purchases { get; set; } + } + + class PurchaseItem + { + public int CourseId { get; set; } + } + + class Purchase + { + public IEnumerable Items { get; set; } + } + + class CommentDto + { + public bool HasUserPurchasedTheCourse { get; set; } + } + } +} diff --git a/src/DelegateDecompiler.Tests/Issue167.cs b/src/DelegateDecompiler.Tests/Issue167.cs new file mode 100644 index 00000000..99df0678 --- /dev/null +++ b/src/DelegateDecompiler.Tests/Issue167.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace DelegateDecompiler.Tests +{ + [TestFixture] + public class Issue167 : DecompilerTestsBase + { + [Test] + public void ShouldFlattenTransparentExpressions() + { + var comments = new Comment[0]; + var expected = comments.AsQueryable().Select(c => new CommentDto + { + IsUserPurchaser = c.Purchases.Any(p => p.UserId == c.UserId) + }); + var actual = comments.AsQueryable().Select(c => ToCommentDto(c)).Decompile(); + + AssertAreEqual(expected.Expression, actual.Expression); + } + + [Decompile] + static CommentDto ToCommentDto(Comment comment) + { + return new CommentDto + { + IsUserPurchaser = comment.Purchases.Any(p => p.UserId == comment.UserId), + }; + } + + public class Comment + { + public int UserId { get; set; } + + public IEnumerable Purchases { get; } + } + + public class Purchase + { + public int UserId { get; set; } + } + + public class CommentDto + { + public object IsUserPurchaser { get; set; } + } + } +} diff --git a/src/DelegateDecompiler.Tests/Issue171.cs b/src/DelegateDecompiler.Tests/Issue171.cs new file mode 100644 index 00000000..764761fb --- /dev/null +++ b/src/DelegateDecompiler.Tests/Issue171.cs @@ -0,0 +1,44 @@ +using NUnit.Framework; + +namespace DelegateDecompiler.Tests +{ + [TestFixture] + public class Issue171 + { + [Test] + public void ShouldSupportStructsWithoutInitializer() + { + var method = typeof(Issue171).GetMethod(nameof(X1)); + var expression = method.Decompile(); + + Assert.That(expression.ToString(), Is.EqualTo("this => new DataOnStack() {StatementCount = 1}")); + } + + [Test] + public void ShouldSupportStructsWithInitializer() + { + var method = typeof(Issue171).GetMethod(nameof(X2)); + var expression = method.Decompile(); + + Assert.That(expression.ToString(), Is.EqualTo("this => new DataOnStack() {StatementCount = 1}")); + } + + public DataOnStack X1() + { + DataOnStack x; + x.StatementCount = 1; + return x; + } + + + public DataOnStack X2() + { + return new DataOnStack {StatementCount = 1}; + } + + public struct DataOnStack + { + public uint StatementCount; + } + } +} diff --git a/src/DelegateDecompiler/DecompileExpressionVisitor.cs b/src/DelegateDecompiler/DecompileExpressionVisitor.cs index 08c8b914..695f853a 100644 --- a/src/DelegateDecompiler/DecompileExpressionVisitor.cs +++ b/src/DelegateDecompiler/DecompileExpressionVisitor.cs @@ -73,7 +73,9 @@ Expression Decompile(MethodInfo method, Expression instance, IList a } } - return Visit(new ReplaceExpressionVisitor(expressions).Visit(expression.Body)); + var body = new ReplaceExpressionVisitor(expressions).Visit(expression.Body); + body = TransparentIdentifierRemovingExpressionVisitor.RemoveTransparentIdentifiers(body); + return Visit(body); } } } diff --git a/src/DelegateDecompiler/MemberExtensions.cs b/src/DelegateDecompiler/MemberExtensions.cs new file mode 100644 index 00000000..e307cb1a --- /dev/null +++ b/src/DelegateDecompiler/MemberExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Reflection; + +namespace DelegateDecompiler +{ + internal static class MemberExtensions + { + public static Type FieldOrPropertyType(this MemberInfo member) + { + switch (member) + { + case FieldInfo field: + return field.FieldType; + case PropertyInfo property: + return property.PropertyType; + default: + throw new NotSupportedException($"MemberInfo {member} is not supported"); + } + } + } +} diff --git a/src/DelegateDecompiler/Processor.cs b/src/DelegateDecompiler/Processor.cs index eb5e70b2..69aed85f 100644 --- a/src/DelegateDecompiler/Processor.cs +++ b/src/DelegateDecompiler/Processor.cs @@ -16,7 +16,7 @@ internal class Processor { class ProcessorState { - public IDictionary Delegates { get; private set; } + public IDictionary, Address> Delegates { get; private set; } public Stack
Stack { get; private set; } public VariableInfo[] Locals { get; private set; } public IList
Args { get; private set; } @@ -26,9 +26,9 @@ class ProcessorState public Instruction Instruction { get; set; } public ProcessorState(Stack
stack, VariableInfo[] locals, IList
args, Instruction instruction, - Instruction last = null, IDictionary delegates = null) + Instruction last = null, IDictionary, Address> delegates = null) { - Delegates = delegates ?? new Dictionary(); + Delegates = delegates ?? new Dictionary, Address>(); Stack = stack; Locals = locals; Args = args; @@ -224,40 +224,23 @@ Expression Process() } else if (state.Instruction.OpCode == OpCodes.Ldfld || state.Instruction.OpCode == OpCodes.Ldflda) { - var instance = state.Stack.Pop(); - state.Stack.Push(Expression.Field(instance, (FieldInfo) state.Instruction.Operand)); + LdFld(state, state.Stack.Pop()); } else if (state.Instruction.OpCode == OpCodes.Ldsfld) { - var field = (FieldInfo) state.Instruction.Operand; - if (IsCachedAnonymousMethodDelegate(field)) - { - Address address; - if (state.Delegates.TryGetValue(field, out address)) - { - state.Stack.Push(address); - } - else - { - state.Stack.Push(Expression.Field(null, field)); - } - } - else - { - state.Stack.Push(Expression.Field(null, field)); - } + LdFld(state, null); } else if (state.Instruction.OpCode == OpCodes.Stsfld) { + var value = state.Stack.Pop(); var field = (FieldInfo) state.Instruction.Operand; if (IsCachedAnonymousMethodDelegate(field)) { - state.Delegates[field] = state.Stack.Pop(); + state.Delegates[Tuple.Create(default(Address), field)] = value; } else { - var pop = state.Stack.Pop(); - state.Stack.Push(Expression.Assign(Expression.Field(null, field), pop)); + state.Stack.Push(Expression.Assign(Expression.Field(null, field), value)); } } else if (state.Instruction.OpCode == OpCodes.Stfld) @@ -265,11 +248,18 @@ Expression Process() var value = state.Stack.Pop(); var instance = state.Stack.Pop(); var field = (FieldInfo) state.Instruction.Operand; - var expression = BuildAssignment(instance.Expression, field, value, out var push); - if (push) - state.Stack.Push(expression); + if (IsCachedAnonymousMethodDelegate(field)) + { + state.Delegates[Tuple.Create(instance, field)] = value; + } else - instance.Expression = expression; + { + var expression = BuildAssignment(instance.Expression, field, value, out var push); + if (push) + state.Stack.Push(expression); + else + instance.Expression = expression; + } } else if (state.Instruction.OpCode == OpCodes.Ldloc_0) { @@ -767,6 +757,20 @@ Expression Process() return state == null ? Expression.Empty() : state.Final(); } + static void LdFld(ProcessorState state, Address instance) + { + var field = (FieldInfo) state.Instruction.Operand; + if (IsCachedAnonymousMethodDelegate(field) && + state.Delegates.TryGetValue(Tuple.Create(instance, field), out var address)) + { + state.Stack.Push(address); + } + else + { + state.Stack.Push(Expression.Field(instance?.Expression, field)); + } + } + static LambdaExpression DecompileLambdaExpression(MethodInfo method, Func @this) { if (method.IsStatic) @@ -1080,10 +1084,12 @@ static void Call(ProcessorState state, MethodInfo m) static Expression BuildAssignment(Expression instance, MemberInfo member, Expression value, out bool push) { + var adjustedValue = AdjustType(value, member.FieldOrPropertyType()); + if (instance.NodeType == ExpressionType.New) { push = false; - return Expression.MemberInit((NewExpression) instance, Expression.Bind(member, value)); + return Expression.MemberInit((NewExpression) instance, Expression.Bind(member, adjustedValue)); } if (instance.NodeType == ExpressionType.MemberInit) @@ -1094,12 +1100,18 @@ static Expression BuildAssignment(Expression instance, MemberInfo member, Expres memberInitExpression.NewExpression, new List(memberInitExpression.Bindings) { - Expression.Bind(member, value) + Expression.Bind(member, adjustedValue) }); } + if (instance.NodeType == ExpressionType.Constant && instance.Type.IsValueType) + { + push = false; + return Expression.MemberInit(Expression.New(instance.Type), Expression.Bind(member, adjustedValue)); + } + push = true; - return Expression.Assign(Expression.MakeMemberAccess(instance, member), value); + return Expression.Assign(Expression.MakeMemberAccess(instance, member), adjustedValue); } static Expression[] GetArguments(ProcessorState state, MethodBase m) diff --git a/src/DelegateDecompiler/TransparentIdentifierRemovingExpressionVisitor.cs b/src/DelegateDecompiler/TransparentIdentifierRemovingExpressionVisitor.cs index 81f83ab0..df87ac4c 100644 --- a/src/DelegateDecompiler/TransparentIdentifierRemovingExpressionVisitor.cs +++ b/src/DelegateDecompiler/TransparentIdentifierRemovingExpressionVisitor.cs @@ -37,12 +37,10 @@ protected override Expression VisitMember(MemberExpression node) private static IEnumerable GetMemberBindingsCreatedByExpression(Expression expression) { - var memberInitExpression = expression as MemberInitExpression; - if (memberInitExpression != null) + if (expression is MemberInitExpression memberInitExpression) return memberInitExpression.Bindings.OfType(); - - var newExpression = expression as NewExpression; - if (newExpression != null && newExpression.Members != null) + + if (expression is NewExpression newExpression && newExpression.Members != null) return newExpression.Members.Select((t, i) => Expression.Bind(t, newExpression.Arguments[i])); return null; @@ -52,9 +50,7 @@ private static bool Match(MemberInfo a, MemberInfo b) { if (a == b) return true; - var methodInfo = b as MethodInfo; - var propertyInfo = a as PropertyInfo; - if (propertyInfo != null && methodInfo != null && propertyInfo.CanRead && methodInfo == propertyInfo.GetGetMethod(true)) + if (a is PropertyInfo propertyInfo && b is MethodInfo methodInfo && propertyInfo.CanRead && methodInfo == propertyInfo.GetGetMethod(true)) return true; return false; diff --git a/src/DelegateDecompiler/VariableInfo.cs b/src/DelegateDecompiler/VariableInfo.cs index 4ec22102..80d01497 100644 --- a/src/DelegateDecompiler/VariableInfo.cs +++ b/src/DelegateDecompiler/VariableInfo.cs @@ -7,7 +7,10 @@ class VariableInfo public VariableInfo(Type type) { Type = type; - Address = new Address(); + Address = new Address + { + Expression = ExpressionHelper.Default(type) + }; } public Type Type { get; set; } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 64353f8b..76b89097 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,7 +3,7 @@ DelegateDecompiler - 0.28.3 + 0.29.0 1.0.0.0 Alexander Zaytsev Copyright (c) Alexander Zaytsev 2012 - 2021