Beispiel #1
0
        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;
        }
Beispiel #2
0
        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);
            }
        }