Esempio n. 1
0
        private static ExpressionSyntax caseExpression(SwitchLabelSyntax label, ExpressionSyntax control, out bool isDefault)
        {
            isDefault = label.Keyword.Kind() == SyntaxKind.DefaultKeyword;

            var caseLabel = label as CaseSwitchLabelSyntax;

            if (caseLabel != null)
            {
                var result = caseLabel.Value;
                if (result is BinaryExpressionSyntax)
                {
                    var expr = result as BinaryExpressionSyntax;
                    if (expr.Left.IsMissing)
                    {
                        return(CSharp.BinaryExpression(expr.Kind(), control, expr.Right));
                    }

                    return(expr);
                }

                return(CSharp.BinaryExpression(SyntaxKind.EqualsExpression, control, result));
            }

            Debug.Assert(isDefault);
            return(null);
        }
            public int Compare(SwitchLabelSyntax x, SwitchLabelSyntax y)
            {
                if (object.ReferenceEquals(x, y))
                {
                    return(0);
                }

                if (x == null)
                {
                    return(-1);
                }

                if (y == null)
                {
                    return(1);
                }

                var label1 = (CaseSwitchLabelSyntax)x;
                var label2 = ((CaseSwitchLabelSyntax)y);

                string value1 = ((LiteralExpressionSyntax)label1.Value).Token.ValueText;
                string value2 = ((LiteralExpressionSyntax)label2.Value).Token.ValueText;

                return(StringComparer.CurrentCulture.Compare(value1, value2));
            }
Esempio n. 3
0
 protected override IValue VisitCaseSwitchLabel(SwitchLabelSyntax node)
 {
     // todo: update
     throw new NotImplementedException();
     //var value = Visit(node.Value);
     //return new CsharpSwichLabel(value, false);
 }
        public static void AnalyzeSwitchSection(SyntaxNodeAnalysisContext context)
        {
            var switchSection = (SwitchSectionSyntax)context.Node;

            SyntaxList <SwitchLabelSyntax> labels = switchSection.Labels;

            int count = labels.Count;

            if (count <= 1)
            {
                return;
            }

            SwitchLabelSyntax lastLabel = labels.Last();

            for (int i = 0; i < count - 1; i++)
            {
                SwitchLabelSyntax label = labels[i];

                if (label.Kind() == SyntaxKind.DefaultSwitchLabel)
                {
                    TextSpan span = TextSpan.FromBounds(label.Span.End, lastLabel.SpanStart);

                    if (!switchSection.ContainsDirectives(span))
                    {
                        context.ReportDiagnostic(
                            DiagnosticDescriptors.DefaultLabelShouldBeLastLabelInSwitchSection,
                            label);

                        break;
                    }
                }
            }
        }
        static SwitchSectionSyntax CreateSection(SwitchLabelSyntax label, StatementSyntax statement)
        {
            var labels = new SyntaxList <SwitchLabelSyntax>();

            labels = labels.Add(label);
            return(SyntaxFactory.SwitchSection(labels, CreateSectionStatements(statement)));
        }
Esempio n. 6
0
            public override SyntaxList <StatementSyntax> VisitSelectBlock(VBSyntax.SelectBlockSyntax node)
            {
                var expr = (ExpressionSyntax)node.SelectStatement.Expression.Accept(_nodesVisitor);
                var exprWithoutTrivia = expr.WithoutTrivia().WithoutAnnotations();
                var sections          = new List <SwitchSectionSyntax>();

                foreach (var block in node.CaseBlocks)
                {
                    var labels = new List <SwitchLabelSyntax>();
                    foreach (var c in block.CaseStatement.Cases)
                    {
                        if (c is VBSyntax.SimpleCaseClauseSyntax s)
                        {
                            var expressionSyntax = (ExpressionSyntax)s.Value.Accept(_nodesVisitor);
                            SwitchLabelSyntax caseSwitchLabelSyntax = SyntaxFactory.CaseSwitchLabel(expressionSyntax);
                            if (!_semanticModel.GetConstantValue(s.Value).HasValue)
                            {
                                caseSwitchLabelSyntax =
                                    WrapInCasePatternSwitchLabelSyntax(expressionSyntax);
                            }

                            labels.Add(caseSwitchLabelSyntax);
                        }
                        else if (c is VBSyntax.ElseCaseClauseSyntax)
                        {
                            labels.Add(SyntaxFactory.DefaultSwitchLabel());
                        }
                        else if (c is VBSyntax.RelationalCaseClauseSyntax relational)
                        {
                            var operatorKind     = VBasic.VisualBasicExtensions.Kind(relational);
                            var cSharpSyntaxNode = SyntaxFactory.BinaryExpression(operatorKind.ConvertToken(TokenContext.Local), exprWithoutTrivia, (ExpressionSyntax)relational.Value.Accept(_nodesVisitor));
                            labels.Add(WrapInCasePatternSwitchLabelSyntax(cSharpSyntaxNode));
                        }
                        else if (c is VBSyntax.RangeCaseClauseSyntax range)
                        {
                            var lowerBoundCheck = SyntaxFactory.BinaryExpression(SyntaxKind.LessThanOrEqualExpression, (ExpressionSyntax)range.LowerBound.Accept(_nodesVisitor), exprWithoutTrivia);
                            var upperBoundCheck = SyntaxFactory.BinaryExpression(SyntaxKind.LessThanOrEqualExpression, exprWithoutTrivia, (ExpressionSyntax)range.UpperBound.Accept(_nodesVisitor));
                            var withinBounds    = SyntaxFactory.BinaryExpression(SyntaxKind.LogicalAndExpression, lowerBoundCheck, upperBoundCheck);
                            labels.Add(WrapInCasePatternSwitchLabelSyntax(withinBounds));
                        }
                        else
                        {
                            throw new NotSupportedException(c.Kind().ToString());
                        }
                    }

                    var csBlockStatements = block.Statements.SelectMany(s => s.Accept(CommentConvertingVisitor)).ToList();
                    if (csBlockStatements.LastOrDefault()
                        ?.IsKind(SyntaxKind.ReturnStatement) != true)
                    {
                        csBlockStatements.Add(SyntaxFactory.BreakStatement());
                    }
                    var list = SingleStatement(SyntaxFactory.Block(csBlockStatements));
                    sections.Add(SyntaxFactory.SwitchSection(SyntaxFactory.List(labels), list));
                }

                var switchStatementSyntax = SyntaxFactory.SwitchStatement(expr, SyntaxFactory.List(sections));

                return(SingleStatement(switchStatementSyntax));
            }
        private static void AnalyzeSwitchSection(SyntaxNodeAnalysisContext context)
        {
            var switchSection = (SwitchSectionSyntax)context.Node;

            SwitchLabelSyntax label = switchSection.Labels.LastOrDefault();

            if (label == null)
            {
                return;
            }

            StatementSyntax statement = switchSection.Statements.FirstOrDefault();

            if (statement == null)
            {
                return;
            }

            if (!switchSection.SyntaxTree.IsSingleLineSpan(TextSpan.FromBounds(label.Span.End, statement.SpanStart)))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(
                context,
                DiagnosticRules.AddNewLineAfterSwitchLabel,
                Location.Create(statement.SyntaxTree, statement.Span.WithLength(0)));
        }
