internal FormattingContext(ParsedToken currentToken, ParsedToken nextToken, SourceText sourceText) { Requires.NotNull(currentToken, nameof(currentToken)); Requires.NotNull(nextToken, nameof(nextToken)); Requires.NotNull(sourceText, nameof(sourceText)); this.CurrentToken = currentToken; this.NextToken = nextToken; this.SourceText = sourceText; }
private static IEnumerable <IndentInfo> GetIndentInformation(ParsedToken parsedToken) { Requires.NotNull(parsedToken, nameof(parsedToken)); List <Trivia> leadingTrivia = parsedToken.Token.LeadingTrivia; if (leadingTrivia.Count <= 0) { yield break; } if (parsedToken.Token.FullStart == 0 && leadingTrivia[0].Type == SyntaxKind.Whitespace) { // First token on first line must have no indentation yield return(new IndentInfo(parsedToken.Token.FullStart, leadingTrivia[0].Text.Length, isBeforeText: false)); } int start = parsedToken.Token.FullStart; int length = 0; for (int i = 0; i < leadingTrivia.Count; ++i) { length = leadingTrivia[i].Text.Length; Trivia currentTrivia = leadingTrivia[i]; bool isLastTrivia = i >= leadingTrivia.Count - 1; if (currentTrivia.Type == SyntaxKind.Whitespace) { bool previousTriviaIsNewline = i > 0 && leadingTrivia[i - 1].Type == SyntaxKind.Newline; bool nextTriviaIsNotNewLine = !isLastTrivia && leadingTrivia[i + 1].Type != SyntaxKind.Newline; if (previousTriviaIsNewline && (isLastTrivia || nextTriviaIsNotNewLine)) { yield return(new IndentInfo(start, length, isBeforeText: true)); } } else if (currentTrivia.Type == SyntaxKind.Newline) { bool previousIsNotWhitespace = i <= 0 || leadingTrivia[i - 1].Type != SyntaxKind.Whitespace; bool nextIsNotWhitespace = isLastTrivia || leadingTrivia[i + 1].Type != SyntaxKind.Whitespace; if (previousIsNotWhitespace && nextIsNotWhitespace && IsLastNewLineInTrivia(leadingTrivia, i)) { yield return(new IndentInfo(start + length, 0, isBeforeText: true)); } } start += length; } }
private static string GetIndentationStringFromBlockLevel(ParsedToken parsedToken, FormattingOptions formattingOptions) { int totalSpaces = GetTotalNumberOfSpaces(parsedToken.BlockLevel, formattingOptions); int spacesNeeded = totalSpaces; int tabsNeeded = 0; if (formattingOptions.UsingTabs && formattingOptions.TabSize > 0) { spacesNeeded = totalSpaces % (int)formattingOptions.TabSize; tabsNeeded = (totalSpaces - spacesNeeded) / (int)formattingOptions.TabSize; } return new string('\t', tabsNeeded) + new string(' ', spacesNeeded); }
private static string GetIndentationStringFromBlockLevel(ParsedToken parsedToken, FormattingOptions formattingOptions) { int totalSpaces = GetTotalNumberOfSpaces(parsedToken.BlockLevel, formattingOptions); int spacesNeeded = totalSpaces; int tabsNeeded = 0; if (formattingOptions.UsingTabs && formattingOptions.TabSize > 0) { spacesNeeded = totalSpaces % (int)formattingOptions.TabSize; tabsNeeded = (totalSpaces - spacesNeeded) / (int)formattingOptions.TabSize; } return(new string('\t', tabsNeeded) + new string(' ', spacesNeeded)); }
/// <summary> /// This is main entry point for the VS side of things. For now, the implementation /// of the function is not final and it just used as a way seeing results in VS. /// Ideally, Format will also take in a "formatting option" object that dictates /// the rules that should be enabled, spacing and tabs. /// </summary> /// <param name="sourceText">The SourceText that represents the text to be formatted</param> /// <param name="range">The range of indicies to be formatted</param> /// <param name="formattingOptions">The options to format with, null leaves the options as they were</param> /// <returns> /// A list of TextEditInfo objects are returned for the spacing between tokens (starting from the /// first token in the document to the last token. After the spacing text edits, the indentation /// text edits follow (starting again from the beginning of the document). I might separate the /// indentation text edits from the spacing text edits in the future but for now they are in /// the same list. /// </returns> public List <TextEditInfo> Format(SourceText sourceText, Range range, FormattingOptions formattingOptions) { Requires.NotNull(formattingOptions, nameof(formattingOptions)); Requires.NotNull(sourceText, nameof(sourceText)); this.formattingOptions = formattingOptions; this.ruleMap = RuleMap.Create(this.formattingOptions.OptionalRuleMap); List <TextEditInfo> textEdits = new List <TextEditInfo>(); SyntaxTree syntaxTree = this.parseTreeProvider.Get(sourceText); List <ParsedToken> parsedTokens = new List <ParsedToken>(ParsedToken.GetParsedTokens(syntaxTree, range)); if (syntaxTree.ErrorList.Count == 0) { for (int i = 0; i < parsedTokens.Count - 1; ++i) { FormattingContext formattingContext = new FormattingContext(parsedTokens[i], parsedTokens[i + 1], sourceText); Rule rule = this.ruleMap.Get(formattingContext); if (rule != null) { textEdits.AddRange(rule.Apply(formattingContext)); } } } textEdits.AddRange(Indenter.GetIndentations(parsedTokens, this.formattingOptions)); textEdits.Sort((x, y) => x.Start < y.Start ? 1 : x.Start == y.Start ? 0 : -1); return(textEdits); }
private static IEnumerable<IndentInfo> GetIndentInformation(ParsedToken parsedToken) { Requires.NotNull(parsedToken, nameof(parsedToken)); List<Trivia> leadingTrivia = parsedToken.Token.LeadingTrivia; if (leadingTrivia.Count <= 0) { yield break; } if (parsedToken.Token.FullStart == 0 && leadingTrivia[0].Type == SyntaxKind.Whitespace) { // First token on first line must have no indentation yield return new IndentInfo(parsedToken.Token.FullStart, leadingTrivia[0].Text.Length, isBeforeText: false); } int start = parsedToken.Token.FullStart; int length = 0; for (int i = 0; i < leadingTrivia.Count; ++i) { length = leadingTrivia[i].Text.Length; Trivia currentTrivia = leadingTrivia[i]; bool isLastTrivia = i >= leadingTrivia.Count - 1; if (currentTrivia.Type == SyntaxKind.Whitespace) { bool previousTriviaIsNewline = i > 0 && leadingTrivia[i - 1].Type == SyntaxKind.Newline; bool nextTriviaIsNotNewLine = !isLastTrivia && leadingTrivia[i + 1].Type != SyntaxKind.Newline; if (previousTriviaIsNewline && (isLastTrivia || nextTriviaIsNotNewLine)) { yield return new IndentInfo(start, length, isBeforeText: true); } } else if (currentTrivia.Type == SyntaxKind.Newline) { bool previousIsNotWhitespace = i <= 0 || leadingTrivia[i - 1].Type != SyntaxKind.Whitespace; bool nextIsNotWhitespace = isLastTrivia || leadingTrivia[i + 1].Type != SyntaxKind.Whitespace; if (previousIsNotWhitespace && nextIsNotWhitespace && IsLastNewLineInTrivia(leadingTrivia, i)) { yield return new IndentInfo(start + length, 0, isBeforeText: true); } } start += length; } }