private static void AddIndentBlockOperations(List <IndentBlockOperation> list, SyntaxNode node) { // only add indent block operation if the base token is the first token on line var text = node.SyntaxTree.GetText(); var baseToken = node.Parent.GetFirstToken(includeZeroWidth: true); list.Add(FormattingOperations.CreateRelativeIndentBlockOperation( baseToken, node.GetFirstToken(includeZeroWidth: true).GetNextToken(includeZeroWidth: true), node.GetLastToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true), indentationDelta: 1, option: IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine)); }
protected void AddIndentBlockOperation( List <IndentBlockOperation> list, SyntaxToken startToken, SyntaxToken endToken, IndentBlockOption option = IndentBlockOption.RelativePosition) { if (startToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.None) { return; } list.Add(FormattingOperations.CreateIndentBlockOperation(startToken, endToken, indentationDelta: 1, option: option)); }
private void AddChangeSignatureIndentOperation(List <IndentBlockOperation> list, SyntaxNode node) { if (node.Parent != null) { var baseToken = node.Parent.GetFirstToken(); var startToken = node.GetFirstToken(); var endToken = node.GetLastToken(); var span = CommonFormattingHelpers.GetSpanIncludingTrailingAndLeadingTriviaOfAdjacentTokens(startToken, endToken); span = TextSpan.FromBounds(Math.Max(baseToken.Span.End, span.Start), span.End); list.Add(FormattingOperations.CreateRelativeIndentBlockOperation(baseToken, startToken, endToken, span, indentationDelta: 1, option: IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine)); } }
public override AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustSpacesOperation> nextOperation) { var spaceOperation = base.GetAdjustSpacesOperation(previousToken, currentToken, optionSet, nextOperation); // if there is force space operation, convert it to ForceSpaceIfSingleLine operation. // (force space basically means remove all line breaks) if (spaceOperation != null && spaceOperation.Option == AdjustSpacesOption.ForceSpaces) { return(FormattingOperations.CreateAdjustSpacesOperation(spaceOperation.Space, AdjustSpacesOption.ForceSpacesIfOnSingleLine)); } return(spaceOperation); }
protected void AddAbsoluteZeroIndentBlockOperation( List <IndentBlockOperation> list, SyntaxToken startToken, SyntaxToken endToken, IndentBlockOption option = IndentBlockOption.AbsolutePosition) { if (startToken.CSharpKind() == SyntaxKind.None || endToken.CSharpKind() == SyntaxKind.None) { return; } list.Add(FormattingOperations.CreateIndentBlockOperation(startToken, endToken, indentationDelta: 0, option: option)); }
private static void AddPropertyDeclarationSuppressOperations(List <SuppressOperation> list, SyntaxNode node) { var basePropertyDeclaration = node as BasePropertyDeclarationSyntax; if (basePropertyDeclaration != null && basePropertyDeclaration.AccessorList != null && basePropertyDeclaration.AccessorList.Accessors.All(a => a.Body == null) && basePropertyDeclaration.GetAnnotatedTrivia(SyntaxAnnotation.ElasticAnnotation).Any()) { var tokens = basePropertyDeclaration.GetFirstAndLastMemberDeclarationTokensAfterAttributes(); list.Add(FormattingOperations.CreateSuppressOperation(tokens.Item1, tokens.Item2, SuppressOption.NoWrapping | SuppressOption.IgnoreElastic)); } }
protected static void AddSuppressOperation( List <SuppressOperation> list, SyntaxToken startToken, SyntaxToken endToken, SuppressOption option ) { if (startToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.None) { return; } list.Add(FormattingOperations.CreateSuppressOperation(startToken, endToken, option)); }
public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter( IEnumerable <IFormattingRule> formattingRules, CompilationUnitSyntax root, ITextSnapshotLine line, OptionSet optionSet, CancellationToken cancellationToken) { Contract.ThrowIfNull(formattingRules); Contract.ThrowIfNull(root); Contract.ThrowIfNull(line); if (optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) != FormattingOptions.IndentStyle.Smart) { return(false); } var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition(); if (!firstNonWhitespacePosition.HasValue) { return(false); } var token = root.FindToken(firstNonWhitespacePosition.Value); if (token.IsKind(SyntaxKind.None) || token.SpanStart != firstNonWhitespacePosition) { return(false); } // first see whether there is a line operation for current token var previousToken = token.GetPreviousToken(includeZeroWidth: true); // only use smart token formatter when we have two visible tokens. if (previousToken.Kind() == SyntaxKind.None || previousToken.IsMissing) { return(false); } var lineOperation = FormattingOperations.GetAdjustNewLinesOperation(formattingRules, previousToken, token, optionSet); if (lineOperation != null && lineOperation.Option != AdjustNewLinesOption.ForceLinesIfOnSingleLine) { return(true); } // no indentation operation, nothing to do for smart token formatter return(false); }
private void SuppressVariableDeclaration(List <SuppressOperation> list, SyntaxNode node, OptionSet optionSet) { if (node.IsKind(SyntaxKind.FieldDeclaration) || node.IsKind(SyntaxKind.EventDeclaration) || node.IsKind(SyntaxKind.EventFieldDeclaration) || node.IsKind(SyntaxKind.LocalDeclarationStatement)) { if (optionSet.GetOption(CSharpFormattingOptions.SpacesIgnoreAroundVariableDeclaration)) { var firstToken = node.GetFirstToken(includeZeroWidth: true); var lastToken = node.GetLastToken(includeZeroWidth: true); list.Add(FormattingOperations.CreateSuppressOperation(firstToken, lastToken, SuppressOption.NoSpacing)); } } }
public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation) { // Since we know the general shape of these new import statements, we simply look for where // tokens are not on the same line and force them to only be separated by a single newline. _text.GetLineAndOffset(previousToken.Span.Start, out int previousLine, out _); _text.GetLineAndOffset(currentToken.Span.Start, out int currentLine, out _); if (previousLine != currentLine) { return(FormattingOperations.CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLines)); } return(null); }
public AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation) { // case: insert blank line in empty method body. if (previousToken.Kind() == SyntaxKind.OpenBraceToken && currentToken.Kind() == SyntaxKind.CloseBraceToken) { if (currentToken.Parent.Kind() == SyntaxKind.Block && currentToken.Parent.Parent.Kind() == SyntaxKind.MethodDeclaration) { return(FormattingOperations.CreateAdjustNewLinesOperation(2, AdjustNewLinesOption.ForceLines)); } } return(nextOperation.Invoke()); }
protected static void AddAlignIndentationOfTokensToBaseTokenOperation( List <AlignTokensOperation> list, SyntaxNode containingNode, SyntaxToken baseNode, IEnumerable <SyntaxToken> tokens, AlignTokensOption option = AlignTokensOption.AlignIndentationOfTokensToBaseToken ) { if (containingNode == null || tokens == null) { return; } list.Add(FormattingOperations.CreateAlignTokensOperation(baseNode, tokens, option)); }
public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation) { if (currentToken.Parent != null) { var currentTokenParentParent = currentToken.Parent.Parent; if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentTokenParentParent != null && (currentTokenParentParent.Kind() == SyntaxKind.SimpleLambdaExpression || currentTokenParentParent.Kind() == SyntaxKind.ParenthesizedLambdaExpression || currentTokenParentParent.Kind() == SyntaxKind.AnonymousMethodExpression)) { return(FormattingOperations.CreateAdjustNewLinesOperation(0, AdjustNewLinesOption.PreserveLines)); } } return(nextOperation.Invoke()); }
protected static void SetAlignmentBlockOperation( List <IndentBlockOperation> list, SyntaxToken baseToken, SyntaxToken startToken, SyntaxToken endToken, IndentBlockOption option = IndentBlockOption.RelativePosition ) { list.Add( FormattingOperations.CreateRelativeIndentBlockOperation( baseToken, startToken, endToken, indentationDelta: 0, option: option ) ); }
public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation) { // no line operation. no line changes what so ever var lineOperation = base.GetAdjustNewLinesOperation(previousToken, currentToken, optionSet, nextOperation); if (lineOperation != null) { // ignore force if same line option if (lineOperation.Option == AdjustNewLinesOption.ForceLinesIfOnSingleLine) { return(null); } // basically means don't ever put new line if there isn't already one, but do // indentation. return(FormattingOperations.CreateAdjustNewLinesOperation(line: 0, option: AdjustNewLinesOption.PreserveLines)); } return(null); }
/// <summary> /// Align all the wrapped parts of the expression with the token after 'return'. /// That way we get: /// /// return a == obj.a && /// b == obj.b && /// ... /// </summary> public override void AddIndentBlockOperations( List <IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet, NextAction <IndentBlockOperation> nextOperation) { if (_syntaxFacts.IsReturnStatement(node)) { var expr = _syntaxFacts.GetExpressionOfReturnStatement(node); if (expr?.ChildNodesAndTokens().Count > 1) { list.Add(FormattingOperations.CreateRelativeIndentBlockOperation( expr.GetFirstToken(), expr.GetFirstToken().GetNextToken(), node.GetLastToken(), indentationDelta: 0, option: IndentBlockOption.RelativePosition)); return; } } nextOperation.Invoke(list); }
protected static void AddUnindentBlockOperation( List <IndentBlockOperation> list, SyntaxToken startToken, SyntaxToken endToken, bool includeTriviaAtEnd = false, IndentBlockOption option = IndentBlockOption.RelativePosition ) { if (startToken.Kind() == SyntaxKind.None || endToken.Kind() == SyntaxKind.None) { return; } if (includeTriviaAtEnd) { list.Add( FormattingOperations.CreateIndentBlockOperation( startToken, endToken, indentationDelta: -1, option: option ) ); } else { var startPosition = CommonFormattingHelpers.GetStartPositionOfSpan(startToken); var endPosition = endToken.Span.End; list.Add( FormattingOperations.CreateIndentBlockOperation( startToken, endToken, TextSpan.FromBounds(startPosition, endPosition), indentationDelta: -1, option: option ) ); } }
protected override AdjustNewLinesOperation GetAdjustNewLinesOperationBetweenMembersAndUsings(SyntaxToken token1, SyntaxToken token2) { var previousToken = (SyntaxToken)token1; var currentToken = (SyntaxToken)token2; // We are not between members or usings if the last token wasn't the end of a statement or if the current token // is the end of a scope. if ((previousToken.Kind() != SyntaxKind.SemicolonToken && previousToken.Kind() != SyntaxKind.CloseBraceToken) || currentToken.Kind() == SyntaxKind.CloseBraceToken) { return(null); } SyntaxNode previousMember = FormattingRangeHelper.GetEnclosingMember(previousToken); SyntaxNode nextMember = FormattingRangeHelper.GetEnclosingMember(currentToken); // Is the previous statement an using directive? If so, treat it like a member to add // the right number of lines. if (previousToken.Kind() == SyntaxKind.SemicolonToken && previousToken.Parent.Kind() == SyntaxKind.UsingDirective) { previousMember = previousToken.Parent; } if (previousMember == null || nextMember == null || previousMember == nextMember) { return(null); } // If we have two members of the same kind, we won't insert a blank line if (previousMember.Kind() == nextMember.Kind()) { return(FormattingOperations.CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLines)); } // Force a blank line between the two nodes by counting the number of lines of // trivia and adding one to it. var triviaList = token1.TrailingTrivia.Concat(token2.LeadingTrivia); return(FormattingOperations.CreateAdjustNewLinesOperation(GetNumberOfLines(triviaList) + 1, AdjustNewLinesOption.ForceLines)); }
private void ReplaceCaseIndentationRules(List <IndentBlockOperation> list, SyntaxNode node) { var section = node as SwitchSectionSyntax; if (section == null || section.Statements.Count == 0) { return; } var startToken = section.Statements.First().GetFirstToken(includeZeroWidth: true); var endToken = section.Statements.Last().GetLastToken(includeZeroWidth: true); for (int i = 0; i < list.Count; i++) { var operation = list[i]; if (operation.StartToken == startToken && operation.EndToken == endToken) { // replace operation list[i] = FormattingOperations.CreateIndentBlockOperation(startToken, endToken, indentationDelta: 1, option: IndentBlockOption.RelativePosition); } } }
public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustNewLinesOperation> nextOperation) { // for extract method case, for a hybrid case, don't force rule, but preserve user style var operation = base.GetAdjustNewLinesOperation(previousToken, currentToken, optionSet, nextOperation); if (operation == null) { return(null); } if (operation.Option == AdjustNewLinesOption.ForceLinesIfOnSingleLine) { return(FormattingOperations.CreateAdjustNewLinesOperation(operation.Line, AdjustNewLinesOption.PreserveLines)); } if (operation.Option != AdjustNewLinesOption.ForceLines) { return(operation); } if (previousToken.RawKind == (int)SyntaxKind.OpenBraceToken) { return(operation); } if (previousToken.BetweenFieldAndNonFieldMember(currentToken)) { // make sure to have at least 2 line breaks between field and other members except field return(FormattingOperations.CreateAdjustNewLinesOperation(2, AdjustNewLinesOption.PreserveLines)); } if (previousToken.HasHybridTriviaBetween(currentToken)) { return(FormattingOperations.CreateAdjustNewLinesOperation(operation.Line, AdjustNewLinesOption.PreserveLines)); } return(operation); }
public override void AddIndentBlockOperations( List <IndentBlockOperation> list, SyntaxNode node, OptionSet optionSet, NextAction <IndentBlockOperation> nextOperation) { if (node.HasAnnotation(SpecializedFormattingAnnotation) && node is ConditionalExpressionSyntax conditional) { var statement = conditional.FirstAncestorOrSelf <StatementSyntax>(); if (statement != null) { var baseToken = statement.GetFirstToken(); // we want to indent the ? and : in one level from the containing statement. list.Add(FormattingOperations.CreateRelativeIndentBlockOperation( baseToken, conditional.QuestionToken, conditional.WhenTrue.GetLastToken(), indentationDelta: 1, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine)); list.Add(FormattingOperations.CreateRelativeIndentBlockOperation( baseToken, conditional.ColonToken, conditional.WhenFalse.GetLastToken(), indentationDelta: 1, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine)); return; } } nextOperation.Invoke(list); }
protected static AdjustNewLinesOperation CreateAdjustNewLinesOperation( int line, AdjustNewLinesOption option ) => FormattingOperations.CreateAdjustNewLinesOperation(line, option);
protected AdjustSpacesOperation CreateAdjustSpacesOperation(int space, AdjustSpacesOption option) => FormattingOperations.CreateAdjustSpacesOperation(space, option);
protected AdjustSpacesOperation CreateAdjustSpacesOperation(int space, AdjustSpacesOption option) { return(FormattingOperations.CreateAdjustSpacesOperation(space, option)); }
protected AdjustNewLinesOperation CreateAdjustNewLinesOperation(int line, AdjustNewLinesOption option) { return(FormattingOperations.CreateAdjustNewLinesOperation(line, option)); }
private AdjustNewLinesOperation GetAdjustNewLinesOperationBetweenMembers(SyntaxToken previousToken, SyntaxToken currentToken) { if (!FormattingRangeHelper.InBetweenTwoMembers(previousToken, currentToken)) { return(null); } var previousMember = FormattingRangeHelper.GetEnclosingMember(previousToken); var nextMember = FormattingRangeHelper.GetEnclosingMember(currentToken); if (previousMember == null || nextMember == null) { return(null); } // see whether first non whitespace trivia after before the current member is a comment or not var triviaList = currentToken.LeadingTrivia; var firstNonWhitespaceTrivia = triviaList.FirstOrDefault(trivia => !IsWhitespace(trivia)); if (firstNonWhitespaceTrivia.IsRegularOrDocComment()) { // the first one is a comment, add two more lines than existing number of lines var numberOfLines = GetNumberOfLines(triviaList); var numberOfLinesBeforeComment = GetNumberOfLines(triviaList.Take(triviaList.IndexOf(firstNonWhitespaceTrivia))); var addedLines = (numberOfLinesBeforeComment < 1) ? 2 : 1; return(CreateAdjustNewLinesOperation(numberOfLines + addedLines, AdjustNewLinesOption.ForceLines)); } // If we have two members of the same kind, we won't insert a blank line if both members // have any content (e.g. accessors bodies, non-empty method bodies, etc.). if (previousMember.Kind() == nextMember.Kind()) { // Easy cases: if (previousMember.Kind() == SyntaxKind.FieldDeclaration || previousMember.Kind() == SyntaxKind.EventFieldDeclaration) { // Ensure that fields and events are each declared on a separate line. return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLines)); } // Don't insert a blank line between properties, indexers or events with no accessors if (previousMember is BasePropertyDeclarationSyntax previousProperty) { var nextProperty = (BasePropertyDeclarationSyntax)nextMember; if (previousProperty?.AccessorList?.Accessors.All(a => a.Body == null) == true && nextProperty?.AccessorList?.Accessors.All(a => a.Body == null) == true) { return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines)); } } // Don't insert a blank line between methods with no bodies if (previousMember is BaseMethodDeclarationSyntax previousMethod) { var nextMethod = (BaseMethodDeclarationSyntax)nextMember; if (previousMethod.Body == null && nextMethod.Body == null) { return(CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines)); } } } return(FormattingOperations.CreateAdjustNewLinesOperation(2 /* +1 for member itself and +1 for a blank line*/, AdjustNewLinesOption.ForceLines)); }
public static bool ShouldUseSmartTokenFormatterInsteadOfIndenter( IEnumerable <AbstractFormattingRule> formattingRules, CompilationUnitSyntax root, TextLine line, OptionSet optionSet, out SyntaxToken token) { Contract.ThrowIfNull(formattingRules); Contract.ThrowIfNull(root); token = default; if (!optionSet.GetOption(FormattingOptions.AutoFormattingOnReturn, LanguageNames.CSharp)) { return(false); } if (optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp) != FormattingOptions.IndentStyle.Smart) { return(false); } var firstNonWhitespacePosition = line.GetFirstNonWhitespacePosition(); if (!firstNonWhitespacePosition.HasValue) { return(false); } token = root.FindToken(firstNonWhitespacePosition.Value); if (IsInvalidToken(token)) { return(false); } if (token.IsKind(SyntaxKind.None) || token.SpanStart != firstNonWhitespacePosition) { return(false); } // first see whether there is a line operation for current token var previousToken = token.GetPreviousToken(includeZeroWidth: true); // only use smart token formatter when we have two visible tokens. if (previousToken.Kind() == SyntaxKind.None || previousToken.IsMissing) { return(false); } var lineOperation = FormattingOperations.GetAdjustNewLinesOperation(formattingRules, previousToken, token, optionSet); if (lineOperation == null || lineOperation.Option == AdjustNewLinesOption.ForceLinesIfOnSingleLine) { // no indentation operation, nothing to do for smart token formatter return(false); } // We're pressing enter between two tokens, have the formatter figure out hte appropriate // indentation. return(true); }
// return 1 space for every token pairs as a default operation public AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation <AdjustSpacesOperation> nextOperation) { int space = currentToken.Kind() == SyntaxKind.EndOfFileToken ? 0 : 1; return(FormattingOperations.CreateAdjustSpacesOperation(space, AdjustSpacesOption.DefaultSpacesIfOnSingleLine)); }