protected override bool IsFixable(StatementSyntax statement, BlockSyntax block, SyntaxKind parentKind)
        {
            if (!parentKind.Is(
                SyntaxKind.MethodDeclaration,
                SyntaxKind.LocalFunctionStatement))
            {
                return false;
            }

            SyntaxList<StatementSyntax> statements = block.Statements;

            if (object.ReferenceEquals(statements.SingleOrDefault(ignoreLocalFunctions: true, shouldThrow: false), statement))
                return false;

            ContainsYieldWalker walker = ContainsYieldWalker.GetInstance();

            bool success = false;

            int index = statements.IndexOf(statement);

            for (int i = 0; i < index; i++)
            {
                walker.VisitStatement(statements[i]);

                success = walker.YieldStatement != null;

                if (success)
                    break;
            }

            ContainsYieldWalker.Free(walker);

            return success;
        }
Esempio n. 2
0
        protected override (ExpressionSyntax expression, SyntaxList <StatementSyntax> statements) GetExpressionOrStatements(MethodDeclarationSyntax declaration)
        {
            BlockSyntax body = declaration.Body;

            if (body == null)
            {
                return(declaration.ExpressionBody?.Expression, default(SyntaxList <StatementSyntax>));
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

            if (!statements.Any())
            {
                return(null, default(SyntaxList <StatementSyntax>));
            }

            switch (statements.SingleOrDefault(shouldThrow: false))
            {
            case ReturnStatementSyntax returnStatement:
                return(returnStatement.Expression, default(SyntaxList <StatementSyntax>));

            case ExpressionStatementSyntax expressionStatement:
                return(expressionStatement.Expression, default(SyntaxList <StatementSyntax>));
            }

            if (!declaration.ReturnsVoid())
            {
                return(null, default(SyntaxList <StatementSyntax>));
            }

            return(null, statements);
        }
Esempio n. 3
0
        public static void AnalyzeInterpolatedStringExpression(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.ContainsDirectives)
            {
                return;
            }

            var interpolatedString = (InterpolatedStringExpressionSyntax)context.Node;

            SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents;

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

            var interpolation = contents.SingleOrDefault(shouldThrow: false) as InterpolationSyntax;

            if (interpolation == null)
            {
                return;
            }

            ExpressionSyntax expression = interpolation.Expression;

            if (expression == null)
            {
                return;
            }

            if (interpolation.AlignmentClause != null)
            {
                return;
            }

            if (interpolation.FormatClause != null)
            {
                return;
            }

            ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(expression, context.CancellationToken);

            if (typeSymbol?.SpecialType != SpecialType.System_String)
            {
                return;
            }

            context.ReportDiagnostic(DiagnosticDescriptors.UnnecessaryInterpolatedString, interpolatedString);

            context.ReportToken(DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolatedString.StringStartToken);
            context.ReportToken(DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolation.OpenBraceToken);
            context.ReportToken(DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolation.CloseBraceToken);
            context.ReportToken(DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolatedString.StringEndToken);
        }
Esempio n. 4
0
 private static bool ContainsOnlyDefaultSection(SyntaxList <SwitchSectionSyntax> sections)
 {
     return(sections
            .SingleOrDefault(shouldThrow: false)?
            .Labels
            .SingleOrDefault(shouldThrow: false)?
            .Kind() == SyntaxKind.DefaultSwitchLabel);
 }
Esempio n. 5
0
        private static StatementSyntax FindStatementToReplace(SyntaxList <StatementSyntax> statements)
        {
            var statementToReplace = statements
                                     .SingleOrDefault(statement => statement
                                                      .NormalizeWhitespace()
                                                      .ToFullString()
                                                      .StartsWith("var result = JsonConvert.DeserializeObject"));

            return(statementToReplace);
        }
