protected internal override CSharpSwitchCase VisitSwitchCase(CSharpSwitchCase node)
        {
            var statements = VisitSequence(node.Statements);

            return(node.Update(statements));
        }
 public CSharpSwitchCaseProxy(CSharpSwitchCase node)
 {
     _node = node;
 }
        protected internal override CSharpSwitchCase VisitSwitchCase(CSharpSwitchCase node)
        {
            var statements = VisitSequence(node.Statements);

            return node.Update(statements);
        }
            public void EnsureLonelyDefault()
            {
                if (DefaultCase != null && !IsDefaultLonely)
                {
                    // We have a default case but it's mingled up with other cases, e.g.
                    //
                    //   switch (x)
                    //   {
                    //     case 1:
                    //     case 2:
                    //     case default:
                    //       ...
                    //       break;
                    //   }
                    //
                    // We can simply drop the other test values for compilation purposes, e.g.
                    //
                    //  switch (x)
                    //  {
                    //    case default:
                    //       ...
                    //       break;
                    //  }

                    var roDefaultTestValues = new TrueReadOnlyCollection<object>(new[] { SwitchCaseDefaultValue });
                    var newDefaultCase = new CSharpSwitchCase(roDefaultTestValues, DefaultCase.Statements);

                    if (DefaultCase == NullCase)
                    {
                        NullCase = null;
                        IsNullLonely = false;
                    }

                    DefaultCase = newDefaultCase;
                    IsDefaultLonely = true;
                }
            }
            public void Analyze(CSharpSwitchCase @case)
            {
                Debug.Assert(_info.HasGotoDefault == false);
                Debug.Assert(_info.GotoCases == null);

                foreach (var stmt in @case.Statements)
                {
                    Visit(stmt);
                }

                if (_info.GotoCases == null)
                {
                    _info.GotoCases = (s_empty ?? (s_empty = new HashSet<object>()));
                }

                SwitchCaseInfos.Add(@case, _info);

                _info = default(SwitchCaseInfo);
            }
 private static SwitchCase ConvertSwitchCase(CSharpSwitchCase @case, Type type)
 {
     return Expression.SwitchCase(MakeBlock(@case.Statements), @case.TestValues.Select(testValue => Expression.Constant(testValue, type)));
 }
        private static IList<CSharpSwitchCase> ReduceGotos(IList<CSharpSwitchCase> cases)
        {
            var testValueToCaseMap = new Dictionary<object, CSharpSwitchCase>();

            var analyzer = new SwitchCaseGotoAnalyzer();

            var defaultCase = default(CSharpSwitchCase);

            foreach (var @case in cases)
            {
                foreach (var testValue in @case.TestValues)
                {
                    if (testValue == SwitchCaseDefaultValue)
                    {
                        defaultCase = @case;
                    }

                    testValueToCaseMap.Add(testValue.OrNullSentinel(), @case);
                }

                analyzer.Analyze(@case);
            }

            var caseHasJumpInto = new HashSet<CSharpSwitchCase>();

            foreach (var info in analyzer.SwitchCaseInfos.Values)
            {
                if (info.HasGotoDefault)
                {
                    if (defaultCase == null)
                    {
                        throw Error.InvalidGotoDefault();
                    }

                    caseHasJumpInto.Add(defaultCase);
                }

                foreach (var gotoCase in info.GotoCases)
                {
                    var @case = default(CSharpSwitchCase);
                    if (!testValueToCaseMap.TryGetValue(gotoCase.OrNullSentinel(), out @case))
                    {
                        throw Error.InvalidGotoCase(gotoCase.ToDebugString());
                    }

                    caseHasJumpInto.Add(@case);
                }
            }

            if (caseHasJumpInto.Count > 0)
            {
                var caseJumpTargets = new Dictionary<CSharpSwitchCase, LabelTarget>();
                var defaultJumpTarget = default(LabelTarget);

                foreach (var @case in caseHasJumpInto)
                {
                    var label = default(LabelTarget);

                    if (@case == defaultCase)
                    {
                        label = defaultJumpTarget = Expression.Label("__default");
                    }
                    else
                    {
                        label = Expression.Label(FormattableString.Invariant($"__case<{@case.TestValues[0].ToDebugString()}>"));
                    }

                    caseJumpTargets.Add(@case, label);
                }

                var rewriter = new SwitchCaseRewriter(testValue => caseJumpTargets[testValueToCaseMap[testValue.OrNullSentinel()]], defaultJumpTarget);

                var newCases = new CSharpSwitchCase[cases.Count];

                var i = 0;
                foreach (var @case in cases)
                {
                    var newBody = rewriter.Visit(@case.Statements);

                    var jumpTarget = default(LabelTarget);
                    if (caseJumpTargets.TryGetValue(@case, out jumpTarget))
                    {
                        newBody = newBody.AddFirst(Expression.Label(jumpTarget)).ToReadOnly();
                    }

                    newCases[i++] = @case.Update(newBody);
                }

                return newCases;
            }
            else
            {
                return cases;
            }
        }