From 014dc3dc89754a738f2f470f8a523db31faade57 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 1 Mar 2022 10:22:42 -0800 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#48067=20(Fix=20?= =?UTF-8?q?incorrect=20parser=20error=20assumpti...)=20into=20release-4.6?= =?UTF-8?q?=20(#48068)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com> --- src/compiler/parser.ts | 13 +------------ .../reference/parser0_004152.errors.txt | 4 ++-- .../parserCorruptionAfterMapInClass.ts | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 tests/cases/fourslash/parserCorruptionAfterMapInClass.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c796e78d45190..0dea81baae43b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1680,19 +1680,8 @@ namespace ts { return; } - // If an initializer was parsed but there is still an error in finding the next semicolon, - // we generally know there was an error already reported in the initializer... - // class Example { a = new Map([), ) } - // ~ if (initializer) { - // ...unless we've found the start of a block after a property declaration, in which - // case we can know that regardless of the initializer we should complain on the block. - // class Example { a = 0 {} } - // ~ - if (token() === SyntaxKind.OpenBraceToken) { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); - } - + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); return; } diff --git a/tests/baselines/reference/parser0_004152.errors.txt b/tests/baselines/reference/parser0_004152.errors.txt index a1790a5f7305c..e0fc3f48e0843 100644 --- a/tests/baselines/reference/parser0_004152.errors.txt +++ b/tests/baselines/reference/parser0_004152.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/parser/ecmascript5/Fuzz/parser0_004152.ts(2,28): error TS2304: Cannot find name 'DisplayPosition'. tests/cases/conformance/parser/ecmascript5/Fuzz/parser0_004152.ts(2,45): error TS1137: Expression or comma expected. -tests/cases/conformance/parser/ecmascript5/Fuzz/parser0_004152.ts(2,46): error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. +tests/cases/conformance/parser/ecmascript5/Fuzz/parser0_004152.ts(2,46): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/Fuzz/parser0_004152.ts(2,49): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/Fuzz/parser0_004152.ts(2,51): error TS2300: Duplicate identifier '3'. tests/cases/conformance/parser/ecmascript5/Fuzz/parser0_004152.ts(2,52): error TS1005: ';' expected. @@ -41,7 +41,7 @@ tests/cases/conformance/parser/ecmascript5/Fuzz/parser0_004152.ts(3,25): error T ~ !!! error TS1137: Expression or comma expected. ~ -!!! error TS1068: Unexpected token. A constructor, method, accessor, or property was expected. +!!! error TS1005: ';' expected. ~ !!! error TS1005: ';' expected. ~ diff --git a/tests/cases/fourslash/parserCorruptionAfterMapInClass.ts b/tests/cases/fourslash/parserCorruptionAfterMapInClass.ts new file mode 100644 index 0000000000000..65bc6c5b1ad70 --- /dev/null +++ b/tests/cases/fourslash/parserCorruptionAfterMapInClass.ts @@ -0,0 +1,17 @@ +/// + +// @target: esnext +// @lib: es2015 +// @strict: true + +//// class C { +//// map = new Set/*$*/ +//// +//// foo() { +//// +//// } +//// } + +goTo.marker('$'); +edit.insert('()'); +verify.getSyntacticDiagnostics([]); From e397ed1e387c19aa9c644fbc48b26dfddcfff8f1 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Fri, 11 Mar 2022 10:37:41 -0800 Subject: [PATCH 2/6] Cherry-pick PR #48207 into release-4.6 (#48213) Component commits: d1b063e7be Move `hasOwn` from Object instance to Object constructor Fixes #48206 Co-authored-by: Ryan Cavanaugh --- src/lib/es2022.object.d.ts | 2 +- .../reference/esNextWeakRefs_IterableWeakMap.symbols | 4 ++-- .../inferenceOptionalPropertiesToIndexSignatures.symbols | 2 +- tests/baselines/reference/unionTypeInference.symbols | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/es2022.object.d.ts b/src/lib/es2022.object.d.ts index 764610213b6ac..7325ef3c343e2 100644 --- a/src/lib/es2022.object.d.ts +++ b/src/lib/es2022.object.d.ts @@ -1,4 +1,4 @@ -interface Object { +interface ObjectConstructor { /** * Determines whether an object has a property with the specified name. * @param o An object. diff --git a/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols b/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols index cf1ed59e66d6e..be0559bfe5251 100644 --- a/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols +++ b/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols @@ -297,7 +297,7 @@ export class IterableWeakMap implements WeakMap { Object.defineProperties(IterableWeakMap.prototype, { >Object.defineProperties : Symbol(ObjectConstructor.defineProperties, Decl(lib.es5.d.ts, --, --)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >defineProperties : Symbol(ObjectConstructor.defineProperties, Decl(lib.es5.d.ts, --, --)) >IterableWeakMap.prototype : Symbol(IterableWeakMap.prototype) >IterableWeakMap : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) @@ -322,7 +322,7 @@ Object.defineProperties(IterableWeakMap.prototype, { >value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 89, 23)) >Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", )!.value : Symbol(PropertyDescriptor.value, Decl(lib.es5.d.ts, --, --)) >Object.getOwnPropertyDescriptor : Symbol(ObjectConstructor.getOwnPropertyDescriptor, Decl(lib.es5.d.ts, --, --)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >getOwnPropertyDescriptor : Symbol(ObjectConstructor.getOwnPropertyDescriptor, Decl(lib.es5.d.ts, --, --)) IterableWeakMap.prototype, diff --git a/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.symbols b/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.symbols index 72d4478539d77..9874e516a2b75 100644 --- a/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.symbols +++ b/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.symbols @@ -72,7 +72,7 @@ const query = Object.entries(obj).map( >Object.entries(obj).map( ([k, v]) => `${k}=${encodeURIComponent(v)}`).join : Symbol(Array.join, Decl(lib.es5.d.ts, --, --)) >Object.entries(obj).map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >obj : Symbol(obj, Decl(inferenceOptionalPropertiesToIndexSignatures.ts, 16, 5)) >map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) diff --git a/tests/baselines/reference/unionTypeInference.symbols b/tests/baselines/reference/unionTypeInference.symbols index a4a24b15ebfcc..11fdc52396485 100644 --- a/tests/baselines/reference/unionTypeInference.symbols +++ b/tests/baselines/reference/unionTypeInference.symbols @@ -230,7 +230,7 @@ async function fun(deepPromised: DeepPromised) { for (const value of Object.values(deepPromisedWithIndexer)) { >value : Symbol(value, Decl(unionTypeInference.ts, 62, 14)) >Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >deepPromisedWithIndexer : Symbol(deepPromisedWithIndexer, Decl(unionTypeInference.ts, 61, 9)) From cfdef9de7235ff9eb80b99be86850a65899d7f81 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 16 Mar 2022 11:57:09 -0700 Subject: [PATCH 3/6] Cherry-pick PR #47657 into release-4.6 (#48223) Component commits: 4516fa8421 fix(47597): ignore commented imports following template expression Co-authored-by: Oleksandr T --- src/services/preProcess.ts | 36 ++++ .../unittests/services/preProcessFile.ts | 171 ++++++++++++++++++ 2 files changed, 207 insertions(+) diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 41845616bbe4b..d5c384e9161cc 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -345,6 +345,42 @@ namespace ts { break; } + if (scanner.getToken() === SyntaxKind.TemplateHead) { + const stack = [scanner.getToken()]; + let token = scanner.scan(); + loop: while (length(stack)) { + switch (token) { + case SyntaxKind.EndOfFileToken: + break loop; + case SyntaxKind.ImportKeyword: + tryConsumeImport(); + break; + case SyntaxKind.TemplateHead: + stack.push(token); + break; + case SyntaxKind.OpenBraceToken: + if (length(stack)) { + stack.push(token); + } + break; + case SyntaxKind.CloseBraceToken: + if (length(stack)) { + if (lastOrUndefined(stack) === SyntaxKind.TemplateHead) { + if (scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === SyntaxKind.TemplateTail) { + stack.pop(); + } + } + else { + stack.pop(); + } + } + break; + } + token = scanner.scan(); + } + nextToken(); + } + // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || tryConsumeImport() || diff --git a/src/testRunner/unittests/services/preProcessFile.ts b/src/testRunner/unittests/services/preProcessFile.ts index fb7a7e62649d4..a6369d6e4d4cf 100644 --- a/src/testRunner/unittests/services/preProcessFile.ts +++ b/src/testRunner/unittests/services/preProcessFile.ts @@ -176,6 +176,177 @@ describe("unittests:: services:: PreProcessFile:", () => { }); }); + it("Correctly ignore commented imports following template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("/**" + "\n" + + " * Before" + "\n" + + " * ```" + "\n" + + " * import * as a from \"a\";" + "\n" + + " * ```" + "\n" + + " */" + "\n" + + "type Foo = `${string}`;" + "\n" + + "/**" + "\n" + + " * After" + "\n" + + " * ```" + "\n" + + " * import { B } from \"b\";" + "\n" + + " * import * as c from \"c\";" + "\n" + + " * ```" + "\n" + + " */", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns imports after a template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("`${foo}`; import \"./foo\";", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [ + { fileName: "./foo", pos: 17, end: 22 } + ], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns dynamic imports from template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("`${(
Text `` ${} text {} " + "\n" + + "${import(\"a\")} {import(\"b\")} " + "\n" + + "${/* A comment */} ${/* import(\"ignored\") */}
)}`", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [ + { fileName: "a", pos: 39, end: 40 }, + { fileName: "b", pos: 53, end: 54 } + ], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns dynamic imports from nested template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("`${foo(`${bar(`${import(\"a\")} ${import(\"b\")}`, `${baz(`${import(\"c\") ${import(\"d\")}`)}`)}`)}`", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [ + { fileName: "a", pos: 24, end: 25 }, + { fileName: "b", pos: 39, end: 40 }, + { fileName: "c", pos: 64, end: 65 }, + { fileName: "d", pos: 78, end: 79 }, + ], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns dynamic imports from tagged template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("foo`${ fn({ a: 100 }, import(\"a\"), `${import(\"b\")}`, import(\"c\"), `${import(\"d\")} foo`, import(\"e\")) }`", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [ + { fileName: "a", pos: 29, end: 30 }, + { fileName: "b", pos: 45, end: 46 }, + { fileName: "c", pos: 60, end: 61 }, + { fileName: "d", pos: 76, end: 77 }, + { fileName: "e", pos: 95, end: 96 }, + ], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns dynamic imports from template expression and imports following it", () => { + /* eslint-disable no-template-curly-in-string */ + test("const x = `hello ${await import(\"a\").default}`;" + "\n\n" + + "import { y } from \"b\";", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [ + { fileName: "a", pos: 32, end: 33 }, + { fileName: "b", pos: 67, end: 68 }, + ], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns dynamic imports from template expressions and other imports", () => { + /* eslint-disable no-template-curly-in-string */ + test("const x = `x ${await import(\"a\").default}`;" + "\n\n" + + "import { y } from \"b\";" + "\n" + + "const y = `y ${import(\"c\")}`;" + "\n\n" + + "import { d } from \"d\";", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [ + { fileName: "a", pos: 28, end: 29 }, + { fileName: "b", pos: 63, end: 64 }, + { fileName: "c", pos: 90, end: 91 }, + { fileName: "d", pos: 117, end: 118 }, + ], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns empty importedFiles with incorrect template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("const foo = `${", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + it("Correctly return ES6 exports", () => { test("export * from \"m1\";" + "\n" + "export {a} from \"m2\";" + "\n" + From 2bed482323cda8d081d87084e9bf38aa335c2725 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 16 Mar 2022 19:25:26 +0000 Subject: [PATCH 4/6] Bump version to 4.6.3 and LKG --- lib/lib.es2022.object.d.ts | 2 +- lib/tsc.js | 6 ++--- lib/tsserver.js | 49 ++++++++++++++++++++++++++++---------- lib/tsserverlibrary.js | 49 ++++++++++++++++++++++++++++---------- lib/typescript.js | 49 ++++++++++++++++++++++++++++---------- lib/typescriptServices.js | 49 ++++++++++++++++++++++++++++---------- lib/typingsInstaller.js | 14 ++--------- package.json | 2 +- src/compiler/corePublic.ts | 2 +- 9 files changed, 155 insertions(+), 67 deletions(-) diff --git a/lib/lib.es2022.object.d.ts b/lib/lib.es2022.object.d.ts index 63460100667e4..2fe2a1917f15e 100644 --- a/lib/lib.es2022.object.d.ts +++ b/lib/lib.es2022.object.d.ts @@ -18,7 +18,7 @@ and limitations under the License. /// -interface Object { +interface ObjectConstructor { /** * Determines whether an object has a property with the specified name. * @param o An object. diff --git a/lib/tsc.js b/lib/tsc.js index 7704b1a2be538..15018eb19297b 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -69,7 +69,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { var ts; (function (ts) { ts.versionMajorMinor = "4.6"; - ts.version = "4.6.2"; + ts.version = "4.6.3"; var NativeCollections; (function (NativeCollections) { var globals = typeof globalThis !== "undefined" ? globalThis : @@ -25262,9 +25262,7 @@ var ts; return; } if (initializer) { - if (token() === 18) { - parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26)); - } + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26)); return; } parseErrorForMissingSemicolonAfter(name); diff --git a/lib/tsserver.js b/lib/tsserver.js index ff74f351d1bd6..5b89bb70fc48a 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -100,7 +100,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.2"; + ts.version = "4.6.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -31354,18 +31354,8 @@ var ts; if (tryParseSemicolon()) { return; } - // If an initializer was parsed but there is still an error in finding the next semicolon, - // we generally know there was an error already reported in the initializer... - // class Example { a = new Map([), ) } - // ~ if (initializer) { - // ...unless we've found the start of a block after a property declaration, in which - // case we can know that regardless of the initializer we should complain on the block. - // class Example { a = 0 {} } - // ~ - if (token() === 18 /* OpenBraceToken */) { - parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); - } + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); return; } parseErrorForMissingSemicolonAfter(name); @@ -140014,6 +140004,41 @@ var ts; if (ts.scanner.getToken() === 1 /* EndOfFileToken */) { break; } + if (ts.scanner.getToken() === 15 /* TemplateHead */) { + var stack = [ts.scanner.getToken()]; + var token = ts.scanner.scan(); + loop: while (ts.length(stack)) { + switch (token) { + case 1 /* EndOfFileToken */: + break loop; + case 100 /* ImportKeyword */: + tryConsumeImport(); + break; + case 15 /* TemplateHead */: + stack.push(token); + break; + case 18 /* OpenBraceToken */: + if (ts.length(stack)) { + stack.push(token); + } + break; + case 19 /* CloseBraceToken */: + if (ts.length(stack)) { + if (ts.lastOrUndefined(stack) === 15 /* TemplateHead */) { + if (ts.scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === 17 /* TemplateTail */) { + stack.pop(); + } + } + else { + stack.pop(); + } + } + break; + } + token = ts.scanner.scan(); + } + nextToken(); + } // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || tryConsumeImport() || diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 9290a3661080e..3da500f878173 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -294,7 +294,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.2"; + ts.version = "4.6.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -31548,18 +31548,8 @@ var ts; if (tryParseSemicolon()) { return; } - // If an initializer was parsed but there is still an error in finding the next semicolon, - // we generally know there was an error already reported in the initializer... - // class Example { a = new Map([), ) } - // ~ if (initializer) { - // ...unless we've found the start of a block after a property declaration, in which - // case we can know that regardless of the initializer we should complain on the block. - // class Example { a = 0 {} } - // ~ - if (token() === 18 /* OpenBraceToken */) { - parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); - } + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); return; } parseErrorForMissingSemicolonAfter(name); @@ -140625,6 +140615,41 @@ var ts; if (ts.scanner.getToken() === 1 /* EndOfFileToken */) { break; } + if (ts.scanner.getToken() === 15 /* TemplateHead */) { + var stack = [ts.scanner.getToken()]; + var token = ts.scanner.scan(); + loop: while (ts.length(stack)) { + switch (token) { + case 1 /* EndOfFileToken */: + break loop; + case 100 /* ImportKeyword */: + tryConsumeImport(); + break; + case 15 /* TemplateHead */: + stack.push(token); + break; + case 18 /* OpenBraceToken */: + if (ts.length(stack)) { + stack.push(token); + } + break; + case 19 /* CloseBraceToken */: + if (ts.length(stack)) { + if (ts.lastOrUndefined(stack) === 15 /* TemplateHead */) { + if (ts.scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === 17 /* TemplateTail */) { + stack.pop(); + } + } + else { + stack.pop(); + } + } + break; + } + token = ts.scanner.scan(); + } + nextToken(); + } // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || tryConsumeImport() || diff --git a/lib/typescript.js b/lib/typescript.js index 89cc0ba3ffb18..a852c867159d1 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -294,7 +294,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.2"; + ts.version = "4.6.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -31548,18 +31548,8 @@ var ts; if (tryParseSemicolon()) { return; } - // If an initializer was parsed but there is still an error in finding the next semicolon, - // we generally know there was an error already reported in the initializer... - // class Example { a = new Map([), ) } - // ~ if (initializer) { - // ...unless we've found the start of a block after a property declaration, in which - // case we can know that regardless of the initializer we should complain on the block. - // class Example { a = 0 {} } - // ~ - if (token() === 18 /* OpenBraceToken */) { - parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); - } + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); return; } parseErrorForMissingSemicolonAfter(name); @@ -140625,6 +140615,41 @@ var ts; if (ts.scanner.getToken() === 1 /* EndOfFileToken */) { break; } + if (ts.scanner.getToken() === 15 /* TemplateHead */) { + var stack = [ts.scanner.getToken()]; + var token = ts.scanner.scan(); + loop: while (ts.length(stack)) { + switch (token) { + case 1 /* EndOfFileToken */: + break loop; + case 100 /* ImportKeyword */: + tryConsumeImport(); + break; + case 15 /* TemplateHead */: + stack.push(token); + break; + case 18 /* OpenBraceToken */: + if (ts.length(stack)) { + stack.push(token); + } + break; + case 19 /* CloseBraceToken */: + if (ts.length(stack)) { + if (ts.lastOrUndefined(stack) === 15 /* TemplateHead */) { + if (ts.scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === 17 /* TemplateTail */) { + stack.pop(); + } + } + else { + stack.pop(); + } + } + break; + } + token = ts.scanner.scan(); + } + nextToken(); + } // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || tryConsumeImport() || diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index d1d97fe03d60c..bff3d39041a05 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -294,7 +294,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.2"; + ts.version = "4.6.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -31548,18 +31548,8 @@ var ts; if (tryParseSemicolon()) { return; } - // If an initializer was parsed but there is still an error in finding the next semicolon, - // we generally know there was an error already reported in the initializer... - // class Example { a = new Map([), ) } - // ~ if (initializer) { - // ...unless we've found the start of a block after a property declaration, in which - // case we can know that regardless of the initializer we should complain on the block. - // class Example { a = 0 {} } - // ~ - if (token() === 18 /* OpenBraceToken */) { - parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); - } + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); return; } parseErrorForMissingSemicolonAfter(name); @@ -140625,6 +140615,41 @@ var ts; if (ts.scanner.getToken() === 1 /* EndOfFileToken */) { break; } + if (ts.scanner.getToken() === 15 /* TemplateHead */) { + var stack = [ts.scanner.getToken()]; + var token = ts.scanner.scan(); + loop: while (ts.length(stack)) { + switch (token) { + case 1 /* EndOfFileToken */: + break loop; + case 100 /* ImportKeyword */: + tryConsumeImport(); + break; + case 15 /* TemplateHead */: + stack.push(token); + break; + case 18 /* OpenBraceToken */: + if (ts.length(stack)) { + stack.push(token); + } + break; + case 19 /* CloseBraceToken */: + if (ts.length(stack)) { + if (ts.lastOrUndefined(stack) === 15 /* TemplateHead */) { + if (ts.scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === 17 /* TemplateTail */) { + stack.pop(); + } + } + else { + stack.pop(); + } + } + break; + } + token = ts.scanner.scan(); + } + nextToken(); + } // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || tryConsumeImport() || diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 67aa6f7336aa4..3db755cbfc790 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -89,7 +89,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.2"; + ts.version = "4.6.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -31343,18 +31343,8 @@ var ts; if (tryParseSemicolon()) { return; } - // If an initializer was parsed but there is still an error in finding the next semicolon, - // we generally know there was an error already reported in the initializer... - // class Example { a = new Map([), ) } - // ~ if (initializer) { - // ...unless we've found the start of a block after a property declaration, in which - // case we can know that regardless of the initializer we should complain on the block. - // class Example { a = 0 {} } - // ~ - if (token() === 18 /* OpenBraceToken */) { - parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); - } + parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(26 /* SemicolonToken */)); return; } parseErrorForMissingSemicolonAfter(name); diff --git a/package.json b/package.json index 709da71b59b40..39326e0ed22b3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "https://www.typescriptlang.org/", - "version": "4.6.2", + "version": "4.6.3", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index 2e0d8a0eeff28..8f47cfd4f1dd2 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -5,7 +5,7 @@ namespace ts { // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - export const version = "4.6.2" as string; + export const version = "4.6.3" as string; /** * Type of objects whose values are all of the same type. From fbc2b677bc08e09669aaac96a1ce4462f3ce6cd0 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 29 Mar 2022 15:13:22 -0700 Subject: [PATCH 5/6] Cherry-pick PR #48463 into release-4.6 (#48477) Component commits: 91631435ca Fix newline inserted in empty block at end of formatting range 79b600aaa3 Clean up 19ef6b67c5 Fix refactoring mistake Co-authored-by: Andrew Branch --- src/services/formatting/formatting.ts | 13 +++++++------ src/services/utilities.ts | 10 ++++++---- .../formatOnTypeOpenCurlyWithBraceCompletion.ts | 12 ++++++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 tests/cases/fourslash/formatOnTypeOpenCurlyWithBraceCompletion.ts diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 3b68b44063e62..5a9948cd35f72 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -439,20 +439,21 @@ namespace ts.formatting { } if (previousRange! && formattingScanner.getStartPos() >= originalRange.end) { - const token = + const tokenInfo = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(enclosingNode).token : undefined; - if (token) { + if (tokenInfo) { + const parent = findPrecedingToken(tokenInfo.end, sourceFile, enclosingNode)?.parent || previousParent!; processPair( - token, - sourceFile.getLineAndCharacterOfPosition(token.pos).line, - enclosingNode, + tokenInfo, + sourceFile.getLineAndCharacterOfPosition(tokenInfo.pos).line, + parent, previousRange, previousRangeStartLine!, previousParent!, - enclosingNode, + parent, /*dynamicIndentation*/ undefined); } } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 016eb35227eda..e0465bce94eef 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1256,8 +1256,10 @@ namespace ts { * Finds the rightmost token satisfying `token.end <= position`, * excluding `JsxText` tokens containing only whitespace. */ - export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node, excludeJsdoc?: boolean): Node | undefined { - const result = find(startNode || sourceFile); + export function findPrecedingToken(position: number, sourceFile: SourceFileLike, startNode: Node, excludeJsdoc?: boolean): Node | undefined; + export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node, excludeJsdoc?: boolean): Node | undefined; + export function findPrecedingToken(position: number, sourceFile: SourceFileLike, startNode?: Node, excludeJsdoc?: boolean): Node | undefined { + const result = find((startNode || sourceFile) as Node); Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result))); return result; @@ -1322,7 +1324,7 @@ namespace ts { return isToken(n) && !isWhiteSpaceOnlyJsxText(n); } - function findRightmostToken(n: Node, sourceFile: SourceFile): Node | undefined { + function findRightmostToken(n: Node, sourceFile: SourceFileLike): Node | undefined { if (isNonWhitespaceToken(n)) { return n; } @@ -1339,7 +1341,7 @@ namespace ts { /** * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens. */ - function findRightmostChildNodeWithTokens(children: Node[], exclusiveStartPosition: number, sourceFile: SourceFile, parentKind: SyntaxKind): Node | undefined { + function findRightmostChildNodeWithTokens(children: Node[], exclusiveStartPosition: number, sourceFile: SourceFileLike, parentKind: SyntaxKind): Node | undefined { for (let i = exclusiveStartPosition - 1; i >= 0; i--) { const child = children[i]; diff --git a/tests/cases/fourslash/formatOnTypeOpenCurlyWithBraceCompletion.ts b/tests/cases/fourslash/formatOnTypeOpenCurlyWithBraceCompletion.ts new file mode 100644 index 0000000000000..b303b1ea62d6d --- /dev/null +++ b/tests/cases/fourslash/formatOnTypeOpenCurlyWithBraceCompletion.ts @@ -0,0 +1,12 @@ +/// + +//// if (foo) { +//// if (bar) {/**/} +//// } + +goTo.marker(""); +format.onType("", "{"); +verify.currentFileContentIs( +`if (foo) { + if (bar) { } +}`); From c242d4a46b1085718d5607591b013288c9c88f9c Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 29 Mar 2022 22:35:54 +0000 Subject: [PATCH 6/6] Bump version to 4.6.4 and LKG --- lib/tsc.js | 2 +- lib/tsserver.js | 16 +++++++--------- lib/tsserverlibrary.js | 16 +++++++--------- lib/typescript.js | 16 +++++++--------- lib/typescriptServices.js | 16 +++++++--------- lib/typingsInstaller.js | 2 +- package.json | 2 +- src/compiler/corePublic.ts | 2 +- 8 files changed, 32 insertions(+), 40 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index 15018eb19297b..636e39ae1f4ff 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -69,7 +69,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { var ts; (function (ts) { ts.versionMajorMinor = "4.6"; - ts.version = "4.6.3"; + ts.version = "4.6.4"; var NativeCollections; (function (NativeCollections) { var globals = typeof globalThis !== "undefined" ? globalThis : diff --git a/lib/tsserver.js b/lib/tsserver.js index 5b89bb70fc48a..60a159a673ef0 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -100,7 +100,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.3"; + ts.version = "4.6.4"; /* @internal */ var Comparison; (function (Comparison) { @@ -124964,12 +124964,8 @@ var ts; } } ts.findNextToken = findNextToken; - /** - * Finds the rightmost token satisfying `token.end <= position`, - * excluding `JsxText` tokens containing only whitespace. - */ function findPrecedingToken(position, sourceFile, startNode, excludeJsdoc) { - var result = find(startNode || sourceFile); + var result = find((startNode || sourceFile)); ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result))); return result; function find(n) { @@ -144061,6 +144057,7 @@ var ts; return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); }); } function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, _a, requestKind, rangeContainsError, sourceFile) { + var _b; var options = _a.options, getRules = _a.getRules, host = _a.host; // formatting context is used by rules provider var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options); @@ -144092,11 +144089,12 @@ var ts; } } if (previousRange && formattingScanner.getStartPos() >= originalRange.end) { - var token = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : + var tokenInfo = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(enclosingNode).token : undefined; - if (token) { - processPair(token, sourceFile.getLineAndCharacterOfPosition(token.pos).line, enclosingNode, previousRange, previousRangeStartLine, previousParent, enclosingNode, + if (tokenInfo) { + var parent = ((_b = ts.findPrecedingToken(tokenInfo.end, sourceFile, enclosingNode)) === null || _b === void 0 ? void 0 : _b.parent) || previousParent; + processPair(tokenInfo, sourceFile.getLineAndCharacterOfPosition(tokenInfo.pos).line, parent, previousRange, previousRangeStartLine, previousParent, parent, /*dynamicIndentation*/ undefined); } } diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 3da500f878173..fcb589891a4d5 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -294,7 +294,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.3"; + ts.version = "4.6.4"; /* @internal */ var Comparison; (function (Comparison) { @@ -125575,12 +125575,8 @@ var ts; } } ts.findNextToken = findNextToken; - /** - * Finds the rightmost token satisfying `token.end <= position`, - * excluding `JsxText` tokens containing only whitespace. - */ function findPrecedingToken(position, sourceFile, startNode, excludeJsdoc) { - var result = find(startNode || sourceFile); + var result = find((startNode || sourceFile)); ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result))); return result; function find(n) { @@ -144672,6 +144668,7 @@ var ts; return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); }); } function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, _a, requestKind, rangeContainsError, sourceFile) { + var _b; var options = _a.options, getRules = _a.getRules, host = _a.host; // formatting context is used by rules provider var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options); @@ -144703,11 +144700,12 @@ var ts; } } if (previousRange && formattingScanner.getStartPos() >= originalRange.end) { - var token = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : + var tokenInfo = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(enclosingNode).token : undefined; - if (token) { - processPair(token, sourceFile.getLineAndCharacterOfPosition(token.pos).line, enclosingNode, previousRange, previousRangeStartLine, previousParent, enclosingNode, + if (tokenInfo) { + var parent = ((_b = ts.findPrecedingToken(tokenInfo.end, sourceFile, enclosingNode)) === null || _b === void 0 ? void 0 : _b.parent) || previousParent; + processPair(tokenInfo, sourceFile.getLineAndCharacterOfPosition(tokenInfo.pos).line, parent, previousRange, previousRangeStartLine, previousParent, parent, /*dynamicIndentation*/ undefined); } } diff --git a/lib/typescript.js b/lib/typescript.js index a852c867159d1..3be91a8fa92f4 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -294,7 +294,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.3"; + ts.version = "4.6.4"; /* @internal */ var Comparison; (function (Comparison) { @@ -125575,12 +125575,8 @@ var ts; } } ts.findNextToken = findNextToken; - /** - * Finds the rightmost token satisfying `token.end <= position`, - * excluding `JsxText` tokens containing only whitespace. - */ function findPrecedingToken(position, sourceFile, startNode, excludeJsdoc) { - var result = find(startNode || sourceFile); + var result = find((startNode || sourceFile)); ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result))); return result; function find(n) { @@ -144672,6 +144668,7 @@ var ts; return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); }); } function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, _a, requestKind, rangeContainsError, sourceFile) { + var _b; var options = _a.options, getRules = _a.getRules, host = _a.host; // formatting context is used by rules provider var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options); @@ -144703,11 +144700,12 @@ var ts; } } if (previousRange && formattingScanner.getStartPos() >= originalRange.end) { - var token = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : + var tokenInfo = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(enclosingNode).token : undefined; - if (token) { - processPair(token, sourceFile.getLineAndCharacterOfPosition(token.pos).line, enclosingNode, previousRange, previousRangeStartLine, previousParent, enclosingNode, + if (tokenInfo) { + var parent = ((_b = ts.findPrecedingToken(tokenInfo.end, sourceFile, enclosingNode)) === null || _b === void 0 ? void 0 : _b.parent) || previousParent; + processPair(tokenInfo, sourceFile.getLineAndCharacterOfPosition(tokenInfo.pos).line, parent, previousRange, previousRangeStartLine, previousParent, parent, /*dynamicIndentation*/ undefined); } } diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index bff3d39041a05..e958d4e4d3a2c 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -294,7 +294,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.3"; + ts.version = "4.6.4"; /* @internal */ var Comparison; (function (Comparison) { @@ -125575,12 +125575,8 @@ var ts; } } ts.findNextToken = findNextToken; - /** - * Finds the rightmost token satisfying `token.end <= position`, - * excluding `JsxText` tokens containing only whitespace. - */ function findPrecedingToken(position, sourceFile, startNode, excludeJsdoc) { - var result = find(startNode || sourceFile); + var result = find((startNode || sourceFile)); ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result))); return result; function find(n) { @@ -144672,6 +144668,7 @@ var ts; return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); }); } function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, _a, requestKind, rangeContainsError, sourceFile) { + var _b; var options = _a.options, getRules = _a.getRules, host = _a.host; // formatting context is used by rules provider var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options); @@ -144703,11 +144700,12 @@ var ts; } } if (previousRange && formattingScanner.getStartPos() >= originalRange.end) { - var token = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : + var tokenInfo = formattingScanner.isOnEOF() ? formattingScanner.readEOFTokenRange() : formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(enclosingNode).token : undefined; - if (token) { - processPair(token, sourceFile.getLineAndCharacterOfPosition(token.pos).line, enclosingNode, previousRange, previousRangeStartLine, previousParent, enclosingNode, + if (tokenInfo) { + var parent = ((_b = ts.findPrecedingToken(tokenInfo.end, sourceFile, enclosingNode)) === null || _b === void 0 ? void 0 : _b.parent) || previousParent; + processPair(tokenInfo, sourceFile.getLineAndCharacterOfPosition(tokenInfo.pos).line, parent, previousRange, previousRangeStartLine, previousParent, parent, /*dynamicIndentation*/ undefined); } } diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 3db755cbfc790..715445fffe2bd 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -89,7 +89,7 @@ var ts; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - ts.version = "4.6.3"; + ts.version = "4.6.4"; /* @internal */ var Comparison; (function (Comparison) { diff --git a/package.json b/package.json index 39326e0ed22b3..30243b6a35587 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "https://www.typescriptlang.org/", - "version": "4.6.3", + "version": "4.6.4", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index 8f47cfd4f1dd2..e170ec832229e 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -5,7 +5,7 @@ namespace ts { // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types - export const version = "4.6.3" as string; + export const version = "4.6.4" as string; /** * Type of objects whose values are all of the same type.