Esempio n. 8
0
        private static bool IsDefaultLabel(SyntaxNodeAnalysisContext context, SwitchLabelSyntax switchLabel)
        {
            switch (switchLabel.Kind())
            {
            case SyntaxKind.DefaultSwitchLabel:
                return(true);

            case SyntaxKind.CasePatternSwitchLabel:
            {
                var casePatternSwitchLabel = (CasePatternSwitchLabelSyntax)switchLabel;

                var condition = casePatternSwitchLabel.WhenClause?.Condition;
                if (condition != null)
                {
                    var constantValue = context.SemanticModel.GetConstantValue(condition, context.CancellationToken);
                    return(constantValue.HasValue &&
                           constantValue.Value is bool boolValue &&
                           boolValue);
                }

                return(casePatternSwitchLabel.Pattern.IsKind(SyntaxKind.VarPattern));
            }

            default:
                return(false);
            }
        }
        public static bool IsDefaultSwitchLabel(SwitchLabelSyntax node)
        {
            // default:
            if (node.IsKind(SyntaxKind.DefaultSwitchLabel))
            {
                return(true);
            }

            if (node.IsKind(SyntaxKind.CasePatternSwitchLabel, out CasePatternSwitchLabelSyntax? @case))
            {
                // case _:
                if (@case.Pattern.IsKind(SyntaxKind.DiscardPattern))
                {
                    return(@case.WhenClause == null);
                }

                // case var _:
                // case var x:
                if (@case.Pattern.IsKind(SyntaxKind.VarPattern, out VarPatternSyntax? varPattern) &&
                    varPattern.Designation.IsKind(SyntaxKind.DiscardDesignation, SyntaxKind.SingleVariableDesignation))
                {
                    return(@case.WhenClause == null);
                }
            }

            return(false);
        }
Esempio n. 10
0
        private static async Task <Document> MoveDefaultLabelToLastPositionAsync(
            Document document,
            SwitchSectionSyntax switchSection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxList <SwitchLabelSyntax> labels = switchSection.Labels;

            SwitchLabelSyntax defaultLabel = labels.First(f => f.IsKind(SyntaxKind.DefaultSwitchLabel));

            int index = labels.IndexOf(defaultLabel);

            SwitchLabelSyntax lastLabel = labels.Last();

            labels = labels.Replace(lastLabel, defaultLabel.WithTriviaFrom(lastLabel));

            labels = labels.Replace(labels[index], lastLabel.WithTriviaFrom(defaultLabel));

            SwitchSectionSyntax newSwitchSection = switchSection.WithLabels(labels);

            SyntaxNode newRoot = root.ReplaceNode(switchSection, newSwitchSection);

            return(document.WithSyntaxRoot(newRoot));
        }
        private static SwitchSectionSyntax CreateSection(SwitchLabelSyntax label, StatementSyntax statement)
        {
            var labels = new SyntaxList<SwitchLabelSyntax>();
            labels = labels.Add(label);

            return SyntaxFactory.SwitchSection(
                labels, CreateSectionStatements(statement)
                );
        }
Esempio n. 12
0
        public void TestConversionsNull()
        {
            var syntaxNode = default(SyntaxNode);
            var wrapper    = (CasePatternSwitchLabelSyntaxWrapper)syntaxNode;

            SwitchLabelSyntax syntax = wrapper;

            Assert.Null(syntax);
        }
Esempio n. 13
0
        private static TextSpan?TryCreateSpanForSwitchLabel(SwitchLabelSyntax switchLabel, int position)
        {
            if (switchLabel.Parent is not SwitchSectionSyntax switchSection || switchSection.Statements.Count == 0)
            {
                return(null);
            }

            return(TryCreateSpanForNode(switchSection.Statements[0], position));
        }
Esempio n. 14
0
        public void TestConversions()
        {
            var syntaxNode = this.CreateCasePatternSwitchLabel();
            var wrapper    = (CasePatternSwitchLabelSyntaxWrapper)syntaxNode;

            SwitchLabelSyntax syntax = wrapper;

            Assert.Same(syntaxNode, syntax);
        }
