Fix existing tests

This commit is contained in:
Andrew Branch
2019-09-05 14:58:42 -07:00
parent 461e6ad8ea
commit 0d96d40cfd
8 changed files with 67 additions and 12 deletions
+15
View File
@@ -329,6 +329,21 @@ namespace ts {
return undefined;
}
/**
* Like `forEach`, but iterates in reverse order.
*/
export function forEachRight<T, U>(array: ReadonlyArray<T> | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
if (array) {
for (let i = array.length - 1; i >= 0; i--) {
const result = callback(array[i], i);
if (result) {
return result;
}
}
}
return undefined;
}
/** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
export function firstDefined<T, U>(array: ReadonlyArray<T> | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
if (array === undefined) {
+21 -3
View File
@@ -651,6 +651,21 @@ namespace ts.formatting {
consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation, node);
}
if (formattingScanner.isOnEOF()) {
const token = formattingScanner.readEOFTokenRange();
if (token.end <= node.end && previousRange) {
processPair(
token,
sourceFile.getLineAndCharacterOfPosition(token.pos).line,
node,
previousRange,
previousRangeStartLine,
previousParent,
contextNode,
nodeDynamicIndentation);
}
}
function processChildNode(
child: Node,
inheritedIndentation: number,
@@ -950,7 +965,10 @@ namespace ts.formatting {
let trimTrailingWhitespaces = false;
let lineAction = LineAction.None;
if (rules) {
for (const rule of rules) {
// Apply rules in reverse order so that higher when higher priority rules (which are first in the array)
// create text changes at the same position as lower priority rules, the higher priority text changes
// are evaluated last.
forEachRight(rules, rule => {
lineAction = applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
switch (lineAction) {
case LineAction.LineRemoved:
@@ -974,10 +992,10 @@ namespace ts.formatting {
// We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
trimTrailingWhitespaces = !(rule.action & RuleAction.DeleteTrivia) && rule.flags !== RuleFlags.CanDeleteNewLines;
}
});
}
else {
trimTrailingWhitespaces = true;
trimTrailingWhitespaces = currentItem.kind !== SyntaxKind.EndOfFileToken;
}
if (currentStartLine !== previousStartLine && trimTrailingWhitespaces) {
@@ -6,7 +6,9 @@ namespace ts.formatting {
export interface FormattingScanner {
advance(): void;
isOnToken(): boolean;
isOnEOF(): boolean;
readTokenInfo(n: Node): TokenInfo;
readEOFTokenRange(): TextRangeWithKind;
getCurrentLeadingTrivia(): TextRangeWithKind[] | undefined;
lastTrailingTriviaWasNewLine(): boolean;
skipToEndOf(node: Node): void;
@@ -38,7 +40,9 @@ namespace ts.formatting {
const res = cb({
advance,
readTokenInfo,
readEOFTokenRange,
isOnToken,
isOnEOF,
getCurrentLeadingTrivia: () => leadingTrivia,
lastTrailingTriviaWasNewLine: () => wasNewLine,
skipToEndOf,
@@ -249,12 +253,22 @@ namespace ts.formatting {
return token;
}
function readEOFTokenRange(): TextRangeWithKind<SyntaxKind.EndOfFileToken> {
Debug.assert(isOnEOF());
return createTextRangeWithKind(scanner.getStartPos(), scanner.getTextPos(), SyntaxKind.EndOfFileToken);
}
function isOnToken(): boolean {
const current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken();
const startPos = lastTokenInfo ? lastTokenInfo.token.pos : scanner.getStartPos();
return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current);
}
function isOnEOF(): boolean {
const current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken();
return current === SyntaxKind.EndOfFileToken;
}
// when containing node in the tree is token
// but its kind differs from the kind that was returned by the scanner,
// then kind needs to be fixed. This might happen in cases
+6 -3
View File
@@ -9,7 +9,9 @@ namespace ts.formatting {
export function getAllRules(): RuleSpec[] {
const allTokens: SyntaxKind[] = [];
for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) {
allTokens.push(token);
if (token !== SyntaxKind.EndOfFileToken) {
allTokens.push(token);
}
}
function anyTokenExcept(...tokens: SyntaxKind[]): TokenRange {
return { tokens: allTokens.filter(t => !tokens.some(t2 => t2 === t)), isSpecific: false };
@@ -17,6 +19,7 @@ namespace ts.formatting {
const anyToken: TokenRange = { tokens: allTokens, isSpecific: false };
const anyTokenIncludingMultilineComments = tokenRangeFrom([...allTokens, SyntaxKind.MultiLineCommentTrivia]);
const anyTokenIncludingEOF = tokenRangeFrom([...allTokens, SyntaxKind.EndOfFileToken]);
const keywords = tokenRangeFromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword);
const binaryOperators = tokenRangeFromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator);
const binaryKeywordOperators = [SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword];
@@ -310,8 +313,8 @@ namespace ts.formatting {
rule("SpaceBeforeTypeAnnotation", anyToken, SyntaxKind.ColonToken, [isOptionEnabled("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], RuleAction.Space),
rule("NoSpaceBeforeTypeAnnotation", anyToken, SyntaxKind.ColonToken, [isOptionDisabledOrUndefined("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], RuleAction.DeleteTrivia),
rule("NoOptionalSemicolon", SyntaxKind.SemicolonToken, anyToken, [isOptionDisabled("insertTrailingSemicolon"), isSemicolonDeletionContext], RuleAction.DeleteToken),
rule("OptionalSemicolon", anyToken, anyToken, [isOptionEnabled("insertTrailingSemicolon"), isSemicolonInsertionContext], RuleAction.TrailingSemicolon),
rule("NoOptionalSemicolon", SyntaxKind.SemicolonToken, anyTokenIncludingEOF, [isOptionDisabled("insertTrailingSemicolon"), isSemicolonDeletionContext], RuleAction.DeleteToken),
rule("OptionalSemicolon", anyToken, anyTokenIncludingEOF, [isOptionEnabled("insertTrailingSemicolon"), isSemicolonInsertionContext], RuleAction.TrailingSemicolon),
];
function isSemicolonDeletionContext(context: FormattingContext): boolean {
+1 -1
View File
@@ -758,7 +758,7 @@ namespace ts {
insertSpaceBeforeFunctionParenthesis: false,
placeOpenBraceOnNewLineForFunctions: false,
placeOpenBraceOnNewLineForControlBlocks: false,
insertTrailingSemicolon: true,
// insertTrailingSemicolon: true,
};
}
+6 -5
View File
@@ -2054,13 +2054,14 @@ namespace ts {
return false;
}
const sourceFile = node.getSourceFile();
const nextToken = findNextToken(node, sourceFile, sourceFile);
if (!nextToken) {
return false;
// See comment in parser’s `parseDoStatement`
if (node.kind === SyntaxKind.DoStatement) {
return true;
}
if (nextToken.kind === SyntaxKind.CloseBraceToken) {
const sourceFile = node.getSourceFile();
const nextToken = findNextToken(node, sourceFile, sourceFile);
if (!nextToken || nextToken.kind === SyntaxKind.CloseBraceToken) {
return true;
}
+2
View File
@@ -3098,6 +3098,7 @@ declare namespace ts {
export interface UserPreferences {
readonly disableSuggestions?: boolean;
readonly quotePreference?: "auto" | "double" | "single";
readonly semicolonPreference?: "auto" | "semicolons" | "no semicolons";
readonly includeCompletionsForModuleExports?: boolean;
readonly includeCompletionsWithInsertText?: boolean;
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
@@ -5305,6 +5306,7 @@ declare namespace ts {
readonly placeOpenBraceOnNewLineForControlBlocks?: boolean;
readonly insertSpaceBeforeTypeAnnotation?: boolean;
readonly indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
readonly insertTrailingSemicolon?: boolean;
}
function getDefaultFormatCodeSettings(newLineCharacter?: string): FormatCodeSettings;
interface DefinitionInfo extends DocumentSpan {
+2
View File
@@ -3098,6 +3098,7 @@ declare namespace ts {
export interface UserPreferences {
readonly disableSuggestions?: boolean;
readonly quotePreference?: "auto" | "double" | "single";
readonly semicolonPreference?: "auto" | "semicolons" | "no semicolons";
readonly includeCompletionsForModuleExports?: boolean;
readonly includeCompletionsWithInsertText?: boolean;
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
@@ -5305,6 +5306,7 @@ declare namespace ts {
readonly placeOpenBraceOnNewLineForControlBlocks?: boolean;
readonly insertSpaceBeforeTypeAnnotation?: boolean;
readonly indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
readonly insertTrailingSemicolon?: boolean;
}
function getDefaultFormatCodeSettings(newLineCharacter?: string): FormatCodeSettings;
interface DefinitionInfo extends DocumentSpan {