| File: Lowering\LocalRewriter\LocalRewriter_DoStatement.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System.Collections.Immutable; namespace Microsoft.CodeAnalysis.CSharp { internal sealed partial class LocalRewriter { public override BoundNode VisitDoStatement(BoundDoStatement node) { Debug.Assert(node != null); var rewrittenCondition = VisitExpression(node.Condition); var rewrittenBody = VisitStatement(node.Body); Debug.Assert(rewrittenBody is { }); var startLabel = new GeneratedLabelSymbol("start"); var syntax = node.Syntax; // EnC: We need to insert a hidden sequence point to handle function remapping in case // the containing method is edited while methods invoked in the condition are being executed. if (!node.WasCompilerGenerated && this.Instrument) { rewrittenCondition = Instrumenter.InstrumentDoStatementCondition(node, rewrittenCondition, _factory); } BoundStatement ifConditionGotoStart = new BoundConditionalGoto(syntax, rewrittenCondition, true, startLabel); if (!node.WasCompilerGenerated && this.Instrument) { ifConditionGotoStart = Instrumenter.InstrumentDoStatementConditionalGotoStart(node, ifConditionGotoStart); } // do // body // while (condition); // // becomes // // start: // { // body // continue: // sequence point // GotoIfTrue condition start; // } // break: if (node.Locals.IsEmpty) { return BoundStatementList.Synthesized(syntax, node.HasErrors, new BoundLabelStatement(syntax, startLabel), rewrittenBody, new BoundLabelStatement(syntax, node.ContinueLabel), ifConditionGotoStart, new BoundLabelStatement(syntax, node.BreakLabel)); } return BoundStatementList.Synthesized(syntax, node.HasErrors, new BoundLabelStatement(syntax, startLabel), new BoundBlock(syntax, node.Locals, ImmutableArray.Create<BoundStatement>(rewrittenBody, new BoundLabelStatement(syntax, node.ContinueLabel), ifConditionGotoStart)), new BoundLabelStatement(syntax, node.BreakLabel)); } } }