Esempio n. 15
0
        private static TextSpan? TryCreateSpanForSwitchLabel(SwitchLabelSyntax switchLabel, int position)
        {
            var switchSection = switchLabel.Parent as SwitchSectionSyntax;
            if (switchSection == null || switchSection.Statements.Count == 0)
            {
                return null;
            }

            return TryCreateSpanForNode(switchSection.Statements[0], position);
        }
Esempio n. 16
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CaseSwitchLabel:
            {
                var  caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                bool wasExpression;
                var  pattern = sectionBinder.BindConstantPattern(
                    node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                bool hasErrors     = pattern.HasErrors;
                var  constantValue = pattern.ConstantValue;
                if (!hasErrors &&
                    (object)constantValue != null &&
                    pattern.Value.Type == SwitchGoverningType &&
                    this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                    hasErrors = true;
                }
                return(new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors));
            }

            case SyntaxKind.DefaultSwitchLabel:
            {
                var  defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                var  pattern            = new BoundWildcardPattern(node);
                bool hasErrors          = pattern.HasErrors;
                if (defaultLabel != null)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                    hasErrors = true;
                }

                // Note that this is semantically last! The caller will place it in the decision tree
                // in the final position.
                defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                return(defaultLabel);
            }

            case SyntaxKind.CasePatternSwitchLabel:
            {
                var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                var pattern          = sectionBinder.BindPattern(
                    matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, label, pattern,
                                                   matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors));
            }

            default:
                throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
Esempio n. 17
0
 public static string SwitchLabel(SwitchLabelSyntax label)
 {
     if (label.CaseOrDefaultKeyword.IsKind(SyntaxKind.CaseKeyword))
     {
         return("case " + SyntaxNode(label.Value) + ":" + NewLine);
     }
     if (label.CaseOrDefaultKeyword.IsKind(SyntaxKind.DefaultKeyword))
     {
         return("default:" + NewLine);
     }
     return("");
 }
Esempio n. 18
0
 public static string SwitchLabel(SwitchLabelSyntax label)
 {
     if (label.CaseOrDefaultKeyword.IsKind(SyntaxKind.CaseKeyword))
     {
         return "case " + SyntaxNode(label.Value) + ":" + NewLine;
     }
     if (label.CaseOrDefaultKeyword.IsKind(SyntaxKind.DefaultKeyword))
     {
         return "default:" + NewLine;
     }
     return "";
 }
Esempio n. 19
0
        public static void Write(this SwitchLabelSyntax syntax, IIndentedTextWriterWrapper textWriter, IContext context)
        {
            var caseSwitch = syntax as CaseSwitchLabelSyntax;

            if (caseSwitch != null)
            {
                caseSwitch.Write(textWriter, context);
                return;
            }

            var defaultSwitch = (DefaultSwitchLabelSyntax)syntax;

            defaultSwitch.Write(textWriter, context);
        }
Esempio n. 20
0
        public static Statement Create(Context cx, SwitchLabelSyntax node, Switch parent, int child)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CaseSwitchLabel:
                return(CaseLabel.Create(cx, (CaseSwitchLabelSyntax)node, parent, child));

            case SyntaxKind.DefaultSwitchLabel:
                return(CaseDefault.Create(cx, (DefaultSwitchLabelSyntax)node, parent, child));

            case SyntaxKind.CasePatternSwitchLabel:
                return(CasePattern.Create(cx, (CasePatternSwitchLabelSyntax)node, parent, child));

            default:
                throw new InternalError(node, "Unhandled case label");
            }
        }
        private BoundSwitchLabel BindSwitchLabel(SwitchLabelSyntax syntax)
        {
            BoundExpression boundExpression;

            switch (syntax.Kind)
            {
            case SyntaxKind.CaseSwitchLabel:
                var caseSwitchLabel = (CaseSwitchLabelSyntax)syntax;
                boundExpression = Bind(caseSwitchLabel.Value, BindExpression);
                break;

            case SyntaxKind.DefaultSwitchLabel:
                boundExpression = null;
                break;

            default:
                throw new InvalidOperationException();
            }
            return(new BoundSwitchLabel(boundExpression));
        }
