|
|
@ -296,10 +296,10 @@ namespace ICSharpCode.Decompiler.Ast.Transforms |
|
|
|
// Delete the variable declaration statement:
|
|
|
|
// Delete the variable declaration statement:
|
|
|
|
AstNode cur = stmt.NextSibling; |
|
|
|
AstNode cur = stmt.NextSibling; |
|
|
|
stmt.Remove(); |
|
|
|
stmt.Remove(); |
|
|
|
if (blockStatement.Parent.NodeType == NodeType.Member || blockStatement.Parent is Accessor) { |
|
|
|
|
|
|
|
// Delete any following statements as long as they assign parameters to the display class
|
|
|
|
// Delete any following statements as long as they assign parameters to the display class
|
|
|
|
// Do parameter handling only for closures created in the top scope (direct child of method/accessor)
|
|
|
|
BlockStatement rootBlock = blockStatement.Ancestors.OfType<BlockStatement>().LastOrDefault() ?? blockStatement; |
|
|
|
List<ILVariable> parameterOccurrances = blockStatement.Descendants.OfType<IdentifierExpression>() |
|
|
|
List<ILVariable> parameterOccurrances = rootBlock.Descendants.OfType<IdentifierExpression>() |
|
|
|
.Select(n => n.Annotation<ILVariable>()).Where(p => p != null && p.IsParameter).ToList(); |
|
|
|
.Select(n => n.Annotation<ILVariable>()).Where(p => p != null && p.IsParameter).ToList(); |
|
|
|
AstNode next; |
|
|
|
AstNode next; |
|
|
|
for (; cur != null; cur = next) { |
|
|
|
for (; cur != null; cur = next) { |
|
|
@ -315,17 +315,22 @@ namespace ICSharpCode.Decompiler.Ast.Transforms |
|
|
|
); |
|
|
|
); |
|
|
|
Match m = closureFieldAssignmentPattern.Match(cur); |
|
|
|
Match m = closureFieldAssignmentPattern.Match(cur); |
|
|
|
if (m != null) { |
|
|
|
if (m != null) { |
|
|
|
|
|
|
|
FieldDefinition fieldDef = m.Get<MemberReferenceExpression>("left").Single().Annotation<FieldReference>().ResolveWithinSameModule(); |
|
|
|
AstNode right = m.Get("right").Single(); |
|
|
|
AstNode right = m.Get("right").Single(); |
|
|
|
bool isParameter = false; |
|
|
|
bool isParameter = false; |
|
|
|
|
|
|
|
bool isDisplayClassParentPointerAssignment = false; |
|
|
|
if (right is ThisReferenceExpression) { |
|
|
|
if (right is ThisReferenceExpression) { |
|
|
|
isParameter = true; |
|
|
|
isParameter = true; |
|
|
|
} else if (right is IdentifierExpression) { |
|
|
|
} else if (right is IdentifierExpression) { |
|
|
|
// handle parameters only if the whole method contains no other occurrance except for 'right'
|
|
|
|
// handle parameters only if the whole method contains no other occurrance except for 'right'
|
|
|
|
ILVariable param = right.Annotation<ILVariable>(); |
|
|
|
ILVariable v = right.Annotation<ILVariable>(); |
|
|
|
isParameter = param.IsParameter && parameterOccurrances.Count(c => c == param) == 1; |
|
|
|
isParameter = v.IsParameter && parameterOccurrances.Count(c => c == v) == 1; |
|
|
|
|
|
|
|
if (!isParameter && TypeAnalysis.IsSameType(v.Type, fieldDef.FieldType) && IsPotentialClosure(context, v.Type.ResolveWithinSameModule())) { |
|
|
|
|
|
|
|
isDisplayClassParentPointerAssignment = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (isParameter) { |
|
|
|
if (isParameter || isDisplayClassParentPointerAssignment) { |
|
|
|
dict[m.Get<MemberReferenceExpression>("left").Single().Annotation<FieldReference>().ResolveWithinSameModule()] = right; |
|
|
|
dict[fieldDef] = right; |
|
|
|
cur.Remove(); |
|
|
|
cur.Remove(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
break; |
|
|
|
break; |
|
|
@ -334,12 +339,11 @@ namespace ICSharpCode.Decompiler.Ast.Transforms |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Now create variables for all fields of the display class (except for those that we already handled as parameters)
|
|
|
|
// Now create variables for all fields of the display class (except for those that we already handled as parameters)
|
|
|
|
List<Tuple<AstType, string>> variablesToDeclare = new List<Tuple<AstType, string>>(); |
|
|
|
List<Tuple<AstType, string>> variablesToDeclare = new List<Tuple<AstType, string>>(); |
|
|
|
foreach (FieldDefinition field in type.Fields) { |
|
|
|
foreach (FieldDefinition field in type.Fields) { |
|
|
|
if (dict.ContainsKey(field)) |
|
|
|
if (dict.ContainsKey(field)) // skip field if it already was handled as parameter
|
|
|
|
continue; |
|
|
|
continue; |
|
|
|
EnsureVariableNameIsAvailable(blockStatement, field.Name); |
|
|
|
EnsureVariableNameIsAvailable(blockStatement, field.Name); |
|
|
|
currentlyUsedVariableNames.Add(field.Name); |
|
|
|
currentlyUsedVariableNames.Add(field.Name); |
|
|
|