protected override Expression VisitGoto(GotoExpression @goto) { if (@goto.Kind != GotoExpressionKind.Goto) { return(base.VisitGoto(@goto)); } var currentBlockFinalExpression = _blocks.Peek()?.Expressions.Last(); if (currentBlockFinalExpression?.NodeType == ExpressionType.Label) { var returnLabel = (LabelExpression)currentBlockFinalExpression; if (@goto.Target == returnLabel.Target) { GotoReturnGotos.Add(@goto); return(base.VisitGoto(@goto)); } } NamedLabelTargets.Add(@goto.Target); return(base.VisitGoto(@goto)); }
private static string TranslateGoto(GotoExpression @goto, TranslationContext context) { if (context.GoesToReturnLabel(@goto)) { return(TranslateReturn(@goto, context)); } return($"goto {@goto.Target.Name};"); }
private static string TranslateReturn(GotoExpression returnExpression, TranslationContext context) { if (returnExpression.Value == null) { return("return;"); } var value = context.TranslateAsCodeBlock(returnExpression.Value); return($"return {value}"); }
private static string TranslateContinue(GotoExpression continueExpression, TranslationContext context) => "continue;";
private static string TranslateBreak(GotoExpression breakExpression, TranslationContext context) => "break;";
/// <summary> /// Returns a value indicating whether the given <paramref name="goto"/> goes to the /// final statement in a block, and so should be rendered as a return statement. /// </summary> /// <param name="goto">The GotoExpression for which to make the determination.</param> /// <returns> /// True if the given <paramref name="goto"/> goes to the final statement in a block, /// otherwise false. /// </returns> public bool GoesToReturnLabel(GotoExpression @goto) => _analyzer.GotoReturnGotos.Contains(@goto);