Esempio n. 22
0
        public static bool CanRefactor(SyntaxNodeAnalysisContext context, SwitchSectionSyntax switchSection)
        {
            SwitchLabelSyntax label = switchSection.Labels.LastOrDefault();

            if (label != null)
            {
                ImmutableArray <Diagnostic> diagnostics = context.SemanticModel.GetDiagnostics(label.Span, context.CancellationToken);

                for (int i = 0; i < diagnostics.Length; i++)
                {
                    switch (diagnostics[i].Id)
                    {
                    case "CS0163":
                    case "CS8070":
                        return(true);
                    }
                }
            }

            return(false);
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, SwitchSectionSyntax switchSection)
        {
            SyntaxList <SwitchLabelSyntax> labels = switchSection.Labels;

            for (int i = 0; i < labels.Count - 1; i++)
            {
                SwitchLabelSyntax label = labels[i];

                if (label.IsKind(SyntaxKind.DefaultSwitchLabel))
                {
                    TextSpan span = TextSpan.FromBounds(label.Span.End, labels.Last().Span.Start);

                    if (!switchSection.ContainsDirectives(span))
                    {
                        context.ReportDiagnostic(
                            DiagnosticDescriptors.DefaultLabelShouldBeLastLabelInSwitchSection,
                            label);
                    }
                }
            }
        }
            private static PatternSyntax GetPattern(SwitchLabelSyntax switchLabel, out WhenClauseSyntax whenClauseOpt)
            {
                switch (switchLabel.Kind())
                {
                case SyntaxKind.CasePatternSwitchLabel:
                    var node = (CasePatternSwitchLabelSyntax)switchLabel;
                    whenClauseOpt = node.WhenClause;
                    return(node.Pattern);

                case SyntaxKind.CaseSwitchLabel:
                    whenClauseOpt = null;
                    return(ConstantPattern(((CaseSwitchLabelSyntax)switchLabel).Value));

                case SyntaxKind.DefaultSwitchLabel:
                    whenClauseOpt = null;
                    return(DiscardPattern());

                case var value:
                    throw ExceptionUtilities.UnexpectedValue(value);
                }
            }
        public static async Task <Document> RefactorAsync(
            Document document,
            SwitchSectionSyntax switchSection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            SyntaxList <SwitchLabelSyntax> labels = switchSection.Labels;

            SwitchLabelSyntax defaultLabel = labels.First(f => f.IsKind(SyntaxKind.DefaultSwitchLabel));

            int index = labels.IndexOf(defaultLabel);

            SwitchLabelSyntax lastLabel = labels.Last();

            labels = labels.Replace(lastLabel, defaultLabel.WithTriviaFrom(lastLabel));

            labels = labels.Replace(labels[index], lastLabel.WithTriviaFrom(defaultLabel));

            SwitchSectionSyntax newSwitchSection = switchSection.WithLabels(labels);

            return(await document.ReplaceNodeAsync(switchSection, newSwitchSection, cancellationToken).ConfigureAwait(false));
        }
        private static Task <Document> CopySwitchSectionAsync(
            Document document,
            SwitchSectionSyntax switchSection,
            bool insertNewLine,
            CancellationToken cancellationToken)
        {
            var switchStatement = (SwitchStatementSyntax)switchSection.Parent;

            SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections;

            int index = sections.IndexOf(switchSection);

            SwitchLabelSyntax label = switchSection.Labels[0];

            SyntaxToken firstToken = label.GetFirstToken();

            SyntaxToken newFirstToken = firstToken.WithNavigationAnnotation();

            if (insertNewLine &&
                !firstToken.LeadingTrivia.Contains(SyntaxKind.EndOfLineTrivia))
            {
                newFirstToken = newFirstToken.PrependToLeadingTrivia(CSharpFactory.NewLine());
            }

            SwitchSectionSyntax newSection = switchSection
                                             .WithLabels(switchSection.Labels.ReplaceAt(0, label.ReplaceToken(firstToken, newFirstToken)))
                                             .WithFormatterAnnotation();

            if (index == sections.Count - 1)
            {
                newSection = newSection.TrimTrailingTrivia();
            }

            SyntaxList <SwitchSectionSyntax> newSections = sections.Insert(index + 1, newSection);

            SwitchStatementSyntax newSwitchStatement = switchStatement.WithSections(newSections);

            return(document.ReplaceNodeAsync(switchStatement, newSwitchStatement, cancellationToken));
        }
Esempio n. 27
0
        private static BoundPatternSwitchLabel BindPatternSwitchSectionLabel(Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, ref DefaultSwitchLabelSyntax defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors);
                    }

                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
                        }

                        defaultLabel = defaultLabelSyntax;
                        return new BoundPatternSwitchLabel(node, pattern, null, node.HasErrors); // note that this is semantically last!
                    }

                default:
                    throw ExceptionUtilities.Unreachable;
            }
        }
Esempio n. 28
0
        private static ExpressionSyntax caseExpression(SwitchLabelSyntax label, ExpressionSyntax control, out bool isDefault)
        {
            isDefault = label.Keyword.Kind() == SyntaxKind.DefaultKeyword;

            var caseLabel = label as CaseSwitchLabelSyntax;
            if (caseLabel != null)
            {
                var result = caseLabel.Value;
                if (result is BinaryExpressionSyntax)
                {
                    var expr = result as BinaryExpressionSyntax;
                    if (expr.Left.IsMissing)
                        return CSharp.BinaryExpression(expr.Kind(), control, expr.Right);

                    return expr;
                }

                return CSharp.BinaryExpression(SyntaxKind.EqualsExpression, control, result);
            }

            Debug.Assert(isDefault);
            return null;
        }
Esempio n. 29
0
 public BoundSwitchLabel(SwitchLabelSyntax syntax, BoundExpression expression)
     : base(BoundNodeKind.SwitchLabel, syntax)
 {
     Expression = expression;
 }
