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(CSharpMetadataNames.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 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 CastExpressionSyntax castExpression))
                {
                    return;
                }

                if (!(castExpression.Expression is 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, DiagnosticDescriptors.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);
                }
                }
            }
Пример #2
0
        public static int GetInsertionIndex <TDeclaration>(
            SyntaxList <TDeclaration> declarationList,
            TDeclaration declaration,
            CodeGenerationOptions options,
            IList <bool> availableIndices,
            IComparer <TDeclaration> comparerWithoutNameCheck,
            IComparer <TDeclaration> comparerWithNameCheck,
            Func <SyntaxList <TDeclaration>, TDeclaration> after  = null,
            Func <SyntaxList <TDeclaration>, TDeclaration> before = null)
            where TDeclaration : SyntaxNode
        {
            Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1);

            if (options != null)
            {
                // Try to strictly obey the after option by inserting immediately after the member containing the location
                if (options.AfterThisLocation != null)
                {
                    var afterMember = declarationList.LastOrDefault(m => m.SpanStart <= options.AfterThisLocation.SourceSpan.Start);
                    if (afterMember != null)
                    {
                        var index = declarationList.IndexOf(afterMember);
                        index = GetPreferredIndex(index + 1, availableIndices, forward: true);
                        if (index != -1)
                        {
                            return(index);
                        }
                    }
                }

                // Try to strictly obey the before option by inserting immediately before the member containing the location
                if (options.BeforeThisLocation != null)
                {
                    var beforeMember = declarationList.FirstOrDefault(m => m.Span.End >= options.BeforeThisLocation.SourceSpan.End);
                    if (beforeMember != null)
                    {
                        var index = declarationList.IndexOf(beforeMember);
                        index = GetPreferredIndex(index, availableIndices, forward: false);
                        if (index != -1)
                        {
                            return(index);
                        }
                    }
                }

                if (options.AutoInsertionLocation)
                {
                    if (declarationList.IsEmpty())
                    {
                        return(0);
                    }

                    var desiredIndex = TryGetDesiredIndexIfGrouped(
                        declarationList, declaration, availableIndices,
                        comparerWithoutNameCheck, comparerWithNameCheck);
                    if (desiredIndex.HasValue)
                    {
                        return(desiredIndex.Value);
                    }

                    if (after != null)
                    {
                        var member = after(declarationList);
                        if (member != null)
                        {
                            var index = declarationList.IndexOf(member);
                            if (index >= 0)
                            {
                                index = GetPreferredIndex(index + 1, availableIndices, forward: true);
                                if (index != -1)
                                {
                                    return(index);
                                }
                            }
                        }
                    }

                    if (before != null)
                    {
                        var member = before(declarationList);
                        if (member != null)
                        {
                            var index = declarationList.IndexOf(member);

                            if (index >= 0)
                            {
                                index = GetPreferredIndex(index, availableIndices, forward: false);
                                if (index != -1)
                                {
                                    return(index);
                                }
                            }
                        }
                    }
                }
            }

            // Otherwise, add the declaration to the end.
            {
                var index = GetPreferredIndex(declarationList.Count, availableIndices, forward: false);
                if (index != -1)
                {
                    return(index);
                }
            }

            return(declarationList.Count);
        }
Пример #3
0
 public static MemberDeclarationSyntax FirstMember(SyntaxList <MemberDeclarationSyntax> members)
 {
     return(members.FirstOrDefault());
 }
Пример #4
0
 public static MemberDeclarationSyntax FirstMethod(SyntaxList <MemberDeclarationSyntax> members)
 {
     return(members.FirstOrDefault(m => m is MethodDeclarationSyntax));
 }