Esempio n. 6
0
        private static bool ContainsSingleNamespaceWithSingleNonNamespaceMember(SyntaxList<MemberDeclarationSyntax> members)
        {
            MemberDeclarationSyntax member = members.SingleOrDefault(shouldThrow: false);

            if (member?.Kind() != SyntaxKind.NamespaceDeclaration)
                return false;

            var namespaceDeclaration = (NamespaceDeclarationSyntax)member;

            member = namespaceDeclaration.Members.SingleOrDefault(shouldThrow: false);

            return member != null
                && member.Kind() != SyntaxKind.NamespaceDeclaration;
        }
Esempio n. 7
0
        private static bool IsEmptyOrContainsOnlyDefaultSection(SwitchStatementSyntax switchStatement)
        {
            SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections;

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

            return(sections
                   .SingleOrDefault(shouldThrow: false)?
                   .Labels
                   .SingleOrDefault(shouldThrow: false)?
                   .Kind() == SyntaxKind.DefaultSwitchLabel);
        }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, LocalFunctionStatementSyntax localFunction)
        {
            TypeSyntax returnType = localFunction.ReturnType;

            if (returnType?.IsVoid() != false)
            {
                return;
            }

            BlockSyntax body = localFunction.Body;

            if (body == null)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

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

            if (statements.SingleOrDefault(shouldThrow: false)?.Kind() == SyntaxKind.ThrowStatement)
            {
                return;
            }

            if (localFunction.ContainsYield())
            {
                return;
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(localFunction, context.CancellationToken);

            ComputeRefactoring(context, methodSymbol, semanticModel, body, returnType);
        }
        public static void ComputeRefactoring(RefactoringContext context, SwitchSectionSyntax switchSection)
        {
            if (!context.Span.IsEmpty)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = switchSection.Statements;

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

            if (statements.SingleOrDefault(shouldThrow: false) is BlockSyntax block &&
                block.CloseBraceToken.Span.Contains(context.Span))
            {
                RegisterRefactoring(context, switchSection);
            }

            if (!IsOnEmptyLine(context.Span, switchSection.GetLeadingTrivia()))
            {
                return;
            }

            var switchStatement = (SwitchStatementSyntax)switchSection.Parent;

            SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections;

            int index = sections.IndexOf(switchSection);

            if (index > 0)
            {
                SwitchSectionSyntax previousSection = sections[index - 1];
                RegisterRefactoring(context, previousSection, insertNewLine: true);
            }
        }
Esempio n. 10
0
        private static void AnalyzeInterpolatedStringExpression(SyntaxNodeAnalysisContext context)
        {
            SyntaxNode node = context.Node;

            if (node.ContainsDiagnostics)
            {
                return;
            }

            if (node.ContainsDirectives)
            {
                return;
            }

            var interpolatedString = (InterpolatedStringExpressionSyntax)node;

            SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents;

            if (ConvertInterpolatedStringToStringLiteralAnalysis.IsFixable(contents))
            {
                ReportDiagnostic(
                    context,
                    DiagnosticDescriptors.UnnecessaryInterpolatedString,
                    Location.Create(interpolatedString.SyntaxTree, GetDollarSpan(interpolatedString)));
            }
            else
            {
                if (!(contents.SingleOrDefault(shouldThrow: false) is InterpolationSyntax interpolation))
                {
                    return;
                }

                if (interpolation.AlignmentClause != null)
                {
                    return;
                }

                if (interpolation.FormatClause != null)
                {
                    return;
                }

                ExpressionSyntax expression = interpolation.Expression?.WalkDownParentheses();

                if (expression == null)
                {
                    return;
                }

                if (!IsNonNullStringExpression(expression))
                {
                    return;
                }

                ReportDiagnostic(context, DiagnosticDescriptors.UnnecessaryInterpolatedString, interpolatedString);

                ReportToken(context, DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolatedString.StringStartToken);
                ReportToken(context, DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolation.OpenBraceToken);
                ReportToken(context, DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolation.CloseBraceToken);
                ReportToken(context, DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolatedString.StringEndToken);
            }

            bool IsNonNullStringExpression(ExpressionSyntax expression)
            {
                if (expression.IsKind(SyntaxKind.StringLiteralExpression, SyntaxKind.InterpolatedStringExpression))
                {
                    return(true);
                }

                Optional <object> constantValue = context.SemanticModel.GetConstantValue(expression, context.CancellationToken);

                return(constantValue.HasValue &&
                       constantValue.Value is string value &&
                       value != null);
            }
        }
        private static void AnalyzeInterpolatedStringExpression(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.ContainsDirectives)
            {
                return;
            }

            var interpolatedString = (InterpolatedStringExpressionSyntax)context.Node;

            SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents;

            if (!(contents.SingleOrDefault(shouldThrow: false) is InterpolationSyntax interpolation))
            {
                return;
            }

            if (interpolation.AlignmentClause != null)
            {
                return;
            }

            if (interpolation.FormatClause != null)
            {
                return;
            }

            ExpressionSyntax expression = interpolation.Expression?.WalkDownParentheses();

            if (expression == null)
            {
                return;
            }

            bool isNonNullStringExpression = false;

            if (expression.IsKind(SyntaxKind.StringLiteralExpression, SyntaxKind.InterpolatedStringExpression))
            {
                isNonNullStringExpression = true;
            }
            else
            {
                Optional <object> constantValue = context.SemanticModel.GetConstantValue(expression, context.CancellationToken);

                if (constantValue.HasValue &&
                    constantValue.Value is string s &&
                    s != null)
                {
                    isNonNullStringExpression = true;
                }
            }

            if (!isNonNullStringExpression)
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UnnecessaryInterpolatedString, interpolatedString);

            DiagnosticHelpers.ReportToken(context, DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolatedString.StringStartToken);
            DiagnosticHelpers.ReportToken(context, DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolation.OpenBraceToken);
            DiagnosticHelpers.ReportToken(context, DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolation.CloseBraceToken);
            DiagnosticHelpers.ReportToken(context, DiagnosticDescriptors.UnnecessaryInterpolatedStringFadeOut, interpolatedString.StringEndToken);
        }
 public static bool IsFixable(SyntaxList <InterpolatedStringContentSyntax> contents)
 {
     return(!contents.Any() ||
            contents.SingleOrDefault(shouldThrow: false)?.Kind() == SyntaxKind.InterpolatedStringText);
 }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration)
        {
            TypeSyntax returnType = methodDeclaration.ReturnType;

            if (returnType?.IsVoid() != false)
            {
                return;
            }

            BlockSyntax body = methodDeclaration.Body;

            if (body == null)
            {
                return;
            }

            SyntaxList <StatementSyntax> statements = body.Statements;

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

            if (statements.SingleOrDefault(shouldThrow: false)?.Kind() == SyntaxKind.ThrowStatement)
            {
                return;
            }

            if (methodDeclaration.ContainsYield())
            {
                return;
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken);

            if (methodSymbol?.IsOverride != false)
            {
                return;
            }

            if (methodSymbol.ImplementsInterfaceMember())
            {
                return;
            }

            if (IsAsyncMethodThatReturnsTask(methodSymbol, semanticModel))
            {
                return;
            }

            ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body);

            if (!analysis.Succeeded)
            {
                return;
            }

            if (!analysis.ReturnStatements.All(IsReturnStatementWithoutExpression))
            {
                return;
            }

            context.RegisterRefactoring(
                "Change return type to 'void'",
                ct => ChangeTypeRefactoring.ChangeTypeAsync(context.Document, returnType, CSharpFactory.VoidType(), ct),
                RefactoringIdentifiers.ChangeMethodReturnTypeToVoid);
        }
Esempio n. 14
0
 internal static TNode SingleOrDefault <TNode>(this SyntaxList <TNode> list, bool shouldThrow) where TNode : SyntaxNode
 {
     return((shouldThrow) ? list.SingleOrDefault() : ((list.Count == 1) ? list[0] : default(TNode)));
 }