mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix existing tests
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -758,7 +758,7 @@ namespace ts {
|
||||
insertSpaceBeforeFunctionParenthesis: false,
|
||||
placeOpenBraceOnNewLineForFunctions: false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
insertTrailingSemicolon: true,
|
||||
// insertTrailingSemicolon: true,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user