Esempio n. 30
0
        private BoundSwitchLabel BindSwitchSectionLabel(SwitchLabelSyntax node, Binder sectionBinder, DiagnosticBag diagnostics)
        {
            var switchGoverningType = GetSwitchGoverningType(diagnostics);
            BoundExpression boundLabelExpressionOpt = null;

            SourceLabelSymbol boundLabelSymbol = null;
            ConstantValue labelExpressionConstant = null;
            List<SourceLabelSymbol> matchedLabelSymbols;

            // Prevent cascading diagnostics
            bool hasErrors = node.HasErrors;

            switch (node.Kind())
            {
                case SyntaxKind.CaseSwitchLabel:
                var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                // Bind the label case expression
                boundLabelExpressionOpt = sectionBinder.BindValue(caseLabelSyntax.Value, diagnostics, BindValueKind.RValue);

                boundLabelExpressionOpt = ConvertCaseExpression(switchGoverningType, caseLabelSyntax, boundLabelExpressionOpt, sectionBinder, ref labelExpressionConstant, diagnostics);

                // Check for bind errors
                hasErrors = hasErrors || boundLabelExpressionOpt.HasAnyErrors;


                // SPEC:    The constant expression of each case label must denote a value that
                // SPEC:    is implicitly convertible (§6.1) to the governing type of the switch statement.

                // Prevent cascading diagnostics
                if (!hasErrors && labelExpressionConstant == null)
                {
                    diagnostics.Add(ErrorCode.ERR_ConstantExpected, caseLabelSyntax.Location);
                    hasErrors = true;
                }

                // LabelSymbols for all the switch case labels are created by BuildLabels().
                // Fetch the matching switch case label symbols
                matchedLabelSymbols = FindMatchingSwitchCaseLabels(labelExpressionConstant, caseLabelSyntax);
                    break;
                case SyntaxKind.CasePatternSwitchLabel:
                    // pattern matching in case is not yet implemented.
                    if (!node.HasErrors)
                    {
                        Error(diagnostics, ErrorCode.ERR_FeatureIsUnimplemented, node, MessageID.IDS_FeaturePatternMatching.Localize());
                        hasErrors = true;
                    }
                    matchedLabelSymbols = new List<SourceLabelSymbol>();
                    break;
                case SyntaxKind.DefaultSwitchLabel:
                matchedLabelSymbols = GetDefaultLabels();
                    break;
                default:
                    throw ExceptionUtilities.Unreachable;
            }

            // Get the corresponding matching label symbol created during BuildLabels()
            // and also check for duplicate case labels.

            Debug.Assert(hasErrors || !matchedLabelSymbols.IsEmpty());
            bool first = true;
            bool hasDuplicateErrors = false;
            foreach (SourceLabelSymbol label in matchedLabelSymbols)
            {
                if (node.Equals(label.IdentifierNodeOrToken.AsNode()))
                {
                    // we must have exactly one matching label created during BuildLabels()
                    boundLabelSymbol = label;

                    // SPEC:    A compile-time error occurs if two or more case labels
                    // SPEC:    in the same switch statement specify the same constant value.

                    if (!hasErrors && !first)
                    {
                        // Skipping the first label symbol ensures that the errors (if any),
                        // are reported on all but the first duplicate case label.
                        diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location,
                            label.SwitchCaseLabelConstant?.Value ?? label.Name);
                        hasDuplicateErrors = true;
                    }
                    break;
                }
                first = false;
            }

            if ((object)boundLabelSymbol == null)
            {
                Debug.Assert(hasErrors);
                boundLabelSymbol = new SourceLabelSymbol((MethodSymbol)this.ContainingMemberOrLambda, node, labelExpressionConstant);
            }

            return new BoundSwitchLabel(
                syntax: node,
                label: boundLabelSymbol,
                expressionOpt: boundLabelExpressionOpt,
                hasErrors: hasErrors || hasDuplicateErrors);
        }
 public ILabelSymbol?ToSymbol(SwitchLabelSyntax node)
 => Model.GetDeclaredSymbol(node, CancellationToken);
Esempio n. 32
0
 public SwitchLabelTranslation(SwitchLabelSyntax syntax, SyntaxTranslation parent) : base(syntax, parent)
 {
 }
Esempio n. 33
0
 public static SwitchSectionSyntax Section(SwitchLabelSyntax label, params StatementSyntax[] statements)
 {
     return(SyntaxFactory.SwitchSection(SyntaxFactory.List(new[] { label }), SyntaxFactory.List(statements)));
 }
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        bool hasErrors = pattern.HasErrors;
                        var constantValue = pattern.ConstantValue;
                        if (!hasErrors && (object)constantValue != null && this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                            hasErrors = true;
                        }
                        return new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        bool hasErrors = pattern.HasErrors;
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, "default");
                            hasErrors = true;
                        }

                        // Note that this is semantically last! The caller will place it in the decision tree
                        // in the final position.
                        defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, hasErrors);
                        return defaultLabel;
                    }

                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, label, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null, node.HasErrors);
                    }

                default:
                    throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
        public SwitchLabelTranslation(SwitchLabelSyntax syntax, SyntaxTranslation parent) : base(syntax, parent)
        {

        }
 private static SwitchSectionSyntax CreateSection(SwitchLabelSyntax label)
 {
     return(SwitchSection(label, BreakStatement()).WithFormatterAnnotation());
 }
Esempio n. 37
0
 /// <summary>
 /// Given a switch label syntax, get the corresponding label symbol.
 /// </summary>
 /// <param name="declarationSyntax">The syntax node of the switch label.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The label symbol for that label.</returns>
 public abstract ILabelSymbol GetDeclaredSymbol(SwitchLabelSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken));
