Browse Source

fix #436 - Incorrectly deducing that some uses of using, MoveNext() and Current can be rewritten as foreach when they cannot.

pull/724/head
Siegfried Pammer 9 years ago
parent
commit
b0e760f004
  1. 41
      ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs

41
ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs

@ -419,6 +419,12 @@ namespace ICSharpCode.Decompiler.Ast.Transforms @@ -419,6 +419,12 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
// We just care that we can move it in front of the loop:
if (declarationPoint != loop)
return null;
// Make sure that the enumerator variable is not used inside the body
foreach (Statement stmt in m.Get<Statement>("statement")) {
if (UsesEnumerator(stmt, enumeratorVar.Name))
return null;
}
BlockStatement newBody = new BlockStatement();
foreach (Statement stmt in m.Get<Statement>("variablesInsideLoop"))
@ -1160,5 +1166,40 @@ namespace ICSharpCode.Decompiler.Ast.Transforms @@ -1160,5 +1166,40 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
return null;
}
#endregion
#region UsesEnumerator helper
class UsesEnumeratorVisitor : DepthFirstAstVisitor<bool>
{
Identifier enumeratorIdentifier;
public UsesEnumeratorVisitor(string identifier)
{
enumeratorIdentifier = Identifier.Create(identifier);
}
protected override bool VisitChildren(AstNode node)
{
AstNode next;
for (var child = node.FirstChild; child != null; child = next) {
// Store next to allow the loop to continue
// if the visitor removes/replaces child.
next = child.NextSibling;
if (child.AcceptVisitor(this))
return true;
}
return false;
}
public override bool VisitIdentifier(Identifier identifier)
{
return identifier.IsMatch(enumeratorIdentifier);
}
}
bool UsesEnumerator(Statement statement, string enumeratorVarName)
{
return statement.AcceptVisitor(new UsesEnumeratorVisitor(enumeratorVarName));
}
#endregion
}
}

Loading…
Cancel
Save