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; }
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); }
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); }
private static bool ContainsOnlyDefaultSection(SyntaxList <SwitchSectionSyntax> sections) { return(sections .SingleOrDefault(shouldThrow: false)? .Labels .SingleOrDefault(shouldThrow: false)? .Kind() == SyntaxKind.DefaultSwitchLabel); }
private static StatementSyntax FindStatementToReplace(SyntaxList <StatementSyntax> statements) { var statementToReplace = statements .SingleOrDefault(statement => statement .NormalizeWhitespace() .ToFullString() .StartsWith("var result = JsonConvert.DeserializeObject")); return(statementToReplace); }
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; }
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); } }
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); }
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))); }