Esempio n. 38
0
        private BoundSwitchLabel BindSwitchSectionLabel(SwitchLabelSyntax node, Binder sectionBinder, LabelSymbol label, DiagnosticBag diagnostics)
        {
            var switchGoverningType = SwitchGoverningType;
            BoundExpression boundLabelExpressionOpt = null;
            ConstantValue labelExpressionConstant = null;

            // Prevent cascading diagnostics
            bool hasErrors = node.HasErrors;

            switch (node.Kind())
            {
                case SyntaxKind.CaseSwitchLabel:
                    var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                    // Bind the label case expression
                    boundLabelExpressionOpt = sectionBinder.BindValue(caseLabelSyntax.Value, diagnostics, BindValueKind.RValue);
                    boundLabelExpressionOpt = ConvertCaseExpression(caseLabelSyntax, boundLabelExpressionOpt, sectionBinder, ref labelExpressionConstant, diagnostics);

                    // Check for bind errors
                    hasErrors = hasErrors || boundLabelExpressionOpt.HasAnyErrors;

                    // SPEC:    The constant expression of each case label must denote a value that
                    // SPEC:    is implicitly convertible (§6.1) to the governing type of the switch statement.
                    if (!hasErrors && labelExpressionConstant == null)
                    {
                        diagnostics.Add(ErrorCode.ERR_ConstantExpected, caseLabelSyntax.Value.Location);
                        hasErrors = true;
                    }

                    if (!hasErrors && (object)labelExpressionConstant != null && FindMatchingSwitchCaseLabel(labelExpressionConstant, caseLabelSyntax) != label)
                    {
                        diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, labelExpressionConstant?.GetValueToDisplay() ?? label.Name);
                        hasErrors = true;
                    }

                    // LabelSymbols for all the switch case labels are created by BuildLabels().
                    // Fetch the matching switch case label symbols
                    break;
                case SyntaxKind.CasePatternSwitchLabel:
                    if (!node.HasErrors)
                    {
                        // This should not occur, because it would have been a syntax error
                        throw ExceptionUtilities.UnexpectedValue(node.Kind());
                    }
                    break;
                case SyntaxKind.DefaultSwitchLabel:
                    if (GetDefaultLabel() != label)
                    {
                        diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                        hasErrors = true;
                    }
                    break;
                default:
                    throw ExceptionUtilities.UnexpectedValue(node.Kind());
            }

            return new BoundSwitchLabel(
                syntax: node,
                label: label,
                expressionOpt: boundLabelExpressionOpt,
                constantValueOpt: labelExpressionConstant,
                hasErrors: hasErrors);
        }
            private IEnumerable<ITypeSymbol> InferTypeInSwitchLabel(
                SwitchLabelSyntax switchLabel, SyntaxToken? previousToken = null)
            {
                if (previousToken.HasValue)
                {
                    if (previousToken.Value != switchLabel.Keyword ||
                        switchLabel.CSharpKind() != SyntaxKind.CaseSwitchLabel)
                    {
                        return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
                    }
                }

                var switchStatement = (SwitchStatementSyntax)switchLabel.Parent.Parent;
                return GetTypes(switchStatement.Expression);
            }
Esempio n. 40
0
        public void VisitSwitchLabel(SwitchLabelSyntax node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            node.Validate();

            _writer.WriteIndent();

            switch (node.Kind)
            {
                case CaseOrDefault.Default:
                    _writer.WriteKeyword(PrinterKeyword.Default);
                    break;

                case CaseOrDefault.Case:
                    _writer.WriteKeyword(PrinterKeyword.Case);
                    _writer.WriteSpace();
                    node.Value.Accept(this);
                    break;
            }

            if (_writer.Configuration.Spaces.Other.BeforeColonInCaseStatement)
                _writer.WriteSpace();

            _writer.WriteSyntax(Syntax.Colon);
        }
Esempio n. 41
0
 private BoundSwitchLabel BindSwitchLabel(SwitchLabelSyntax syntax)
 {
     BoundExpression boundExpression;
     switch (syntax.Kind)
     {
         case SyntaxKind.CaseSwitchLabel:
             var caseSwitchLabel = (CaseSwitchLabelSyntax) syntax;
             boundExpression = Bind(caseSwitchLabel.Value, BindExpression);
             break;
         case SyntaxKind.DefaultSwitchLabel:
             boundExpression = null;
             break;
         default:
             throw new InvalidOperationException();
     }
     return new BoundSwitchLabel(boundExpression);
 }
Esempio n. 42
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
            case SyntaxKind.CaseSwitchLabel:
            {
                var  caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                bool wasExpression;
                var  pattern = sectionBinder.BindConstantPattern(
                    node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                bool hasErrors     = pattern.HasErrors;
                var  constantValue = pattern.ConstantValue;
                if (!hasErrors &&
                    (object)constantValue != null &&
                    pattern.Value.Type == SwitchGoverningType &&
                    this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                    hasErrors = true;
                }

                if (caseLabelSyntax.Value.Kind() == SyntaxKind.DefaultLiteralExpression)
                {
                    diagnostics.Add(ErrorCode.WRN_DefaultInSwitch, caseLabelSyntax.Value.Location);
                }

                // Until we've determined whether or not the switch label is reachable, we assume it
                // is. The caller updates isReachable after determining if the label is subsumed.
                const bool isReachable = true;
                return(new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors));
            }

            case SyntaxKind.DefaultSwitchLabel:
            {
                var  defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                var  pattern            = new BoundWildcardPattern(node);
                bool hasErrors          = pattern.HasErrors;
                if (defaultLabel != null)
                {
                    diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                    hasErrors = true;
                }

                // We always treat the default label as reachable, even if the switch is complete.
                const bool isReachable = true;

                // Note that this is semantically last! The caller will place it in the decision tree
                // in the final position.
                defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                return(defaultLabel);
            }

            case SyntaxKind.CasePatternSwitchLabel:
            {
                var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                var pattern          = sectionBinder.BindPattern(
                    matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                return(new BoundPatternSwitchLabel(node, label, pattern,
                                                   matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null,
                                                   true, node.HasErrors));
            }

            default:
                throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
Esempio n. 43
0
        public override ILabelSymbol GetDeclaredSymbol(SwitchLabelSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken))
        {
            CheckSyntaxNode(declarationSyntax);

            var binder = this.GetEnclosingBinder(GetAdjustedNodePosition(declarationSyntax));
            while (binder != null && !(binder is SwitchBinder))
            {
                binder = binder.Next;
            }

            if (binder != null)
            {
                foreach (var label in binder.Labels)
                {
                    if (label.IdentifierNodeOrToken.IsNode &&
                        label.IdentifierNodeOrToken.AsNode() == declarationSyntax)
                    {
                        return label;
                    }
                }
            }

            return null;
        }
