public override void VisitSwitchStatement(SwitchStatementSyntax node) { var afterSwitchState = GetNextState(); var sectionStates = node.Sections.Select(x => GetNextState()).ToArray(); var newSwitchStatement = Js.Switch( (JsExpression)node.Expression.Accept(Transformer), node.Sections .Select((x, i) => { var section = Js.Section(x.Labels.Select(y => y.Kind() == SyntaxKind.CaseSwitchLabel ? Js.CaseLabel((JsExpression)((CaseSwitchLabelSyntax)y).Value.Accept(Transformer)) : Js.DefaultLabel()).ToArray()); section.Statements.AddRange(GotoStateStatements(sectionStates[i])); return(section); }) .ToArray()); CurrentState.Add(newSwitchStatement); GotoState(afterSwitchState); Accept(() => { for (var i = 0; i < node.Sections.Count; i++) { var section = node.Sections[i]; var sectionState = sectionStates[i]; CurrentState = sectionState; foreach (var statement in section.Statements) { AcceptStatement(statement); } } }, afterSwitchState); CurrentState = afterSwitchState; }
private JsStatement TransformBody(JsStatement body) { var block = body is JsBlockStatement ? (JsBlockStatement)body : Js.Block(body); if (!escapeStatements.Any()) { return(Js.Express(idioms.Wrap(block))); } else { if (!(block.Statements.Last() is JsReturnStatement)) { block.Return(Js.Object(Js.Item(EscapeTypeField, Js.Primitive(0))).Compact()); } var wrapped = idioms.Wrap(block); var outerBlock = new JsBlockStatement(); var loopResult = outerBlock.Local("$loopResult", wrapped); if (escapeStatements.Any(x => x.Type == Return)) { outerBlock.If(loopResult.GetReference().Member(EscapeTypeField).EqualTo(Js.Primitive(Return)), Js.Return(loopResult.GetReference().Member(EscapeValueField))); } if (escapeStatements.Any(x => x.Type == Continue)) { var escapes = escapeStatements.Where(x => x.Type == Continue).Distinct(); JsStatement ifTrue; if (!escapes.Any(x => x.Label != null)) { ifTrue = Js.Continue(); } else { ifTrue = Js.Switch( loopResult.GetReference().Member(EscapeLabelField), escapes .Where(x => x.Label == null) .Select(x => Js.Section(Js.Null()).Statement(Js.Continue())) .Concat(escapes .Where(x => x.Label != null && transformer.GetLabelDepth(x.Label) == loopDepth) .Select(x => Js.Section(Js.Primitive(x.Label)).Statement(Js.Continue(x.Label)))) .Concat(new[] { Js.Section(Js.DefaultLabel()).Statements(Js.Return(loopResult.GetReference())) }) .ToArray()); } outerBlock.If(loopResult.GetReference().Member(EscapeTypeField).EqualTo(Js.Primitive(Continue)), ifTrue); } if (escapeStatements.Any(x => x.Type == Break)) { var escapes = escapeStatements.Where(x => x.Type == Break).Distinct(); JsStatement ifTrue; if (!escapes.Any(x => x.Label != null)) { ifTrue = Js.Break(); } else { ifTrue = Js.Switch(loopResult.GetReference().Member(EscapeLabelField), escapes.Select(x => Js.Section(Js.Primitive(x.Label)).Statement(Js.Break(x.Label))).ToArray()); } outerBlock.If(loopResult.GetReference().Member(EscapeTypeField).EqualTo(Js.Primitive(Break)), ifTrue); } return(outerBlock); } }