/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_While.vb
152 строки
8 KB
Jonathon Marolf
update headers
23 янв 2020, 04:01
Не верифицирован
23 янв 2020, 04:01
91571a3
Код
Авторство
О чём код?
' 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. Imports System.Collections.Immutable Imports System.Diagnostics Imports System.Runtime.InteropServices Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports TypeKind = Microsoft.CodeAnalysis.TypeKind Namespace Microsoft.CodeAnalysis.VisualBasic Partial Friend NotInheritable Class LocalRewriter Public Overrides Function VisitWhileStatement(node As BoundWhileStatement) As BoundNode Dim generateUnstructuredExceptionHandlingResumeCode As Boolean = ShouldGenerateUnstructuredExceptionHandlingResumeCode(node) Dim loopResumeLabel As BoundLabelStatement = Nothing Dim conditionResumeTarget As ImmutableArray(Of BoundStatement) = Nothing If generateUnstructuredExceptionHandlingResumeCode Then loopResumeLabel = RegisterUnstructuredExceptionHandlingNonThrowingResumeTarget(node.Syntax) conditionResumeTarget = RegisterUnstructuredExceptionHandlingResumeTarget(node.Syntax, canThrow:=True) End If Dim rewrittenBody = DirectCast(Visit(node.Body), BoundStatement) Dim afterBodyResumeLabel As BoundLabelStatement = Nothing If generateUnstructuredExceptionHandlingResumeCode Then afterBodyResumeLabel = RegisterUnstructuredExceptionHandlingNonThrowingResumeTarget(node.Syntax) End If Return RewriteWhileStatement(node, VisitExpressionNode(node.Condition), rewrittenBody, node.ContinueLabel, node.ExitLabel, True, loopResumeLabel, conditionResumeTarget, afterBodyResumeLabel) End Function Protected Function RewriteWhileStatement( statement As BoundStatement, rewrittenCondition As BoundExpression, rewrittenBody As BoundStatement, continueLabel As LabelSymbol, exitLabel As LabelSymbol, Optional loopIfTrue As Boolean = True, Optional loopResumeLabelOpt As BoundLabelStatement = Nothing, Optional conditionResumeTargetOpt As ImmutableArray(Of BoundStatement) = Nothing, Optional afterBodyResumeTargetOpt As BoundStatement = Nothing ) As BoundNode Dim startLabel = GenerateLabel("start") Dim statementSyntax = statement.Syntax Dim instrument As Boolean = Me.Instrument(statement) If instrument Then Select Case statement.Kind Case BoundKind.WhileStatement afterBodyResumeTargetOpt = _instrumenterOpt.InstrumentWhileEpilogue(DirectCast(statement, BoundWhileStatement), afterBodyResumeTargetOpt) Case BoundKind.DoLoopStatement afterBodyResumeTargetOpt = _instrumenterOpt.InstrumentDoLoopEpilogue(DirectCast(statement, BoundDoLoopStatement), afterBodyResumeTargetOpt) Case BoundKind.ForEachStatement Case Else Throw ExceptionUtilities.UnexpectedValue(statement.Kind) End Select End If rewrittenBody = Concat(rewrittenBody, afterBodyResumeTargetOpt) ' 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 rewrittenCondition IsNot Nothing AndAlso instrument Then Select Case statement.Kind Case BoundKind.WhileStatement rewrittenCondition = _instrumenterOpt.InstrumentWhileStatementCondition(DirectCast(statement, BoundWhileStatement), rewrittenCondition, _currentMethodOrLambda) Case BoundKind.DoLoopStatement rewrittenCondition = _instrumenterOpt.InstrumentDoLoopStatementCondition(DirectCast(statement, BoundDoLoopStatement), rewrittenCondition, _currentMethodOrLambda) Case BoundKind.ForEachStatement rewrittenCondition = _instrumenterOpt.InstrumentForEachStatementCondition(DirectCast(statement, BoundForEachStatement), rewrittenCondition, _currentMethodOrLambda) Case Else Throw ExceptionUtilities.UnexpectedValue(statement.Kind) End Select End If Dim ifConditionGotoStart As BoundStatement = New BoundConditionalGoto( statementSyntax, rewrittenCondition, loopIfTrue, startLabel) If Not conditionResumeTargetOpt.IsDefaultOrEmpty Then ifConditionGotoStart = New BoundStatementList(ifConditionGotoStart.Syntax, conditionResumeTargetOpt.Add(ifConditionGotoStart)) End If If instrument Then Select Case statement.Kind Case BoundKind.WhileStatement ifConditionGotoStart = _instrumenterOpt.InstrumentWhileStatementConditionalGotoStart(DirectCast(statement, BoundWhileStatement), ifConditionGotoStart) Case BoundKind.DoLoopStatement ifConditionGotoStart = _instrumenterOpt.InstrumentDoLoopStatementEntryOrConditionalGotoStart(DirectCast(statement, BoundDoLoopStatement), ifConditionGotoStart) Case BoundKind.ForEachStatement ifConditionGotoStart = _instrumenterOpt.InstrumentForEachStatementConditionalGotoStart(DirectCast(statement, BoundForEachStatement), ifConditionGotoStart) Case Else Throw ExceptionUtilities.UnexpectedValue(statement.Kind) End Select End If ' While condition ' body ' End While ' ' becomes ' ' goto continue; ' start: ' body ' continue: ' {GotoIfTrue condition start} ' exit: 'mark the initial jump as hidden. 'We do not want to associate it with statement before. 'This jump may be a target of another jump (for example if loops are nested) and that will make 'impression of the previous statement being re-executed Dim gotoContinue As BoundStatement = New BoundGotoStatement(statementSyntax, continueLabel, Nothing) If loopResumeLabelOpt IsNot Nothing Then gotoContinue = Concat(loopResumeLabelOpt, gotoContinue) End If If instrument Then gotoContinue = SyntheticBoundNodeFactory.HiddenSequencePoint(gotoContinue) End If Return New BoundStatementList(statementSyntax, ImmutableArray.Create(Of BoundStatement)( gotoContinue, New BoundLabelStatement(statementSyntax, startLabel), rewrittenBody, New BoundLabelStatement(statementSyntax, continueLabel), ifConditionGotoStart, New BoundLabelStatement(statementSyntax, exitLabel) )) End Function End Class End Namespace