Esempio n. 44
0
        private BoundPatternSwitchLabel BindPatternSwitchSectionLabel(
            Binder sectionBinder, BoundExpression boundSwitchExpression, SwitchLabelSyntax node, LabelSymbol label, ref BoundPatternSwitchLabel defaultLabel, DiagnosticBag diagnostics)
        {
            switch (node.Kind())
            {
                case SyntaxKind.CaseSwitchLabel:
                    {
                        var caseLabelSyntax = (CaseSwitchLabelSyntax)node;
                        bool wasExpression;
                        var pattern = sectionBinder.BindConstantPattern(
                            node, boundSwitchExpression, boundSwitchExpression.Type, caseLabelSyntax.Value, node.HasErrors, diagnostics, out wasExpression, wasSwitchCase: true);
                        bool hasErrors = pattern.HasErrors;
                        var constantValue = pattern.ConstantValue;
                        if (!hasErrors &&
                            (object)constantValue != null &&
                            pattern.Value.Type == SwitchGoverningType &&
                            this.FindMatchingSwitchCaseLabel(constantValue, caseLabelSyntax) != label)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, pattern.ConstantValue.GetValueToDisplay() ?? label.Name);
                            hasErrors = true;
                        }

                        // Until we've determined whether or not the switch label is reachable, we assume it
                        // is. The caller updates isReachable after determining if the label is subsumed.
                        const bool isReachable = true;
                        return new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                    }

                case SyntaxKind.DefaultSwitchLabel:
                    {
                        var defaultLabelSyntax = (DefaultSwitchLabelSyntax)node;
                        var pattern = new BoundWildcardPattern(node);
                        bool hasErrors = pattern.HasErrors;
                        if (defaultLabel != null)
                        {
                            diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location, label.Name);
                            hasErrors = true;
                        }

                        // We always treat the default label as reachable, even if the switch is complete.
                        const bool isReachable = true;

                        // Note that this is semantically last! The caller will place it in the decision tree
                        // in the final position.
                        defaultLabel = new BoundPatternSwitchLabel(node, label, pattern, null, isReachable, hasErrors);
                        return defaultLabel;
                    }

                case SyntaxKind.CasePatternSwitchLabel:
                    {
                        var matchLabelSyntax = (CasePatternSwitchLabelSyntax)node;
                        var pattern = sectionBinder.BindPattern(
                            matchLabelSyntax.Pattern, boundSwitchExpression, boundSwitchExpression.Type, node.HasErrors, diagnostics, wasSwitchCase: true);
                        return new BoundPatternSwitchLabel(node, label, pattern,
                            matchLabelSyntax.WhenClause != null ? sectionBinder.BindBooleanExpression(matchLabelSyntax.WhenClause.Condition, diagnostics) : null,
                            true, node.HasErrors);
                    }

                default:
                    throw ExceptionUtilities.UnexpectedValue(node);
            }
        }
Esempio n. 45
0
        /// <summary>
        /// Given a switch label syntax, get the corresponding label symbol.
        /// </summary>
        /// <param name="declarationSyntax">The syntax node of the switch label.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The label symbol for that label.</returns>
        public override ILabelSymbol GetDeclaredSymbol(SwitchLabelSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken))
        {
            using (Logger.LogBlock(FunctionId.CSharp_SemanticModel_GetDeclaredSymbol, message: this.SyntaxTree.FilePath, cancellationToken: cancellationToken))
            {
                CheckSyntaxNode(declarationSyntax);

                var memberModel = this.GetMemberModel(declarationSyntax);
                return memberModel == null ? null : memberModel.GetDeclaredSymbol(declarationSyntax, cancellationToken);
            }
        }
Esempio n. 46
0
 public static SwitchSectionSyntax Section(SwitchLabelSyntax label, params StatementSyntax[] statements)
 {
     return SyntaxFactory.SwitchSection(SyntaxFactory.List(new[] { label }), SyntaxFactory.List(statements));
 }
