private void IdentifyTokenSpacing(SyntaxToken token) { // don't adjust spacing in genernal if there are already line breaks if (TextFacts.HasLineBreaks(token.Trivia)) { return; } // if no previous token then leave as is var prev = token.GetPreviousToken(); if (prev == null) { return; } if (IsIdentifierOrKeyword(token) && IsIdentifierOrKeyword(prev)) { // always have space between two adjacent names if (token.Trivia != " ") { AddRule(token, SpacingRule.From(SpacingKind.SingleSpaceIfOnSameLine)); } } else if (token.Parent is BinaryExpression be && be.Operator == token || prev.Parent is BinaryExpression pbe && pbe.Operator == prev) { // space before and after binary operator if (token.Trivia != " ") { AddRule(token, SpacingRule.From(SpacingKind.SingleSpaceIfOnSameLine)); } }
private static Diagnostic SetLocation(Diagnostic d, SyntaxElement location) { if (location.Width == 0) { if (location is SyntaxToken token) { // move location to next token if it is // lest than two spaces away and not separated by line breaks var next = token.GetNextToken(); if (next != null && (next.TextStart - token.End) < 2 && !TextFacts.HasLineBreaks(next.Trivia)) { location = next; } } } return(d.WithLocation(location)); }
private void WriteTrivia(SyntaxToken token, int indentation, SpacingKind spacingKind, bool hasFollowingToken) { var trivia = token.Trivia; var cursorInTrivia = _cursorPosition >= token.TriviaStart && _cursorPosition < token.TextStart; switch (spacingKind) { case SpacingKind.NoSpace: // all spacing is removed return; case SpacingKind.SingleSpace: // all spacing is replace by a single space _builder.Append(" "); return; } if (spacingKind != SpacingKind.AsIs && TextFacts.HasLineBreaks(trivia)) { // adjust and write all trivia lines for (int lineStart = 0, lineEnd = 0; lineStart < trivia.Length; lineStart = lineEnd) { int whitespaceEnd = SkipWhitespace(trivia, lineStart); if (lineStart == 0) { // write existing whitespace for first line, since this is whitespace that follows the last // token on the last line (may contain trailing comments) _builder.Append(trivia, lineStart, whitespaceEnd - lineStart); } else { // write standardized indentation instead of existing whitespace WriteIndentation(indentation); } // write remainder of line (possible comments and/or EOL) var nextLineBreakStart = TextFacts.GetNextLineBreakStart(trivia, whitespaceEnd); var nextLineStart = TextFacts.GetNextLineStart(trivia, whitespaceEnd); lineEnd = nextLineStart >= 0 ? nextLineStart : trivia.Length; _builder.Append(trivia, whitespaceEnd, lineEnd - whitespaceEnd); // if the last thing in the trivia was a line break, add indentation for following token. if (lineEnd >= trivia.Length && nextLineBreakStart >= 0 && hasFollowingToken) { WriteIndentation(indentation); } } } else { switch (spacingKind) { case SpacingKind.NoSpaceIfOnSameLine: // there was no line break, so make it have no spacing by writing nothing break; case SpacingKind.SingleSpaceIfOnSameLine: // there was no line break, so make it a single space by writing a single space _builder.Append(" "); break; case SpacingKind.NewLine: // there was no line break so add one _builder.AppendLine(); WriteIndentation(indentation); break; case SpacingKind.AsIs: case SpacingKind.AlignOnly: default: _builder.Append(trivia); break; } } }