diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 8144162763533..c55a08808a93b 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -834,9 +834,10 @@ namespace ts.textChanges { /** Note: output node may be mutated input node. */ export function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLineCharacter: string): { text: string, node: Node } { - const writer = new Writer(newLineCharacter); + const omitTrailingSemicolon = !!sourceFile && !probablyUsesSemicolons(sourceFile); + const writer = createWriter(newLineCharacter, omitTrailingSemicolon); const newLine = newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed; - createPrinter({ newLine, neverAsciiEscape: true }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer); + createPrinter({ newLine, neverAsciiEscape: true, omitTrailingSemicolon }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer); return { text: writer.getText(), node: assignPositionsToNode(node) }; } } @@ -874,143 +875,168 @@ namespace ts.textChanges { return nodeArray; } - class Writer implements EmitTextWriter, PrintHandlers { - private lastNonTriviaPosition = 0; - private readonly writer: EmitTextWriter; - - public readonly onEmitNode: PrintHandlers["onEmitNode"]; - public readonly onBeforeEmitNodeArray: PrintHandlers["onBeforeEmitNodeArray"]; - public readonly onAfterEmitNodeArray: PrintHandlers["onAfterEmitNodeArray"]; - public readonly onBeforeEmitToken: PrintHandlers["onBeforeEmitToken"]; - public readonly onAfterEmitToken: PrintHandlers["onAfterEmitToken"]; - - constructor(newLine: string) { - this.writer = createTextWriter(newLine); - this.onEmitNode = (hint, node, printCallback) => { - if (node) { - setPos(node, this.lastNonTriviaPosition); - } - printCallback(hint, node); - if (node) { - setEnd(node, this.lastNonTriviaPosition); - } - }; - this.onBeforeEmitNodeArray = nodes => { - if (nodes) { - setPos(nodes, this.lastNonTriviaPosition); - } - }; - this.onAfterEmitNodeArray = nodes => { - if (nodes) { - setEnd(nodes, this.lastNonTriviaPosition); - } - }; - this.onBeforeEmitToken = node => { - if (node) { - setPos(node, this.lastNonTriviaPosition); - } - }; - this.onAfterEmitToken = node => { - if (node) { - setEnd(node, this.lastNonTriviaPosition); - } - }; - } + interface TextChangesWriter extends EmitTextWriter, PrintHandlers {} + + function createWriter(newLine: string, omitTrailingSemicolon?: boolean): TextChangesWriter { + let lastNonTriviaPosition = 0; + - private setLastNonTriviaPosition(s: string, force: boolean) { + const writer = omitTrailingSemicolon ? getTrailingSemicolonOmittingWriter(createTextWriter(newLine)) : createTextWriter(newLine); + const onEmitNode: PrintHandlers["onEmitNode"] = (hint, node, printCallback) => { + if (node) { + setPos(node, lastNonTriviaPosition); + } + printCallback(hint, node); + if (node) { + setEnd(node, lastNonTriviaPosition); + } + }; + const onBeforeEmitNodeArray: PrintHandlers["onBeforeEmitNodeArray"] = nodes => { + if (nodes) { + setPos(nodes, lastNonTriviaPosition); + } + }; + const onAfterEmitNodeArray: PrintHandlers["onAfterEmitNodeArray"] = nodes => { + if (nodes) { + setEnd(nodes, lastNonTriviaPosition); + } + }; + const onBeforeEmitToken: PrintHandlers["onBeforeEmitToken"] = node => { + if (node) { + setPos(node, lastNonTriviaPosition); + } + }; + const onAfterEmitToken: PrintHandlers["onAfterEmitToken"] = node => { + if (node) { + setEnd(node, lastNonTriviaPosition); + } + }; + + function setLastNonTriviaPosition(s: string, force: boolean) { if (force || !isTrivia(s)) { - this.lastNonTriviaPosition = this.writer.getTextPos(); + lastNonTriviaPosition = writer.getTextPos(); let i = 0; while (isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) { i++; } // trim trailing whitespaces - this.lastNonTriviaPosition -= i; + lastNonTriviaPosition -= i; } } - write(s: string): void { - this.writer.write(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeComment(s: string): void { - this.writer.writeComment(s); - } - writeKeyword(s: string): void { - this.writer.writeKeyword(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeOperator(s: string): void { - this.writer.writeOperator(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writePunctuation(s: string): void { - this.writer.writePunctuation(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeTrailingSemicolon(s: string): void { - this.writer.writeTrailingSemicolon(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeParameter(s: string): void { - this.writer.writeParameter(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeProperty(s: string): void { - this.writer.writeProperty(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeSpace(s: string): void { - this.writer.writeSpace(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeStringLiteral(s: string): void { - this.writer.writeStringLiteral(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeSymbol(s: string, sym: Symbol): void { - this.writer.writeSymbol(s, sym); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeLine(): void { - this.writer.writeLine(); - } - increaseIndent(): void { - this.writer.increaseIndent(); - } - decreaseIndent(): void { - this.writer.decreaseIndent(); - } - getText(): string { - return this.writer.getText(); - } - rawWrite(s: string): void { - this.writer.rawWrite(s); - this.setLastNonTriviaPosition(s, /*force*/ false); - } - writeLiteral(s: string): void { - this.writer.writeLiteral(s); - this.setLastNonTriviaPosition(s, /*force*/ true); - } - getTextPos(): number { - return this.writer.getTextPos(); - } - getLine(): number { - return this.writer.getLine(); - } - getColumn(): number { - return this.writer.getColumn(); - } - getIndent(): number { - return this.writer.getIndent(); - } - isAtStartOfLine(): boolean { - return this.writer.isAtStartOfLine(); - } - clear(): void { - this.writer.clear(); - this.lastNonTriviaPosition = 0; + function write(s: string): void { + writer.write(s); + setLastNonTriviaPosition(s, /*force*/ false); } + function writeComment(s: string): void { + writer.writeComment(s); + } + function writeKeyword(s: string): void { + writer.writeKeyword(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeOperator(s: string): void { + writer.writeOperator(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writePunctuation(s: string): void { + writer.writePunctuation(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeTrailingSemicolon(s: string): void { + writer.writeTrailingSemicolon(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeParameter(s: string): void { + writer.writeParameter(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeProperty(s: string): void { + writer.writeProperty(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeSpace(s: string): void { + writer.writeSpace(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeStringLiteral(s: string): void { + writer.writeStringLiteral(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeSymbol(s: string, sym: Symbol): void { + writer.writeSymbol(s, sym); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeLine(): void { + writer.writeLine(); + } + function increaseIndent(): void { + writer.increaseIndent(); + } + function decreaseIndent(): void { + writer.decreaseIndent(); + } + function getText(): string { + return writer.getText(); + } + function rawWrite(s: string): void { + writer.rawWrite(s); + setLastNonTriviaPosition(s, /*force*/ false); + } + function writeLiteral(s: string): void { + writer.writeLiteral(s); + setLastNonTriviaPosition(s, /*force*/ true); + } + function getTextPos(): number { + return writer.getTextPos(); + } + function getLine(): number { + return writer.getLine(); + } + function getColumn(): number { + return writer.getColumn(); + } + function getIndent(): number { + return writer.getIndent(); + } + function isAtStartOfLine(): boolean { + return writer.isAtStartOfLine(); + } + function clear(): void { + writer.clear(); + lastNonTriviaPosition = 0; + } + + return { + onEmitNode, + onBeforeEmitNodeArray, + onAfterEmitNodeArray, + onBeforeEmitToken, + onAfterEmitToken, + write, + writeComment, + writeKeyword, + writeOperator, + writePunctuation, + writeTrailingSemicolon, + writeParameter, + writeProperty, + writeSpace, + writeStringLiteral, + writeSymbol, + writeLine, + increaseIndent, + decreaseIndent, + getText, + rawWrite, + writeLiteral, + getTextPos, + getLine, + getColumn, + getIndent, + isAtStartOfLine, + clear + }; } function getInsertionPositionAtSourceFileTop(sourceFile: SourceFile): number { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 5506b45d3808d..4c6549b002c9c 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1991,4 +1991,51 @@ namespace ts { }); return typeIsAccessible ? res : undefined; } + + export function syntaxUsuallyHasTrailingSemicolon(kind: SyntaxKind) { + return kind === SyntaxKind.VariableStatement + || kind === SyntaxKind.ExpressionStatement + || kind === SyntaxKind.DoStatement + || kind === SyntaxKind.ContinueStatement + || kind === SyntaxKind.BreakStatement + || kind === SyntaxKind.ReturnStatement + || kind === SyntaxKind.ThrowStatement + || kind === SyntaxKind.DebuggerStatement + || kind === SyntaxKind.PropertyDeclaration + || kind === SyntaxKind.TypeAliasDeclaration + || kind === SyntaxKind.ImportDeclaration + || kind === SyntaxKind.ImportEqualsDeclaration + || kind === SyntaxKind.ExportDeclaration; + } + + export function probablyUsesSemicolons(sourceFile: SourceFile): boolean { + let withSemicolon = 0; + let withoutSemicolon = 0; + const nStatementsToObserve = 5; + forEachChild(sourceFile, function visit(node): boolean | undefined { + if (syntaxUsuallyHasTrailingSemicolon(node.kind)) { + const lastToken = node.getLastToken(sourceFile); + if (lastToken && lastToken.kind === SyntaxKind.SemicolonToken) { + withSemicolon++; + } + else { + withoutSemicolon++; + } + } + if (withSemicolon + withoutSemicolon >= nStatementsToObserve) { + return true; + } + + return forEachChild(node, visit); + }); + + // One statement missing a semicolon isn’t sufficient evidence to say the user + // doesn’t want semicolons, because they may not even be done writing that statement. + if (withSemicolon === 0 && withoutSemicolon <= 1) { + return true; + } + + // If even 2/5 places have a semicolon, the user probably wants semicolons + return withSemicolon / withoutSemicolon > 1 / nStatementsToObserve; + } } diff --git a/tests/cases/fourslash/completionsImport_default_anonymous.ts b/tests/cases/fourslash/completionsImport_default_anonymous.ts index a1eb5da64900d..80ad6494dc6e7 100644 --- a/tests/cases/fourslash/completionsImport_default_anonymous.ts +++ b/tests/cases/fourslash/completionsImport_default_anonymous.ts @@ -14,25 +14,25 @@ goTo.marker("0"); const preferences: FourSlashInterface.UserPreferences = { includeCompletionsForModuleExports: true }; verify.completions( - { + { marker: "0", exact: [ - completion.globalThisEntry, - completion.undefinedVarEntry, - ...completion.statementKeywordsWithTypes - ], - preferences + completion.globalThisEntry, + completion.undefinedVarEntry, + ...completion.statementKeywordsWithTypes + ], + preferences }, { marker: "1", includes: { - name: "fooBar", - source: "/src/foo-bar", - sourceDisplay: "./foo-bar", - text: "(property) default: 0", - kind: "property", - hasAction: true, - sortText: completion.SortText.AutoImportSuggestions + name: "fooBar", + source: "/src/foo-bar", + sourceDisplay: "./foo-bar", + text: "(property) default: 0", + kind: "property", + hasAction: true, + sortText: completion.SortText.AutoImportSuggestions }, preferences, }, @@ -41,7 +41,7 @@ verify.applyCodeActionFromCompletion("1", { name: "fooBar", source: "/src/foo-bar", description: `Import default 'fooBar' from module "./foo-bar"`, - newFileContent: `import fooBar from "./foo-bar"; + newFileContent: `import fooBar from "./foo-bar" def fooB`, diff --git a/tests/cases/fourslash/completionsImport_exportEquals_anonymous.ts b/tests/cases/fourslash/completionsImport_exportEquals_anonymous.ts index b28de47c69db1..e8d675cba8bd7 100644 --- a/tests/cases/fourslash/completionsImport_exportEquals_anonymous.ts +++ b/tests/cases/fourslash/completionsImport_exportEquals_anonymous.ts @@ -38,7 +38,7 @@ verify.applyCodeActionFromCompletion("0", { name: "fooBar", source: "/src/foo-bar", description: `Import 'fooBar' from module "./foo-bar"`, - newFileContent: `import fooBar = require("./foo-bar"); + newFileContent: `import fooBar = require("./foo-bar") exp fooB`, diff --git a/tests/cases/fourslash/completionsImport_noSemicolons.ts b/tests/cases/fourslash/completionsImport_noSemicolons.ts new file mode 100644 index 0000000000000..f1e183b8b3c30 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_noSemicolons.ts @@ -0,0 +1,20 @@ +/// + +// @Filename: /a.ts +////export function foo() {} + +// @Filename: /b.ts +////const x = 0 +////const y = 1 +////const z = fo/**/ + +verify.applyCodeActionFromCompletion("", { + name: "foo", + source: "/a", + description: `Import 'foo' from module "./a"`, + newFileContent: `import { foo } from "./a" + +const x = 0 +const y = 1 +const z = fo`, +}); diff --git a/tests/cases/fourslash/extract-method-in-anonymous-function-declaration.ts b/tests/cases/fourslash/extract-method-in-anonymous-function-declaration.ts index 6566d129874b7..197ad698088e1 100644 --- a/tests/cases/fourslash/extract-method-in-anonymous-function-declaration.ts +++ b/tests/cases/fourslash/extract-method-in-anonymous-function-declaration.ts @@ -1,7 +1,7 @@ /// ////export default function() { -//// /*start*/0/*end*/ +//// /*start*/0/*end*/; ////} goTo.select('start', 'end') diff --git a/tests/cases/fourslash/refactorExtractType11.ts b/tests/cases/fourslash/refactorExtractType11.ts index feb5e68c44093..7f465bef11125 100644 --- a/tests/cases/fourslash/refactorExtractType11.ts +++ b/tests/cases/fourslash/refactorExtractType11.ts @@ -1,7 +1,7 @@ /// //// function foo(a: number, b?: number, ...c: number[]): boolean { -//// return false as /*a*/boolean/*b*/ +//// return false as /*a*/boolean/*b*/; //// } goTo.select("a", "b"); @@ -12,6 +12,6 @@ edit.applyRefactor({ newContent: `function foo(a: number, b?: number, ...c: number[]): boolean { type /*RENAME*/NewType = boolean; - return false as NewType + return false as NewType; }`, }); diff --git a/tests/cases/fourslash/refactorExtractType14.ts b/tests/cases/fourslash/refactorExtractType14.ts index 4d5667bb54001..296550869216d 100644 --- a/tests/cases/fourslash/refactorExtractType14.ts +++ b/tests/cases/fourslash/refactorExtractType14.ts @@ -1,6 +1,6 @@ /// -//// type A = string | number | T +//// type A = string | number | T; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = boolean; -type A = string | number | T`, +type A = string | number | T;`, }); diff --git a/tests/cases/fourslash/refactorExtractType15.ts b/tests/cases/fourslash/refactorExtractType15.ts index a716f42509ad8..84a26de6be4d0 100644 --- a/tests/cases/fourslash/refactorExtractType15.ts +++ b/tests/cases/fourslash/refactorExtractType15.ts @@ -1,6 +1,6 @@ /// -//// type A = /*a*/string/*b*/ | number | T +//// type A = /*a*/string/*b*/ | number | T; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = string; -type A = NewType | number | T`, +type A = NewType | number | T;`, }); diff --git a/tests/cases/fourslash/refactorExtractType17.ts b/tests/cases/fourslash/refactorExtractType17.ts index ae62b402fe3c6..605fccb25d61b 100644 --- a/tests/cases/fourslash/refactorExtractType17.ts +++ b/tests/cases/fourslash/refactorExtractType17.ts @@ -1,6 +1,6 @@ /// -//// type A = string | number | /*a*/T/*b*/ +//// type A = string | number | /*a*/T/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = T; -type A = string | number | NewType`, +type A = string | number | NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType18.ts b/tests/cases/fourslash/refactorExtractType18.ts index 1ebe8a2b35480..310be9b0e289b 100644 --- a/tests/cases/fourslash/refactorExtractType18.ts +++ b/tests/cases/fourslash/refactorExtractType18.ts @@ -1,6 +1,6 @@ /// -//// type A = /*a*/Partial/*b*/ & D | C +//// type A = /*a*/Partial/*b*/ & D | C; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,6 +9,6 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = Partial; -type A = NewType & D | C`, +type A = NewType & D | C;`, }); diff --git a/tests/cases/fourslash/refactorExtractType19.ts b/tests/cases/fourslash/refactorExtractType19.ts index 4a982f6899db4..4ecd563c7ea99 100644 --- a/tests/cases/fourslash/refactorExtractType19.ts +++ b/tests/cases/fourslash/refactorExtractType19.ts @@ -1,6 +1,6 @@ /// -//// type A = /*a*/Partial/*b*/ & D | C +//// type A = /*a*/Partial/*b*/ & D | C; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,6 +9,6 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = Partial; -type A = NewType & D | C`, +type A = NewType & D | C;`, }); diff --git a/tests/cases/fourslash/refactorExtractType20.ts b/tests/cases/fourslash/refactorExtractType20.ts index b31f208704f08..2994418355bd2 100644 --- a/tests/cases/fourslash/refactorExtractType20.ts +++ b/tests/cases/fourslash/refactorExtractType20.ts @@ -1,6 +1,6 @@ /// -//// type A = () => (v: /*a*/T/*b*/) => (v: T) => (v: T) => U +//// type A = () => (v: /*a*/T/*b*/) => (v: T) => (v: T) => U; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = T; -type A = () => (v: NewType) => (v: T) => (v: T) => U`, +type A = () => (v: NewType) => (v: T) => (v: T) => U;`, }); diff --git a/tests/cases/fourslash/refactorExtractType21.ts b/tests/cases/fourslash/refactorExtractType21.ts index e97485c82696e..157e38af75e1b 100644 --- a/tests/cases/fourslash/refactorExtractType21.ts +++ b/tests/cases/fourslash/refactorExtractType21.ts @@ -1,6 +1,6 @@ /// -//// type A = () => (v: T) => (v: /*a*/T/*b*/) => (v: T) => U +//// type A = () => (v: T) => (v: /*a*/T/*b*/) => (v: T) => U; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = T; -type A = () => (v: T) => (v: NewType) => (v: T) => U`, +type A = () => (v: T) => (v: NewType) => (v: T) => U;`, }); diff --git a/tests/cases/fourslash/refactorExtractType22.ts b/tests/cases/fourslash/refactorExtractType22.ts index f7282df4ef707..16344397db656 100644 --- a/tests/cases/fourslash/refactorExtractType22.ts +++ b/tests/cases/fourslash/refactorExtractType22.ts @@ -1,6 +1,6 @@ /// -//// type A = () => (v: T) => (v: T) => (v: /*a*/T/*b*/) => U +//// type A = () => (v: T) => (v: T) => (v: /*a*/T/*b*/) => U; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = T; -type A = () => (v: T) => (v: T) => (v: NewType) => U`, +type A = () => (v: T) => (v: T) => (v: NewType) => U;`, }); diff --git a/tests/cases/fourslash/refactorExtractType23.ts b/tests/cases/fourslash/refactorExtractType23.ts index 9e219dd3383dd..ea8082a3b2a65 100644 --- a/tests/cases/fourslash/refactorExtractType23.ts +++ b/tests/cases/fourslash/refactorExtractType23.ts @@ -1,6 +1,6 @@ /// -//// type A = () => (v: T) => (v: T) => (v: T) => /*a*/U/*b*/ +//// type A = () => (v: T) => (v: T) => (v: T) => /*a*/U/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = U; -type A = () => (v: T) => (v: T) => (v: T) => NewType`, +type A = () => (v: T) => (v: T) => (v: T) => NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType24.ts b/tests/cases/fourslash/refactorExtractType24.ts index 54b36acb252f7..98f3edecc676f 100644 --- a/tests/cases/fourslash/refactorExtractType24.ts +++ b/tests/cases/fourslash/refactorExtractType24.ts @@ -1,6 +1,6 @@ /// -//// type A = () => (v: T) => (v: T) => /*a*/(v: T) => U/*b*/ +//// type A = () => (v: T) => (v: T) => /*a*/(v: T) => U/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = (v: T) => U; -type A = () => (v: T) => (v: T) => NewType`, +type A = () => (v: T) => (v: T) => NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType25.ts b/tests/cases/fourslash/refactorExtractType25.ts index b09d04912c1d9..9ad43742111d1 100644 --- a/tests/cases/fourslash/refactorExtractType25.ts +++ b/tests/cases/fourslash/refactorExtractType25.ts @@ -1,6 +1,6 @@ /// -//// type A = () => (v: T) => /*a*/(v: T) => (v: T) => U/*b*/ +//// type A = () => (v: T) => /*a*/(v: T) => (v: T) => U/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = (v: T) => (v: T) => U; -type A = () => (v: T) => NewType`, +type A = () => (v: T) => NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType26.ts b/tests/cases/fourslash/refactorExtractType26.ts index 662ce7eb8dcab..2dffef7e9ac8b 100644 --- a/tests/cases/fourslash/refactorExtractType26.ts +++ b/tests/cases/fourslash/refactorExtractType26.ts @@ -1,6 +1,6 @@ /// -//// type A = () => /*a*/(v: T) => (v: T) => (v: T) => U/*b*/ +//// type A = () => /*a*/(v: T) => (v: T) => (v: T) => U/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = (v: T) => (v: T) => (v: T) => U; -type A = () => NewType`, +type A = () => NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType27.ts b/tests/cases/fourslash/refactorExtractType27.ts index 5163fd2d48055..e9c8d05601c5b 100644 --- a/tests/cases/fourslash/refactorExtractType27.ts +++ b/tests/cases/fourslash/refactorExtractType27.ts @@ -1,6 +1,6 @@ /// -//// type A = /*a*/() => (v: T) => (v: T) => (v: T) => U/*b*/ +//// type A = /*a*/() => (v: T) => (v: T) => (v: T) => U/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = () => (v: T) => (v: T) => (v: T) => U; -type A = NewType`, +type A = NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType28.ts b/tests/cases/fourslash/refactorExtractType28.ts index 81d1356ca2116..4e53e463a90aa 100644 --- a/tests/cases/fourslash/refactorExtractType28.ts +++ b/tests/cases/fourslash/refactorExtractType28.ts @@ -1,6 +1,6 @@ /// -//// type Item = /*a*/T/*b*/ extends (infer P)[] ? P : never +//// type Item = /*a*/T/*b*/ extends (infer P)[] ? P : never; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = T; -type Item = NewType extends (infer P)[] ? P : never`, +type Item = NewType extends (infer P)[] ? P : never;`, }); diff --git a/tests/cases/fourslash/refactorExtractType29.ts b/tests/cases/fourslash/refactorExtractType29.ts index a1fb2ac405c4f..29fd2ec7e6182 100644 --- a/tests/cases/fourslash/refactorExtractType29.ts +++ b/tests/cases/fourslash/refactorExtractType29.ts @@ -1,6 +1,6 @@ /// -//// type Item = T extends (infer P)[] ? /*a*/P/*b*/ : never +//// type Item = T extends (infer P)[] ? /*a*/P/*b*/ : never; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType

= P; -type Item = T extends (infer P)[] ? NewType

: never`, +type Item = T extends (infer P)[] ? NewType

: never;`, }); diff --git a/tests/cases/fourslash/refactorExtractType30.ts b/tests/cases/fourslash/refactorExtractType30.ts index a0684cabb5300..a3943d3212818 100644 --- a/tests/cases/fourslash/refactorExtractType30.ts +++ b/tests/cases/fourslash/refactorExtractType30.ts @@ -1,6 +1,6 @@ /// -//// type Item = T extends (infer P)[] ? P : /*a*/never/*b*/ +//// type Item = T extends (infer P)[] ? P : /*a*/never/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = never; -type Item = T extends (infer P)[] ? P : NewType`, +type Item = T extends (infer P)[] ? P : NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType34.ts b/tests/cases/fourslash/refactorExtractType34.ts index 114d08a09a6cf..45b4c116549e0 100644 --- a/tests/cases/fourslash/refactorExtractType34.ts +++ b/tests/cases/fourslash/refactorExtractType34.ts @@ -1,6 +1,6 @@ /// -//// type Item = /*a*/T extends (infer P)[] ? P : never/*b*/ +//// type Item = /*a*/T extends (infer P)[] ? P : never/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = T extends (infer P)[] ? P : never; -type Item = NewType`, +type Item = NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType35.ts b/tests/cases/fourslash/refactorExtractType35.ts index 8ace9f929b8b9..979918e13e821 100644 --- a/tests/cases/fourslash/refactorExtractType35.ts +++ b/tests/cases/fourslash/refactorExtractType35.ts @@ -1,6 +1,6 @@ /// -//// type Union = /*a*/U | T/*b*/ +//// type Union = /*a*/U | T/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = U | T; -type Union = NewType`, +type Union = NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType36.ts b/tests/cases/fourslash/refactorExtractType36.ts index 5086bf130cecc..e36983e7440a1 100644 --- a/tests/cases/fourslash/refactorExtractType36.ts +++ b/tests/cases/fourslash/refactorExtractType36.ts @@ -1,6 +1,6 @@ /// -//// type A = (v: /*a*/string | number/*b*/) => v is string +//// type A = (v: /*a*/string | number/*b*/) => v is string; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,6 +9,6 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = string | number; -type A = (v: NewType) => v is string`, +type A = (v: NewType) => v is string;`, }); diff --git a/tests/cases/fourslash/refactorExtractType37.ts b/tests/cases/fourslash/refactorExtractType37.ts index b24e219b3e4e3..d3c9514e4d2e9 100644 --- a/tests/cases/fourslash/refactorExtractType37.ts +++ b/tests/cases/fourslash/refactorExtractType37.ts @@ -1,6 +1,6 @@ /// -//// type A = (v: string | number) => v is /*a*/string/*b*/ +//// type A = (v: string | number) => v is /*a*/string/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = string; -type A = (v: string | number) => v is NewType`, +type A = (v: string | number) => v is NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType39.ts b/tests/cases/fourslash/refactorExtractType39.ts index 1f55dcee39aaf..d5a9688930421 100644 --- a/tests/cases/fourslash/refactorExtractType39.ts +++ b/tests/cases/fourslash/refactorExtractType39.ts @@ -1,6 +1,6 @@ /// -//// type A = /*a*/(v: string | number) => v is string/*b*/ +//// type A = /*a*/(v: string | number) => v is string/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = (v: string | number) => v is string; -type A = NewType`, +type A = NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType42.ts b/tests/cases/fourslash/refactorExtractType42.ts index 29692ab06e6a3..67b6dc51875e4 100644 --- a/tests/cases/fourslash/refactorExtractType42.ts +++ b/tests/cases/fourslash/refactorExtractType42.ts @@ -1,15 +1,15 @@ /// -//// const a = 1 -//// type A = (v: string | number) => /*a*/typeof a/*b*/ +//// const a = 1; +//// type A = (v: string | number) => /*a*/typeof a/*b*/; goTo.select("a", "b"); edit.applyRefactor({ refactorName: "Extract type", actionName: "Extract to type alias", actionDescription: "Extract to type alias", - newContent: `const a = 1 + newContent: `const a = 1; type /*RENAME*/NewType = typeof a; -type A = (v: string | number) => NewType`, +type A = (v: string | number) => NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType44.ts b/tests/cases/fourslash/refactorExtractType44.ts index 22e1a9172dc82..e570c9d60e9bc 100644 --- a/tests/cases/fourslash/refactorExtractType44.ts +++ b/tests/cases/fourslash/refactorExtractType44.ts @@ -1,6 +1,6 @@ /// -//// type A = /*a*/B.C.D/*b*/ +//// type A = /*a*/B.C.D/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = B.C.D; -type A = NewType`, +type A = NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType45.ts b/tests/cases/fourslash/refactorExtractType45.ts index 60d9d77bc29eb..bfc3288e58713 100644 --- a/tests/cases/fourslash/refactorExtractType45.ts +++ b/tests/cases/fourslash/refactorExtractType45.ts @@ -1,6 +1,6 @@ /// -//// type A = /*a*/B.C.D/*b*/ +//// type A = /*a*/B.C.D/*b*/; goTo.select("a", "b"); edit.applyRefactor({ @@ -9,5 +9,5 @@ edit.applyRefactor({ actionDescription: "Extract to type alias", newContent: `type /*RENAME*/NewType = B.C.D; -type A = NewType`, +type A = NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType46.ts b/tests/cases/fourslash/refactorExtractType46.ts index ddcfa4878c9c1..0f244f0ec023e 100644 --- a/tests/cases/fourslash/refactorExtractType46.ts +++ b/tests/cases/fourslash/refactorExtractType46.ts @@ -1,15 +1,15 @@ /// -//// namespace A { export const b = 1 } -//// function a(b: string): /*a*/typeof A.b/*b*/ { return 1 } +//// namespace A { export const b = 1; } +//// function a(b: string): /*a*/typeof A.b/*b*/ { return 1; } goTo.select("a", "b"); edit.applyRefactor({ refactorName: "Extract type", actionName: "Extract to type alias", actionDescription: "Extract to type alias", - newContent: `namespace A { export const b = 1 } + newContent: `namespace A { export const b = 1; } type /*RENAME*/NewType = typeof A.b; -function a(b: string): NewType { return 1 }`, +function a(b: string): NewType { return 1; }`, }); diff --git a/tests/cases/fourslash/refactorExtractType49.ts b/tests/cases/fourslash/refactorExtractType49.ts index 7d965ee3d09e8..96429a91881e6 100644 --- a/tests/cases/fourslash/refactorExtractType49.ts +++ b/tests/cases/fourslash/refactorExtractType49.ts @@ -1,15 +1,15 @@ /// -//// type A = T -//// type B = /*a*/A/*b*/ +//// type A = T; +//// type B = /*a*/A/*b*/; goTo.select("a", "b"); edit.applyRefactor({ refactorName: "Extract type", actionName: "Extract to type alias", actionDescription: "Extract to type alias", - newContent: `type A = T + newContent: `type A = T; type /*RENAME*/NewType = A; -type B = NewType`, +type B = NewType;`, }); diff --git a/tests/cases/fourslash/refactorExtractType7.ts b/tests/cases/fourslash/refactorExtractType7.ts index a5b1f4c7dd049..d1a40f8357997 100644 --- a/tests/cases/fourslash/refactorExtractType7.ts +++ b/tests/cases/fourslash/refactorExtractType7.ts @@ -1,7 +1,7 @@ /// //// function foo(a: /*a*/number/*b*/, b?: number, ...c: number[]): boolean { -//// return false as boolean +//// return false as boolean; //// } goTo.select("a", "b"); @@ -12,6 +12,6 @@ edit.applyRefactor({ newContent: `type /*RENAME*/NewType = number; function foo(a: NewType, b?: number, ...c: number[]): boolean { - return false as boolean + return false as boolean; }`, }); diff --git a/tests/cases/fourslash/refactorExtractType8.ts b/tests/cases/fourslash/refactorExtractType8.ts index 61121c6737457..c13e68e10f511 100644 --- a/tests/cases/fourslash/refactorExtractType8.ts +++ b/tests/cases/fourslash/refactorExtractType8.ts @@ -1,7 +1,7 @@ /// //// function foo(a: number, b?: /*a*/number/*b*/, ...c: number[]): boolean { -//// return false as boolean +//// return false as boolean; //// } goTo.select("a", "b"); @@ -12,6 +12,6 @@ edit.applyRefactor({ newContent: `type /*RENAME*/NewType = number; function foo(a: number, b?: NewType, ...c: number[]): boolean { - return false as boolean + return false as boolean; }`, }); diff --git a/tests/cases/fourslash/refactorExtractType9.ts b/tests/cases/fourslash/refactorExtractType9.ts index 921f2a005a507..49a5f737ee94c 100644 --- a/tests/cases/fourslash/refactorExtractType9.ts +++ b/tests/cases/fourslash/refactorExtractType9.ts @@ -1,7 +1,7 @@ /// //// function foo(a: number, b?: number, ...c: /*a*/number[]/*b*/): boolean { -//// return false as boolean +//// return false as boolean; //// } goTo.select("a", "b"); @@ -12,6 +12,6 @@ edit.applyRefactor({ newContent: `type /*RENAME*/NewType = number[]; function foo(a: number, b?: number, ...c: NewType): boolean { - return false as boolean + return false as boolean; }`, });