Esempio n. 47
0
        private BoundSwitchLabel BindSwitchSectionLabel(SwitchLabelSyntax node, DiagnosticBag diagnostics)
        {
            var switchGoverningType = GetSwitchGoverningType(diagnostics);
            BoundExpression boundLabelExpressionOpt = null;

            SourceLabelSymbol boundLabelSymbol = null;
            ConstantValue labelExpressionConstant = null;
            List<SourceLabelSymbol> matchedLabelSymbols;

            // Prevent cascading diagnostics
            bool hasErrors = node.HasErrors;

            if (node.Value != null)
            {
                Debug.Assert(node.Kind == SyntaxKind.CaseSwitchLabel);

                // Bind the label case expression
                boundLabelExpressionOpt = BindValue(node.Value, diagnostics, BindValueKind.RValue);

                boundLabelExpressionOpt = ConvertCaseExpression(switchGoverningType, node, boundLabelExpressionOpt, ref labelExpressionConstant, diagnostics);

                // Check for bind errors
                hasErrors = hasErrors || boundLabelExpressionOpt.HasAnyErrors;


                // SPEC:    The constant expression of each case label must denote a value that
                // SPEC:    is implicitly convertible (§6.1) to the governing type of the switch statement.

                // Prevent cascading diagnostics
                if (!hasErrors && labelExpressionConstant == null)
                {
                    diagnostics.Add(ErrorCode.ERR_ConstantExpected, node.Location);
                    hasErrors = true;
                }

                // LabelSymbols for all the switch case labels are created by BuildLabels().
                // Fetch the matching switch case label symbols
                matchedLabelSymbols = FindMatchingSwitchCaseLabels(labelExpressionConstant, node);
            }
            else
            {
                Debug.Assert(node.Kind == SyntaxKind.DefaultSwitchLabel);
                matchedLabelSymbols = GetDefaultLabels();
            }

            // Get the corresponding matching label symbol created during BuildLabels()
            // and also check for duplicate case labels.

            Debug.Assert(!matchedLabelSymbols.IsEmpty());
            bool first = true;
            bool hasDuplicateErrors = false;
            foreach (SourceLabelSymbol label in matchedLabelSymbols)
            {
                if (node.Equals(label.IdentifierNodeOrToken.AsNode()))
                {
                    // we must have exactly one matching label created during BuildLabels()
                    boundLabelSymbol = label;

                    // SPEC:    A compile-time error occurs if two or more case labels
                    // SPEC:    in the same switch statement specify the same constant value.

                    if (!hasErrors && !first)
                    {
                        // Skipping the first label symbol ensures that the errors (if any),
                        // are reported on all but the first duplicate case label.
                        diagnostics.Add(ErrorCode.ERR_DuplicateCaseLabel, node.Location,
                            label.SwitchCaseLabelConstant == null ? label.Name : label.SwitchCaseLabelConstant.Value);
                        hasDuplicateErrors = true;
                    }
                    break;
                }
                first = false;
            }

            if ((object)boundLabelSymbol == null)
            {
                Debug.Assert(hasErrors);
                boundLabelSymbol = new SourceLabelSymbol(this.Owner, node, labelExpressionConstant);
            }

            return new BoundSwitchLabel(
                syntax: node,
                label: boundLabelSymbol,
                expressionOpt: boundLabelExpressionOpt,
                hasErrors: hasErrors || hasDuplicateErrors);
        }
        /// <summary>
        /// Given a switch label syntax, get the corresponding label symbol.
        /// </summary>
        /// <param name="declarationSyntax">The syntax node of the switch label.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The label symbol for that label.</returns>
        public override ILabelSymbol GetDeclaredSymbol(SwitchLabelSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken))
        {
            CheckSyntaxNode(declarationSyntax);

            var memberModel = this.GetMemberModel(declarationSyntax);
            return memberModel == null ? null : memberModel.GetDeclaredSymbol(declarationSyntax, cancellationToken);
        }
        private static void AnalyzeSwitchStatement(SyntaxNodeAnalysisContext context)
        {
            var switchStatement = (SwitchStatementSyntax)context.Node;

            SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections;

            if (!sections.Any())
            {
                return;
            }

            ExpressionSyntax switchExpression = switchStatement.Expression;

            SingleLocalDeclarationStatementInfo localInfo = default;

            string name = GetName();

            if (name == null)
            {
                return;
            }

            ITypeSymbol kindSymbol = context.SemanticModel.GetTypeSymbol(switchExpression, context.CancellationToken);

            if (kindSymbol?.HasMetadataName(RoslynMetadataNames.Microsoft_CodeAnalysis_CSharp_SyntaxKind) != true)
            {
                return;
            }

            foreach (SwitchSectionSyntax section in sections)
            {
                SwitchLabelSyntax label = section.Labels.SingleOrDefault(shouldThrow: false);

                if (label == null)
                {
                    return;
                }

                SyntaxKind labelKind = label.Kind();

                if (labelKind == SyntaxKind.DefaultSwitchLabel)
                {
                    continue;
                }

                if (labelKind != SyntaxKind.CaseSwitchLabel)
                {
                    Debug.Assert(labelKind == SyntaxKind.CasePatternSwitchLabel, labelKind.ToString());
                    return;
                }

                var caseLabel = (CaseSwitchLabelSyntax)label;

                ExpressionSyntax value = caseLabel.Value;

                if (!value.IsKind(SyntaxKind.SimpleMemberAccessExpression))
                {
                    return;
                }

                var memberAccess = (MemberAccessExpressionSyntax)value;

                if (memberAccess.Name is not IdentifierNameSyntax identifierName)
                {
                    return;
                }

                string kindName = identifierName.Identifier.ValueText;

                if (!_syntaxKindNames.Contains(kindName))
                {
                    return;
                }

                SyntaxList <StatementSyntax> statements = section.Statements;

                StatementSyntax statement = statements.FirstOrDefault();

                if (statement == null)
                {
                    return;
                }

                if (statement is BlockSyntax block)
                {
                    statement = block.Statements.FirstOrDefault();
                }

                if (!statement.IsKind(SyntaxKind.LocalDeclarationStatement))
                {
                    return;
                }

                SingleLocalDeclarationStatementInfo localStatement = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)statement);

                if (!localStatement.Success)
                {
                    return;
                }

                if (localStatement.Value is not CastExpressionSyntax castExpression)
                {
                    return;
                }

                if (castExpression.Expression is not IdentifierNameSyntax localName)
                {
                    return;
                }

                if (name != localName.Identifier.ValueText)
                {
                    return;
                }

                if (!IsFixableSyntaxSymbol(castExpression.Type, kindName, context.SemanticModel, context.CancellationToken))
                {
                    return;
                }
            }

            if (localInfo.Success &&
                IsLocalVariableReferenced(context, localInfo, switchStatement))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.UsePatternMatching, switchStatement.SwitchKeyword);

            string GetName()
            {
                switch (switchExpression.Kind())
                {
                case SyntaxKind.IdentifierName:
                {
                    StatementSyntax previousStatement = switchStatement.PreviousStatement();

                    if (!previousStatement.IsKind(SyntaxKind.LocalDeclarationStatement))
                    {
                        return(null);
                    }

                    localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)previousStatement);

                    if (!localInfo.Success)
                    {
                        return(null);
                    }

                    if (localInfo.IdentifierText != ((IdentifierNameSyntax)switchExpression).Identifier.ValueText)
                    {
                        return(null);
                    }

                    if (!localInfo.Value.IsKind(SyntaxKind.InvocationExpression))
                    {
                        return(null);
                    }

                    return(GetName2((InvocationExpressionSyntax)localInfo.Value));
                }

                case SyntaxKind.InvocationExpression:
                {
                    return(GetName2((InvocationExpressionSyntax)switchExpression));
                }

                default:
                {
                    return(null);
                }
                }
            }