Пример #5
0
        public static int GetInsertionIndex <TDeclaration>(
            SyntaxList <TDeclaration> declarationList,
            TDeclaration declaration,
            CodeGenerationOptions options,
            IList <bool> availableIndices,
            Func <SyntaxList <TDeclaration>, TDeclaration> after  = null,
            Func <SyntaxList <TDeclaration>, TDeclaration> before = null)
            where TDeclaration : SyntaxNode
        {
            Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1);

            if (options != null)
            {
                // Try to strictly obey the after option by inserting immediately after the member containing the location
                if (options.AfterThisLocation != null)
                {
                    var afterMember = declarationList.LastOrDefault(m => m.SpanStart <= options.AfterThisLocation.SourceSpan.Start);
                    if (afterMember != null)
                    {
                        var index = declarationList.IndexOf(afterMember);
                        index = GetPreferredIndex(index + 1, availableIndices, forward: true);
                        if (index != -1)
                        {
                            return(index);
                        }
                    }
                }

                // Try to strictly obey the before option by inserting immediately before the member containing the location
                if (options.BeforeThisLocation != null)
                {
                    var beforeMember = declarationList.FirstOrDefault(m => m.Span.End >= options.BeforeThisLocation.SourceSpan.End);
                    if (beforeMember != null)
                    {
                        var index = declarationList.IndexOf(beforeMember);
                        index = GetPreferredIndex(index, availableIndices, forward: false);
                        if (index != -1)
                        {
                            return(index);
                        }
                    }
                }

                if (options.AutoInsertionLocation)
                {
                    if (declarationList.IsEmpty())
                    {
                        return(0);
                    }
                    else if (declarationList.IsSorted(CSharpDeclarationComparer.Instance))
                    {
                        var result = Array.BinarySearch(declarationList.ToArray(), declaration, CSharpDeclarationComparer.Instance);
                        var index  = GetPreferredIndex(result < 0 ? ~result : result, availableIndices, forward: true);
                        if (index != -1)
                        {
                            return(index);
                        }
                    }

                    if (after != null)
                    {
                        var member = after(declarationList);
                        if (member != null)
                        {
                            var index = declarationList.IndexOf(member);
                            if (index >= 0)
                            {
                                index = GetPreferredIndex(index + 1, availableIndices, forward: true);
                                if (index != -1)
                                {
                                    return(index);
                                }
                            }
                        }
                    }

                    if (before != null)
                    {
                        var member = before(declarationList);
                        if (member != null)
                        {
                            var index = declarationList.IndexOf(member);

                            if (index >= 0)
                            {
                                index = GetPreferredIndex(index, availableIndices, forward: false);
                                if (index != -1)
                                {
                                    return(index);
                                }
                            }
                        }
                    }
                }
            }

            // Otherwise, add the declaration to the end.
            {
                var index = GetPreferredIndex(declarationList.Count, availableIndices, forward: false);
                if (index != -1)
                {
                    return(index);
                }
            }

            return(declarationList.Count);
        }
 public static MemberDeclarationSyntax?FirstMethod(SyntaxList <MemberDeclarationSyntax> members)
 => members.FirstOrDefault(m => m is MethodDeclarationSyntax);
 public static MemberDeclarationSyntax?FirstMember(SyntaxList <MemberDeclarationSyntax> members)
 => members.FirstOrDefault();
Пример #8
0
        private bool TryRemoveSummaryPrefix(ref SyntaxList <XmlNodeSyntax> summaryContent, string prefix)
        {
            XmlNodeSyntax firstContent = summaryContent.FirstOrDefault(IsContentElement);
            XmlTextSyntax firstText    = firstContent as XmlTextSyntax;

            if (firstText == null)
            {
                return(false);
            }

            string firstTextContent = string.Concat(firstText.DescendantTokens());

            if (!firstTextContent.TrimStart().StartsWith(prefix, StringComparison.Ordinal))
            {
                return(false);
            }

            // Find the token containing the prefix, such as "Gets or sets "
            SyntaxToken prefixToken = default(SyntaxToken);

            foreach (SyntaxToken textToken in firstText.TextTokens)
            {
                if (textToken.IsMissing)
                {
                    continue;
                }

                if (!textToken.Text.TrimStart().StartsWith(prefix, StringComparison.Ordinal))
                {
                    continue;
                }

                prefixToken = textToken;
                break;
            }

            if (prefixToken.IsMissingOrDefault())
            {
                return(false);
            }

            string text      = prefixToken.Text;
            string valueText = prefixToken.ValueText;
            int    index     = text.IndexOf(prefix);

            if (index >= 0)
            {
                bool additionalCharacters = index + prefix.Length < text.Length;
                text = text.Substring(0, index)
                       + (additionalCharacters ? char.ToUpperInvariant(text[index + prefix.Length]).ToString() : string.Empty)
                       + text.Substring(index + (additionalCharacters ? (prefix.Length + 1) : prefix.Length));
            }

            index = valueText.IndexOf(prefix);
            if (index >= 0)
            {
                valueText = valueText.Remove(index, prefix.Length);
            }

            SyntaxToken replaced = SyntaxFactory.Token(prefixToken.LeadingTrivia, prefixToken.Kind(), text, valueText, prefixToken.TrailingTrivia);

            summaryContent = summaryContent.Replace(firstText, firstText.ReplaceToken(prefixToken, replaced));
            return(true);
        }
Пример #9
0
 private static SwitchSectionSyntax GetDefaultExpression(SyntaxList <SwitchSectionSyntax> caseSyntaxes)
 {
     return(caseSyntaxes.FirstOrDefault(x => x.Labels.FirstOrDefault() is DefaultSwitchLabelSyntax));
 }