public static FormattingSuggestion AnalyzeNewLineBeforeOrAfter( SyntaxToken token, ExpressionSyntax expression, NewLinePosition newLinePosition) { SyntaxToken previousToken = token.GetPreviousToken(); if (newLinePosition == NewLinePosition.Before && SyntaxTriviaAnalysis.IsEmptyOrSingleWhitespaceTrivia(previousToken.TrailingTrivia)) { if (!token.LeadingTrivia.Any() && SyntaxTriviaAnalysis.IsOptionalWhitespaceThenEndOfLineTrivia(token.TrailingTrivia) && SyntaxTriviaAnalysis.IsEmptyOrSingleWhitespaceTrivia(expression.GetLeadingTrivia())) { return(FormattingSuggestion.AddNewLineBefore); } } else if (newLinePosition == NewLinePosition.After && SyntaxTriviaAnalysis.IsOptionalWhitespaceThenEndOfLineTrivia(previousToken.TrailingTrivia)) { if (SyntaxTriviaAnalysis.IsEmptyOrSingleWhitespaceTrivia(token.LeadingTrivia) && SyntaxTriviaAnalysis.IsEmptyOrSingleWhitespaceTrivia(token.TrailingTrivia) && !expression.GetLeadingTrivia().Any()) { return(FormattingSuggestion.AddNewLineAfter); } } return(FormattingSuggestion.None); }
private static void AnalyzeArrowExpressionClause(SyntaxNodeAnalysisContext context) { var arrowExpressionClause = (ArrowExpressionClauseSyntax)context.Node; SyntaxToken arrowToken = arrowExpressionClause.ArrowToken; NewLinePosition newLinePosition = context.GetArrowTokenNewLinePosition(); if (newLinePosition == NewLinePosition.None) { return; } FormattingSuggestion suggestion = FormattingAnalysis.AnalyzeNewLineBeforeOrAfter(arrowToken, arrowExpressionClause.Expression, newLinePosition); if (suggestion == FormattingSuggestion.AddNewLineBefore) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeArrowToken, arrowToken.GetLocation(), "before"); } else if (suggestion == FormattingSuggestion.AddNewLineAfter) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeArrowToken, arrowToken.GetLocation(), properties: DiagnosticProperties.AnalyzerOption_Invert, "after"); } }
private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxToken token, ExpressionSyntax expression) { NewLinePosition newLinePosition = context.GetEqualsSignNewLinePosition(); if (newLinePosition == NewLinePosition.None) { return; } FormattingSuggestion suggestion = FormattingAnalysis.AnalyzeNewLineBeforeOrAfter(token, expression, newLinePosition); if (suggestion == FormattingSuggestion.AddNewLineBefore) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeEqualsToken, token.GetLocation(), "before"); } else if (suggestion == FormattingSuggestion.AddNewLineAfter) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeEqualsToken, token.GetLocation(), properties: DiagnosticProperties.AnalyzerOption_Invert, "after"); } }
private static void AnalyzeConditionalAccess(SyntaxNodeAnalysisContext context) { var conditionalAccess = (ConditionalAccessExpressionSyntax)context.Node; ExpressionSyntax left = conditionalAccess.Expression; if (left.IsMissing) { return; } ExpressionSyntax right = conditionalAccess.WhenNotNull; if (right.IsMissing) { return; } NewLinePosition newLinePosition = context.GetNullConditionalOperatorNewLinePosition(); if (newLinePosition == NewLinePosition.None) { return; } SyntaxToken operatorToken = conditionalAccess.OperatorToken; if (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(left, operatorToken, right)) { if (newLinePosition == NewLinePosition.Before) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeNullConditionalOperator, operatorToken, "before"); } } else if (SyntaxTriviaAnalysis.IsTokenPrecededWithNewLineAndNotFollowedWithNewLine(left, operatorToken, right) && newLinePosition == NewLinePosition.After) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeNullConditionalOperator, Location.Create(conditionalAccess.SyntaxTree, operatorToken.Span), DiagnosticProperties.NewLinePosition_After, "after"); } }
private static void AnalyzeBinaryExpression(SyntaxNodeAnalysisContext context) { var binaryExpression = (BinaryExpressionSyntax)context.Node; ExpressionSyntax left = binaryExpression.Left; if (left.IsMissing) { return; } ExpressionSyntax right = binaryExpression.Right; if (right.IsMissing) { return; } NewLinePosition newLinePosition = context.GetBinaryExpressionNewLinePosition(); if (newLinePosition == NewLinePosition.None) { return; } if (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(left, binaryExpression.OperatorToken, right)) { if (newLinePosition == NewLinePosition.Before) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeBinaryOperator, Location.Create(binaryExpression.SyntaxTree, binaryExpression.OperatorToken.Span.WithLength(0)), "before"); } } else if (SyntaxTriviaAnalysis.IsTokenPrecededWithNewLineAndNotFollowedWithNewLine(left, binaryExpression.OperatorToken, right) && newLinePosition == NewLinePosition.After) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeBinaryOperator, Location.Create(binaryExpression.SyntaxTree, binaryExpression.OperatorToken.Span.WithLength(0)), properties: DiagnosticProperties.AnalyzerOption_Invert, "after"); } }
private static bool TryGetNewLinePosition( AnalyzerConfigOptions configOptions, ConfigOptionDescriptor option, out NewLinePosition newLinePosition) { if (ConfigOptions.TryGetValue(configOptions, option, out string rawValue)) { if (string.Equals(rawValue, "before", StringComparison.OrdinalIgnoreCase)) { newLinePosition = NewLinePosition.Before; return(true); } else if (string.Equals(rawValue, "after", StringComparison.OrdinalIgnoreCase)) { newLinePosition = NewLinePosition.After; return(true); } } newLinePosition = NewLinePosition.None; return(false); }
public override ElementInfo <ParameterSyntax> CreateInfo(ParameterSyntax node, int insertIndex, NewLinePosition newLinePosition) { return(new ParamElementInfo(node, insertIndex, newLinePosition)); }
public ParamElementInfo(ParameterSyntax node, int insertIndex, NewLinePosition newLinePosition) : base(node, insertIndex, newLinePosition) { }
public abstract ElementInfo <TNode> CreateInfo(TNode node, int insertIndex, NewLinePosition newLinePosition);
protected ElementInfo(TNode node, int insertIndex, NewLinePosition newLinePosition) { Node = node; InsertIndex = insertIndex; NewLinePosition = newLinePosition; }
public static NewLinePosition GetNullConditionalOperatorNewLinePosition(this SyntaxNodeAnalysisContext context, NewLinePosition defaultValue = NewLinePosition.None) { return(context.GetConfigOptions().GetNullConditionalOperatorNewLinePosition(defaultValue)); }
public static NewLinePosition GetNullConditionalOperatorNewLinePosition(this AnalyzerConfigOptions configOptions, NewLinePosition defaultValue = NewLinePosition.None) { return((TryGetNewLinePosition(configOptions, ConfigOptions.NullConditionalOperatorNewLine, out NewLinePosition newLinePosition)) ? newLinePosition : defaultValue); }
private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) { var conditionalExpression = (ConditionalExpressionSyntax)context.Node; ExpressionSyntax condition = conditionalExpression.Condition; if (condition.IsMissing) { return; } ExpressionSyntax whenTrue = conditionalExpression.WhenTrue; if (whenTrue.IsMissing) { return; } NewLinePosition newLinePosition = context.GetConditionalExpressionNewLinePosition(); if (newLinePosition == NewLinePosition.None) { return; } if (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(condition, conditionalExpression.QuestionToken, whenTrue)) { if (newLinePosition == NewLinePosition.Before) { ReportDiagnostic(conditionalExpression.QuestionToken, ImmutableDictionary <string, string> .Empty, "before"); return; } } else if (SyntaxTriviaAnalysis.IsTokenPrecededWithNewLineAndNotFollowedWithNewLine(condition, conditionalExpression.QuestionToken, whenTrue)) { if (newLinePosition == NewLinePosition.After) { ReportDiagnostic(conditionalExpression.QuestionToken, DiagnosticProperties.AnalyzerOption_Invert, "after"); return; } } ExpressionSyntax whenFalse = conditionalExpression.WhenFalse; if (!whenFalse.IsMissing) { if (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(whenTrue, conditionalExpression.ColonToken, whenFalse)) { if (newLinePosition == NewLinePosition.Before) { ReportDiagnostic(conditionalExpression.ColonToken, ImmutableDictionary <string, string> .Empty, "before"); } } else if (SyntaxTriviaAnalysis.IsTokenPrecededWithNewLineAndNotFollowedWithNewLine(whenTrue, conditionalExpression.ColonToken, whenFalse)) { if (newLinePosition == NewLinePosition.After) { ReportDiagnostic(conditionalExpression.ColonToken, DiagnosticProperties.AnalyzerOption_Invert, "after"); } } } void ReportDiagnostic( SyntaxToken token, ImmutableDictionary <string, string> properties, string messageArg) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.PlaceNewLineAfterOrBeforeConditionalOperator, Location.Create(token.SyntaxTree, token.Span.WithLength(0)), properties: properties, messageArg); } }
public static Task <Document> FixCallChainAsync( Document document, ExpressionSyntax expression, TextSpan span, CancellationToken cancellationToken = default) { NewLinePosition conditionalAccessOperatorNewLinePosition = document.GetConfigOptions(expression.SyntaxTree).GetNullConditionalOperatorNewLinePosition(NewLinePosition.After); 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 (!memberBinding.HasLeadingTrivia) { SyntaxToken prevToken = memberBinding.GetFirstToken().GetPreviousToken(); if (prevToken.IsKind(SyntaxKind.QuestionToken) && prevToken.IsParentKind(SyntaxKind.ConditionalAccessExpression)) { var conditionalAccess = (ConditionalAccessExpressionSyntax)prevToken.Parent; if (expression.SyntaxTree.IsMultiLineSpan(TextSpan.FromBounds(conditionalAccess.Expression.Span.End, conditionalAccess.OperatorToken.SpanStart))) { continue; } } } if (conditionalAccessOperatorNewLinePosition == NewLinePosition.After && !SetIndentation(memberBinding.OperatorToken)) { break; } } else if (kind == SyntaxKind.ConditionalAccessExpression) { var conditionalAccess = (ConditionalAccessExpressionSyntax)node; if (conditionalAccessOperatorNewLinePosition == NewLinePosition.Before || expression.SyntaxTree.IsMultiLineSpan(TextSpan.FromBounds(conditionalAccess.Expression.Span.End, conditionalAccess.OperatorToken.SpanStart))) { if (!SetIndentation(conditionalAccess.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); SetIndentation2(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); SetIndentation2(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); SetIndentation2(token, prevIndex); prevIndex = trivia.SpanStart; return(true); } } prevIndex = leading.Span.Start - 1; return(true); } void SetIndentation2(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); } } } }