Пример #1
0
        public object VisitSwitchStatement(SwitchStatement switchStatement, object data)
        {
            // We have a problem: given is still not implemented in boo.
            // So here's the if / else workaround:
            string oldSwitchTempName = currentSwitchTempName;

            currentSwitchTempName = GenerateName();
            ArrayList l = new ArrayList(3);

            B.BinaryExpression init = new B.BinaryExpression(B.BinaryOperatorType.Assign,
                                                             new B.ReferenceExpression(currentSwitchTempName),
                                                             ConvertExpression(switchStatement.SwitchExpression));
            l.Add(new B.ExpressionStatement(init));
            B.IfStatement    dummyStatement = new B.IfStatement(GetLexicalInfo(switchStatement));
            B.IfStatement    first          = null;
            B.IfStatement    current        = dummyStatement;
            B.BreakStatement bs;
            for (int i = 0; i < switchStatement.SwitchSections.Count; i++)
            {
                current = (B.IfStatement)((INode)switchStatement.SwitchSections[i]).AcceptVisitor(this, current);
                if (i == 0)
                {
                    first = current;
                }
                bs = GetLastStatement(current.TrueBlock) as B.BreakStatement;
                if (bs != null)
                {
                    bs.ReplaceBy(null);
                }
            }
            bs = GetLastStatement(current.FalseBlock) as B.BreakStatement;
            if (bs != null)
            {
                bs.ReplaceBy(null);
            }

            string endSwitchName = currentSwitchTempName + "_end";

            first.Accept(new ReplaceBreakStatementsVisitor(endSwitchName));

            FindUnneededLabelsVisitor fulv = new FindUnneededLabelsVisitor(currentSwitchTempName + "_", nameComparer);

            first.Accept(fulv);

            bool needsEndLabel = fulv.NeededLabels.Contains(endSwitchName);

            fulv.RemoveLabels();             // remove "goto case" labels that aren't needed
            currentSwitchTempName = oldSwitchTempName;

            if (first == dummyStatement)
            {
                l.AddRange(dummyStatement.FalseBlock.Statements);
            }
            else
            {
                l.Add(first);
            }
            if (needsEndLabel)
            {
                l.Add(MakeLabel(endSwitchName));
            }

            return(l);
        }