|
|
|
@ -403,8 +403,16 @@ namespace ICSharpCode.Decompiler.CSharp |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#region foreach construction
|
|
|
|
#region foreach construction
|
|
|
|
static readonly InvocationExpression getEnumeratorPattern = new InvocationExpression(new MemberReferenceExpression(new AnyNode("collection").ToExpression(), "GetEnumerator")); |
|
|
|
static readonly InvocationExpression getEnumeratorPattern = new InvocationExpression( |
|
|
|
static readonly InvocationExpression moveNextConditionPattern = new InvocationExpression(new MemberReferenceExpression(new NamedNode("enumerator", new IdentifierExpression(Pattern.AnyString)), "MoveNext")); |
|
|
|
new Choice { |
|
|
|
|
|
|
|
new MemberReferenceExpression(new AnyNode("collection").ToExpression(), "GetEnumerator"), |
|
|
|
|
|
|
|
new MemberReferenceExpression(new AnyNode("collection").ToExpression(), "GetAsyncEnumerator") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
static readonly Expression moveNextConditionPattern = new Choice { |
|
|
|
|
|
|
|
new InvocationExpression(new MemberReferenceExpression(new NamedNode("enumerator", new IdentifierExpression(Pattern.AnyString)), "MoveNext")), |
|
|
|
|
|
|
|
new UnaryOperatorExpression(UnaryOperatorType.Await, new InvocationExpression(new MemberReferenceExpression(new NamedNode("enumerator", new IdentifierExpression(Pattern.AnyString)), "MoveNextAsync"))) |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
protected internal override TranslatedStatement VisitUsingInstruction(UsingInstruction inst) |
|
|
|
protected internal override TranslatedStatement VisitUsingInstruction(UsingInstruction inst) |
|
|
|
{ |
|
|
|
{ |
|
|
|
@ -484,6 +492,9 @@ namespace ICSharpCode.Decompiler.CSharp |
|
|
|
// The using body must be a BlockContainer.
|
|
|
|
// The using body must be a BlockContainer.
|
|
|
|
if (!(inst.Body is BlockContainer container) || !m.Success) |
|
|
|
if (!(inst.Body is BlockContainer container) || !m.Success) |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
|
|
|
|
bool isAsync = ((MemberReferenceExpression)((InvocationExpression)resource).Target).MemberName == "GetAsyncEnumerator"; |
|
|
|
|
|
|
|
if (isAsync != inst.IsAsync) |
|
|
|
|
|
|
|
return null; |
|
|
|
// The using-variable is the enumerator.
|
|
|
|
// The using-variable is the enumerator.
|
|
|
|
var enumeratorVar = inst.Variable; |
|
|
|
var enumeratorVar = inst.Variable; |
|
|
|
// If there's another BlockContainer nested in this container and it only has one child block, unwrap it.
|
|
|
|
// If there's another BlockContainer nested in this container and it only has one child block, unwrap it.
|
|
|
|
@ -499,6 +510,8 @@ namespace ICSharpCode.Decompiler.CSharp |
|
|
|
var m2 = moveNextConditionPattern.Match(condition.Expression); |
|
|
|
var m2 = moveNextConditionPattern.Match(condition.Expression); |
|
|
|
if (!m2.Success) |
|
|
|
if (!m2.Success) |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
|
|
|
|
if (condition.Expression is UnaryOperatorExpression { Operator: UnaryOperatorType.Await } != isAsync) |
|
|
|
|
|
|
|
return null; |
|
|
|
// Check enumerator variable references.
|
|
|
|
// Check enumerator variable references.
|
|
|
|
var enumeratorVar2 = m2.Get<IdentifierExpression>("enumerator").Single().GetILVariable(); |
|
|
|
var enumeratorVar2 = m2.Get<IdentifierExpression>("enumerator").Single().GetILVariable(); |
|
|
|
if (enumeratorVar2 != enumeratorVar) |
|
|
|
if (enumeratorVar2 != enumeratorVar) |
|
|
|
@ -604,6 +617,7 @@ namespace ICSharpCode.Decompiler.CSharp |
|
|
|
|
|
|
|
|
|
|
|
// Construct the foreach loop.
|
|
|
|
// Construct the foreach loop.
|
|
|
|
var foreachStmt = new ForeachStatement { |
|
|
|
var foreachStmt = new ForeachStatement { |
|
|
|
|
|
|
|
IsAsync = isAsync, |
|
|
|
VariableType = useVar ? new SimpleType("var") : exprBuilder.ConvertType(foreachVariable.Type), |
|
|
|
VariableType = useVar ? new SimpleType("var") : exprBuilder.ConvertType(foreachVariable.Type), |
|
|
|
VariableDesignation = designation, |
|
|
|
VariableDesignation = designation, |
|
|
|
InExpression = collectionExpr.Detach(), |
|
|
|
InExpression = collectionExpr.Detach(), |
|
|
|
|