|
|
|
@ -103,6 +103,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -103,6 +103,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
int initializerItemsCount = 0; |
|
|
|
|
bool initializerContainsInitOnlyItems = false; |
|
|
|
|
possibleIndexVariables.Clear(); |
|
|
|
|
currentPath.Clear(); |
|
|
|
|
isCollection = false; |
|
|
|
@ -113,13 +114,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -113,13 +114,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
// if the method is a setter we're dealing with an object initializer
|
|
|
|
|
// if the method is named Add and has at least 2 arguments we're dealing with a collection/dictionary initializer
|
|
|
|
|
while (pos + initializerItemsCount + 1 < block.Instructions.Count |
|
|
|
|
&& IsPartOfInitializer(block.Instructions, pos + initializerItemsCount + 1, v, instType, ref blockKind, context)) |
|
|
|
|
&& IsPartOfInitializer(block.Instructions, pos + initializerItemsCount + 1, v, instType, ref blockKind, ref initializerContainsInitOnlyItems, context)) |
|
|
|
|
{ |
|
|
|
|
initializerItemsCount++; |
|
|
|
|
} |
|
|
|
|
// Do not convert the statements into an initializer if there's an incompatible usage of the initializer variable
|
|
|
|
|
// directly after the possible initializer.
|
|
|
|
|
if (IsMethodCallOnVariable(block.Instructions[pos + initializerItemsCount + 1], v)) |
|
|
|
|
if (!initializerContainsInitOnlyItems && IsMethodCallOnVariable(block.Instructions[pos + initializerItemsCount + 1], v)) |
|
|
|
|
return; |
|
|
|
|
// Calculate the correct number of statements inside the initializer:
|
|
|
|
|
// All index variables that were used in the initializer have Index set to -1.
|
|
|
|
@ -200,7 +201,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -200,7 +201,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
bool isCollection; |
|
|
|
|
readonly Stack<HashSet<AccessPathElement>> pathStack = new Stack<HashSet<AccessPathElement>>(); |
|
|
|
|
|
|
|
|
|
bool IsPartOfInitializer(InstructionCollection<ILInstruction> instructions, int pos, ILVariable target, IType rootType, ref BlockKind blockKind, StatementTransformContext context) |
|
|
|
|
bool IsPartOfInitializer(InstructionCollection<ILInstruction> instructions, int pos, ILVariable target, IType rootType, ref BlockKind blockKind, ref bool initializerContainsInitOnlyItems, StatementTransformContext context) |
|
|
|
|
{ |
|
|
|
|
// Include any stores to local variables that are single-assigned and do not reference the initializer-variable
|
|
|
|
|
// in the list of possible index variables.
|
|
|
|
@ -255,6 +256,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -255,6 +256,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
return false; |
|
|
|
|
if (blockKind != BlockKind.ObjectInitializer && blockKind != BlockKind.WithInitializer) |
|
|
|
|
blockKind = BlockKind.ObjectInitializer; |
|
|
|
|
initializerContainsInitOnlyItems |= lastElement.Member is IProperty { Setter.IsInitOnly: true }; |
|
|
|
|
return true; |
|
|
|
|
default: |
|
|
|
|
return false; |
|
|
|
|