private static void Analyze( SyntaxNodeAnalysisContext context, SyntaxToken token, SyntaxNode node) { SyntaxTriviaList trailingTrivia = token.TrailingTrivia; SyntaxTriviaList leadingTrivia = node.GetLeadingTrivia(); if (!IsStandardTriviaBetweenLines(trailingTrivia, leadingTrivia) && token .SyntaxTree .GetLineSpan(TextSpan.FromBounds(token.Span.End, node.Span.Start), context.CancellationToken) .GetLineCount() == 3) { SyntaxTrivia trivia = leadingTrivia .SkipWhile(f => f.IsWhitespaceTrivia()) .FirstOrDefault(); if (trivia.IsEndOfLineTrivia() && trailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) && leadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { context.ReportDiagnostic( DiagnosticDescriptors.RemoveRedundantEmptyLine, Location.Create(token.SyntaxTree, TextSpan.FromBounds(node.FullSpan.Start, trivia.Span.End))); } } }
private static T RemoveNode <T>( T declaration, Func <T, SyntaxList <MemberDeclarationSyntax> > getMembers, int index, SyntaxRemoveOptions removeOptions) where T : SyntaxNode { SyntaxList <MemberDeclarationSyntax> members = getMembers(declaration); T newDeclaration = declaration.RemoveNode(members[index], removeOptions); if (index == 0 && index < members.Count - 1) { members = getMembers(newDeclaration); MemberDeclarationSyntax nextMember = members[index]; SyntaxTriviaList leadingTrivia = nextMember.GetLeadingTrivia(); SyntaxTrivia trivia = leadingTrivia.FirstOrDefault(); if (trivia.IsEndOfLineTrivia()) { MemberDeclarationSyntax newNextMember = nextMember.WithLeadingTrivia(leadingTrivia.RemoveAt(0)); newDeclaration = newDeclaration.ReplaceNode(nextMember, newNextMember); } } return(newDeclaration); }
public static SyntaxTrivia DetermineEndOfLine(SyntaxToken token, SyntaxTrivia?defaultValue = null) { SyntaxTrivia trivia = FindEndOfLine(token); return((trivia.IsEndOfLineTrivia()) ? trivia : defaultValue ?? CSharpFactory.NewLine()); }
private static void Analyze( SyntaxNodeAnalysisContext context, StatementSyntax containingStatement, SyntaxToken token, StatementSyntax statement) { if (token.IsMissing) { return; } if (statement?.IsKind(SyntaxKind.Block, SyntaxKind.EmptyStatement) != false) { return; } if (!containingStatement.SyntaxTree.IsMultiLineSpan(TextSpan.FromBounds(token.SpanStart, statement.SpanStart))) { return; } SyntaxNode parent = containingStatement.Parent; if (parent?.Kind() != SyntaxKind.Block) { return; } var block = (BlockSyntax)parent; SyntaxList <StatementSyntax> statements = block.Statements; int index = statements.IndexOf(containingStatement); if (index == statements.Count - 1) { return; } if (containingStatement .SyntaxTree .GetLineCount(TextSpan.FromBounds(statement.Span.End, statements[index + 1].SpanStart)) > 2) { return; } SyntaxTrivia trivia = statement .GetTrailingTrivia() .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (!trivia.IsEndOfLineTrivia()) { return; } context.ReportDiagnostic(DiagnosticDescriptors.AddEmptyLineAfterEmbeddedStatement, trivia); }
private static void Analyze( SyntaxNodeAnalysisContext context, StatementSyntax containingStatement, SyntaxToken token, StatementSyntax statement) { if (token.IsMissing) { return; } if (statement?.IsKind(SyntaxKind.Block, SyntaxKind.EmptyStatement) != false) { return; } StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(containingStatement); if (!statementsInfo.Success) { return; } SyntaxTree syntaxTree = containingStatement.SyntaxTree; if (!syntaxTree.IsMultiLineSpan(TextSpan.FromBounds(token.SpanStart, statement.SpanStart))) { return; } StatementSyntax nextStatement = containingStatement.NextStatement(); if (nextStatement == null) { return; } if (syntaxTree.GetLineCount(TextSpan.FromBounds(statement.Span.End, nextStatement.SpanStart)) > 2) { return; } SyntaxTrivia trivia = statement .GetTrailingTrivia() .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (!trivia.IsEndOfLineTrivia()) { return; } DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.AddEmptyLineAfterEmbeddedStatement, Location.Create(syntaxTree, trivia.Span.WithLength(0))); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); SyntaxTrivia trivia = root.FindTrivia(context.Span.Start); Debug.Assert(trivia.IsEndOfLineTrivia(), $"{nameof(trivia)} is not EOF"); if (!trivia.IsEndOfLineTrivia()) { return; } CodeAction codeAction = CodeAction.Create( "Add empty line", cancellationToken => RefactorAsync(context.Document, trivia.Token, cancellationToken), DiagnosticIdentifiers.AddEmptyLineAfterClosingBrace + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, context.Diagnostics); }
private static void Analyze(SyntaxNodeAnalysisContext context, MemberDeclarationSyntax declaration, SyntaxToken openToken, SyntaxToken closeToken) { if (declaration.IsParentKind(SyntaxKind.CompilationUnit)) { return; } if (openToken.IsMissing) { return; } if (closeToken.IsMissing) { return; } int closeTokenLine = closeToken.GetSpanEndLine(); if (openToken.GetSpanEndLine() == closeTokenLine) { return; } MemberDeclarationSyntax nextDeclaration = GetNextDeclaration(declaration); if (nextDeclaration == null) { return; } int diff = nextDeclaration.GetSpanStartLine() - closeTokenLine; if (diff >= 2) { return; } SyntaxTrivia trivia = declaration.GetTrailingTrivia().LastOrDefault(); if (trivia.IsEndOfLineTrivia()) { context.ReportDiagnostic(DiagnosticDescriptors.AddEmptyLineBetweenDeclarations, trivia); } else { context.ReportDiagnostic(DiagnosticDescriptors.AddEmptyLineBetweenDeclarations, closeToken); } }
public static void Analyze(SyntaxNodeAnalysisContext context, SwitchStatementSyntax switchStatement) { SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections; if (sections.Any()) { AnalyzeStart(context, sections.First(), switchStatement.OpenBraceToken); AnalyzeEnd(context, sections.Last(), switchStatement.CloseBraceToken); if (sections.Count > 1) { SwitchSectionSyntax prevSection = sections.First(); for (int i = 1; i < sections.Count; i++) { if (prevSection.Statements.LastOrDefault()?.IsKind(SyntaxKind.Block) == true) { SwitchSectionSyntax section = sections[i]; SyntaxTriviaList trailingTrivia = prevSection.GetTrailingTrivia(); SyntaxTriviaList leadingTrivia = section.GetLeadingTrivia(); if (!IsStandardTriviaBetweenSections(trailingTrivia, leadingTrivia) && switchStatement .SyntaxTree .GetLineSpan(TextSpan.FromBounds(prevSection.Span.End, section.Span.Start), context.CancellationToken) .GetLineCount() == 3) { SyntaxTrivia trivia = leadingTrivia .SkipWhile(f => f.IsWhitespaceTrivia()) .FirstOrDefault(); if (trivia.IsEndOfLineTrivia() && trailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) && leadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { context.ReportDiagnostic( DiagnosticDescriptors.RemoveRedundantEmptyLine, Location.Create(switchStatement.SyntaxTree, TextSpan.FromBounds(section.FullSpan.Start, trivia.Span.End))); } } } prevSection = sections[i]; } } } }
public static void Analyze(SyntaxNodeAnalysisContext context, DoStatementSyntax doStatement) { StatementSyntax statement = doStatement.Statement; if (statement?.IsKind(SyntaxKind.Block) == true) { var block = (BlockSyntax)statement; SyntaxList <StatementSyntax> statements = block.Statements; if (statements.Any()) { SyntaxToken closeBrace = block.CloseBraceToken; if (!closeBrace.IsMissing) { SyntaxToken whileKeyword = doStatement.WhileKeyword; if (!whileKeyword.IsMissing) { int closeBraceLine = closeBrace.GetSpanEndLine(); if (closeBraceLine == whileKeyword.GetSpanStartLine()) { StatementSyntax last = statements.Last(); int line = last.GetSpanEndLine(context.CancellationToken); if (closeBraceLine - line == 1) { SyntaxTrivia trivia = last .GetTrailingTrivia() .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (trivia.IsEndOfLineTrivia()) { context.ReportDiagnostic( DiagnosticDescriptors.AddEmptyLineAfterLastStatementInDoStatement, Location.Create(doStatement.SyntaxTree, trivia.Span)); } } } } } } } }
public static void AnalyzeMemberDeclaration(SyntaxNodeAnalysisContext context) { var declaration = (MemberDeclarationSyntax)context.Node; if (!declaration.IsParentKind(SyntaxKind.CompilationUnit)) { TokenPair tokenPair = GetTokenPair(declaration); SyntaxToken openToken = tokenPair.OpenToken; SyntaxToken closeToken = tokenPair.CloseToken; if (!openToken.IsKind(SyntaxKind.None) && !openToken.IsMissing && !closeToken.IsKind(SyntaxKind.None) && !closeToken.IsMissing) { int closeTokenLine = closeToken.GetSpanEndLine(); if (openToken.GetSpanEndLine() != closeTokenLine) { MemberDeclarationSyntax nextDeclaration = GetNextDeclaration(declaration); if (nextDeclaration != null) { int diff = nextDeclaration.GetSpanStartLine() - closeTokenLine; if (diff < 2) { SyntaxTrivia trivia = declaration.GetTrailingTrivia().LastOrDefault(); if (trivia.IsEndOfLineTrivia()) { context.ReportDiagnostic( DiagnosticDescriptors.AddEmptyLineBetweenDeclarations, trivia); } else { context.ReportDiagnostic( DiagnosticDescriptors.AddEmptyLineBetweenDeclarations, closeToken); } } } } } } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration) { VariableDeclarationSyntax declaration = localDeclaration.Declaration; TypeSyntax type = declaration?.Type; if (type?.IsVar == false) { VariableDeclaratorSyntax declarator = declaration.Variables.FirstOrDefault(); if (declarator != null && context.Span.Start >= type.Span.Start) { SyntaxTriviaList triviaList = type.GetTrailingTrivia(); if (triviaList.Any()) { SyntaxTrivia trivia = triviaList .SkipWhile(f => f.IsWhitespaceTrivia()) .FirstOrDefault(); if (trivia.IsEndOfLineTrivia() && context.Span.End <= trivia.Span.Start) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken); string name = NameGenerator.Default.CreateUniqueLocalName( typeSymbol, semanticModel, declarator.SpanStart, cancellationToken: context.CancellationToken); if (name != null) { context.RegisterRefactoring( $"Add identifier '{name}'", c => RefactorAsync(context.Document, type, name, c)); } } } } } }
private static IEnumerable <TextLine> GetEmptyLines(SourceText sourceText, SyntaxNode root, TextSpan span) { foreach (TextLine line in sourceText .Lines .SkipWhile(f => f.Start < span.Start) .TakeWhile(f => f.EndIncludingLineBreak <= span.End)) { if (line.Span.Length == 0 || StringUtility.IsWhitespace(line.ToString())) { SyntaxTrivia endOfLine = root.FindTrivia(line.End, findInsideTrivia: true); if (endOfLine.IsEndOfLineTrivia()) { yield return(line); } } } }
private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxToken closeBrace, StatementSyntax blockOrStatement) { StatementSyntax nextStatement = blockOrStatement.NextStatement(); if (nextStatement != null && closeBrace.SyntaxTree.GetLineCount(TextSpan.FromBounds(closeBrace.Span.End, nextStatement.SpanStart)) == 2) { SyntaxTrivia endOfLine = closeBrace .TrailingTrivia .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (endOfLine.IsEndOfLineTrivia()) { context.ReportDiagnostic( DiagnosticDescriptors.AddEmptyLineBetweenBlockAndStatement, Location.Create(endOfLine.SyntaxTree, endOfLine.Span.WithLength(0))); } } }
private static void Analyze( SyntaxNodeAnalysisContext context, StatementSyntax containingStatement, SyntaxToken token, StatementSyntax statement) { if (!token.IsKind(SyntaxKind.None) && !token.IsMissing && statement?.IsKind(SyntaxKind.Block, SyntaxKind.EmptyStatement) == false && context.SyntaxTree().IsMultiLineSpan(TextSpan.FromBounds(token.SpanStart, statement.SpanStart))) { SyntaxNode parent = containingStatement.Parent; if (parent?.IsKind(SyntaxKind.Block) == true) { var block = (BlockSyntax)parent; SyntaxList <StatementSyntax> statements = block.Statements; int index = statements.IndexOf(containingStatement); if (index < statements.Count - 1 && context .SyntaxTree() .GetLineCount(TextSpan.FromBounds(statement.Span.End, statements[index + 1].SpanStart)) <= 2) { SyntaxTrivia trivia = statement .GetTrailingTrivia() .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (trivia.IsEndOfLineTrivia()) { context.ReportDiagnostic( DiagnosticDescriptors.AddEmptyLineAfterEmbeddedStatement, trivia.GetLocation()); } } } } }
private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxToken closeBrace, StatementSyntax blockOrStatement) { StatementSyntax nextStatement = (blockOrStatement is IfStatementSyntax ifStatement) ? ifStatement.GetTopmostIf().NextStatement() : blockOrStatement.NextStatement(); if (nextStatement != null && closeBrace.SyntaxTree.GetLineCount(TextSpan.FromBounds(closeBrace.Span.End, nextStatement.SpanStart)) == 2) { SyntaxTrivia endOfLine = closeBrace .TrailingTrivia .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (endOfLine.IsEndOfLineTrivia()) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.AddBlankLineBetweenClosingBraceAndNextStatement, Location.Create(endOfLine.SyntaxTree, endOfLine.Span.WithLength(0))); } } }
private void AnalyzeStatement(SyntaxNodeAnalysisContext context, StatementSyntax statement, SyntaxToken openBrace, SyntaxToken closeBrace) { var block = (BlockSyntax)statement.Parent; SyntaxList <StatementSyntax> statements = block.Statements; int index = statements.IndexOf(statement); Debug.Assert(index != -1, ""); if (index != -1 && index < statements.Count - 1) { int startLine = openBrace.GetSpanStartLine(); int endLine = closeBrace.GetSpanEndLine(); if (startLine < endLine) { StatementSyntax nextStatement = statements[index + 1]; if (nextStatement.GetSpanStartLine() - endLine == 1) { SyntaxTrivia trivia = closeBrace .TrailingTrivia .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (trivia.IsEndOfLineTrivia()) { context.ReportDiagnostic( DiagnosticDescriptors.AddEmptyLineAfterClosingBrace, trivia); } } } } }
public static SyntaxTrivia GetEndOfLine(SyntaxToken token) { SyntaxTrivia trivia = FindEndOfLine(token); return((trivia.IsEndOfLineTrivia()) ? trivia : CSharpFactory.NewLine()); }
public static Task <Document> FixBinaryExpressionAsync( Document document, BinaryExpressionSyntax binaryExpression, TextSpan span, CancellationToken cancellationToken) { IndentationAnalysis indentationAnalysis = AnalyzeIndentation(binaryExpression, cancellationToken); string indentation; if (indentationAnalysis.Indentation == binaryExpression.GetLeadingTrivia().LastOrDefault() && AnalyzerOptions.AddNewLineAfterBinaryOperatorInsteadOfBeforeIt.IsEnabled(document, binaryExpression)) { indentation = indentationAnalysis.Indentation.ToString(); } else { indentation = indentationAnalysis.GetIncreasedIndentation(); } string endOfLineAndIndentation = DetermineEndOfLine(binaryExpression).ToString() + indentation; var textChanges = new List <TextChange>(); int prevIndex = binaryExpression.Span.End; SyntaxKind binaryKind = binaryExpression.Kind(); while (true) { SyntaxToken token = binaryExpression.OperatorToken; if (token.Span.End > span.End) { continue; } if (token.SpanStart < span.Start) { break; } ExpressionSyntax left = binaryExpression.Left; ExpressionSyntax right = binaryExpression.Right; SyntaxTriviaList leftTrailing = left.GetTrailingTrivia(); SyntaxTriviaList tokenTrailing = token.TrailingTrivia; if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(leftTrailing)) { if (!SetIndentation(token)) { break; } } else if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(tokenTrailing)) { if (!SetIndentation(right)) { break; } } else if (leftTrailing.IsEmptyOrWhitespace() && tokenTrailing.IsEmptyOrWhitespace()) { if (AnalyzerOptions.AddNewLineAfterBinaryOperatorInsteadOfBeforeIt.IsEnabled(document, binaryExpression)) { if (!SetIndentation(right)) { break; } } else if (!SetIndentation(token)) { break; } } if (!left.IsKind(binaryKind)) { break; } binaryExpression = (BinaryExpressionSyntax)left; } if (textChanges.Count > 0) { SyntaxTriviaList leading = binaryExpression.GetLeadingTrivia(); if (!leading.Any()) { SyntaxTrivia trivia = binaryExpression.GetFirstToken().GetPreviousToken().TrailingTrivia.LastOrDefault(); if (trivia.IsEndOfLineTrivia() && trivia.Span.End == binaryExpression.SpanStart) { textChanges.Add(new TextSpan(binaryExpression.SpanStart, 0), indentation); } } } FormattingVerifier.VerifyChangedSpansAreWhitespace(binaryExpression, textChanges); return(document.WithTextChangesAsync(textChanges, cancellationToken)); bool SetIndentation(SyntaxNodeOrToken nodeOrToken) { SyntaxTriviaList leading = nodeOrToken.GetLeadingTrivia(); SyntaxTriviaList.Reversed.Enumerator en = leading.Reverse().GetEnumerator(); if (!en.MoveNext()) { SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.SpanStart - 1); string newText = (trivia.IsEndOfLineTrivia()) ? indentation : endOfLineAndIndentation; int start = (trivia.IsWhitespaceTrivia()) ? trivia.SpanStart : nodeOrToken.SpanStart; TextSpan span = (trivia.IsWhitespaceTrivia()) ? trivia.Span : new TextSpan(nodeOrToken.SpanStart, 0); textChanges.Add(span, newText); SetIndendation(nodeOrToken, prevIndex); prevIndex = start; return(true); } SyntaxTrivia last = en.Current; SyntaxKind kind = en.Current.Kind(); if (kind == SyntaxKind.WhitespaceTrivia) { if (en.Current.Span.Length != indentation.Length) { if (!en.MoveNext() || en.Current.IsEndOfLineTrivia()) { SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.FullSpan.Start - 1); if (trivia.IsEndOfLineTrivia()) { AddTextChange((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span); SetIndendation(nodeOrToken, prevIndex); prevIndex = trivia.SpanStart; return(true); } } } } else if (kind == SyntaxKind.EndOfLineTrivia) { SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.FullSpan.Start - 1); if (trivia.IsEndOfLineTrivia()) { AddTextChange((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span); SetIndendation(nodeOrToken, prevIndex); prevIndex = trivia.SpanStart; return(true); } } prevIndex = leading.Span.Start - 1; return(true); void AddTextChange(TextSpan span) => textChanges.Add(span, indentation); } void SetIndendation(SyntaxNodeOrToken nodeOrToken, int endIndex) { ImmutableArray <IndentationInfo> indentations = FindIndentations( binaryExpression, TextSpan.FromBounds(nodeOrToken.SpanStart, endIndex)) .ToImmutableArray(); if (!indentations.Any()) { return; } int firstIndentationLength = indentations[0].Span.Length; for (int j = 0; j < indentations.Length; j++) { IndentationInfo indentationInfo = indentations[j]; string replacement = indentation + indentationAnalysis.GetSingleIndentation(); if (j > 0 && indentationInfo.Span.Length > firstIndentationLength) { replacement += indentationInfo.ToString().Substring(firstIndentationLength); } if (indentationInfo.Span.Length != replacement.Length) { textChanges.Add(indentationInfo.Span, replacement); } } } }
public static Task <Document> FixCallChainAsync( Document document, ExpressionSyntax expression, TextSpan span, CancellationToken cancellationToken = default) { IndentationAnalysis indentationAnalysis = AnalyzeIndentation(expression, cancellationToken); string indentation = indentationAnalysis.GetIncreasedIndentation(); string endOfLineAndIndentation = DetermineEndOfLine(expression).ToString() + indentation; var textChanges = new List <TextChange>(); int prevIndex = expression.Span.End; foreach (SyntaxNode node in new MethodChain(expression)) { SyntaxKind kind = node.Kind(); if (kind == SyntaxKind.SimpleMemberAccessExpression) { var memberAccess = (MemberAccessExpressionSyntax)node; if (!SetIndentation(memberAccess.OperatorToken)) { break; } } else if (kind == SyntaxKind.MemberBindingExpression) { var memberBinding = (MemberBindingExpressionSyntax)node; if (!SetIndentation(memberBinding.OperatorToken)) { break; } } } FormattingVerifier.VerifyChangedSpansAreWhitespace(expression, textChanges); return(document.WithTextChangesAsync(textChanges, cancellationToken)); bool SetIndentation(SyntaxToken token) { if (token.Span.End > span.End) { return(true); } if (token.SpanStart < span.Start) { return(false); } SyntaxTriviaList leading = token.LeadingTrivia; SyntaxTriviaList.Reversed.Enumerator en = leading.Reverse().GetEnumerator(); if (!en.MoveNext()) { SyntaxTrivia trivia = expression.FindTrivia(token.SpanStart - 1); string newText = (trivia.IsEndOfLineTrivia()) ? indentation : endOfLineAndIndentation; textChanges.Add(new TextSpan(token.SpanStart, 0), newText); SetIndendation(token, prevIndex); prevIndex = (trivia.IsEndOfLineTrivia()) ? trivia.SpanStart : token.SpanStart; return(true); } SyntaxTrivia last = en.Current; SyntaxKind kind = en.Current.Kind(); if (kind == SyntaxKind.WhitespaceTrivia) { if (en.Current.Span.Length != indentation.Length) { if (!en.MoveNext() || en.Current.IsEndOfLineTrivia()) { SyntaxTrivia trivia = expression.FindTrivia(token.FullSpan.Start - 1); if (trivia.IsEndOfLineTrivia()) { textChanges.Add((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span, indentation); SetIndendation(token, prevIndex); prevIndex = trivia.SpanStart; return(true); } } } } else if (kind == SyntaxKind.EndOfLineTrivia) { SyntaxTrivia trivia = expression.FindTrivia(token.FullSpan.Start - 1); if (trivia.IsEndOfLineTrivia()) { textChanges.Add((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span, indentation); SetIndendation(token, prevIndex); prevIndex = trivia.SpanStart; return(true); } } prevIndex = leading.Span.Start - 1; return(true); } void SetIndendation(SyntaxToken token, int endIndex) { ImmutableArray <IndentationInfo> indentations = FindIndentations( expression, TextSpan.FromBounds(token.SpanStart, endIndex)) .ToImmutableArray(); if (!indentations.Any()) { return; } int firstIndentationLength = indentations[0].Span.Length; for (int j = 0; j < indentations.Length; j++) { IndentationInfo indentationInfo = indentations[j]; string replacement = indentation + indentationAnalysis.GetSingleIndentation(); if (j > 0 && indentationInfo.Span.Length > firstIndentationLength) { replacement += indentationInfo.ToString().Substring(firstIndentationLength); } if (indentationInfo.Span.Length != replacement.Length) { textChanges.Add(indentationInfo.Span, replacement); } } } }
private static void AnalyzeTrailingTrivia(SyntaxTreeAnalysisContext context) { if (!context.Tree.TryGetText(out SourceText sourceText)) { return; } if (!context.Tree.TryGetRoot(out SyntaxNode root)) { return; } var emptyLines = default(TextSpan); bool previousLineIsEmpty = false; int i = 0; foreach (TextLine textLine in sourceText.Lines) { bool lineIsEmpty = false; if (textLine.Span.Length == 0) { SyntaxTrivia endOfLine = root.FindTrivia(textLine.End); if (endOfLine.IsEndOfLineTrivia()) { lineIsEmpty = true; if (previousLineIsEmpty) { if (emptyLines.IsEmpty) { emptyLines = endOfLine.Span; } else { emptyLines = TextSpan.FromBounds(emptyLines.Start, endOfLine.Span.End); } } } else { emptyLines = default; } } else { if (!emptyLines.IsEmpty) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveRedundantEmptyLine, Location.Create(context.Tree, emptyLines)); } emptyLines = default; int end = textLine.End - 1; if (char.IsWhiteSpace(sourceText[end])) { int start = end; while (start > textLine.Span.Start && char.IsWhiteSpace(sourceText[start - 1])) { start--; } TextSpan whitespace = TextSpan.FromBounds(start, end + 1); if (root.FindTrivia(start).IsWhitespaceTrivia() || root.FindToken(start, findInsideTrivia: true).IsKind(SyntaxKind.XmlTextLiteralToken)) { if (previousLineIsEmpty && start == textLine.Start) { whitespace = TextSpan.FromBounds( sourceText.Lines[i - 1].End, whitespace.End); } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveTrailingWhitespace, Location.Create(context.Tree, whitespace)); } } } previousLineIsEmpty = lineIsEmpty; i++; } }
private static void AnalyzeDoStatement(SyntaxNodeAnalysisContext context) { var doStatement = (DoStatementSyntax)context.Node; StatementSyntax statement = doStatement.Statement; if (statement?.Kind() != SyntaxKind.Block) { return; } var block = (BlockSyntax)statement; StatementSyntax lastStatement = block.Statements.LastOrDefault(); if (lastStatement == null) { return; } SyntaxToken closeBrace = block.CloseBraceToken; if (closeBrace.IsMissing) { return; } SyntaxToken whileKeyword = doStatement.WhileKeyword; if (whileKeyword.IsMissing) { return; } int closeBraceLine = closeBrace.GetSpanEndLine(); if (closeBraceLine != whileKeyword.GetSpanStartLine()) { return; } int line = lastStatement.GetSpanEndLine(context.CancellationToken); if (closeBraceLine - line != 1) { return; } SyntaxTrivia trivia = lastStatement .GetTrailingTrivia() .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (!trivia.IsEndOfLineTrivia()) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.AddEmptyLineBeforeWhileInDoStatement, Location.Create(doStatement.SyntaxTree, trivia.Span)); }
private static void AnalyzeEmbeddedStatement(SyntaxNodeAnalysisContext context) { SyntaxToken token = GetToken(context.Node); if (token.IsMissing) { return; } StatementSyntax statement = GetStatement(context.Node); if (statement.IsKind(SyntaxKind.Block)) { return; } if (statement.IsKind(SyntaxKind.EmptyStatement)) { return; } if (token.GetSpanStartLine() == statement.GetSpanStartLine()) { context.ReportDiagnostic( DiagnosticDescriptors.FormatEmbeddedStatementOnSeparateLine, statement.GetLocation()); } else { var parentStatement = (StatementSyntax)context.Node; var block = parentStatement.Parent as BlockSyntax; if (block == null) { return; } int index = block.Statements.IndexOf(parentStatement); if (index == block.Statements.Count - 1) { return; } int diff = block.Statements[index + 1].GetSpanStartLine() - statement.GetSpanEndLine(); if (diff < 2) { SyntaxTrivia trivia = statement .GetTrailingTrivia() .FirstOrDefault(f => f.IsEndOfLineTrivia()); if (trivia.IsEndOfLineTrivia()) { context.ReportDiagnostic( DiagnosticDescriptors.AddEmptyLineAfterEmbeddedStatement, trivia.GetLocation()); } } } }
public static bool IsWhitespaceOrEndOfLineTrivia(this SyntaxTrivia trivia) { return(trivia.IsWhitespaceTrivia() || trivia.IsEndOfLineTrivia()); }