From 64704a160d58d52350dc6c0043bc9f75a8d23343 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Wed, 15 Jan 2020 15:42:38 -0500 Subject: [PATCH 01/28] sys: Use readdir withFileTypes option to skip lots of stat syscalls (#35286) This makes walking large directory trees much more efficient on Node 10.10 or later. See: https://lwn.net/Articles/606995/ https://www.python.org/dev/peps/pep-0471/ https://github.com/nodejs/node/pull/22020 https://nodejs.org/en/blog/release/v10.10.0/ Signed-off-by: Anders Kaseorg --- src/compiler/sys.ts | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 514e4333af1e6..a347687e5f883 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1617,23 +1617,32 @@ namespace ts { function getAccessibleFileSystemEntries(path: string): FileSystemEntries { perfLogger.logEvent("ReadDir: " + (path || ".")); try { - const entries = _fs.readdirSync(path || ".").sort(); + const entries = _fs.readdirSync(path || ".", { withFileTypes: true }); const files: string[] = []; const directories: string[] = []; - for (const entry of entries) { + for (const dirent of entries) { + // withFileTypes is not supported before Node 10.10. + const entry = typeof dirent === "string" ? dirent : dirent.name; + // This is necessary because on some file system node fails to exclude // "." and "..". See https://github.com/nodejs/node/issues/4002 if (entry === "." || entry === "..") { continue; } - const name = combinePaths(path, entry); let stat: any; - try { - stat = _fs.statSync(name); + if (typeof dirent === "string" || dirent.isSymbolicLink()) { + const name = combinePaths(path, entry); + + try { + stat = _fs.statSync(name); + } + catch (e) { + continue; + } } - catch (e) { - continue; + else { + stat = dirent; } if (stat.isFile()) { @@ -1643,6 +1652,8 @@ namespace ts { directories.push(entry); } } + files.sort(); + directories.sort(); return { files, directories }; } catch (e) { @@ -1677,8 +1688,7 @@ namespace ts { } function getDirectories(path: string): string[] { - perfLogger.logEvent("ReadDir: " + path); - return filter(_fs.readdirSync(path), dir => fileSystemEntryExists(combinePaths(path, dir), FileSystemEntryKind.Directory)); + return getAccessibleFileSystemEntries(path).directories.slice(); } function realpath(path: string): string { From a9cbea42595d76236bedd9613702b07e78d65a04 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 15 Jan 2020 12:53:40 -0800 Subject: [PATCH 02/28] Use fs.existsSync to check for cancellation (#36190) Unlike statSync, it doesn't throw if the file doesn't exist, saving both time and allocations. --- src/cancellationToken/cancellationToken.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/cancellationToken/cancellationToken.ts b/src/cancellationToken/cancellationToken.ts index 059ef37c8f1e0..aaa19750b8710 100644 --- a/src/cancellationToken/cancellationToken.ts +++ b/src/cancellationToken/cancellationToken.ts @@ -9,13 +9,14 @@ interface ServerCancellationToken { } function pipeExists(name: string): boolean { - try { - fs.statSync(name); - return true; - } - catch (e) { - return false; - } + // Unlike statSync, existsSync doesn't throw an exception if the target doesn't exist. + // A comment in the node code suggests they're stuck with that decision for back compat + // (https://github.com/nodejs/node/blob/9da241b600182a9ff400f6efc24f11a6303c27f7/lib/fs.js#L222). + // Caveat: If a named pipe does exist, the first call to existsSync will return true, as for + // statSync. Subsequent calls will return false, whereas statSync would throw an exception + // indicating that the pipe was busy. The difference is immaterial, since our statSync + // implementation returned false from its catch block. + return fs.existsSync(name); } function createCancellationToken(args: string[]): ServerCancellationToken { From 81a942e7b943ce3a598a640f2a3149ab5f7a97c8 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 15 Jan 2020 13:13:11 -0800 Subject: [PATCH 03/28] Fix completions triggered on existing private identifier property access (#36191) --- src/services/completions.ts | 2 +- .../fourslash/completionsECMAPrivateMember.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/completionsECMAPrivateMember.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index 471d8e4c142c6..9de0d2cb7613f 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -877,7 +877,7 @@ namespace ts.Completions { // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. - if (contextToken && position <= contextToken.end && (isIdentifier(contextToken) || isKeyword(contextToken.kind))) { + if (contextToken && position <= contextToken.end && (isIdentifierOrPrivateIdentifier(contextToken) || isKeyword(contextToken.kind))) { const start = timestamp(); contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined)!; // TODO: GH#18217 log("getCompletionData: Get previous token 2: " + (timestamp() - start)); diff --git a/tests/cases/fourslash/completionsECMAPrivateMember.ts b/tests/cases/fourslash/completionsECMAPrivateMember.ts new file mode 100644 index 0000000000000..16735cc93cc8d --- /dev/null +++ b/tests/cases/fourslash/completionsECMAPrivateMember.ts @@ -0,0 +1,21 @@ +/// + +// @target: esnext + +////class K { +//// #value: number; +//// +//// foo() { +//// this.#va/**/ +//// } +////} + +verify.completions({ + marker: "", + exact: [{ + name: "#value", + insertText: undefined + }, { + name: "foo" + }] +}); From f220e62ce7d4ca63d3bd597acec87404df056142 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Thu, 16 Jan 2020 00:08:17 +0100 Subject: [PATCH 04/28] importsNotUsedAsValue affects semantic diagnostics (#36001) * importsNotUsedAsValue affects semantic diagnostics * add tests --- src/compiler/commandLineParser.ts | 1 + .../unittests/tscWatch/programUpdates.ts | 39 +++ ...mit-when-importsNotUsedAsValues-changes.js | 239 ++++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 tests/baselines/reference/tscWatch/programUpdates/updates-errors-and-emit-when-importsNotUsedAsValues-changes.js diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 300e403b3717f..70bd2c29b7aaa 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -480,6 +480,7 @@ namespace ts { error: importsNotUsedAsValues.Error }), affectsEmit: true, + affectsSemanticDiagnostics: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types }, diff --git a/src/testRunner/unittests/tscWatch/programUpdates.ts b/src/testRunner/unittests/tscWatch/programUpdates.ts index a8539eff38bbc..ede0927aa1967 100644 --- a/src/testRunner/unittests/tscWatch/programUpdates.ts +++ b/src/testRunner/unittests/tscWatch/programUpdates.ts @@ -1121,6 +1121,45 @@ foo().hello` ] }); + verifyTscWatch({ + scenario, + subScenario: "updates errors and emit when importsNotUsedAsValues changes", + commandLineArgs: ["-w"], + sys: () => { + const aFile: File = { + path: `${projectRoot}/a.ts`, + content: `export class C {}` + }; + const bFile: File = { + path: `${projectRoot}/b.ts`, + content: `import {C} from './a'; +export function f(p: C) { return p; }` + }; + const config: File = { + path: `${projectRoot}/tsconfig.json`, + content: JSON.stringify({ compilerOptions: {} }) + }; + return createWatchedSystem([aFile, bFile, config, libFile], { currentDirectory: projectRoot }); + }, + changes: [ + sys => { + sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "remove" } })); + sys.runQueuedTimeoutCallbacks(); + return 'Set to "remove"'; + }, + sys => { + sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "error" } })); + sys.runQueuedTimeoutCallbacks(); + return 'Set to "error"'; + }, + sys => { + sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { importsNotUsedAsValues: "preserve" } })); + sys.runQueuedTimeoutCallbacks(); + return 'Set to "preserve"'; + }, + ] + }); + verifyTscWatch({ scenario, subScenario: "updates errors when ambient modules of program changes", diff --git a/tests/baselines/reference/tscWatch/programUpdates/updates-errors-and-emit-when-importsNotUsedAsValues-changes.js b/tests/baselines/reference/tscWatch/programUpdates/updates-errors-and-emit-when-importsNotUsedAsValues-changes.js new file mode 100644 index 0000000000000..f4d689a0a5ba6 --- /dev/null +++ b/tests/baselines/reference/tscWatch/programUpdates/updates-errors-and-emit-when-importsNotUsedAsValues-changes.js @@ -0,0 +1,239 @@ +/a/lib/tsc.js -w +//// [/user/username/projects/myproject/a.ts] +export class C {} + +//// [/user/username/projects/myproject/b.ts] +import {C} from './a'; +export function f(p: C) { return p; } + +//// [/user/username/projects/myproject/tsconfig.json] +{"compilerOptions":{}} + +//// [/a/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } + +//// [/user/username/projects/myproject/a.js] +"use strict"; +exports.__esModule = true; +var C = /** @class */ (function () { + function C() { + } + return C; +}()); +exports.C = C; + + +//// [/user/username/projects/myproject/b.js] +"use strict"; +exports.__esModule = true; +function f(p) { return p; } +exports.f = f; + + + +Output:: +>> Screen clear +12:00:23 AM - Starting compilation in watch mode... + + + +12:00:28 AM - Found 0 errors. Watching for file changes. + + +Program root files: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts"] +Program options: {"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"} +Program files:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts +/user/username/projects/myproject/b.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts +/user/username/projects/myproject/b.ts + +WatchedFiles:: +/user/username/projects/myproject/tsconfig.json: + {"pollingInterval":250} +/user/username/projects/myproject/a.ts: + {"pollingInterval":250} +/user/username/projects/myproject/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/user/username/projects/myproject/node_modules/@types: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +Change:: Set to "remove" + +//// [/user/username/projects/myproject/tsconfig.json] +{"compilerOptions":{"importsNotUsedAsValues":"remove"}} + +//// [/user/username/projects/myproject/a.js] file written with same contents +//// [/user/username/projects/myproject/b.js] file written with same contents + +Output:: +>> Screen clear +12:00:32 AM - File change detected. Starting incremental compilation... + + + +12:00:39 AM - Found 0 errors. Watching for file changes. + + +Program root files: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts"] +Program options: {"importsNotUsedAsValues":0,"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"} +Program files:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts +/user/username/projects/myproject/b.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts +/user/username/projects/myproject/b.ts + +WatchedFiles:: +/user/username/projects/myproject/tsconfig.json: + {"pollingInterval":250} +/user/username/projects/myproject/a.ts: + {"pollingInterval":250} +/user/username/projects/myproject/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/user/username/projects/myproject/node_modules/@types: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +Change:: Set to "error" + +//// [/user/username/projects/myproject/tsconfig.json] +{"compilerOptions":{"importsNotUsedAsValues":"error"}} + +//// [/user/username/projects/myproject/a.js] file written with same contents +//// [/user/username/projects/myproject/b.js] +"use strict"; +exports.__esModule = true; +require("./a"); +function f(p) { return p; } +exports.f = f; + + + +Output:: +>> Screen clear +12:00:43 AM - File change detected. Starting incremental compilation... + + +b.ts(1,1): error TS1371: This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'. + + +12:00:50 AM - Found 1 error. Watching for file changes. + + +Program root files: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts"] +Program options: {"importsNotUsedAsValues":2,"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"} +Program files:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts +/user/username/projects/myproject/b.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts +/user/username/projects/myproject/b.ts + +WatchedFiles:: +/user/username/projects/myproject/tsconfig.json: + {"pollingInterval":250} +/user/username/projects/myproject/a.ts: + {"pollingInterval":250} +/user/username/projects/myproject/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/user/username/projects/myproject/node_modules/@types: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +Change:: Set to "preserve" + +//// [/user/username/projects/myproject/tsconfig.json] +{"compilerOptions":{"importsNotUsedAsValues":"preserve"}} + +//// [/user/username/projects/myproject/a.js] file written with same contents +//// [/user/username/projects/myproject/b.js] file written with same contents + +Output:: +>> Screen clear +12:00:54 AM - File change detected. Starting incremental compilation... + + + +12:01:01 AM - Found 0 errors. Watching for file changes. + + +Program root files: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts"] +Program options: {"importsNotUsedAsValues":1,"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"} +Program files:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts +/user/username/projects/myproject/b.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts +/user/username/projects/myproject/b.ts + +WatchedFiles:: +/user/username/projects/myproject/tsconfig.json: + {"pollingInterval":250} +/user/username/projects/myproject/a.ts: + {"pollingInterval":250} +/user/username/projects/myproject/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/user/username/projects/myproject/node_modules/@types: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined From f99072593dc130e0073762d3071aa64882be0823 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 15 Jan 2020 16:48:00 -0800 Subject: [PATCH 05/28] Move individual duration properties into a `performanceData` object (#36210) --- src/server/protocol.ts | 7 ++++++- src/server/session.ts | 6 +++++- src/testRunner/unittests/tsserver/session.ts | 10 +++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 973d1ddedb207..e4317934f08ef 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -237,10 +237,15 @@ namespace ts.server.protocol { */ metadata?: unknown; + /* @internal */ + performanceData?: PerformanceData; + } + + /* @internal */ + export interface PerformanceData { /** * Time spent updating the program graph, in milliseconds. */ - /* @internal */ updateGraphDurationMs?: number; } diff --git a/src/server/session.ts b/src/server/session.ts index 932598104e826..b256dfe139cef 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -807,7 +807,11 @@ namespace ts.server { command: cmdName, request_seq: reqSeq, success, - updateGraphDurationMs: this.updateGraphDurationMs, + performanceData: !this.updateGraphDurationMs + ? undefined + : { + updateGraphDurationMs: this.updateGraphDurationMs, + }, }; if (success) { diff --git a/src/testRunner/unittests/tsserver/session.ts b/src/testRunner/unittests/tsserver/session.ts index 68c5ff274fe5e..258ac29d26ffc 100644 --- a/src/testRunner/unittests/tsserver/session.ts +++ b/src/testRunner/unittests/tsserver/session.ts @@ -101,7 +101,7 @@ namespace ts.server { message: "Unrecognized JSON command: foobar", request_seq: 0, success: false, - updateGraphDurationMs: undefined, + performanceData: undefined, }; expect(lastSent).to.deep.equal(expected); }); @@ -128,7 +128,7 @@ namespace ts.server { request_seq: 0, seq: 0, body: undefined, - updateGraphDurationMs: undefined, + performanceData: undefined, }); }); it("should handle literal types in request", () => { @@ -329,7 +329,7 @@ namespace ts.server { request_seq: 0, seq: 0, body: undefined, - updateGraphDurationMs: undefined, + performanceData: undefined, }); }); }); @@ -420,7 +420,7 @@ namespace ts.server { command, body, success: true, - updateGraphDurationMs: undefined, + performanceData: undefined, }); }); }); @@ -540,7 +540,7 @@ namespace ts.server { command, body, success: true, - updateGraphDurationMs: undefined, + performanceData: undefined, }); }); it("can add and respond to new protocol handlers", () => { From dbd55b3928cec8c571b0a55623e781535039f1cb Mon Sep 17 00:00:00 2001 From: Alexander T Date: Thu, 16 Jan 2020 02:56:40 +0200 Subject: [PATCH 06/28] fix(35944): show spell checking quick fix for non-existent private named property access (#36195) --- src/compiler/types.ts | 2 +- src/services/codefixes/fixSpelling.ts | 5 +++-- .../fourslash/codeFixSpellingPropertyAccess.ts | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/codeFixSpellingPropertyAccess.ts diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 98f2531b6c6d1..6102205a4d0c6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3484,7 +3484,7 @@ namespace ts { */ /* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined; getApparentType(type: Type): Type; - /* @internal */ getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined; + /* @internal */ getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined; /* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined; /* @internal */ getSuggestionForNonexistentExport(node: Identifier, target: Symbol): string | undefined; getBaseConstraintOfType(type: Type): Type | undefined; diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index a2fa37b22fe72..725237dd99ec2 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -36,12 +36,13 @@ namespace ts.codefix { let suggestion: string | undefined; if (isPropertyAccessExpression(node.parent) && node.parent.name === node) { - Debug.assert(node.kind === SyntaxKind.Identifier, "Expected an identifier for spelling (property access)"); + Debug.assert(isIdentifierOrPrivateIdentifier(node), "Expected an identifier for spelling (property access)"); let containingType = checker.getTypeAtLocation(node.parent.expression); if (node.parent.flags & NodeFlags.OptionalChain) { containingType = checker.getNonNullableType(containingType); } - suggestion = checker.getSuggestionForNonexistentProperty(node as Identifier, containingType); + const name = node as Identifier | PrivateIdentifier; + suggestion = checker.getSuggestionForNonexistentProperty(name, containingType); } else if (isImportSpecifier(node.parent) && node.parent.name === node) { Debug.assert(node.kind === SyntaxKind.Identifier, "Expected an identifier for spelling (import)"); diff --git a/tests/cases/fourslash/codeFixSpellingPropertyAccess.ts b/tests/cases/fourslash/codeFixSpellingPropertyAccess.ts new file mode 100644 index 0000000000000..04ddb9a5caa29 --- /dev/null +++ b/tests/cases/fourslash/codeFixSpellingPropertyAccess.ts @@ -0,0 +1,17 @@ +/// + +////const foo = { +//// bar: 1 +////} +//// +////const bar = [|foo.#bar|]; + +verify.codeFixAvailable([ + { description: "Change spelling to 'bar'" }, +]); + +verify.codeFix({ + index: 0, + description: "Change spelling to 'bar'", + newRangeContent: "foo.bar" +}); From eeff036519362513cc86a95e260a281a725295f4 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Thu, 16 Jan 2020 19:01:21 +0200 Subject: [PATCH 07/28] fix(35954): Change spelling for private field incorrectly fixes to a string property (#36079) * fix(35954): code fix incorrectly fixes private properties spelling issues * remove duplicate function calls --- src/compiler/checker.ts | 7 +++-- src/compiler/types.ts | 3 ++ src/services/codefixes/fixSpelling.ts | 31 ++++++++++++------- .../codeFixSpellingPrivatePropertyName.ts | 21 +++++++++++++ ...deFixSpellingPropertyNameStartsWithHash.ts | 20 ++++++++++++ 5 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts create mode 100644 tests/cases/fourslash/codeFixSpellingPropertyNameStartsWithHash.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 966e6f4e4c75c..b6a40258f69e6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -570,9 +570,12 @@ namespace ts { isArrayLikeType, isTypeInvalidDueToUnionDiscriminant, getAllPossiblePropertiesOfTypes, - getSuggestionForNonexistentProperty: (node, type) => getSuggestionForNonexistentProperty(node, type), + getSuggestedSymbolForNonexistentProperty, + getSuggestionForNonexistentProperty, + getSuggestedSymbolForNonexistentSymbol: (location, name, meaning) => getSuggestedSymbolForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning), getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning), - getSuggestionForNonexistentExport: (node, target) => getSuggestionForNonexistentExport(node, target), + getSuggestedSymbolForNonexistentModule, + getSuggestionForNonexistentExport, getBaseConstraintOfType, getDefaultFromTypeParameter: type => type && type.flags & TypeFlags.TypeParameter ? getDefaultFromTypeParameter(type as TypeParameter) : undefined, resolveName(name, location, meaning, excludeGlobals) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6102205a4d0c6..1009e75fa89c8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3484,8 +3484,11 @@ namespace ts { */ /* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined; getApparentType(type: Type): Type; + /* @internal */ getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined; /* @internal */ getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined; + /* @internal */ getSuggestedSymbolForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): Symbol | undefined; /* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined; + /* @internal */ getSuggestedSymbolForNonexistentModule(node: Identifier, target: Symbol): Symbol | undefined; /* @internal */ getSuggestionForNonexistentExport(node: Identifier, target: Symbol): string | undefined; getBaseConstraintOfType(type: Type): Type | undefined; getDefaultFromTypeParameter(type: Type): Type | undefined; diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index 725237dd99ec2..037f00462c05a 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -14,27 +14,27 @@ namespace ts.codefix { const { sourceFile } = context; const info = getInfo(sourceFile, context.span.start, context); if (!info) return undefined; - const { node, suggestion } = info; + const { node, suggestedSymbol } = info; const { target } = context.host.getCompilationSettings(); - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node, suggestion, target!)); - return [createCodeFixAction("spelling", changes, [Diagnostics.Change_spelling_to_0, suggestion], fixId, Diagnostics.Fix_all_detected_spelling_errors)]; + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node, suggestedSymbol, target!)); + return [createCodeFixAction("spelling", changes, [Diagnostics.Change_spelling_to_0, symbolName(suggestedSymbol)], fixId, Diagnostics.Fix_all_detected_spelling_errors)]; }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { const info = getInfo(diag.file, diag.start, context); const { target } = context.host.getCompilationSettings(); - if (info) doChange(changes, context.sourceFile, info.node, info.suggestion, target!); + if (info) doChange(changes, context.sourceFile, info.node, info.suggestedSymbol, target!); }), }); - function getInfo(sourceFile: SourceFile, pos: number, context: CodeFixContextBase): { node: Node, suggestion: string } | undefined { + function getInfo(sourceFile: SourceFile, pos: number, context: CodeFixContextBase): { node: Node, suggestedSymbol: Symbol } | undefined { // This is the identifier of the misspelled word. eg: // this.speling = 1; // ^^^^^^^ const node = getTokenAtPosition(sourceFile, pos); const checker = context.program.getTypeChecker(); - let suggestion: string | undefined; + let suggestedSymbol: Symbol | undefined; if (isPropertyAccessExpression(node.parent) && node.parent.name === node) { Debug.assert(isIdentifierOrPrivateIdentifier(node), "Expected an identifier for spelling (property access)"); let containingType = checker.getTypeAtLocation(node.parent.expression); @@ -42,29 +42,36 @@ namespace ts.codefix { containingType = checker.getNonNullableType(containingType); } const name = node as Identifier | PrivateIdentifier; - suggestion = checker.getSuggestionForNonexistentProperty(name, containingType); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(name, containingType); } else if (isImportSpecifier(node.parent) && node.parent.name === node) { Debug.assert(node.kind === SyntaxKind.Identifier, "Expected an identifier for spelling (import)"); const importDeclaration = findAncestor(node, isImportDeclaration)!; const resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration); if (resolvedSourceFile && resolvedSourceFile.symbol) { - suggestion = checker.getSuggestionForNonexistentExport(node as Identifier, resolvedSourceFile.symbol); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(node as Identifier, resolvedSourceFile.symbol); } } else { const meaning = getMeaningFromLocation(node); const name = getTextOfNode(node); Debug.assert(name !== undefined, "name should be defined"); - suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); } - return suggestion === undefined ? undefined : { node, suggestion }; + return suggestedSymbol === undefined ? undefined : { node, suggestedSymbol }; } - function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: Node, suggestion: string, target: ScriptTarget) { + function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: Node, suggestedSymbol: Symbol, target: ScriptTarget) { + const suggestion = symbolName(suggestedSymbol); if (!isIdentifierText(suggestion, target) && isPropertyAccessExpression(node.parent)) { - changes.replaceNode(sourceFile, node.parent, createElementAccess(node.parent.expression, createLiteral(suggestion))); + const valDecl = suggestedSymbol.valueDeclaration; + if (isNamedDeclaration(valDecl) && isPrivateIdentifier(valDecl.name)) { + changes.replaceNode(sourceFile, node, createIdentifier(suggestion)); + } + else { + changes.replaceNode(sourceFile, node.parent, createElementAccess(node.parent.expression, createLiteral(suggestion))); + } } else { changes.replaceNode(sourceFile, node, createIdentifier(suggestion)); diff --git a/tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts b/tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts new file mode 100644 index 0000000000000..7952f45ab5f5a --- /dev/null +++ b/tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts @@ -0,0 +1,21 @@ +/// + +////class A { +//// #foo: number; +//// constructor() { +//// [|this.foo = 1;|] +//// } +////} + +verify.codeFixAvailable([ + { description: "Change spelling to '#foo'" }, + { description: "Declare property 'foo'" }, + { description: "Add index signature for property 'foo'" }, + { description: "Remove declaration for: '#foo'" }, +]); + +verify.codeFix({ + index: 0, + description: "Change spelling to '#foo'", + newRangeContent: "this.#foo = 1;" +}); diff --git a/tests/cases/fourslash/codeFixSpellingPropertyNameStartsWithHash.ts b/tests/cases/fourslash/codeFixSpellingPropertyNameStartsWithHash.ts new file mode 100644 index 0000000000000..0bc7eff06cd6a --- /dev/null +++ b/tests/cases/fourslash/codeFixSpellingPropertyNameStartsWithHash.ts @@ -0,0 +1,20 @@ +/// + +////class A { +//// "#foo": number = 100; +//// constructor() { +//// [|this.foo = 1;|] +//// } +////} + +verify.codeFixAvailable([ + { description: "Change spelling to '#foo'" }, + { description: "Declare property 'foo'" }, + { description: "Add index signature for property 'foo'" } +]); + +verify.codeFix({ + index: 0, + description: "Change spelling to '#foo'", + newRangeContent: 'this["#foo"] = 1;' +}); From 797c5362a2fc43c130a0d80807b9caaa759cf372 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 16 Jan 2020 10:07:37 -0800 Subject: [PATCH 08/28] =?UTF-8?q?Codefix:=20Don=E2=80=99t=20return=20a=20`?= =?UTF-8?q?fixId`=20if=20there=E2=80=99s=20definitely=20nothing=20else=20t?= =?UTF-8?q?hat=20can=20be=20fixed=20(#35765)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Start fixing fixId * Fix tests * Add comment * Fix unit tests, remove fixAllDescription when unavailable * Add codeFixAllAvailable to fourslash harness --- src/harness/fourslashImpl.ts | 28 ++++++++++++++++--- src/harness/fourslashInterfaceImpl.ts | 4 +++ src/services/codeFixProvider.ts | 28 ++++++++++++++++--- src/services/codefixes/addMissingAwait.ts | 4 ++- src/services/codefixes/addMissingConst.ts | 6 ++-- src/services/codefixes/convertToEs6Module.ts | 2 +- .../codefixes/disableJsDiagnostics.ts | 2 +- src/services/codefixes/fixAddMissingMember.ts | 2 +- .../fixEnableExperimentalDecorators.ts | 2 +- src/services/codefixes/fixEnableJsxFlag.ts | 2 +- .../codefixes/fixInvalidImportSyntax.ts | 4 +-- src/services/codefixes/importFixes.ts | 5 ++-- .../unittests/tsserver/duplicatePackages.ts | 4 +-- .../unittests/tsserver/untitledFiles.ts | 4 +-- .../codeFixAddMissingAwait_initializer4.ts | 11 +------- .../fourslash/codeFixAddMissingMember10.ts | 6 ++-- .../fourslash/codeFixAddMissingMember11.ts | 6 ++-- .../fourslash/codeFixAddMissingMember9.ts | 6 ++-- ...eFixAddMissingMember_generator_function.ts | 6 ++-- ...AddMissingMember_non_generator_function.ts | 6 ++-- .../fourslash/codeFixInferFromUsageCallJS.ts | 6 ++-- tests/cases/fourslash/fourslash.ts | 1 + .../importNameCodeFixWithPrologue.ts | 10 +++---- 23 files changed, 97 insertions(+), 58 deletions(-) diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 972c191f189f0..eb33a99d6f6ec 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -2544,8 +2544,8 @@ namespace FourSlash { public verifyCodeFixAll({ fixId, fixAllDescription, newFileContent, commands: expectedCommands }: FourSlashInterface.VerifyCodeFixAllOptions): void { const fixWithId = ts.find(this.getCodeFixes(this.activeFile.fileName), a => a.fixId === fixId); - ts.Debug.assert(fixWithId !== undefined, "No available code fix has that group id.", () => - `Expected '${fixId}'. Available action ids: ${ts.mapDefined(this.getCodeFixes(this.activeFile.fileName), a => a.fixId)}`); + ts.Debug.assert(fixWithId !== undefined, "No available code fix has the expected id. Fix All is not available if there is only one potentially fixable diagnostic present.", () => + `Expected '${fixId}'. Available actions:\n${ts.mapDefined(this.getCodeFixes(this.activeFile.fileName), a => `${a.fixName} (${a.fixId || "no fix id"})`).join("\n")}`); ts.Debug.assertEqual(fixWithId!.fixAllDescription, fixAllDescription); const { changes, commands } = this.languageService.getCombinedCodeFix({ type: "file", fileName: this.activeFile.fileName }, fixId, this.formatCodeSettings, ts.emptyOptions); @@ -2681,7 +2681,7 @@ namespace FourSlash { } const range = ts.firstOrUndefined(ranges); - const codeFixes = this.getCodeFixes(fileName, errorCode, preferences).filter(f => f.fixId === ts.codefix.importFixId); + const codeFixes = this.getCodeFixes(fileName, errorCode, preferences).filter(f => f.fixName === ts.codefix.importFixName); if (codeFixes.length === 0) { if (expectedTextArray.length !== 0) { @@ -2717,7 +2717,7 @@ namespace FourSlash { const codeFixes = this.getCodeFixes(marker.fileName, ts.Diagnostics.Cannot_find_name_0.code, { includeCompletionsForModuleExports: true, includeCompletionsWithInsertText: true - }, marker.position).filter(f => f.fixId === ts.codefix.importFixId); + }, marker.position).filter(f => f.fixName === ts.codefix.importFixName); const actualModuleSpecifiers = ts.mapDefined(codeFixes, fix => { return ts.forEach(ts.flatMap(fix.changes, c => c.textChanges), c => { @@ -3044,6 +3044,26 @@ namespace FourSlash { } } + public verifyCodeFixAllAvailable(negative: boolean, fixName: string) { + const availableFixes = this.getCodeFixes(this.activeFile.fileName); + const hasFix = availableFixes.some(fix => fix.fixName === fixName && fix.fixId); + if (negative && hasFix) { + this.raiseError(`Expected not to find a fix with the name '${fixName}', but one exists.`); + } + else if (!negative && !hasFix) { + if (availableFixes.some(fix => fix.fixName === fixName)) { + this.raiseError(`Found a fix with the name '${fixName}', but fix-all is not available.`); + } + + this.raiseError( + `Expected to find a fix with the name '${fixName}', but none exists.` + + availableFixes.length + ? ` Available fixes: ${availableFixes.map(fix => `${fix.fixName} (${fix.fixId ? "with" : "without"} fix-all)`).join(", ")}` + : "" + ); + } + } + public verifyApplicableRefactorAvailableAtMarker(negative: boolean, markerName: string) { const isAvailable = this.getApplicableRefactors(this.getMarkerByName(markerName)).length > 0; if (negative && isAvailable) { diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 91ddf5b6293dd..04441468a7313 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -191,6 +191,10 @@ namespace FourSlashInterface { this.state.verifyCodeFixAvailable(this.negative, options); } + public codeFixAllAvailable(fixName: string) { + this.state.verifyCodeFixAllAvailable(this.negative, fixName); + } + public applicableRefactorAvailableAtMarker(markerName: string) { this.state.verifyApplicableRefactorAvailableAtMarker(this.negative, markerName); } diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index 1673a63d702bd..e50477358eda3 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -10,7 +10,7 @@ namespace ts.codefix { : getLocaleSpecificMessage(diag); } - export function createCodeFixActionNoFixId(fixName: string, changes: FileTextChanges[], description: DiagnosticAndArguments) { + export function createCodeFixActionWithoutFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticAndArguments) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined); } @@ -38,8 +38,24 @@ namespace ts.codefix { return arrayFrom(errorCodeToFixes.keys()); } + function removeFixIdIfFixAllUnavailable(registration: CodeFixRegistration, diagnostics: Diagnostic[]) { + const { errorCodes } = registration; + let maybeFixableDiagnostics = 0; + for (const diag of diagnostics) { + if (contains(errorCodes, diag.code)) maybeFixableDiagnostics++; + if (maybeFixableDiagnostics > 1) break; + } + + const fixAllUnavailable = maybeFixableDiagnostics < 2; + return ({ fixId, fixAllDescription, ...action }: CodeFixAction): CodeFixAction => { + return fixAllUnavailable ? action : { ...action, fixId, fixAllDescription }; + }; + } + export function getFixes(context: CodeFixContext): readonly CodeFixAction[] { - return flatMap(errorCodeToFixes.get(String(context.errorCode)) || emptyArray, f => f.getCodeActions(context)); + const diagnostics = getDiagnostics(context); + const registrations = errorCodeToFixes.get(String(context.errorCode)); + return flatMap(registrations, f => map(f.getCodeActions(context), removeFixIdIfFixAllUnavailable(f, diagnostics))); } export function getAllFixes(context: CodeFixAllContext): CombinedCodeActions { @@ -65,11 +81,15 @@ namespace ts.codefix { return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands); } - export function eachDiagnostic({ program, sourceFile, cancellationToken }: CodeFixAllContext, errorCodes: readonly number[], cb: (diag: DiagnosticWithLocation) => void): void { - for (const diag of program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(computeSuggestionDiagnostics(sourceFile, program, cancellationToken))) { + export function eachDiagnostic(context: CodeFixAllContext, errorCodes: readonly number[], cb: (diag: DiagnosticWithLocation) => void): void { + for (const diag of getDiagnostics(context)) { if (contains(errorCodes, diag.code)) { cb(diag as DiagnosticWithLocation); } } } + + function getDiagnostics({ program, sourceFile, cancellationToken }: CodeFixContextBase) { + return program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); + } } diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts index 96cf09ed08a75..60f5814c39612 100644 --- a/src/services/codefixes/addMissingAwait.ts +++ b/src/services/codefixes/addMissingAwait.ts @@ -68,7 +68,9 @@ namespace ts.codefix { makeChange(t, errorCode, sourceFile, checker, expression, fixedDeclarations); } }); - return createCodeFixActionNoFixId( + // No fix-all because it will already be included once with the use site fix, + // and for simplicity the fix-all doesn‘t let the user choose between use-site and declaration-site fixes. + return createCodeFixActionWithoutFixAll( "addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 diff --git a/src/services/codefixes/addMissingConst.ts b/src/services/codefixes/addMissingConst.ts index 37739d01eee07..1c819cafe0f73 100644 --- a/src/services/codefixes/addMissingConst.ts +++ b/src/services/codefixes/addMissingConst.ts @@ -30,7 +30,7 @@ namespace ts.codefix { if (forInitializer) return applyChange(changeTracker, forInitializer, sourceFile, fixedNodes); const parent = token.parent; - if (isBinaryExpression(parent) && isExpressionStatement(parent.parent)) { + if (isBinaryExpression(parent) && parent.operatorToken.kind === SyntaxKind.EqualsToken && isExpressionStatement(parent.parent)) { return applyChange(changeTracker, token, sourceFile, fixedNodes); } @@ -104,6 +104,8 @@ namespace ts.codefix { return every([expression.left, expression.right], expression => expressionCouldBeVariableDeclaration(expression, checker)); } - return isIdentifier(expression.left) && !checker.getSymbolAtLocation(expression.left); + return expression.operatorToken.kind === SyntaxKind.EqualsToken + && isIdentifier(expression.left) + && !checker.getSymbolAtLocation(expression.left); } } diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index 70abac28bb6da..3880f85bad08e 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -13,7 +13,7 @@ namespace ts.codefix { } }); // No support for fix-all since this applies to the whole file at once anyway. - return [createCodeFixActionNoFixId("convertToEs6Module", changes, Diagnostics.Convert_to_ES6_module)]; + return [createCodeFixActionWithoutFixAll("convertToEs6Module", changes, Diagnostics.Convert_to_ES6_module)]; }, }); diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts index bde8b118264eb..a4feeaa2dbdf8 100644 --- a/src/services/codefixes/disableJsDiagnostics.ts +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -18,7 +18,7 @@ namespace ts.codefix { const fixes: CodeFixAction[] = [ // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file. - createCodeFixActionNoFixId( + createCodeFixActionWithoutFixAll( fixName, [createFileTextChanges(sourceFile.fileName, [ createTextChange(sourceFile.checkJsDirective diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index c57565531514c..5c1e7a655a314 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -255,7 +255,7 @@ namespace ts.codefix { const changes = textChanges.ChangeTracker.with(context, t => t.insertNodeAtClassStart(declSourceFile, classDeclaration, indexSignature)); // No fixId here because code-fix-all currently only works on adding individual named properties. - return createCodeFixActionNoFixId(fixName, changes, [Diagnostics.Add_index_signature_for_property_0, tokenName]); + return createCodeFixActionWithoutFixAll(fixName, changes, [Diagnostics.Add_index_signature_for_property_0, tokenName]); } function getActionForMethodDeclaration( diff --git a/src/services/codefixes/fixEnableExperimentalDecorators.ts b/src/services/codefixes/fixEnableExperimentalDecorators.ts index 8ab1c2769104d..8c8f6726b4392 100644 --- a/src/services/codefixes/fixEnableExperimentalDecorators.ts +++ b/src/services/codefixes/fixEnableExperimentalDecorators.ts @@ -13,7 +13,7 @@ namespace ts.codefix { } const changes = textChanges.ChangeTracker.with(context, changeTracker => doChange(changeTracker, configFile)); - return [createCodeFixActionNoFixId(fixId, changes, Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; + return [createCodeFixActionWithoutFixAll(fixId, changes, Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes) => { diff --git a/src/services/codefixes/fixEnableJsxFlag.ts b/src/services/codefixes/fixEnableJsxFlag.ts index 728366392f1ea..d108505264623 100644 --- a/src/services/codefixes/fixEnableJsxFlag.ts +++ b/src/services/codefixes/fixEnableJsxFlag.ts @@ -14,7 +14,7 @@ namespace ts.codefix { doChange(changeTracker, configFile) ); return [ - createCodeFixActionNoFixId(fixID, changes, Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) + createCodeFixActionWithoutFixAll(fixID, changes, Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) ]; }, fixIds: [fixID], diff --git a/src/services/codefixes/fixInvalidImportSyntax.ts b/src/services/codefixes/fixInvalidImportSyntax.ts index dc37aeff12b33..5893a1e5e74a3 100644 --- a/src/services/codefixes/fixInvalidImportSyntax.ts +++ b/src/services/codefixes/fixInvalidImportSyntax.ts @@ -26,7 +26,7 @@ namespace ts.codefix { function createAction(context: CodeFixContext, sourceFile: SourceFile, node: Node, replacement: Node): CodeFixAction { const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, node, replacement)); - return createCodeFixActionNoFixId(fixName, changes, [Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); + return createCodeFixActionWithoutFixAll(fixName, changes, [Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); } registerCodeFix({ @@ -89,7 +89,7 @@ namespace ts.codefix { if (isExpression(expr) && !(isNamedDeclaration(expr.parent) && expr.parent.name === expr)) { const sourceFile = context.sourceFile; const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, expr, createPropertyAccess(expr, "default"), {})); - fixes.push(createCodeFixActionNoFixId(fixName, changes, Diagnostics.Use_synthetic_default_member)); + fixes.push(createCodeFixActionWithoutFixAll(fixName, changes, Diagnostics.Use_synthetic_default_member)); } return fixes; } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index e5e141407cb6c..557362fb4b834 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -1,6 +1,7 @@ /* @internal */ namespace ts.codefix { - export const importFixId = "fixMissingImport"; + export const importFixName = "import"; + const importFixId = "fixMissingImport"; const errorCodes: readonly number[] = [ Diagnostics.Cannot_find_name_0.code, Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, @@ -542,7 +543,7 @@ namespace ts.codefix { const changes = textChanges.ChangeTracker.with(context, tracker => { diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, quotePreference); }); - return createCodeFixAction("import", changes, diag, importFixId, Diagnostics.Add_all_missing_imports); + return createCodeFixAction(importFixName, changes, diag, importFixId, Diagnostics.Add_all_missing_imports); } function codeActionForFixWorker(changes: textChanges.ChangeTracker, sourceFile: SourceFile, symbolName: string, fix: ImportFix, quotePreference: QuotePreference): DiagnosticAndArguments { switch (fix.kind) { diff --git a/src/testRunner/unittests/tsserver/duplicatePackages.ts b/src/testRunner/unittests/tsserver/duplicatePackages.ts index 3de23225cd78e..c6e4868ba4ab7 100644 --- a/src/testRunner/unittests/tsserver/duplicatePackages.ts +++ b/src/testRunner/unittests/tsserver/duplicatePackages.ts @@ -35,8 +35,6 @@ namespace ts.projectSystem { { description: `Import 'foo' from module "foo"`, fixName: "import", - fixId: "fixMissingImport", - fixAllDescription: "Add all missing imports", changes: [{ fileName: user.path, textChanges: [{ @@ -46,6 +44,8 @@ namespace ts.projectSystem { }], }], commands: undefined, + fixId: undefined, + fixAllDescription: undefined }, ]); } diff --git a/src/testRunner/unittests/tsserver/untitledFiles.ts b/src/testRunner/unittests/tsserver/untitledFiles.ts index 7f5c36ac6e2f5..31612d49a14ea 100644 --- a/src/testRunner/unittests/tsserver/untitledFiles.ts +++ b/src/testRunner/unittests/tsserver/untitledFiles.ts @@ -26,8 +26,6 @@ namespace ts.projectSystem { assert.deepEqual(response, [ { description: "Change spelling to 'foo'", - fixAllDescription: "Fix all detected spelling errors", - fixId: "fixSpelling", fixName: "spelling", changes: [{ fileName: untitledFile, @@ -38,6 +36,8 @@ namespace ts.projectSystem { }], }], commands: undefined, + fixId: undefined, + fixAllDescription: undefined }, ]); }); diff --git a/tests/cases/fourslash/codeFixAddMissingAwait_initializer4.ts b/tests/cases/fourslash/codeFixAddMissingAwait_initializer4.ts index 3106eaeccb62b..349370b09e4a7 100644 --- a/tests/cases/fourslash/codeFixAddMissingAwait_initializer4.ts +++ b/tests/cases/fourslash/codeFixAddMissingAwait_initializer4.ts @@ -16,13 +16,4 @@ verify.codeFix({ }` }); -verify.codeFixAll({ - fixAllDescription: ts.Diagnostics.Fix_all_expressions_possibly_missing_await.message, - fixId: "addMissingAwait", - newFileContent: -`async function fn(a: string, b: Promise) { - const x = await b; - const y = await b; - x + y; -}` -}); +verify.not.codeFixAllAvailable("addMissingAwait"); diff --git a/tests/cases/fourslash/codeFixAddMissingMember10.ts b/tests/cases/fourslash/codeFixAddMissingMember10.ts index 990d86ec49aec..3a33d17b117ee 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember10.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember10.ts @@ -3,9 +3,9 @@ //// class C {} //// const n: number = new C().add(1, 2); -verify.codeFixAll({ - fixId: "addMissingMember", - fixAllDescription: "Add all missing members", +verify.codeFix({ + index: 0, + description: ignoreInterpolations(ts.Diagnostics.Declare_method_0), newFileContent: `class C { add(arg0: number, arg1: number): number { diff --git a/tests/cases/fourslash/codeFixAddMissingMember11.ts b/tests/cases/fourslash/codeFixAddMissingMember11.ts index 6f68502d4c9fc..c87115e5a6be5 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember11.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember11.ts @@ -4,9 +4,9 @@ //// function f(v: number): void { } //// f(new C().add(1, 2)) -verify.codeFixAll({ - fixId: "addMissingMember", - fixAllDescription: "Add all missing members", +verify.codeFix({ + index: 0, + description: ignoreInterpolations(ts.Diagnostics.Declare_method_0), newFileContent: `class C { add(arg0: number, arg1: number): number { diff --git a/tests/cases/fourslash/codeFixAddMissingMember9.ts b/tests/cases/fourslash/codeFixAddMissingMember9.ts index e22e854c2e51a..7fa8b47e366bd 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember9.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember9.ts @@ -8,9 +8,9 @@ //// } ////} -verify.codeFixAll({ - fixId: "addMissingMember", - fixAllDescription: "Add all missing members", +verify.codeFix({ + index: 0, + description: ignoreInterpolations(ts.Diagnostics.Declare_method_0), newFileContent: `class C { z: boolean = true; diff --git a/tests/cases/fourslash/codeFixAddMissingMember_generator_function.ts b/tests/cases/fourslash/codeFixAddMissingMember_generator_function.ts index ad0bd7b47cad5..12adb5b071722 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember_generator_function.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember_generator_function.ts @@ -6,9 +6,9 @@ //// } ////} -verify.codeFixAll({ - fixId: "addMissingMember", - fixAllDescription: "Add all missing members", +verify.codeFix({ + index: 0, + description: ignoreInterpolations(ts.Diagnostics.Declare_method_0), newFileContent: `class C { *method() { diff --git a/tests/cases/fourslash/codeFixAddMissingMember_non_generator_function.ts b/tests/cases/fourslash/codeFixAddMissingMember_non_generator_function.ts index c3773bf285c30..acb2f4c86c41e 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember_non_generator_function.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember_non_generator_function.ts @@ -6,9 +6,9 @@ //// } ////} -verify.codeFixAll({ - fixId: "addMissingMember", - fixAllDescription: "Add all missing members", +verify.codeFix({ + index: 0, + description: ignoreInterpolations(ts.Diagnostics.Declare_method_0), newFileContent: `class C { method() { diff --git a/tests/cases/fourslash/codeFixInferFromUsageCallJS.ts b/tests/cases/fourslash/codeFixInferFromUsageCallJS.ts index fa7eb5ee67130..edb8a0bea5fb7 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageCallJS.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageCallJS.ts @@ -8,9 +8,9 @@ //// b(); ////} -verify.codeFixAll({ - fixId: "inferFromUsage", - fixAllDescription: "Infer all types from usage", +verify.codeFix({ + index: 0, + description: ignoreInterpolations(ts.Diagnostics.Infer_parameter_types_from_usage), newFileContent: `/** * @param {() => void} b diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 84b770fc394c1..baeff000912b8 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -236,6 +236,7 @@ declare namespace FourSlashInterface { commands?: {}[], }); codeFixAvailable(options?: ReadonlyArray | string): void; + codeFixAllAvailable(fixName: string): void; applicableRefactorAvailableAtMarker(markerName: string): void; codeFixDiagnosticsAvailableAtMarkers(markerNames: string[], diagnosticCode?: number): void; applicableRefactorAvailableForRange(): void; diff --git a/tests/cases/fourslash/importNameCodeFixWithPrologue.ts b/tests/cases/fourslash/importNameCodeFixWithPrologue.ts index 383f8b1555e71..c71d03c063d04 100644 --- a/tests/cases/fourslash/importNameCodeFixWithPrologue.ts +++ b/tests/cases/fourslash/importNameCodeFixWithPrologue.ts @@ -17,9 +17,8 @@ ////export class B extends A { } goTo.file("/b.ts"); -verify.codeFixAll({ - fixId: "fixMissingImport", - fixAllDescription: "Add all missing imports", +verify.codeFix({ + description: ignoreInterpolations(ts.Diagnostics.Import_0_from_module_1), newFileContent: `"use strict"; @@ -29,9 +28,8 @@ export class B extends A { }`, }); goTo.file("/c.ts"); -verify.codeFixAll({ - fixId: "fixMissingImport", - fixAllDescription: "Add all missing imports", +verify.codeFix({ + description: ignoreInterpolations(ts.Diagnostics.Import_0_from_module_1), newFileContent: `/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. From b2a7d420322e2f16bcae6e74bdf6023b3ea3d53a Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 16 Jan 2020 15:38:55 -0800 Subject: [PATCH 09/28] Handle untitled files from vscode which are of format: untitled:^Untitled-1 (#36240) * Test for #36200 * Handle dynamic files by vscode Fixes #36200 --- src/server/editorServices.ts | 2 +- src/server/scriptInfo.ts | 3 +- .../unittests/tsserver/externalProjects.ts | 1 + src/testRunner/unittests/tsserver/projects.ts | 3 ++ .../unittests/tsserver/untitledFiles.ts | 44 +++++++++++++++++-- 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 2e3e0ae67e5cd..c5bc372e179cd 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1304,7 +1304,7 @@ namespace ts.server { // Closing file should trigger re-reading the file content from disk. This is // because the user may chose to discard the buffer content before saving // to the disk, and the server's version of the file can be out of sync. - const fileExists = this.host.fileExists(info.fileName); + const fileExists = info.isDynamic ? false : this.host.fileExists(info.fileName); info.close(fileExists); this.stopWatchingConfigFilesForClosedScriptInfo(info); diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 02d3bff1a0f8c..f630b9329aaa7 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -272,7 +272,8 @@ namespace ts.server { /*@internal*/ export function isDynamicFileName(fileName: NormalizedPath) { - return fileName[0] === "^"; + return fileName[0] === "^" || + (stringContains(fileName, ":^") && !stringContains(fileName, directorySeparator)); } /*@internal*/ diff --git a/src/testRunner/unittests/tsserver/externalProjects.ts b/src/testRunner/unittests/tsserver/externalProjects.ts index 172d264242b77..54a488c0c94c2 100644 --- a/src/testRunner/unittests/tsserver/externalProjects.ts +++ b/src/testRunner/unittests/tsserver/externalProjects.ts @@ -221,6 +221,7 @@ namespace ts.projectSystem { checkNumberOfExternalProjects(projectService, 1); checkNumberOfInferredProjects(projectService, 0); + verifyDynamic(projectService, "/^scriptdocument1 file1.ts"); externalFiles[0].content = "let x =1;"; projectService.applyChangesInOpenFiles(arrayIterator(externalFiles)); diff --git a/src/testRunner/unittests/tsserver/projects.ts b/src/testRunner/unittests/tsserver/projects.ts index 369b0d8905ed8..7c4c5ef522cc0 100644 --- a/src/testRunner/unittests/tsserver/projects.ts +++ b/src/testRunner/unittests/tsserver/projects.ts @@ -1094,6 +1094,7 @@ namespace ts.projectSystem { const project = projectService.inferredProjects[0]; checkProjectRootFiles(project, [file.path]); checkProjectActualFiles(project, [file.path, libFile.path]); + verifyDynamic(projectService, `/${file.path}`); assert.strictEqual(projectService.ensureDefaultProjectForFile(server.toNormalizedPath(file.path)), project); const indexOfX = file.content.indexOf("x"); @@ -1124,6 +1125,7 @@ var x = 10;` const host = createServerHost([libFile]); const projectService = createProjectService(host); projectService.openClientFile(file.path, file.content); + verifyDynamic(projectService, projectService.toPath(file.path)); projectService.checkNumberOfProjects({ inferredProjects: 1 }); const project = projectService.inferredProjects[0]; @@ -1152,6 +1154,7 @@ var x = 10;` const projectService = session.getProjectService(); checkNumberOfProjects(projectService, { inferredProjects: 1 }); checkProjectActualFiles(projectService.inferredProjects[0], [file.path, libFile.path]); + verifyDynamic(projectService, `${tscWatch.projectRoot}/${file.path}`); session.executeCommandSeq({ command: protocol.CommandTypes.GetOutliningSpans, diff --git a/src/testRunner/unittests/tsserver/untitledFiles.ts b/src/testRunner/unittests/tsserver/untitledFiles.ts index 31612d49a14ea..6ba8da3cf398f 100644 --- a/src/testRunner/unittests/tsserver/untitledFiles.ts +++ b/src/testRunner/unittests/tsserver/untitledFiles.ts @@ -1,20 +1,25 @@ namespace ts.projectSystem { + export function verifyDynamic(service: server.ProjectService, path: string) { + const info = Debug.assertDefined(service.filenameToScriptInfo.get(path), `Expected ${path} in :: ${JSON.stringify(arrayFrom(service.filenameToScriptInfo.entries(), ([key, f]) => ({ key, fileName: f.fileName, path: f.path })))}`); + assert.isTrue(info.isDynamic); + } + describe("unittests:: tsserver:: Untitled files", () => { + const untitledFile = "untitled:^Untitled-1"; it("Can convert positions to locations", () => { const aTs: File = { path: "/proj/a.ts", content: "" }; const tsconfig: File = { path: "/proj/tsconfig.json", content: "{}" }; - const session = createSession(createServerHost([aTs, tsconfig])); + const session = createSession(createServerHost([aTs, tsconfig]), { useInferredProjectPerProjectRoot: true }); openFilesForSession([aTs], session); - const untitledFile = "untitled:^Untitled-1"; executeSessionRequestNoResponse(session, protocol.CommandTypes.Open, { file: untitledFile, fileContent: `/// \nlet foo = 1;\nfooo/**/`, scriptKindName: "TS", projectRootPath: "/proj", }); - + verifyDynamic(session.getProjectService(), `/proj/untitled:^untitled-1`); const response = executeSessionRequest(session, protocol.CommandTypes.GetCodeFixes, { file: untitledFile, startLine: 3, @@ -41,5 +46,38 @@ namespace ts.projectSystem { }, ]); }); + + it("opening untitled files", () => { + const config: File = { + path: `${tscWatch.projectRoot}/tsconfig.json`, + content: "{}" + }; + const host = createServerHost([config, libFile], { useCaseSensitiveFileNames: true, currentDirectory: tscWatch.projectRoot }); + const service = createProjectService(host); + service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, tscWatch.projectRoot); + checkNumberOfProjects(service, { inferredProjects: 1 }); + checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); + verifyDynamic(service, `${tscWatch.projectRoot}/${untitledFile}`); + + const untitled: File = { + path: `${tscWatch.projectRoot}/Untitled-1.ts`, + content: "const x = 10;" + }; + host.writeFile(untitled.path, untitled.content); + host.checkTimeoutQueueLength(0); + service.openClientFile(untitled.path, untitled.content, /*scriptKind*/ undefined, tscWatch.projectRoot); + checkNumberOfProjects(service, { configuredProjects: 1, inferredProjects: 1 }); + checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]); + checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); + + service.closeClientFile(untitledFile); + checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]); + checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); + + service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, tscWatch.projectRoot); + verifyDynamic(service, `${tscWatch.projectRoot}/${untitledFile}`); + checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]); + checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]); + }); }); } From 8517df6fa2fb57b68b76a5b6012a305ff04edff8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 16 Jan 2020 16:49:51 -0800 Subject: [PATCH 10/28] Fix erroneous optional chain narrowing (#36145) * Not all optional chains are narrowable references * Add regression test --- src/compiler/binder.ts | 17 ++++---- .../controlFlowOptionalChain.errors.txt | 12 ++++++ .../reference/controlFlowOptionalChain.js | 22 +++++++++- .../controlFlowOptionalChain.symbols | 31 ++++++++++++++ .../reference/controlFlowOptionalChain.types | 42 +++++++++++++++++++ .../controlFlow/controlFlowOptionalChain.ts | 12 ++++++ 6 files changed, 128 insertions(+), 8 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 647ff65143a6a..af63463cdd247 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -861,7 +861,7 @@ namespace ts { case SyntaxKind.ThisKeyword: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: - return isNarrowableReference(expr); + return containsNarrowableReference(expr); case SyntaxKind.CallExpression: return hasNarrowableArgument(expr); case SyntaxKind.ParenthesizedExpression: @@ -879,20 +879,23 @@ namespace ts { function isNarrowableReference(expr: Expression): boolean { return expr.kind === SyntaxKind.Identifier || expr.kind === SyntaxKind.ThisKeyword || expr.kind === SyntaxKind.SuperKeyword || (isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || - isElementAccessExpression(expr) && isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) || - isOptionalChain(expr); + isElementAccessExpression(expr) && isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression); + } + + function containsNarrowableReference(expr: Expression): boolean { + return isNarrowableReference(expr) || isOptionalChain(expr) && containsNarrowableReference(expr.expression); } function hasNarrowableArgument(expr: CallExpression) { if (expr.arguments) { for (const argument of expr.arguments) { - if (isNarrowableReference(argument)) { + if (containsNarrowableReference(argument)) { return true; } } } if (expr.expression.kind === SyntaxKind.PropertyAccessExpression && - isNarrowableReference((expr.expression).expression)) { + containsNarrowableReference((expr.expression).expression)) { return true; } return false; @@ -909,7 +912,7 @@ namespace ts { function isNarrowingBinaryExpression(expr: BinaryExpression) { switch (expr.operatorToken.kind) { case SyntaxKind.EqualsToken: - return isNarrowableReference(expr.left); + return containsNarrowableReference(expr.left); case SyntaxKind.EqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: case SyntaxKind.EqualsEqualsEqualsToken: @@ -938,7 +941,7 @@ namespace ts { return isNarrowableOperand((expr).right); } } - return isNarrowableReference(expr); + return containsNarrowableReference(expr); } function createBranchLabel(): FlowLabel { diff --git a/tests/baselines/reference/controlFlowOptionalChain.errors.txt b/tests/baselines/reference/controlFlowOptionalChain.errors.txt index 3606034699bab..df3c5a5553419 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.errors.txt +++ b/tests/baselines/reference/controlFlowOptionalChain.errors.txt @@ -764,4 +764,16 @@ tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(567,21): error T someFunction(someObject); someFunction(undefined); + + // Repro from #35970 + + let i = 0; + declare const arr: { tag: ("left" | "right") }[]; + + while (arr[i]?.tag === "left") { + i += 1; + if (arr[i]?.tag === "right") { + console.log("I should ALSO be reachable"); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowOptionalChain.js b/tests/baselines/reference/controlFlowOptionalChain.js index cd7b9a9237776..dc2361d860984 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.js +++ b/tests/baselines/reference/controlFlowOptionalChain.js @@ -576,11 +576,23 @@ const someObject: SomeObject = { someFunction(someObject); someFunction(undefined); + +// Repro from #35970 + +let i = 0; +declare const arr: { tag: ("left" | "right") }[]; + +while (arr[i]?.tag === "left") { + i += 1; + if (arr[i]?.tag === "right") { + console.log("I should ALSO be reachable"); + } +} //// [controlFlowOptionalChain.js] "use strict"; -var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; +var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v; var a; o === null || o === void 0 ? void 0 : o[a = 1]; a.toString(); @@ -1071,3 +1083,11 @@ var someObject = { }; someFunction(someObject); someFunction(undefined); +// Repro from #35970 +var i = 0; +while (((_u = arr[i]) === null || _u === void 0 ? void 0 : _u.tag) === "left") { + i += 1; + if (((_v = arr[i]) === null || _v === void 0 ? void 0 : _v.tag) === "right") { + console.log("I should ALSO be reachable"); + } +} diff --git a/tests/baselines/reference/controlFlowOptionalChain.symbols b/tests/baselines/reference/controlFlowOptionalChain.symbols index 42c32487f6ed1..5354a1ef95bd3 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.symbols +++ b/tests/baselines/reference/controlFlowOptionalChain.symbols @@ -1801,3 +1801,34 @@ someFunction(undefined); >someFunction : Symbol(someFunction, Decl(controlFlowOptionalChain.ts, 561, 42)) >undefined : Symbol(undefined) +// Repro from #35970 + +let i = 0; +>i : Symbol(i, Decl(controlFlowOptionalChain.ts, 580, 3)) + +declare const arr: { tag: ("left" | "right") }[]; +>arr : Symbol(arr, Decl(controlFlowOptionalChain.ts, 581, 13)) +>tag : Symbol(tag, Decl(controlFlowOptionalChain.ts, 581, 20)) + +while (arr[i]?.tag === "left") { +>arr[i]?.tag : Symbol(tag, Decl(controlFlowOptionalChain.ts, 581, 20)) +>arr : Symbol(arr, Decl(controlFlowOptionalChain.ts, 581, 13)) +>i : Symbol(i, Decl(controlFlowOptionalChain.ts, 580, 3)) +>tag : Symbol(tag, Decl(controlFlowOptionalChain.ts, 581, 20)) + + i += 1; +>i : Symbol(i, Decl(controlFlowOptionalChain.ts, 580, 3)) + + if (arr[i]?.tag === "right") { +>arr[i]?.tag : Symbol(tag, Decl(controlFlowOptionalChain.ts, 581, 20)) +>arr : Symbol(arr, Decl(controlFlowOptionalChain.ts, 581, 13)) +>i : Symbol(i, Decl(controlFlowOptionalChain.ts, 580, 3)) +>tag : Symbol(tag, Decl(controlFlowOptionalChain.ts, 581, 20)) + + console.log("I should ALSO be reachable"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + } +} + diff --git a/tests/baselines/reference/controlFlowOptionalChain.types b/tests/baselines/reference/controlFlowOptionalChain.types index 37a688ca25cfc..23aa740074c13 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.types +++ b/tests/baselines/reference/controlFlowOptionalChain.types @@ -2031,3 +2031,45 @@ someFunction(undefined); >someFunction : (someOptionalObject: SomeObject | undefined) => void >undefined : undefined +// Repro from #35970 + +let i = 0; +>i : number +>0 : 0 + +declare const arr: { tag: ("left" | "right") }[]; +>arr : { tag: "left" | "right"; }[] +>tag : "left" | "right" + +while (arr[i]?.tag === "left") { +>arr[i]?.tag === "left" : boolean +>arr[i]?.tag : "left" | "right" +>arr[i] : { tag: "left" | "right"; } +>arr : { tag: "left" | "right"; }[] +>i : number +>tag : "left" | "right" +>"left" : "left" + + i += 1; +>i += 1 : number +>i : number +>1 : 1 + + if (arr[i]?.tag === "right") { +>arr[i]?.tag === "right" : boolean +>arr[i]?.tag : "left" | "right" +>arr[i] : { tag: "left" | "right"; } +>arr : { tag: "left" | "right"; }[] +>i : number +>tag : "left" | "right" +>"right" : "right" + + console.log("I should ALSO be reachable"); +>console.log("I should ALSO be reachable") : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>"I should ALSO be reachable" : "I should ALSO be reachable" + } +} + diff --git a/tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts b/tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts index 443716ef8c3d5..e5495a313aa0d 100644 --- a/tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts +++ b/tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts @@ -578,3 +578,15 @@ const someObject: SomeObject = { someFunction(someObject); someFunction(undefined); + +// Repro from #35970 + +let i = 0; +declare const arr: { tag: ("left" | "right") }[]; + +while (arr[i]?.tag === "left") { + i += 1; + if (arr[i]?.tag === "right") { + console.log("I should ALSO be reachable"); + } +} From 57925d4e35c895524cb17295cc73f97f3a6f63f0 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 16 Jan 2020 17:24:03 -0800 Subject: [PATCH 11/28] Instead of checking if file exists before file read, handle exceptions from file read (#36244) Fixes #36236 --- src/compiler/sys.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index a347687e5f883..4ac6187f3486d 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1559,10 +1559,13 @@ namespace ts { } function readFileWorker(fileName: string, _encoding?: string): string | undefined { - if (!fileExists(fileName)) { + let buffer: Buffer; + try { + buffer = _fs.readFileSync(fileName); + } + catch (e) { return undefined; } - const buffer = _fs.readFileSync(fileName); let len = buffer.length; if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) { // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js, From 70ba8512bbbde6a73c5fd56e780835394e8dfc1d Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 17 Jan 2020 04:10:10 +0000 Subject: [PATCH 12/28] LEGO: check in for master to temporary branch. --- .../diagnosticMessages/diagnosticMessages.generated.json.lcl | 2 +- .../diagnosticMessages/diagnosticMessages.generated.json.lcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 74c16b4fa96a7..77ee3d71df32a 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4204,7 +4204,7 @@ - + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3103936fb5017..0988b700922f2 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -4204,7 +4204,7 @@ - + From 1a10e712e62dee157abe714314c3e27e5f9c3db0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 17 Jan 2020 11:50:38 -0800 Subject: [PATCH 13/28] Improve variance measurement (#36261) * No covariance default for recursive references in variance measurement * Add tests * Accept new baselines --- src/compiler/checker.ts | 17 +- ...eckInfiniteExpansionTermination.errors.txt | 32 --- .../recursiveTypeComparison.errors.txt | 27 --- .../reference/varianceMeasurement.errors.txt | 122 ++++++++++++ .../reference/varianceMeasurement.js | 83 ++++++++ .../reference/varianceMeasurement.symbols | 185 ++++++++++++++++++ .../reference/varianceMeasurement.types | 133 +++++++++++++ tests/cases/compiler/varianceMeasurement.ts | 64 ++++++ 8 files changed, 600 insertions(+), 63 deletions(-) delete mode 100644 tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt delete mode 100644 tests/baselines/reference/recursiveTypeComparison.errors.txt create mode 100644 tests/baselines/reference/varianceMeasurement.errors.txt create mode 100644 tests/baselines/reference/varianceMeasurement.js create mode 100644 tests/baselines/reference/varianceMeasurement.symbols create mode 100644 tests/baselines/reference/varianceMeasurement.types create mode 100644 tests/cases/compiler/varianceMeasurement.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b6a40258f69e6..512e431fbe5ae 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -306,6 +306,7 @@ namespace ts { const emptySymbols = createSymbolTable(); const identityMapper: (type: Type) => Type = identity; + const arrayVariances = [VarianceFlags.Covariant]; const compilerOptions = host.getCompilerOptions(); const languageVersion = getEmitScriptTarget(compilerOptions); @@ -15406,6 +15407,9 @@ namespace ts { source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { const variances = getAliasVariances(source.aliasSymbol); + if (variances === emptyArray) { + return Ternary.Maybe; + } const varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -15602,6 +15606,12 @@ namespace ts { // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. const variances = getVariances((source).target); + // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This + // effectively means we measure variance only from type parameter occurrences that aren't nested in + // recursive instantiations of the generic type. + if (variances === emptyArray) { + return Ternary.Maybe; + } const varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -16421,8 +16431,7 @@ namespace ts { // a digest of the type comparisons that occur for each type argument when instantiations of the // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function - // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function - // has been invoked recursively for the given generic type. + // returns the emptyArray singleton when invoked recursively for the given generic type. function getVariancesWorker(typeParameters: readonly TypeParameter[] = emptyArray, cache: TCache, createMarkerType: (input: TCache, param: TypeParameter, marker: Type) => Type): VarianceFlags[] { let variances = cache.variances; if (!variances) { @@ -16465,9 +16474,9 @@ namespace ts { } function getVariances(type: GenericType): VarianceFlags[] { - // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters) + // Arrays and tuples are known to be covariant, no need to spend time computing this. if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) { - return emptyArray; + return arrayVariances; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); } diff --git a/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt b/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt deleted file mode 100644 index 014087ff6275e..0000000000000 --- a/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt +++ /dev/null @@ -1,32 +0,0 @@ -tests/cases/compiler/checkInfiniteExpansionTermination.ts(16,1): error TS2322: Type 'ISubject' is not assignable to type 'IObservable'. - Types of property 'n' are incompatible. - Type 'IObservable' is not assignable to type 'IObservable'. - Type 'Bar[]' is not assignable to type 'Foo[]'. - Property 'x' is missing in type 'Bar' but required in type 'Foo'. - - -==== tests/cases/compiler/checkInfiniteExpansionTermination.ts (1 errors) ==== - // Regression test for #1002 - // Before fix this code would cause infinite loop - - interface IObservable { - n: IObservable; // Needed, must be T[] - } - - // Needed - interface ISubject extends IObservable { } - - interface Foo { x } - interface Bar { y } - - var values: IObservable; - var values2: ISubject; - values = values2; - ~~~~~~ -!!! error TS2322: Type 'ISubject' is not assignable to type 'IObservable'. -!!! error TS2322: Types of property 'n' are incompatible. -!!! error TS2322: Type 'IObservable' is not assignable to type 'IObservable'. -!!! error TS2322: Type 'Bar[]' is not assignable to type 'Foo[]'. -!!! error TS2322: Property 'x' is missing in type 'Bar' but required in type 'Foo'. -!!! related TS2728 tests/cases/compiler/checkInfiniteExpansionTermination.ts:11:17: 'x' is declared here. - \ No newline at end of file diff --git a/tests/baselines/reference/recursiveTypeComparison.errors.txt b/tests/baselines/reference/recursiveTypeComparison.errors.txt deleted file mode 100644 index f647763b2e275..0000000000000 --- a/tests/baselines/reference/recursiveTypeComparison.errors.txt +++ /dev/null @@ -1,27 +0,0 @@ -tests/cases/compiler/recursiveTypeComparison.ts(14,5): error TS2322: Type 'Observable<{}>' is not assignable to type 'Property'. - Types of property 'needThisOne' are incompatible. - Type 'Observable<{}>' is not assignable to type 'Observable'. - Type '{}' is not assignable to type 'number'. - - -==== tests/cases/compiler/recursiveTypeComparison.ts (1 errors) ==== - // Before fix this would take an exceeding long time to complete (#1170) - - interface Observable { - // This member can't be of type T, Property, or Observable - needThisOne: Observable; - // Add more to make it slower - expo1: Property; // 0.31 seconds in check - expo2: Property; // 3.11 seconds - expo3: Property; // 82.28 seconds - } - interface Property extends Observable { } - - var p: Observable<{}>; - var stuck: Property = p; - ~~~~~ -!!! error TS2322: Type 'Observable<{}>' is not assignable to type 'Property'. -!!! error TS2322: Types of property 'needThisOne' are incompatible. -!!! error TS2322: Type 'Observable<{}>' is not assignable to type 'Observable'. -!!! error TS2322: Type '{}' is not assignable to type 'number'. - \ No newline at end of file diff --git a/tests/baselines/reference/varianceMeasurement.errors.txt b/tests/baselines/reference/varianceMeasurement.errors.txt new file mode 100644 index 0000000000000..eb77b28564669 --- /dev/null +++ b/tests/baselines/reference/varianceMeasurement.errors.txt @@ -0,0 +1,122 @@ +tests/cases/compiler/varianceMeasurement.ts(10,7): error TS2322: Type 'Foo1' is not assignable to type 'Foo1<"a">'. + Type 'string' is not assignable to type '"a"'. +tests/cases/compiler/varianceMeasurement.ts(21,7): error TS2322: Type 'Foo2' is not assignable to type 'Foo2<"a">'. + Types of property 'x' are incompatible. + Type 'string' is not assignable to type '"a"'. +tests/cases/compiler/varianceMeasurement.ts(22,7): error TS2322: Type 'Foo2' is not assignable to type 'Foo2'. + The types of 'y.x' are incompatible between these types. + Type '(arg: string) => void' is not assignable to type '(arg: unknown) => void'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/compiler/varianceMeasurement.ts(33,7): error TS2322: Type 'Foo3' is not assignable to type 'Foo3<"a">'. + Type 'string' is not assignable to type '"a"'. +tests/cases/compiler/varianceMeasurement.ts(44,7): error TS2322: Type 'Foo4' is not assignable to type 'Foo4<"a">'. + Types of property 'x' are incompatible. + Type 'string' is not assignable to type '"a"'. +tests/cases/compiler/varianceMeasurement.ts(45,7): error TS2322: Type 'Foo4' is not assignable to type 'Foo4'. + The types of 'y.x' are incompatible between these types. + Type '(arg: string) => void' is not assignable to type '(arg: unknown) => void'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/compiler/varianceMeasurement.ts(57,7): error TS2322: Type 'Fn' is not assignable to type 'Fn'. + Type 'unknown' is not assignable to type 'string'. +tests/cases/compiler/varianceMeasurement.ts(62,7): error TS2322: Type 'Fn' is not assignable to type 'Fn'. + Type 'number' is not assignable to type '0'. + + +==== tests/cases/compiler/varianceMeasurement.ts (8 errors) ==== + // The type below should be invariant in T but is measured as covariant because + // we don't analyze recursive references. + + interface Foo1 { + x: T; + y: Foo1<(arg: T) => void>; + } + + declare const f10: Foo1; + const f11: Foo1<'a'> = f10; + ~~~ +!!! error TS2322: Type 'Foo1' is not assignable to type 'Foo1<"a">'. +!!! error TS2322: Type 'string' is not assignable to type '"a"'. + const f12: Foo1 = f10; + + // The type below is invariant in T and is measured as such. + + interface Foo2 { + x: T; + y: { x: (arg: T) => void, y: Foo2<(arg: T) => void>; } + } + + declare const f20: Foo2; + const f21: Foo2<'a'> = f20; + ~~~ +!!! error TS2322: Type 'Foo2' is not assignable to type 'Foo2<"a">'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type '"a"'. + const f22: Foo2 = f20; + ~~~ +!!! error TS2322: Type 'Foo2' is not assignable to type 'Foo2'. +!!! error TS2322: The types of 'y.x' are incompatible between these types. +!!! error TS2322: Type '(arg: string) => void' is not assignable to type '(arg: unknown) => void'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + // The type below should be invariant in T but is measured as covariant because + // we don't analyze recursive references. + + type Foo3 = { + x: T; + y: Foo3<(arg: T) => void>; + } + + declare const f30: Foo3; + const f31: Foo3<'a'> = f30; + ~~~ +!!! error TS2322: Type 'Foo3' is not assignable to type 'Foo3<"a">'. +!!! error TS2322: Type 'string' is not assignable to type '"a"'. + const f32: Foo3 = f30; + + // The type below is invariant in T and is measured as such. + + type Foo4 = { + x: T; + y: { x: (arg: T) => void, y: Foo4<(arg: T) => void>; } + } + + declare const f40: Foo4; + const f41: Foo4<'a'> = f40; + ~~~ +!!! error TS2322: Type 'Foo4' is not assignable to type 'Foo4<"a">'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type '"a"'. + const f42: Foo4 = f40; + ~~~ +!!! error TS2322: Type 'Foo4' is not assignable to type 'Foo4'. +!!! error TS2322: The types of 'y.x' are incompatible between these types. +!!! error TS2322: Type '(arg: string) => void' is not assignable to type '(arg: unknown) => void'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + // Repro from #3580 + + interface Fn { + (a: A): B; + then(next: Fn): Fn; + } + + declare const fn: Fn; + + // Contravariant in A + const fn1: Fn = fn; // Error + ~~~ +!!! error TS2322: Type 'Fn' is not assignable to type 'Fn'. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + const fn2: Fn<'a', number> = fn; + + // Covariant in B + const fn3: Fn = fn; + const fn4: Fn = fn; // Error + ~~~ +!!! error TS2322: Type 'Fn' is not assignable to type 'Fn'. +!!! error TS2322: Type 'number' is not assignable to type '0'. + \ No newline at end of file diff --git a/tests/baselines/reference/varianceMeasurement.js b/tests/baselines/reference/varianceMeasurement.js new file mode 100644 index 0000000000000..b597e5d24639b --- /dev/null +++ b/tests/baselines/reference/varianceMeasurement.js @@ -0,0 +1,83 @@ +//// [varianceMeasurement.ts] +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. + +interface Foo1 { + x: T; + y: Foo1<(arg: T) => void>; +} + +declare const f10: Foo1; +const f11: Foo1<'a'> = f10; +const f12: Foo1 = f10; + +// The type below is invariant in T and is measured as such. + +interface Foo2 { + x: T; + y: { x: (arg: T) => void, y: Foo2<(arg: T) => void>; } +} + +declare const f20: Foo2; +const f21: Foo2<'a'> = f20; +const f22: Foo2 = f20; + +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. + +type Foo3 = { + x: T; + y: Foo3<(arg: T) => void>; +} + +declare const f30: Foo3; +const f31: Foo3<'a'> = f30; +const f32: Foo3 = f30; + +// The type below is invariant in T and is measured as such. + +type Foo4 = { + x: T; + y: { x: (arg: T) => void, y: Foo4<(arg: T) => void>; } +} + +declare const f40: Foo4; +const f41: Foo4<'a'> = f40; +const f42: Foo4 = f40; + +// Repro from #3580 + +interface Fn { + (a: A): B; + then(next: Fn): Fn; +} + +declare const fn: Fn; + +// Contravariant in A +const fn1: Fn = fn; // Error +const fn2: Fn<'a', number> = fn; + +// Covariant in B +const fn3: Fn = fn; +const fn4: Fn = fn; // Error + + +//// [varianceMeasurement.js] +"use strict"; +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. +var f11 = f10; +var f12 = f10; +var f21 = f20; +var f22 = f20; +var f31 = f30; +var f32 = f30; +var f41 = f40; +var f42 = f40; +// Contravariant in A +var fn1 = fn; // Error +var fn2 = fn; +// Covariant in B +var fn3 = fn; +var fn4 = fn; // Error diff --git a/tests/baselines/reference/varianceMeasurement.symbols b/tests/baselines/reference/varianceMeasurement.symbols new file mode 100644 index 0000000000000..98d36fe16f91d --- /dev/null +++ b/tests/baselines/reference/varianceMeasurement.symbols @@ -0,0 +1,185 @@ +=== tests/cases/compiler/varianceMeasurement.ts === +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. + +interface Foo1 { +>Foo1 : Symbol(Foo1, Decl(varianceMeasurement.ts, 0, 0)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 3, 15)) + + x: T; +>x : Symbol(Foo1.x, Decl(varianceMeasurement.ts, 3, 19)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 3, 15)) + + y: Foo1<(arg: T) => void>; +>y : Symbol(Foo1.y, Decl(varianceMeasurement.ts, 4, 7)) +>Foo1 : Symbol(Foo1, Decl(varianceMeasurement.ts, 0, 0)) +>arg : Symbol(arg, Decl(varianceMeasurement.ts, 5, 11)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 3, 15)) +} + +declare const f10: Foo1; +>f10 : Symbol(f10, Decl(varianceMeasurement.ts, 8, 13)) +>Foo1 : Symbol(Foo1, Decl(varianceMeasurement.ts, 0, 0)) + +const f11: Foo1<'a'> = f10; +>f11 : Symbol(f11, Decl(varianceMeasurement.ts, 9, 5)) +>Foo1 : Symbol(Foo1, Decl(varianceMeasurement.ts, 0, 0)) +>f10 : Symbol(f10, Decl(varianceMeasurement.ts, 8, 13)) + +const f12: Foo1 = f10; +>f12 : Symbol(f12, Decl(varianceMeasurement.ts, 10, 5)) +>Foo1 : Symbol(Foo1, Decl(varianceMeasurement.ts, 0, 0)) +>f10 : Symbol(f10, Decl(varianceMeasurement.ts, 8, 13)) + +// The type below is invariant in T and is measured as such. + +interface Foo2 { +>Foo2 : Symbol(Foo2, Decl(varianceMeasurement.ts, 10, 31)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 14, 15)) + + x: T; +>x : Symbol(Foo2.x, Decl(varianceMeasurement.ts, 14, 19)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 14, 15)) + + y: { x: (arg: T) => void, y: Foo2<(arg: T) => void>; } +>y : Symbol(Foo2.y, Decl(varianceMeasurement.ts, 15, 7)) +>x : Symbol(x, Decl(varianceMeasurement.ts, 16, 6)) +>arg : Symbol(arg, Decl(varianceMeasurement.ts, 16, 11)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 14, 15)) +>y : Symbol(y, Decl(varianceMeasurement.ts, 16, 27)) +>Foo2 : Symbol(Foo2, Decl(varianceMeasurement.ts, 10, 31)) +>arg : Symbol(arg, Decl(varianceMeasurement.ts, 16, 37)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 14, 15)) +} + +declare const f20: Foo2; +>f20 : Symbol(f20, Decl(varianceMeasurement.ts, 19, 13)) +>Foo2 : Symbol(Foo2, Decl(varianceMeasurement.ts, 10, 31)) + +const f21: Foo2<'a'> = f20; +>f21 : Symbol(f21, Decl(varianceMeasurement.ts, 20, 5)) +>Foo2 : Symbol(Foo2, Decl(varianceMeasurement.ts, 10, 31)) +>f20 : Symbol(f20, Decl(varianceMeasurement.ts, 19, 13)) + +const f22: Foo2 = f20; +>f22 : Symbol(f22, Decl(varianceMeasurement.ts, 21, 5)) +>Foo2 : Symbol(Foo2, Decl(varianceMeasurement.ts, 10, 31)) +>f20 : Symbol(f20, Decl(varianceMeasurement.ts, 19, 13)) + +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. + +type Foo3 = { +>Foo3 : Symbol(Foo3, Decl(varianceMeasurement.ts, 21, 31)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 26, 10)) + + x: T; +>x : Symbol(x, Decl(varianceMeasurement.ts, 26, 16)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 26, 10)) + + y: Foo3<(arg: T) => void>; +>y : Symbol(y, Decl(varianceMeasurement.ts, 27, 7)) +>Foo3 : Symbol(Foo3, Decl(varianceMeasurement.ts, 21, 31)) +>arg : Symbol(arg, Decl(varianceMeasurement.ts, 28, 11)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 26, 10)) +} + +declare const f30: Foo3; +>f30 : Symbol(f30, Decl(varianceMeasurement.ts, 31, 13)) +>Foo3 : Symbol(Foo3, Decl(varianceMeasurement.ts, 21, 31)) + +const f31: Foo3<'a'> = f30; +>f31 : Symbol(f31, Decl(varianceMeasurement.ts, 32, 5)) +>Foo3 : Symbol(Foo3, Decl(varianceMeasurement.ts, 21, 31)) +>f30 : Symbol(f30, Decl(varianceMeasurement.ts, 31, 13)) + +const f32: Foo3 = f30; +>f32 : Symbol(f32, Decl(varianceMeasurement.ts, 33, 5)) +>Foo3 : Symbol(Foo3, Decl(varianceMeasurement.ts, 21, 31)) +>f30 : Symbol(f30, Decl(varianceMeasurement.ts, 31, 13)) + +// The type below is invariant in T and is measured as such. + +type Foo4 = { +>Foo4 : Symbol(Foo4, Decl(varianceMeasurement.ts, 33, 31)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 37, 10)) + + x: T; +>x : Symbol(x, Decl(varianceMeasurement.ts, 37, 16)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 37, 10)) + + y: { x: (arg: T) => void, y: Foo4<(arg: T) => void>; } +>y : Symbol(y, Decl(varianceMeasurement.ts, 38, 7)) +>x : Symbol(x, Decl(varianceMeasurement.ts, 39, 6)) +>arg : Symbol(arg, Decl(varianceMeasurement.ts, 39, 11)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 37, 10)) +>y : Symbol(y, Decl(varianceMeasurement.ts, 39, 27)) +>Foo4 : Symbol(Foo4, Decl(varianceMeasurement.ts, 33, 31)) +>arg : Symbol(arg, Decl(varianceMeasurement.ts, 39, 37)) +>T : Symbol(T, Decl(varianceMeasurement.ts, 37, 10)) +} + +declare const f40: Foo4; +>f40 : Symbol(f40, Decl(varianceMeasurement.ts, 42, 13)) +>Foo4 : Symbol(Foo4, Decl(varianceMeasurement.ts, 33, 31)) + +const f41: Foo4<'a'> = f40; +>f41 : Symbol(f41, Decl(varianceMeasurement.ts, 43, 5)) +>Foo4 : Symbol(Foo4, Decl(varianceMeasurement.ts, 33, 31)) +>f40 : Symbol(f40, Decl(varianceMeasurement.ts, 42, 13)) + +const f42: Foo4 = f40; +>f42 : Symbol(f42, Decl(varianceMeasurement.ts, 44, 5)) +>Foo4 : Symbol(Foo4, Decl(varianceMeasurement.ts, 33, 31)) +>f40 : Symbol(f40, Decl(varianceMeasurement.ts, 42, 13)) + +// Repro from #3580 + +interface Fn { +>Fn : Symbol(Fn, Decl(varianceMeasurement.ts, 44, 31)) +>A : Symbol(A, Decl(varianceMeasurement.ts, 48, 13)) +>B : Symbol(B, Decl(varianceMeasurement.ts, 48, 15)) + + (a: A): B; +>a : Symbol(a, Decl(varianceMeasurement.ts, 49, 3)) +>A : Symbol(A, Decl(varianceMeasurement.ts, 48, 13)) +>B : Symbol(B, Decl(varianceMeasurement.ts, 48, 15)) + + then(next: Fn): Fn; +>then : Symbol(Fn.then, Decl(varianceMeasurement.ts, 49, 12)) +>C : Symbol(C, Decl(varianceMeasurement.ts, 50, 7)) +>next : Symbol(next, Decl(varianceMeasurement.ts, 50, 10)) +>Fn : Symbol(Fn, Decl(varianceMeasurement.ts, 44, 31)) +>B : Symbol(B, Decl(varianceMeasurement.ts, 48, 15)) +>C : Symbol(C, Decl(varianceMeasurement.ts, 50, 7)) +>Fn : Symbol(Fn, Decl(varianceMeasurement.ts, 44, 31)) +>A : Symbol(A, Decl(varianceMeasurement.ts, 48, 13)) +>C : Symbol(C, Decl(varianceMeasurement.ts, 50, 7)) +} + +declare const fn: Fn; +>fn : Symbol(fn, Decl(varianceMeasurement.ts, 53, 13)) +>Fn : Symbol(Fn, Decl(varianceMeasurement.ts, 44, 31)) + +// Contravariant in A +const fn1: Fn = fn; // Error +>fn1 : Symbol(fn1, Decl(varianceMeasurement.ts, 56, 5)) +>Fn : Symbol(Fn, Decl(varianceMeasurement.ts, 44, 31)) +>fn : Symbol(fn, Decl(varianceMeasurement.ts, 53, 13)) + +const fn2: Fn<'a', number> = fn; +>fn2 : Symbol(fn2, Decl(varianceMeasurement.ts, 57, 5)) +>Fn : Symbol(Fn, Decl(varianceMeasurement.ts, 44, 31)) +>fn : Symbol(fn, Decl(varianceMeasurement.ts, 53, 13)) + +// Covariant in B +const fn3: Fn = fn; +>fn3 : Symbol(fn3, Decl(varianceMeasurement.ts, 60, 5)) +>Fn : Symbol(Fn, Decl(varianceMeasurement.ts, 44, 31)) +>fn : Symbol(fn, Decl(varianceMeasurement.ts, 53, 13)) + +const fn4: Fn = fn; // Error +>fn4 : Symbol(fn4, Decl(varianceMeasurement.ts, 61, 5)) +>Fn : Symbol(Fn, Decl(varianceMeasurement.ts, 44, 31)) +>fn : Symbol(fn, Decl(varianceMeasurement.ts, 53, 13)) + diff --git a/tests/baselines/reference/varianceMeasurement.types b/tests/baselines/reference/varianceMeasurement.types new file mode 100644 index 0000000000000..83be34759f1ed --- /dev/null +++ b/tests/baselines/reference/varianceMeasurement.types @@ -0,0 +1,133 @@ +=== tests/cases/compiler/varianceMeasurement.ts === +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. + +interface Foo1 { + x: T; +>x : T + + y: Foo1<(arg: T) => void>; +>y : Foo1<(arg: T) => void> +>arg : T +} + +declare const f10: Foo1; +>f10 : Foo1 + +const f11: Foo1<'a'> = f10; +>f11 : Foo1<"a"> +>f10 : Foo1 + +const f12: Foo1 = f10; +>f12 : Foo1 +>f10 : Foo1 + +// The type below is invariant in T and is measured as such. + +interface Foo2 { + x: T; +>x : T + + y: { x: (arg: T) => void, y: Foo2<(arg: T) => void>; } +>y : { x: (arg: T) => void; y: Foo2<(arg: T) => void>; } +>x : (arg: T) => void +>arg : T +>y : Foo2<(arg: T) => void> +>arg : T +} + +declare const f20: Foo2; +>f20 : Foo2 + +const f21: Foo2<'a'> = f20; +>f21 : Foo2<"a"> +>f20 : Foo2 + +const f22: Foo2 = f20; +>f22 : Foo2 +>f20 : Foo2 + +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. + +type Foo3 = { +>Foo3 : Foo3 + + x: T; +>x : T + + y: Foo3<(arg: T) => void>; +>y : Foo3<(arg: T) => void> +>arg : T +} + +declare const f30: Foo3; +>f30 : Foo3 + +const f31: Foo3<'a'> = f30; +>f31 : Foo3<"a"> +>f30 : Foo3 + +const f32: Foo3 = f30; +>f32 : Foo3 +>f30 : Foo3 + +// The type below is invariant in T and is measured as such. + +type Foo4 = { +>Foo4 : Foo4 + + x: T; +>x : T + + y: { x: (arg: T) => void, y: Foo4<(arg: T) => void>; } +>y : { x: (arg: T) => void; y: Foo4<(arg: T) => void>; } +>x : (arg: T) => void +>arg : T +>y : Foo4<(arg: T) => void> +>arg : T +} + +declare const f40: Foo4; +>f40 : Foo4 + +const f41: Foo4<'a'> = f40; +>f41 : Foo4<"a"> +>f40 : Foo4 + +const f42: Foo4 = f40; +>f42 : Foo4 +>f40 : Foo4 + +// Repro from #3580 + +interface Fn { + (a: A): B; +>a : A + + then(next: Fn): Fn; +>then : (next: Fn) => Fn +>next : Fn +} + +declare const fn: Fn; +>fn : Fn + +// Contravariant in A +const fn1: Fn = fn; // Error +>fn1 : Fn +>fn : Fn + +const fn2: Fn<'a', number> = fn; +>fn2 : Fn<"a", number> +>fn : Fn + +// Covariant in B +const fn3: Fn = fn; +>fn3 : Fn +>fn : Fn + +const fn4: Fn = fn; // Error +>fn4 : Fn +>fn : Fn + diff --git a/tests/cases/compiler/varianceMeasurement.ts b/tests/cases/compiler/varianceMeasurement.ts new file mode 100644 index 0000000000000..6c327291d97a2 --- /dev/null +++ b/tests/cases/compiler/varianceMeasurement.ts @@ -0,0 +1,64 @@ +// @strict: true + +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. + +interface Foo1 { + x: T; + y: Foo1<(arg: T) => void>; +} + +declare const f10: Foo1; +const f11: Foo1<'a'> = f10; +const f12: Foo1 = f10; + +// The type below is invariant in T and is measured as such. + +interface Foo2 { + x: T; + y: { x: (arg: T) => void, y: Foo2<(arg: T) => void>; } +} + +declare const f20: Foo2; +const f21: Foo2<'a'> = f20; +const f22: Foo2 = f20; + +// The type below should be invariant in T but is measured as covariant because +// we don't analyze recursive references. + +type Foo3 = { + x: T; + y: Foo3<(arg: T) => void>; +} + +declare const f30: Foo3; +const f31: Foo3<'a'> = f30; +const f32: Foo3 = f30; + +// The type below is invariant in T and is measured as such. + +type Foo4 = { + x: T; + y: { x: (arg: T) => void, y: Foo4<(arg: T) => void>; } +} + +declare const f40: Foo4; +const f41: Foo4<'a'> = f40; +const f42: Foo4 = f40; + +// Repro from #3580 + +interface Fn { + (a: A): B; + then(next: Fn): Fn; +} + +declare const fn: Fn; + +// Contravariant in A +const fn1: Fn = fn; // Error +const fn2: Fn<'a', number> = fn; + +// Covariant in B +const fn3: Fn = fn; +const fn4: Fn = fn; // Error From 96e8fbc657121699c17dd04bc2c756372798e202 Mon Sep 17 00:00:00 2001 From: Sheon Han Date: Fri, 17 Jan 2020 16:56:50 -0500 Subject: [PATCH 14/28] Fix for issue #32528: Prevent meta property from appearing twice (#35844) * fix meta property from appearing twice * handle case where ImportMeta has props defined * rename file * use exclude instead of exact * undo comment * this file should have no change * change file name back * add more test cases * remove comment and text validation * fix formatting --- src/services/completions.ts | 2 +- tests/cases/fourslash/completionImportMeta.ts | 24 ++++++++++- ...mpletionImportMetaWithGlobalDeclaration.ts | 41 +++++++++++++++++++ tests/cases/fourslash/completionsNewTarget.ts | 10 ++++- 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/completionImportMetaWithGlobalDeclaration.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index 9de0d2cb7613f..cf5b38a71d196 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1143,7 +1143,7 @@ namespace ts.Completions { } } - if (isMetaProperty(node) && (node.keywordToken === SyntaxKind.NewKeyword || node.keywordToken === SyntaxKind.ImportKeyword)) { + if (isMetaProperty(node) && (node.keywordToken === SyntaxKind.NewKeyword || node.keywordToken === SyntaxKind.ImportKeyword) && contextToken === node.getChildAt(1)) { const completion = (node.keywordToken === SyntaxKind.NewKeyword) ? "target" : "meta"; symbols.push(typeChecker.createSymbol(SymbolFlags.Property, escapeLeadingUnderscores(completion))); return; diff --git a/tests/cases/fourslash/completionImportMeta.ts b/tests/cases/fourslash/completionImportMeta.ts index 45b6f889a1133..255c1aa569af1 100644 --- a/tests/cases/fourslash/completionImportMeta.ts +++ b/tests/cases/fourslash/completionImportMeta.ts @@ -1,5 +1,25 @@ /// -////import./**/ +// @Filename: a.ts +////import./*1*/ -verify.completions({ marker: "", exact: "meta" }); +// @Filename: b.ts +////import.meta./*2*/ + +// @Filename: c.ts +////import./*3*/meta + +verify.completions( + { + marker: "1", + exact: "meta" + }, + { + marker: "2", + exact: undefined + }, + { + marker: "3", + exact: "meta" + } +); diff --git a/tests/cases/fourslash/completionImportMetaWithGlobalDeclaration.ts b/tests/cases/fourslash/completionImportMetaWithGlobalDeclaration.ts new file mode 100644 index 0000000000000..2be5ea546925f --- /dev/null +++ b/tests/cases/fourslash/completionImportMetaWithGlobalDeclaration.ts @@ -0,0 +1,41 @@ +/// + +// Module: esnext + +// @Filename: a.ts +////import./*1*/ + +// @Filename: b.ts +////declare global { +//// interface ImportMeta { +//// url: string; +//// } +////} +////import.meta./*2*/ + +// @Filename: c.ts +////import.meta./*3*/url + +// @Filename: d.ts +////import./*4*/meta + +verify.completions( + { + marker: "1", + exact: "meta" + }, + { + marker: "2", + includes: ["url"], + excludes: ["meta"] + }, + { + marker: "3", + includes: ["url"], + excludes: ["meta"] + }, + { + marker: "4", + exact: "meta" + } +); diff --git a/tests/cases/fourslash/completionsNewTarget.ts b/tests/cases/fourslash/completionsNewTarget.ts index 5c25ecbc73929..293b2c32ff052 100644 --- a/tests/cases/fourslash/completionsNewTarget.ts +++ b/tests/cases/fourslash/completionsNewTarget.ts @@ -2,8 +2,14 @@ ////class C { //// constructor() { -//// if (C === new./**/) +//// if (C === new./*1*/) +//// } +////} +////class D { +//// constructor() { +//// if (D === new.target./*2*/) //// } ////} -verify.completions({ marker: "", exact: "target" }); +verify.completions({ marker: "1", exact: "target" }); +verify.completions({ marker: "2", excludes: ["target"] }); From ce4c4b618330aa5cd2209091de314efa3804f288 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Sat, 18 Jan 2020 00:24:46 +0200 Subject: [PATCH 15/28] fix(36023): fix crash in document highlight service (#36233) --- src/services/documentHighlights.ts | 8 ++++++-- .../fourslash/documentHighlightDefaultInKeyword.ts | 8 ++++++++ .../fourslash/documentHighlightDefaultInSwitch.ts | 13 +++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/documentHighlightDefaultInKeyword.ts create mode 100644 tests/cases/fourslash/documentHighlightDefaultInSwitch.ts diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index d3a165f3b8de3..378739144110d 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -66,8 +66,12 @@ namespace ts { case SyntaxKind.SwitchKeyword: return useParent(node.parent, isSwitchStatement, getSwitchCaseDefaultOccurrences); case SyntaxKind.CaseKeyword: - case SyntaxKind.DefaultKeyword: - return useParent(node.parent.parent.parent, isSwitchStatement, getSwitchCaseDefaultOccurrences); + case SyntaxKind.DefaultKeyword: { + if (isDefaultClause(node.parent) || isCaseClause(node.parent)) { + return useParent(node.parent.parent.parent, isSwitchStatement, getSwitchCaseDefaultOccurrences); + } + return undefined; + } case SyntaxKind.BreakKeyword: case SyntaxKind.ContinueKeyword: return useParent(node.parent, isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences); diff --git a/tests/cases/fourslash/documentHighlightDefaultInKeyword.ts b/tests/cases/fourslash/documentHighlightDefaultInKeyword.ts new file mode 100644 index 0000000000000..98d45f88ceb73 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightDefaultInKeyword.ts @@ -0,0 +1,8 @@ +/// + +////[|case|] +////[|default|] + +const [defaultKeywordRange, caseKeywordRange] = test.ranges(); +verify.noDocumentHighlights(defaultKeywordRange); +verify.noDocumentHighlights(caseKeywordRange); diff --git a/tests/cases/fourslash/documentHighlightDefaultInSwitch.ts b/tests/cases/fourslash/documentHighlightDefaultInSwitch.ts new file mode 100644 index 0000000000000..e30366bcf27f8 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightDefaultInSwitch.ts @@ -0,0 +1,13 @@ +/// + +////const foo = 'foo'; +////[|switch|] (foo) { +//// [|case|] 'foo': +//// [|break|]; +//// [|default|]: +//// [|break|]; +////} + +const [r0, r1, r2, r3, r4] = test.ranges(); +verify.documentHighlightsOf(r1, [r0, r1, r2, r3, r4]); +verify.documentHighlightsOf(r4, [r0, r1, r2, r3, r4]); From 94e8db7e078533bfcf6e3c409897c3376cb2024c Mon Sep 17 00:00:00 2001 From: Alexander T Date: Sat, 18 Jan 2020 00:26:36 +0200 Subject: [PATCH 16/28] =?UTF-8?q?fix(35043):=20TS=20Server:=20references?= =?UTF-8?q?=20does=20not=20mark=20isDefinition=20o=E2=80=A6=20(#36051)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/findAllReferences.ts | 11 ++++++++--- .../cases/fourslash/findAllReferencesOfConstructor.ts | 6 +++--- .../findAllReferencesOfConstructor_badOverload.ts | 4 ++-- .../findAllRefsExportDefaultClassConstructor.ts | 2 +- tests/cases/fourslash/findAllRefsOfConstructor.ts | 4 ++-- tests/cases/fourslash/findAllRefsOfConstructor2.ts | 6 +++--- .../findAllRefsOfConstructor_multipleFiles.ts | 2 +- .../findAllRefsOfConstructor_withModifier.ts | 2 +- tests/cases/fourslash/renameJsExports03.ts | 2 +- 9 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 5a8ae1a3f4b3e..5215b28a40396 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -337,9 +337,7 @@ namespace ts.FindAllReferences { return { ...documentSpan, isWriteAccess: isWriteAccessForReference(node), - isDefinition: node.kind === SyntaxKind.DefaultKeyword - || !!getDeclarationFromName(node) - || isLiteralComputedPropertyDeclarationName(node), + isDefinition: isDefinitionForReference(node), isInString: kind === EntryKind.StringLiteral ? true : undefined, }; } @@ -470,6 +468,13 @@ namespace ts.FindAllReferences { return !!decl && declarationIsWriteAccess(decl) || node.kind === SyntaxKind.DefaultKeyword || isWriteAccess(node); } + function isDefinitionForReference(node: Node): boolean { + return node.kind === SyntaxKind.DefaultKeyword + || !!getDeclarationFromName(node) + || isLiteralComputedPropertyDeclarationName(node) + || (node.kind === SyntaxKind.ConstructorKeyword && isConstructorDeclaration(node.parent)); + } + /** * True if 'decl' provides a value, as in `function f() {}`; * false if 'decl' is just a location for a future write, as in 'let x;' diff --git a/tests/cases/fourslash/findAllReferencesOfConstructor.ts b/tests/cases/fourslash/findAllReferencesOfConstructor.ts index a952a2c6ee740..eecf3185ebae9 100644 --- a/tests/cases/fourslash/findAllReferencesOfConstructor.ts +++ b/tests/cases/fourslash/findAllReferencesOfConstructor.ts @@ -2,9 +2,9 @@ // @Filename: a.ts ////export class C { -//// [|[|{| "contextRangeIndex": 0 |}constructor|](n: number);|] -//// [|[|{| "contextRangeIndex": 2 |}constructor|]();|] -//// [|[|{| "contextRangeIndex": 4 |}constructor|](n?: number){}|] +//// [|[|{| "contextRangeIndex": 0, "isDefinition": true |}constructor|](n: number);|] +//// [|[|{| "contextRangeIndex": 2, "isDefinition": true |}constructor|]();|] +//// [|[|{| "contextRangeIndex": 4, "isDefinition": true |}constructor|](n?: number){}|] //// static f() { //// this.f(); //// new [|this|](); diff --git a/tests/cases/fourslash/findAllReferencesOfConstructor_badOverload.ts b/tests/cases/fourslash/findAllReferencesOfConstructor_badOverload.ts index c343df86e7a7f..00ca23cda2785 100644 --- a/tests/cases/fourslash/findAllReferencesOfConstructor_badOverload.ts +++ b/tests/cases/fourslash/findAllReferencesOfConstructor_badOverload.ts @@ -1,8 +1,8 @@ /// ////class C { -//// [|[|{| "contextRangeIndex": 0 |}constructor|](n: number);|] -//// [|[|{| "contextRangeIndex": 2 |}constructor|](){}|] +//// [|[|{| "contextRangeIndex": 0, "isDefinition": true |}constructor|](n: number);|] +//// [|[|{| "contextRangeIndex": 2, "isDefinition": true |}constructor|](){}|] ////} verify.singleReferenceGroup("class C", "constructor"); diff --git a/tests/cases/fourslash/findAllRefsExportDefaultClassConstructor.ts b/tests/cases/fourslash/findAllRefsExportDefaultClassConstructor.ts index 5a882023c22f6..3d374fefbb435 100644 --- a/tests/cases/fourslash/findAllRefsExportDefaultClassConstructor.ts +++ b/tests/cases/fourslash/findAllRefsExportDefaultClassConstructor.ts @@ -1,5 +1,5 @@ ////export default class { -//// [|[|{| "contextRangeIndex": 0 |}constructor|]() {}|] +//// [|[|{| "contextRangeIndex": 0, "isDefinition": true |}constructor|]() {}|] ////} verify.singleReferenceGroup("class default", "constructor"); diff --git a/tests/cases/fourslash/findAllRefsOfConstructor.ts b/tests/cases/fourslash/findAllRefsOfConstructor.ts index b5c02e09c03f0..d703126a6354b 100644 --- a/tests/cases/fourslash/findAllRefsOfConstructor.ts +++ b/tests/cases/fourslash/findAllRefsOfConstructor.ts @@ -2,11 +2,11 @@ ////class A { -//// [|[|{| "contextRangeIndex": 0 |}constructor|](s: string) {}|] +//// [|[|{| "contextRangeIndex": 0, "isDefinition": true |}constructor|](s: string) {}|] ////} ////class B extends A { } ////class C extends B { -//// [|[|{| "contextRangeIndex": 2 |}constructor|]() { +//// [|[|{| "contextRangeIndex": 2, "isDefinition": true |}constructor|]() { //// [|super|](""); //// }|] ////} diff --git a/tests/cases/fourslash/findAllRefsOfConstructor2.ts b/tests/cases/fourslash/findAllRefsOfConstructor2.ts index 5c65a098f4fa7..b9d9219693a64 100644 --- a/tests/cases/fourslash/findAllRefsOfConstructor2.ts +++ b/tests/cases/fourslash/findAllRefsOfConstructor2.ts @@ -2,13 +2,13 @@ ////class A { -//// [|[|{| "contextRangeIndex": 0 |}constructor|](s: string) {}|] +//// [|[|{| "contextRangeIndex": 0, "isDefinition": true |}constructor|](s: string) {}|] ////} ////class B extends A { -//// [|[|{| "contextRangeIndex": 2 |}constructor|]() { [|super|](""); }|] +//// [|[|{| "contextRangeIndex": 2, "isDefinition": true |}constructor|]() { [|super|](""); }|] ////} ////class C extends B { -//// [|[|{| "contextRangeIndex": 5 |}constructor|]() { +//// [|[|{| "contextRangeIndex": 5, "isDefinition": true |}constructor|]() { //// [|super|](); //// }|] ////} diff --git a/tests/cases/fourslash/findAllRefsOfConstructor_multipleFiles.ts b/tests/cases/fourslash/findAllRefsOfConstructor_multipleFiles.ts index f768cb1df2655..4d5418f6c7a20 100644 --- a/tests/cases/fourslash/findAllRefsOfConstructor_multipleFiles.ts +++ b/tests/cases/fourslash/findAllRefsOfConstructor_multipleFiles.ts @@ -3,7 +3,7 @@ // @Filename: f.ts ////class A { -//// [|[|{| "contextRangeIndex": 0 |}constructor|](s: string) {}|] +//// [|[|{| "contextRangeIndex": 0, "isDefinition": true |}constructor|](s: string) {}|] ////} ////class B extends A { } ////[|export { [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 2 |}A|], [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 2 |}B|] };|] diff --git a/tests/cases/fourslash/findAllRefsOfConstructor_withModifier.ts b/tests/cases/fourslash/findAllRefsOfConstructor_withModifier.ts index f89bd730a772a..a8df6c05b3e3c 100644 --- a/tests/cases/fourslash/findAllRefsOfConstructor_withModifier.ts +++ b/tests/cases/fourslash/findAllRefsOfConstructor_withModifier.ts @@ -1,7 +1,7 @@ /// ////class X { -//// [|public [|{| "contextRangeIndex": 0 |}constructor|]() {}|] +//// [|public [|{| "contextRangeIndex": 0, "isDefinition": true |}constructor|]() {}|] ////} ////var x = new [|X|](); diff --git a/tests/cases/fourslash/renameJsExports03.ts b/tests/cases/fourslash/renameJsExports03.ts index d1fafa70c8089..02704eda8c7dc 100644 --- a/tests/cases/fourslash/renameJsExports03.ts +++ b/tests/cases/fourslash/renameJsExports03.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: a.js ////[|class [|{| "isWriteAccess": true, "isDefinition": true, "contextRangeIndex": 0 |}A|] { -//// [|[|{| "contextRangeIndex": 2 |}constructor|]() { }|] +//// [|[|{| "contextRangeIndex": 2, "isDefinition": true |}constructor|]() { }|] ////}|] ////[|module.exports = [|{| "contextRangeIndex": 4 |}A|];|] From afa11d3c7ac37c49fc97230a897e4208ee132ae4 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Sat, 18 Jan 2020 00:27:12 +0200 Subject: [PATCH 17/28] fix(34621): show suggestions in class property initializer (#35999) --- src/services/completions.ts | 3 ++ .../completionsClassPropertiesAssignment.ts | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/cases/fourslash/completionsClassPropertiesAssignment.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index cf5b38a71d196..50b8a5e2a8a9a 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -2608,6 +2608,9 @@ namespace ts.Completions { if (!contextToken) return undefined; switch (contextToken.kind) { + case SyntaxKind.EqualsToken: // class c { public prop = | /* global completions */ } + return undefined; + case SyntaxKind.SemicolonToken: // class c {getValue(): number; | } case SyntaxKind.CloseBraceToken: // class c { method() { } | } // class c { method() { } b| } diff --git a/tests/cases/fourslash/completionsClassPropertiesAssignment.ts b/tests/cases/fourslash/completionsClassPropertiesAssignment.ts new file mode 100644 index 0000000000000..a3be4038c36e0 --- /dev/null +++ b/tests/cases/fourslash/completionsClassPropertiesAssignment.ts @@ -0,0 +1,29 @@ +/// + +////class Class1 { +//// protected a = /*1*/ +//// private b = /*2*/ +//// public c = /*3*/ +//// public d = this./*4*/ +////} +//// +////class Class2 { +//// a = /*5*/ +////} +////class Class3 { +//// a = /*6*/ +////} +//// +////const prop = 'prop'; +////class Class4 { +//// [prop] = /*7*/ +////} + +const exact = completion.globalsPlus(["Class1", "Class2", "Class3", "prop", "Class4"]); +verify.completions({ marker: ["1"], exact }); +verify.completions({ marker: ["2"], exact }); +verify.completions({ marker: ["3"], exact }); +verify.completions({ marker: ["4"], exact: ['a', 'b', 'c', 'd'], isGlobalCompletion: false }); +verify.completions({ marker: ["5"], exact }); +verify.completions({ marker: ["6"], exact }); +verify.completions({ marker: ["7"], exact }); From 50adabe32da9741adc2714c9d4ab213f9f9ea18b Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sat, 18 Jan 2020 12:24:08 -0800 Subject: [PATCH 18/28] Improve diagnostics and add code fixes for top-level await (#36173) --- src/compiler/checker.ts | 19 ++-- src/compiler/core.ts | 5 ++ src/compiler/diagnosticMessages.json | 22 ++++- src/harness/fourslashImpl.ts | 6 +- src/harness/fourslashInterfaceImpl.ts | 2 +- .../codefixes/addEmptyExportDeclaration.ts | 20 +++++ .../codefixes/fixAwaitInSyncFunction.ts | 2 +- .../codefixes/fixModuleAndTargetOptions.ts | 44 ++++++++++ src/services/codefixes/helpers.ts | 33 ++++--- src/services/textChanges.ts | 88 ++++++++++++++----- src/services/tsconfig.json | 2 + .../reference/awaitAndYield.errors.txt | 4 +- .../awaitAndYieldInProperty.errors.txt | 16 ++-- .../awaitInClassInAsyncFunction.errors.txt | 4 +- .../awaitInNonAsyncFunction.errors.txt | 32 +++---- .../reference/awaitLiteralValues.errors.txt | 24 ++--- ...it(module=esnext,target=es2015).errors.txt | 4 +- ...it(module=system,target=es2015).errors.txt | 4 +- .../topLevelAwaitNonModule.errors.txt | 4 +- ...deFixAwaitShouldNotCrashIfNotInFunction.ts | 2 +- ...assImplementInterfaceEmptyMultilineBody.ts | 23 +++++ ...bleJsxFlag_blankCompilerOptionsJsConfig.ts | 2 +- ...bleJsxFlag_blankCompilerOptionsTsConfig.ts | 2 +- ...t_module_blankCompilerOptionsInTsConfig.ts | 14 +++ ...ule_compatibleCompilerOptionsInTsConfig.ts | 15 ++++ ...odule_existingCompilerOptionsInTsConfig.ts | 25 ++++++ ...module_missingCompilerOptionsInTsConfig.ts | 11 +++ .../codeFixTopLevelAwait_module_noTsConfig.ts | 8 ++ ...e_targetES2017CompilerOptionsInTsConfig.ts | 28 ++++++ .../codeFixTopLevelAwait_notAModule.ts | 21 +++++ ...t_target_blankCompilerOptionsInTsConfig.ts | 25 ++++++ ...get_compatibleCompilerOptionsInTsConfig.ts | 15 ++++ ...arget_existingCompilerOptionsInTsConfig.ts | 25 ++++++ ...target_missingCompilerOptionsInTsConfig.ts | 23 +++++ .../codeFixTopLevelAwait_target_noTsConfig.ts | 8 ++ ...corators_blankCompilerOptionsInJsconfig.ts | 2 +- ...corators_blankCompilerOptionsInTsconfig.ts | 2 +- ...rators_missingCompilerOptionsInJsconfig.ts | 4 +- ...rators_missingCompilerOptionsInTsconfig.ts | 4 +- ...sxFlag_missingCompilerOptionsInJsconfig.ts | 4 +- ...sxFlag_missingCompilerOptionsInTsconfig.ts | 4 +- tests/cases/fourslash/fourslash.ts | 2 +- 42 files changed, 500 insertions(+), 104 deletions(-) create mode 100644 src/services/codefixes/addEmptyExportDeclaration.ts create mode 100644 src/services/codefixes/fixModuleAndTargetOptions.ts create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceEmptyMultilineBody.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_module_blankCompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_module_compatibleCompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_module_existingCompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_module_missingCompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_module_noTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_module_targetES2017CompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_notAModule.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_target_blankCompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_target_compatibleCompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_target_existingCompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_target_missingCompilerOptionsInTsConfig.ts create mode 100644 tests/cases/fourslash/codeFixTopLevelAwait_target_noTsConfig.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 512e431fbe5ae..0150d5236bdef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26665,13 +26665,18 @@ namespace ts { if (!(node.flags & NodeFlags.AwaitContext)) { if (isTopLevelAwait(node)) { const sourceFile = getSourceFileOfNode(node); - if ((moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) || - languageVersion < ScriptTarget.ES2017 || - !isEffectiveExternalModule(sourceFile, compilerOptions)) { - if (!hasParseDiagnostics(sourceFile)) { - const span = getSpanOfTokenAtPosition(sourceFile, node.pos); + if (!hasParseDiagnostics(sourceFile)) { + let span: TextSpan | undefined; + if (!isEffectiveExternalModule(sourceFile, compilerOptions)) { + if (!span) span = getSpanOfTokenAtPosition(sourceFile, node.pos); + const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, + Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); + diagnostics.add(diagnostic); + } + if ((moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) || languageVersion < ScriptTarget.ES2017) { + span = getSpanOfTokenAtPosition(sourceFile, node.pos); const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, - Diagnostics.await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher); + Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher); diagnostics.add(diagnostic); } } @@ -26681,7 +26686,7 @@ namespace ts { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { const span = getSpanOfTokenAtPosition(sourceFile, node.pos); - const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.await_expression_is_only_allowed_within_an_async_function); + const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); const func = getContainingFunction(node); if (func && func.kind !== SyntaxKind.Constructor && (getFunctionFlags(func) & FunctionFlags.Async) === 0) { const relatedInfo = createDiagnosticForNode(func, Diagnostics.Did_you_mean_to_mark_this_function_as_async); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index cd81020c0f1b7..8d31323a5d8c0 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1269,6 +1269,11 @@ namespace ts { return result; } + /** + * Creates a new object by adding the own properties of `second`, then the own properties of `first`. + * + * NOTE: This means that if a property exists in both `first` and `second`, the property in `first` will be chosen. + */ export function extend(first: T1, second: T2): T1 & T2 { const result: T1 & T2 = {}; for (const id in second) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9ef1f69749b71..78e1a6d6a9545 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -863,7 +863,7 @@ "category": "Error", "code": 1300 }, - "'await' expression is only allowed within an async function.": { + "'await' expressions are only allowed within async functions and at the top levels of modules.": { "category": "Error", "code": 1308 }, @@ -1085,7 +1085,7 @@ }, "Split all invalid type-only imports": { "category": "Message", - "code": 1377 + "code": 1367 }, "Specify emit/checking behavior for imports that are only used for types": { "category": "Message", @@ -1115,10 +1115,14 @@ "category": "Message", "code": 1374 }, - "'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher.": { + "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.": { "category": "Error", "code": 1375 }, + "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.": { + "category": "Error", + "code": 1376 + }, "The types of '{0}' are incompatible between these types.": { "category": "Error", "code": 2200 @@ -5416,6 +5420,18 @@ "category": "Message", "code": 95096 }, + "Add 'export {}' to make this file into a module": { + "category": "Message", + "code": 95097 + }, + "Set the 'target' option in your configuration file to '{0}'": { + "category": "Message", + "code": 95098 + }, + "Set the 'module' option in your configuration file to '{0}'": { + "category": "Message", + "code": 95099 + }, "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": { "category": "Error", diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index eb33a99d6f6ec..b3437e811b935 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -254,7 +254,7 @@ namespace FourSlash { const tsConfig = ts.convertCompilerOptionsFromJson(configJson.config.compilerOptions, baseDirectory, file.fileName); if (!tsConfig.errors || !tsConfig.errors.length) { - compilationOptions = ts.extend(compilationOptions, tsConfig.options); + compilationOptions = ts.extend(tsConfig.options, compilationOptions); } } configFileName = file.fileName; @@ -2574,6 +2574,10 @@ namespace FourSlash { if (typeof options.description === "string") { assert.equal(action.description, options.description); } + else if (Array.isArray(options.description)) { + const description = ts.formatStringFromArgs(options.description[0], options.description, 1); + assert.equal(action.description, description); + } else { assert.match(action.description, templateToRegExp(options.description.template)); } diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 04441468a7313..f3e3953ce3fbc 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1556,7 +1556,7 @@ namespace FourSlashInterface { } export interface VerifyCodeFixOptions extends NewContentOptions { - readonly description: string | DiagnosticIgnoredInterpolations; + readonly description: string | [string, ...(string | number)[]] | DiagnosticIgnoredInterpolations; readonly errorCode?: number; readonly index?: number; readonly preferences?: ts.UserPreferences; diff --git a/src/services/codefixes/addEmptyExportDeclaration.ts b/src/services/codefixes/addEmptyExportDeclaration.ts new file mode 100644 index 0000000000000..2b4c32cd11ab5 --- /dev/null +++ b/src/services/codefixes/addEmptyExportDeclaration.ts @@ -0,0 +1,20 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: [Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code], + getCodeActions: context => { + const { sourceFile } = context; + const changes = textChanges.ChangeTracker.with(context, changes => { + const exportDeclaration = createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createNamedExports([]), + /*moduleSpecifier*/ undefined, + /*isTypeOnly*/ false + ); + changes.insertNodeAtEndOfScope(sourceFile, sourceFile, exportDeclaration); + }); + return [createCodeFixActionWithoutFixAll("addEmptyExportDeclaration", changes, Diagnostics.Add_export_to_make_this_file_into_a_module)]; + }, + }); +} \ No newline at end of file diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index 55dd4bd05567f..7f9cfd8731511 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -2,7 +2,7 @@ namespace ts.codefix { const fixId = "fixAwaitInSyncFunction"; const errorCodes = [ - Diagnostics.await_expression_is_only_allowed_within_an_async_function.code, + Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code, Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code, ]; registerCodeFix({ diff --git a/src/services/codefixes/fixModuleAndTargetOptions.ts b/src/services/codefixes/fixModuleAndTargetOptions.ts new file mode 100644 index 0000000000000..fe3eaebae9597 --- /dev/null +++ b/src/services/codefixes/fixModuleAndTargetOptions.ts @@ -0,0 +1,44 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: [Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code], + getCodeActions: context => { + const compilerOptions = context.program.getCompilerOptions(); + const { configFile } = compilerOptions; + if (configFile === undefined) { + return undefined; + } + + const codeFixes: CodeFixAction[] = []; + const moduleKind = getEmitModuleKind(compilerOptions); + const moduleOutOfRange = moduleKind >= ModuleKind.ES2015 && moduleKind < ModuleKind.ESNext; + if (moduleOutOfRange) { + const changes = textChanges.ChangeTracker.with(context, changes => { + setJsonCompilerOptionValue(changes, configFile, "module", createStringLiteral("esnext")); + }); + codeFixes.push(createCodeFixActionWithoutFixAll("fixModuleOption", changes, [Diagnostics.Set_the_module_option_in_your_configuration_file_to_0, "esnext"])); + } + + const target = getEmitScriptTarget(compilerOptions); + const targetOutOfRange = target < ScriptTarget.ES2017 || target > ScriptTarget.ESNext; + if (targetOutOfRange) { + const changes = textChanges.ChangeTracker.with(context, tracker => { + const configObject = getTsConfigObjectLiteralExpression(configFile); + if (!configObject) return; + + const options: [string, Expression][] = [["target", createStringLiteral("es2017")]]; + if (moduleKind === ModuleKind.CommonJS) { + // Ensure we preserve the default module kind (commonjs), as targets >= ES2015 have a default module kind of es2015. + options.push(["module", createStringLiteral("commonjs")]); + } + + setJsonCompilerOptionValues(tracker, configFile, options); + }); + + codeFixes.push(createCodeFixActionWithoutFixAll("fixTargetOption", changes, [Diagnostics.Set_the_target_option_in_your_configuration_file_to_0, "es2017"])); + } + + return codeFixes.length ? codeFixes : undefined; + } + }); +} diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 95fc499a2f9c6..930e703864f31 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -310,11 +310,10 @@ namespace ts.codefix { return undefined; } - export function setJsonCompilerOptionValue( + export function setJsonCompilerOptionValues( changeTracker: textChanges.ChangeTracker, configFile: TsConfigSourceFile, - optionName: string, - optionValue: Expression, + options: [string, Expression][] ) { const tsconfigObjectLiteral = getTsConfigObjectLiteralExpression(configFile); if (!tsconfigObjectLiteral) return undefined; @@ -323,9 +322,7 @@ namespace ts.codefix { if (compilerOptionsProperty === undefined) { changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment( "compilerOptions", - createObjectLiteral([ - createJsonPropertyAssignment(optionName, optionValue), - ]))); + createObjectLiteral(options.map(([optionName, optionValue]) => createJsonPropertyAssignment(optionName, optionValue)), /*multiLine*/ true))); return; } @@ -334,16 +331,26 @@ namespace ts.codefix { return; } - const optionProperty = findJsonProperty(compilerOptions, optionName); - - if (optionProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); - } - else { - changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + for (const [optionName, optionValue] of options) { + const optionProperty = findJsonProperty(compilerOptions, optionName); + if (optionProperty === undefined) { + changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); + } + else { + changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + } } } + export function setJsonCompilerOptionValue( + changeTracker: textChanges.ChangeTracker, + configFile: TsConfigSourceFile, + optionName: string, + optionValue: Expression, + ) { + setJsonCompilerOptionValues(changeTracker, configFile, [[optionName, optionValue]]); + } + export function createJsonPropertyAssignment(name: string, initializer: Expression) { return createPropertyAssignment(createStringLiteral(name), initializer); } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 69cffe9b8f5f0..127b7ed1b0346 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -477,33 +477,69 @@ namespace ts.textChanges { public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration, newElement: ClassElement): void { this.insertNodeAtStartWorker(sourceFile, cls, newElement); } + public insertNodeAtObjectStart(sourceFile: SourceFile, obj: ObjectLiteralExpression, newElement: ObjectLiteralElementLike): void { this.insertNodeAtStartWorker(sourceFile, obj, newElement); } private insertNodeAtStartWorker(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression, newElement: ClassElement | ObjectLiteralElementLike): void { - const clsStart = cls.getStart(sourceFile); - const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) - + this.formatContext.options.indentSize!; - this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, { indentation, ...this.getInsertNodeAtStartPrefixSuffix(sourceFile, cls) }); - } - - private getInsertNodeAtStartPrefixSuffix(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression): { prefix: string, suffix: string } { - const comma = isObjectLiteralExpression(cls) ? "," : ""; - if (getMembersOrProperties(cls).length === 0) { - if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), { node: cls, sourceFile })) { - // For `class C {\n}`, don't add the trailing "\n" - const [open, close] = getClassOrObjectBraceEnds(cls, sourceFile); - const shouldSuffix = open && close && positionsAreOnSameLine(open, close, sourceFile); - return { prefix: this.newLineCharacter, suffix: comma + (shouldSuffix ? this.newLineCharacter : "") }; + const indentation = this.guessIndentationFromExistingMembers(sourceFile, cls) ?? this.computeIndentationForNewMember(sourceFile, cls); + this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, this.getInsertNodeAtStartInsertOptions(sourceFile, cls, indentation)); + } + + /** + * Tries to guess the indentation from the existing members of a class/interface/object. All members must be on + * new lines and must share the same indentation. + */ + private guessIndentationFromExistingMembers(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression) { + let indentation: number | undefined; + let lastRange: TextRange = cls; + for (const member of getMembersOrProperties(cls)) { + if (rangeStartPositionsAreOnSameLine(lastRange, member, sourceFile)) { + // each indented member must be on a new line + return undefined; } - else { - return { prefix: "", suffix: comma + this.newLineCharacter }; + const memberStart = member.getStart(sourceFile); + const memberIndentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); + if (indentation === undefined) { + indentation = memberIndentation; } + else if (memberIndentation !== indentation) { + // indentation of multiple members is not consistent + return undefined; + } + lastRange = member; } - else { - return { prefix: this.newLineCharacter, suffix: comma }; - } + return indentation; + } + + private computeIndentationForNewMember(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression) { + const clsStart = cls.getStart(sourceFile); + return formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) + + (this.formatContext.options.indentSize ?? 4); + } + + private getInsertNodeAtStartInsertOptions(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression, indentation: number): InsertNodeOptions { + // Rules: + // - Always insert leading newline. + // - For object literals: + // - Add a trailing comma if there are existing members in the node, or the source file is not a JSON file + // (because trailing commas are generally illegal in a JSON file). + // - Add a leading comma if the source file is not a JSON file, there are existing insertions, + // and the node is empty (because we didn't add a trailing comma per the previous rule). + // - Only insert a trailing newline if body is single-line and there are no other insertions for the node. + // NOTE: This is handled in `finishClassesWithNodesInsertedAtStart`. + + const members = getMembersOrProperties(cls); + const isEmpty = members.length === 0; + const isFirstInsertion = addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), { node: cls, sourceFile }); + const insertTrailingComma = isObjectLiteralExpression(cls) && (!isJsonSourceFile(sourceFile) || !isEmpty); + const insertLeadingComma = isObjectLiteralExpression(cls) && isJsonSourceFile(sourceFile) && isEmpty && !isFirstInsertion; + return { + indentation, + prefix: (insertLeadingComma ? "," : "") + this.newLineCharacter, + suffix: insertTrailingComma ? "," : "" + }; } public insertNodeAfterComma(sourceFile: SourceFile, after: Node, newNode: Node): void { @@ -544,6 +580,7 @@ namespace ts.textChanges { prefix: after.end === sourceFile.end && isStatement(after) ? (options.prefix ? `\n${options.prefix}` : "\n") : options.prefix, }; } + private getInsertNodeAfterOptionsWorker(node: Node): InsertNodeOptions { switch (node.kind) { case SyntaxKind.ClassDeclaration: @@ -726,9 +763,16 @@ namespace ts.textChanges { private finishClassesWithNodesInsertedAtStart(): void { this.classesWithNodesInsertedAtStart.forEach(({ node, sourceFile }) => { const [openBraceEnd, closeBraceEnd] = getClassOrObjectBraceEnds(node, sourceFile); - // For `class C { }` remove the whitespace inside the braces. - if (openBraceEnd && closeBraceEnd && positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) { - this.deleteRange(sourceFile, createRange(openBraceEnd, closeBraceEnd - 1)); + if (openBraceEnd !== undefined && closeBraceEnd !== undefined) { + const isEmpty = getMembersOrProperties(node).length === 0; + const isSingleLine = positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile); + if (isEmpty && isSingleLine && openBraceEnd !== closeBraceEnd - 1) { + // For `class C { }` remove the whitespace inside the braces. + this.deleteRange(sourceFile, createRange(openBraceEnd, closeBraceEnd - 1)); + } + if (isSingleLine) { + this.insertText(sourceFile, closeBraceEnd - 1, this.newLineCharacter); + } } }); } diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 946fe575d1823..47b525771eda3 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -47,6 +47,7 @@ "codeFixProvider.ts", "refactorProvider.ts", "codefixes/addConvertToUnknownForNonOverlappingTypes.ts", + "codefixes/addEmptyExportDeclaration.ts", "codefixes/addMissingAwait.ts", "codefixes/addMissingConst.ts", "codefixes/addMissingDeclareProperty.ts", @@ -70,6 +71,7 @@ "codefixes/fixConstructorForDerivedNeedSuperCall.ts", "codefixes/fixEnableExperimentalDecorators.ts", "codefixes/fixEnableJsxFlag.ts", + "codefixes/fixModuleAndTargetOptions.ts", "codefixes/fixExtendsInterfaceBecomesImplements.ts", "codefixes/fixForgottenThisPropertyAccess.ts", "codefixes/fixUnusedIdentifier.ts", diff --git a/tests/baselines/reference/awaitAndYield.errors.txt b/tests/baselines/reference/awaitAndYield.errors.txt index 54794fb01de8b..87842d35cc93f 100644 --- a/tests/baselines/reference/awaitAndYield.errors.txt +++ b/tests/baselines/reference/awaitAndYield.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/enums/awaitAndYield.ts(3,15): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/conformance/enums/awaitAndYield.ts(3,15): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/conformance/enums/awaitAndYield.ts(4,15): error TS1163: A 'yield' expression is only allowed in a generator body. @@ -7,7 +7,7 @@ tests/cases/conformance/enums/awaitAndYield.ts(4,15): error TS1163: A 'yield' ex enum E { foo = await x, ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. baz = yield 1, ~~~~~ !!! error TS1163: A 'yield' expression is only allowed in a generator body. diff --git a/tests/baselines/reference/awaitAndYieldInProperty.errors.txt b/tests/baselines/reference/awaitAndYieldInProperty.errors.txt index 0b6634dcc88d2..2aec2af52788f 100644 --- a/tests/baselines/reference/awaitAndYieldInProperty.errors.txt +++ b/tests/baselines/reference/awaitAndYieldInProperty.errors.txt @@ -1,15 +1,15 @@ tests/cases/conformance/classes/awaitAndYieldInProperty.ts(3,9): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. -tests/cases/conformance/classes/awaitAndYieldInProperty.ts(3,21): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/conformance/classes/awaitAndYieldInProperty.ts(3,21): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(4,16): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. -tests/cases/conformance/classes/awaitAndYieldInProperty.ts(4,28): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/conformance/classes/awaitAndYieldInProperty.ts(4,28): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(6,9): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(6,21): error TS1163: A 'yield' expression is only allowed in a generator body. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(7,16): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(7,28): error TS1163: A 'yield' expression is only allowed in a generator body. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(11,9): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. -tests/cases/conformance/classes/awaitAndYieldInProperty.ts(11,21): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/conformance/classes/awaitAndYieldInProperty.ts(11,21): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(12,16): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. -tests/cases/conformance/classes/awaitAndYieldInProperty.ts(12,28): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/conformance/classes/awaitAndYieldInProperty.ts(12,28): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(14,9): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(14,21): error TS1163: A 'yield' expression is only allowed in a generator body. tests/cases/conformance/classes/awaitAndYieldInProperty.ts(15,16): error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. @@ -23,12 +23,12 @@ tests/cases/conformance/classes/awaitAndYieldInProperty.ts(15,28): error TS1163: ~~~~~~~~~ !!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. static [await x] = await x; ~~~~~~~~~ !!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. [yield 1] = yield 2; ~~~~~~~~~ @@ -47,12 +47,12 @@ tests/cases/conformance/classes/awaitAndYieldInProperty.ts(15,28): error TS1163: ~~~~~~~~~ !!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. static [await x] = await x; ~~~~~~~~~ !!! error TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type. ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. [yield 1] = yield 2; ~~~~~~~~~ diff --git a/tests/baselines/reference/awaitInClassInAsyncFunction.errors.txt b/tests/baselines/reference/awaitInClassInAsyncFunction.errors.txt index 549fbd0b74866..53d4a48dd45af 100644 --- a/tests/baselines/reference/awaitInClassInAsyncFunction.errors.txt +++ b/tests/baselines/reference/awaitInClassInAsyncFunction.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/awaitInClassInAsyncFunction.ts(9,15): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInClassInAsyncFunction.ts(9,15): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. ==== tests/cases/compiler/awaitInClassInAsyncFunction.ts (1 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/awaitInClassInAsyncFunction.ts(9,15): error TS1308: 'await' return new class { baz = await bar(); ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. }; } \ No newline at end of file diff --git a/tests/baselines/reference/awaitInNonAsyncFunction.errors.txt b/tests/baselines/reference/awaitInNonAsyncFunction.errors.txt index aa07a57b57ce2..8224911c3c63d 100644 --- a/tests/baselines/reference/awaitInNonAsyncFunction.errors.txt +++ b/tests/baselines/reference/awaitInNonAsyncFunction.errors.txt @@ -1,19 +1,19 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(4,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(5,10): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInNonAsyncFunction.ts(5,10): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/compiler/awaitInNonAsyncFunction.ts(9,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(10,10): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInNonAsyncFunction.ts(10,10): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/compiler/awaitInNonAsyncFunction.ts(14,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(15,3): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInNonAsyncFunction.ts(15,3): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/compiler/awaitInNonAsyncFunction.ts(19,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(20,10): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInNonAsyncFunction.ts(20,10): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/compiler/awaitInNonAsyncFunction.ts(24,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(25,9): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInNonAsyncFunction.ts(25,9): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/compiler/awaitInNonAsyncFunction.ts(30,9): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(31,5): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInNonAsyncFunction.ts(31,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/compiler/awaitInNonAsyncFunction.ts(34,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(35,5): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitInNonAsyncFunction.ts(35,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. tests/cases/compiler/awaitInNonAsyncFunction.ts(39,5): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. -tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. +tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1376: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher. ==== tests/cases/compiler/awaitInNonAsyncFunction.ts (16 errors) ==== @@ -26,7 +26,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' out !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:3:10: Did you mean to mark this function as 'async'? return await p; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:3:10: Did you mean to mark this function as 'async'? } @@ -37,7 +37,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' out !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:8:17: Did you mean to mark this function as 'async'? return await p; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:8:17: Did you mean to mark this function as 'async'? } @@ -48,7 +48,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' out !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:13:28: Did you mean to mark this function as 'async'? await p; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:13:28: Did you mean to mark this function as 'async'? } @@ -59,7 +59,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' out !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:18:19: Did you mean to mark this function as 'async'? return await p; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:18:19: Did you mean to mark this function as 'async'? }; @@ -70,7 +70,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' out !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:23:11: Did you mean to mark this function as 'async'? yield await p; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:23:11: Did you mean to mark this function as 'async'? } @@ -81,7 +81,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' out !!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. await p; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. } method(p: Promise) { for await (const _ of []); @@ -90,7 +90,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' out !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:33:3: Did you mean to mark this function as 'async'? await p; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:33:3: Did you mean to mark this function as 'async'? } } @@ -100,4 +100,4 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1375: 'await' out !!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator. await null; ~~~~~ -!!! error TS1375: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. \ No newline at end of file +!!! error TS1376: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher. \ No newline at end of file diff --git a/tests/baselines/reference/awaitLiteralValues.errors.txt b/tests/baselines/reference/awaitLiteralValues.errors.txt index eb3237186e37f..b2e882eb44027 100644 --- a/tests/baselines/reference/awaitLiteralValues.errors.txt +++ b/tests/baselines/reference/awaitLiteralValues.errors.txt @@ -1,51 +1,51 @@ -tests/cases/compiler/awaitLiteralValues.ts(2,5): error TS1308: 'await' expression is only allowed within an async function. -tests/cases/compiler/awaitLiteralValues.ts(6,5): error TS1308: 'await' expression is only allowed within an async function. -tests/cases/compiler/awaitLiteralValues.ts(10,5): error TS1308: 'await' expression is only allowed within an async function. -tests/cases/compiler/awaitLiteralValues.ts(14,5): error TS1308: 'await' expression is only allowed within an async function. -tests/cases/compiler/awaitLiteralValues.ts(18,5): error TS1308: 'await' expression is only allowed within an async function. -tests/cases/compiler/awaitLiteralValues.ts(22,5): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitLiteralValues.ts(2,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. +tests/cases/compiler/awaitLiteralValues.ts(6,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. +tests/cases/compiler/awaitLiteralValues.ts(10,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. +tests/cases/compiler/awaitLiteralValues.ts(14,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. +tests/cases/compiler/awaitLiteralValues.ts(18,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. +tests/cases/compiler/awaitLiteralValues.ts(22,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. ==== tests/cases/compiler/awaitLiteralValues.ts (6 errors) ==== function awaitString() { await 'literal'; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitLiteralValues.ts:1:10: Did you mean to mark this function as 'async'? } function awaitNumber() { await 1; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitLiteralValues.ts:5:10: Did you mean to mark this function as 'async'? } function awaitTrue() { await true; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitLiteralValues.ts:9:10: Did you mean to mark this function as 'async'? } function awaitFalse() { await false; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitLiteralValues.ts:13:10: Did you mean to mark this function as 'async'? } function awaitNull() { await null; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitLiteralValues.ts:17:10: Did you mean to mark this function as 'async'? } function awaitUndefined() { await undefined; ~~~~~ -!!! error TS1308: 'await' expression is only allowed within an async function. +!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules. !!! related TS1356 tests/cases/compiler/awaitLiteralValues.ts:21:10: Did you mean to mark this function as 'async'? } \ No newline at end of file diff --git a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).errors.txt b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).errors.txt index 0bd384b85206d..10de2df71c67a 100644 --- a/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).errors.txt +++ b/tests/baselines/reference/topLevelAwait(module=esnext,target=es2015).errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/externalModules/topLevelAwait.ts(2,1): error TS1375: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. +tests/cases/conformance/externalModules/topLevelAwait.ts(2,1): error TS1376: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher. ==== tests/cases/conformance/externalModules/topLevelAwait.ts (1 errors) ==== export const x = 1; await x; ~~~~~ -!!! error TS1375: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. +!!! error TS1376: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher. \ No newline at end of file diff --git a/tests/baselines/reference/topLevelAwait(module=system,target=es2015).errors.txt b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).errors.txt index 0bd384b85206d..10de2df71c67a 100644 --- a/tests/baselines/reference/topLevelAwait(module=system,target=es2015).errors.txt +++ b/tests/baselines/reference/topLevelAwait(module=system,target=es2015).errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/externalModules/topLevelAwait.ts(2,1): error TS1375: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. +tests/cases/conformance/externalModules/topLevelAwait.ts(2,1): error TS1376: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher. ==== tests/cases/conformance/externalModules/topLevelAwait.ts (1 errors) ==== export const x = 1; await x; ~~~~~ -!!! error TS1375: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. +!!! error TS1376: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher. \ No newline at end of file diff --git a/tests/baselines/reference/topLevelAwaitNonModule.errors.txt b/tests/baselines/reference/topLevelAwaitNonModule.errors.txt index 888c565e7a9d5..4cfb7239b9224 100644 --- a/tests/baselines/reference/topLevelAwaitNonModule.errors.txt +++ b/tests/baselines/reference/topLevelAwaitNonModule.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts(1,1): error TS1375: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. +tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts(1,1): error TS1375: 'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module. tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts(1,7): error TS2304: Cannot find name 'x'. ==== tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts (2 errors) ==== await x; ~~~~~ -!!! error TS1375: 'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher. +!!! error TS1375: 'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module. ~ !!! error TS2304: Cannot find name 'x'. \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixAwaitShouldNotCrashIfNotInFunction.ts b/tests/cases/fourslash/codeFixAwaitShouldNotCrashIfNotInFunction.ts index 1ce5c771ed40b..38d0d92e673c7 100644 --- a/tests/cases/fourslash/codeFixAwaitShouldNotCrashIfNotInFunction.ts +++ b/tests/cases/fourslash/codeFixAwaitShouldNotCrashIfNotInFunction.ts @@ -2,4 +2,4 @@ ////await a -verify.not.codeFixAvailable(); +verify.not.codeFixAvailable("addMissingAwait"); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyMultilineBody.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyMultilineBody.ts new file mode 100644 index 0000000000000..f0a98ececa89e --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyMultilineBody.ts @@ -0,0 +1,23 @@ +/// + +// @lib: es2017 + +////interface I { +//// x: number; +//// y: number; +////} +////class C implements I { +////} + +verify.codeFix({ + description: "Implement interface 'I'", + newFileContent: +`interface I { + x: number; + y: number; +} +class C implements I { + x: number; + y: number; +}`, +}); diff --git a/tests/cases/fourslash/codeFixEnableJsxFlag_blankCompilerOptionsJsConfig.ts b/tests/cases/fourslash/codeFixEnableJsxFlag_blankCompilerOptionsJsConfig.ts index 9d3c14f45bbbd..6681c2e814652 100644 --- a/tests/cases/fourslash/codeFixEnableJsxFlag_blankCompilerOptionsJsConfig.ts +++ b/tests/cases/fourslash/codeFixEnableJsxFlag_blankCompilerOptionsJsConfig.ts @@ -16,7 +16,7 @@ verify.codeFix({ "/dir/jsconfig.json": `{ "compilerOptions": { - "jsx": "react", + "jsx": "react" } }`, }, diff --git a/tests/cases/fourslash/codeFixEnableJsxFlag_blankCompilerOptionsTsConfig.ts b/tests/cases/fourslash/codeFixEnableJsxFlag_blankCompilerOptionsTsConfig.ts index 7b314feeecd50..0234610090edf 100644 --- a/tests/cases/fourslash/codeFixEnableJsxFlag_blankCompilerOptionsTsConfig.ts +++ b/tests/cases/fourslash/codeFixEnableJsxFlag_blankCompilerOptionsTsConfig.ts @@ -16,7 +16,7 @@ verify.codeFix({ "/dir/tsconfig.json": `{ "compilerOptions": { - "jsx": "react", + "jsx": "react" } }`, }, diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_module_blankCompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_module_blankCompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..deced910eb658 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_module_blankCompilerOptionsInTsConfig.ts @@ -0,0 +1,14 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +//// "compilerOptions": { +//// } +////} + + +// Cannot fix module when default module option is `commonjs`... +verify.not.codeFixAvailable("fixModuleOption"); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_module_compatibleCompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_module_compatibleCompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..dd592d1c3eb24 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_module_compatibleCompilerOptionsInTsConfig.ts @@ -0,0 +1,15 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +//// "compilerOptions": { +//// "target": "es2017", +//// "module": "esnext" +//// } +////} + + +verify.not.codeFixAvailable("fixModuleOption"); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_module_existingCompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_module_existingCompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..7dd5101341ee3 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_module_existingCompilerOptionsInTsConfig.ts @@ -0,0 +1,25 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +//// "compilerOptions": { +//// "module": "es2015" +//// } +////} + + +verify.codeFix({ + description: [ts.Diagnostics.Set_the_module_option_in_your_configuration_file_to_0.message, "esnext"], + index: 0, + newFileContent: { + "/dir/tsconfig.json": +`{ + "compilerOptions": { + "module": "esnext" + } +}` + } +}); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_module_missingCompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_module_missingCompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..8c84776ae47c2 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_module_missingCompilerOptionsInTsConfig.ts @@ -0,0 +1,11 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +////} + +// cannot fix module when default options are applied +verify.not.codeFixAvailable("fixModuleOption"); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_module_noTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_module_noTsConfig.ts new file mode 100644 index 0000000000000..906fda09298ea --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_module_noTsConfig.ts @@ -0,0 +1,8 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; + + +verify.not.codeFixAvailable("fixModuleOption"); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_module_targetES2017CompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_module_targetES2017CompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..3857ab2ddefe9 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_module_targetES2017CompilerOptionsInTsConfig.ts @@ -0,0 +1,28 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +//// "compilerOptions": { +//// "target": "es2017" +//// } +////} + +verify.not.codeFixAvailable("fixTargetOption"); +verify.codeFixAvailable("fixModuleOption"); + +// verify.codeFix({ +// description: [ts.Diagnostics.Set_the_module_option_in_your_configuration_file_to_0.message, "esnext"], +// index: 0, +// newFileContent: { +// "/dir/tsconfig.json": +// `{ +// "compilerOptions": { +// "target": "es2017", +// "module": "esnext", +// } +// }` +// } +// }); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_notAModule.ts b/tests/cases/fourslash/codeFixTopLevelAwait_notAModule.ts new file mode 100644 index 0000000000000..453571cb87592 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_notAModule.ts @@ -0,0 +1,21 @@ +/// +////declare const p: Promise; +////await p; +// @filename: /dir/tsconfig.json +////{ +//// "compilerOptions": { +//// "target": "esnext", +//// "module": "esnext" +//// } +////} + +verify.codeFix({ + description: ts.Diagnostics.Add_export_to_make_this_file_into_a_module.message, + index: 0, + newFileContent: + `declare const p: Promise; +await p; + +export { }; +` +}); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_target_blankCompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_target_blankCompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..1c647bfc12ae1 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_target_blankCompilerOptionsInTsConfig.ts @@ -0,0 +1,25 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +//// "compilerOptions": { +//// } +////} + + +verify.codeFix({ + description: [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0.message, "es2017"], + index: 0, + newFileContent: { + "/dir/tsconfig.json": +`{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs" + } +}` + } +}); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_target_compatibleCompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_target_compatibleCompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..7236dea342c27 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_target_compatibleCompilerOptionsInTsConfig.ts @@ -0,0 +1,15 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +//// "compilerOptions": { +//// "target": "es2017", +//// "module": "esnext" +//// } +////} + + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_target_existingCompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_target_existingCompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..c50aa0d5728dc --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_target_existingCompilerOptionsInTsConfig.ts @@ -0,0 +1,25 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +//// "compilerOptions": { +//// "target": "es2015" +//// } +////} + + +verify.codeFix({ + description: [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0.message, "es2017"], + index: 1, + newFileContent: { + "/dir/tsconfig.json": +`{ + "compilerOptions": { + "target": "es2017" + } +}` + } +}); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_target_missingCompilerOptionsInTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_target_missingCompilerOptionsInTsConfig.ts new file mode 100644 index 0000000000000..65102909524ac --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_target_missingCompilerOptionsInTsConfig.ts @@ -0,0 +1,23 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; +// @filename: /dir/tsconfig.json +////{ +////} + + +verify.codeFix({ + description: [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0.message, "es2017"], + index: 0, + newFileContent: { + "/dir/tsconfig.json": +`{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs" + } +}` + } +}); diff --git a/tests/cases/fourslash/codeFixTopLevelAwait_target_noTsConfig.ts b/tests/cases/fourslash/codeFixTopLevelAwait_target_noTsConfig.ts new file mode 100644 index 0000000000000..0173b6f198236 --- /dev/null +++ b/tests/cases/fourslash/codeFixTopLevelAwait_target_noTsConfig.ts @@ -0,0 +1,8 @@ +/// +// @filename: /dir/a.ts +////declare const p: Promise; +////await p; +////export {}; + + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codefixEnableExperimentalDecorators_blankCompilerOptionsInJsconfig.ts b/tests/cases/fourslash/codefixEnableExperimentalDecorators_blankCompilerOptionsInJsconfig.ts index f8dcbf75e4824..0f52d496b700a 100644 --- a/tests/cases/fourslash/codefixEnableExperimentalDecorators_blankCompilerOptionsInJsconfig.ts +++ b/tests/cases/fourslash/codefixEnableExperimentalDecorators_blankCompilerOptionsInJsconfig.ts @@ -19,7 +19,7 @@ verify.codeFix({ "/dir/jsconfig.json": `{ "compilerOptions": { - "experimentalDecorators": true, + "experimentalDecorators": true } }`, }, diff --git a/tests/cases/fourslash/codefixEnableExperimentalDecorators_blankCompilerOptionsInTsconfig.ts b/tests/cases/fourslash/codefixEnableExperimentalDecorators_blankCompilerOptionsInTsconfig.ts index 0e19b42d92133..48bc32e58213c 100644 --- a/tests/cases/fourslash/codefixEnableExperimentalDecorators_blankCompilerOptionsInTsconfig.ts +++ b/tests/cases/fourslash/codefixEnableExperimentalDecorators_blankCompilerOptionsInTsconfig.ts @@ -19,7 +19,7 @@ verify.codeFix({ "/dir/tsconfig.json": `{ "compilerOptions": { - "experimentalDecorators": true, + "experimentalDecorators": true } }`, }, diff --git a/tests/cases/fourslash/codefixEnableExperimentalDecorators_missingCompilerOptionsInJsconfig.ts b/tests/cases/fourslash/codefixEnableExperimentalDecorators_missingCompilerOptionsInJsconfig.ts index 644fce3a35f56..d3370433b6a6a 100644 --- a/tests/cases/fourslash/codefixEnableExperimentalDecorators_missingCompilerOptionsInJsconfig.ts +++ b/tests/cases/fourslash/codefixEnableExperimentalDecorators_missingCompilerOptionsInJsconfig.ts @@ -16,7 +16,9 @@ verify.codeFix({ newFileContent: { "/dir/jsconfig.json": `{ - "compilerOptions": { "experimentalDecorators": true }, + "compilerOptions": { + "experimentalDecorators": true + } }`, }, }); diff --git a/tests/cases/fourslash/codefixEnableExperimentalDecorators_missingCompilerOptionsInTsconfig.ts b/tests/cases/fourslash/codefixEnableExperimentalDecorators_missingCompilerOptionsInTsconfig.ts index 6d7006f3ce1ac..de51cafee224e 100644 --- a/tests/cases/fourslash/codefixEnableExperimentalDecorators_missingCompilerOptionsInTsconfig.ts +++ b/tests/cases/fourslash/codefixEnableExperimentalDecorators_missingCompilerOptionsInTsconfig.ts @@ -16,7 +16,9 @@ verify.codeFix({ newFileContent: { "/dir/tsconfig.json": `{ - "compilerOptions": { "experimentalDecorators": true }, + "compilerOptions": { + "experimentalDecorators": true + } }`, }, }); diff --git a/tests/cases/fourslash/codefixEnableJsxFlag_missingCompilerOptionsInJsconfig.ts b/tests/cases/fourslash/codefixEnableJsxFlag_missingCompilerOptionsInJsconfig.ts index 89769c49d0b9b..4a041b67a1f38 100644 --- a/tests/cases/fourslash/codefixEnableJsxFlag_missingCompilerOptionsInJsconfig.ts +++ b/tests/cases/fourslash/codefixEnableJsxFlag_missingCompilerOptionsInJsconfig.ts @@ -13,7 +13,9 @@ verify.codeFix({ newFileContent: { "/dir/jsconfig.json": `{ - "compilerOptions": { "jsx": "react" }, + "compilerOptions": { + "jsx": "react" + } }`, }, }); diff --git a/tests/cases/fourslash/codefixEnableJsxFlag_missingCompilerOptionsInTsconfig.ts b/tests/cases/fourslash/codefixEnableJsxFlag_missingCompilerOptionsInTsconfig.ts index dc81c7970af27..f41bd8bc210de 100644 --- a/tests/cases/fourslash/codefixEnableJsxFlag_missingCompilerOptionsInTsconfig.ts +++ b/tests/cases/fourslash/codefixEnableJsxFlag_missingCompilerOptionsInTsconfig.ts @@ -13,7 +13,9 @@ verify.codeFix({ newFileContent: { "/dir/tsconfig.json": `{ - "compilerOptions": { "jsx": "react" }, + "compilerOptions": { + "jsx": "react" + } }`, }, }); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index baeff000912b8..692e47a1421da 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -226,7 +226,7 @@ declare namespace FourSlashInterface { jsxClosingTag(map: { [markerName: string]: { readonly newText: string } | undefined }): void; isInCommentAtPosition(onlyMultiLineDiverges?: boolean): void; codeFix(options: { - description: string | DiagnosticIgnoredInterpolations, + description: string | [string, ...(string | number)[]] | DiagnosticIgnoredInterpolations, newFileContent?: NewFileContent, newRangeContent?: string, errorCode?: number, From 0dd4c9cebe14a5b8284e39a836a1377ac1c42339 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Sat, 18 Jan 2020 23:28:19 +0200 Subject: [PATCH 19/28] feat(36231): Improve message for "Remove declaration for: ..." (#36283) --- src/compiler/diagnosticMessages.json | 2 +- src/services/codefixes/fixUnusedIdentifier.ts | 2 +- tests/cases/fourslash/codeFixClassPropertyInitialization.ts | 2 +- tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts | 2 +- .../fourslash/codeFixUnusedIdentifier_delete_templateTag.ts | 4 ++-- .../fourslash/codeFixUnusedIdentifier_parameter_modifier.ts | 2 +- .../codeFixUnusedIdentifier_parameter_modifier_and_arg.ts | 2 +- tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts | 4 ++-- tests/cases/fourslash/unusedMethodInClass1.ts | 2 +- tests/cases/fourslash/unusedMethodInClass2.ts | 2 +- tests/cases/fourslash/unusedMethodInClass3.ts | 2 +- tests/cases/fourslash/unusedMethodInClass4.ts | 2 +- tests/cases/fourslash/unusedMethodInClass5.ts | 2 +- tests/cases/fourslash/unusedMethodInClass6.ts | 2 +- tests/cases/fourslash/unusedNamespaceInNamespace.ts | 2 +- tests/cases/fourslash/unusedParameterInFunction1.ts | 2 +- tests/cases/fourslash/unusedParameterInFunction2.ts | 2 +- tests/cases/fourslash/unusedParameterInLambda1.ts | 2 +- tests/cases/fourslash/unusedParameterInLambda2.ts | 2 +- tests/cases/fourslash/unusedParameterInLambda3.ts | 2 +- tests/cases/fourslash/unusedTypeAliasInNamespace1.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInClass2.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInClass3.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInFunction2.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInFunction3.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInLambda2.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInLambda3.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInLambda4.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInMethod2.ts | 2 +- tests/cases/fourslash/unusedTypeParametersInMethods1.ts | 2 +- tests/cases/fourslash/unusedVariableInBlocks.ts | 2 +- tests/cases/fourslash/unusedVariableInClass1.ts | 2 +- tests/cases/fourslash/unusedVariableInClass2.ts | 2 +- tests/cases/fourslash/unusedVariableInClass3.ts | 2 +- tests/cases/fourslash/unusedVariableInForLoop1FS.ts | 2 +- tests/cases/fourslash/unusedVariableInForLoop2FS.ts | 2 +- tests/cases/fourslash/unusedVariableInForLoop3FS.ts | 2 +- tests/cases/fourslash/unusedVariableInForLoop4FS.ts | 2 +- tests/cases/fourslash/unusedVariableInForLoop6FS.ts | 2 +- tests/cases/fourslash/unusedVariableInForLoop7FS.ts | 2 +- tests/cases/fourslash/unusedVariableInModule1.ts | 2 +- tests/cases/fourslash/unusedVariableInModule2.ts | 2 +- tests/cases/fourslash/unusedVariableInModule3.ts | 2 +- tests/cases/fourslash/unusedVariableInModule4.ts | 2 +- tests/cases/fourslash/unusedVariableInNamespace1.ts | 2 +- tests/cases/fourslash/unusedVariableInNamespace2.ts | 2 +- tests/cases/fourslash/unusedVariableInNamespace3.ts | 2 +- 47 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 78e1a6d6a9545..f9577606a1acd 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4928,7 +4928,7 @@ "category": "Message", "code": 90003 }, - "Remove declaration for: '{0}'": { + "Remove unused declaration for: '{0}'": { "category": "Message", "code": 90004 }, diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index 316142df0b6c2..313597bed809d 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -56,7 +56,7 @@ namespace ts.codefix { tryDeleteDeclaration(sourceFile, token, t, checker, sourceFiles, /*isFixAll*/ false)); if (deletion.length) { const name = isComputedPropertyName(token.parent) ? token.parent : token; - result.push(createDeleteFix(deletion, [Diagnostics.Remove_declaration_for_Colon_0, name.getText(sourceFile)])); + result.push(createDeleteFix(deletion, [Diagnostics.Remove_unused_declaration_for_Colon_0, name.getText(sourceFile)])); } } diff --git a/tests/cases/fourslash/codeFixClassPropertyInitialization.ts b/tests/cases/fourslash/codeFixClassPropertyInitialization.ts index fd1317ccaeb10..59f2b1b2c54a0 100644 --- a/tests/cases/fourslash/codeFixClassPropertyInitialization.ts +++ b/tests/cases/fourslash/codeFixClassPropertyInitialization.ts @@ -56,5 +56,5 @@ verify.codeFixAvailable([ ...fixes("j", "A", { noInitializer: true }), ...fixes("k", "AT"), ...fixes("l", "Foo"), - { description: "Remove declaration for: 'c'" }, + { description: "Remove unused declaration for: 'c'" }, ]); diff --git a/tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts b/tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts index 7952f45ab5f5a..609015d3df1c7 100644 --- a/tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts +++ b/tests/cases/fourslash/codeFixSpellingPrivatePropertyName.ts @@ -11,7 +11,7 @@ verify.codeFixAvailable([ { description: "Change spelling to '#foo'" }, { description: "Declare property 'foo'" }, { description: "Add index signature for property 'foo'" }, - { description: "Remove declaration for: '#foo'" }, + { description: "Remove unused declaration for: '#foo'" }, ]); verify.codeFix({ diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_delete_templateTag.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_delete_templateTag.ts index c8647be8124df..01ab6985d8374 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_delete_templateTag.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_delete_templateTag.ts @@ -13,7 +13,7 @@ goTo.file("/first.js"); verify.codeFix({ index: 0, - description: "Remove declaration for: 'T'", + description: "Remove unused declaration for: 'T'", newFileContent: `/** * Doc @@ -33,7 +33,7 @@ function first(p) { return p; }`, goTo.file("/second.js"); verify.codeFix({ - description: "Remove declaration for: 'U'", + description: "Remove unused declaration for: 'U'", index: 0, newFileContent: `/** diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_modifier.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_modifier.ts index 5f544df5c2efa..bcb792efbf1d4 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_modifier.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_modifier.ts @@ -11,7 +11,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'arg'", + description: "Remove unused declaration for: 'arg'", newFileContent: `export class Example { prop: any; diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_modifier_and_arg.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_modifier_and_arg.ts index 0f33db06dfa61..f95ecec60f2d2 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_modifier_and_arg.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter_modifier_and_arg.ts @@ -9,7 +9,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'arg'", + description: "Remove unused declaration for: 'arg'", newFileContent: `export class Example { constructor() { diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts index 9f9eb992adeb0..19e06e0616593 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts @@ -28,7 +28,7 @@ verify.getSuggestionDiagnostics([ verify.codeFixAvailable( [ "Infer parameter types from usage", - "Remove declaration for: 'p'", + "Remove unused declaration for: 'p'", "Prefix 'p' with an underscore", - "Remove declaration for: 'x'" + "Remove unused declaration for: 'x'" ].map(description => ({ description }))); diff --git a/tests/cases/fourslash/unusedMethodInClass1.ts b/tests/cases/fourslash/unusedMethodInClass1.ts index 1f6f955b791d9..f851925741cae 100644 --- a/tests/cases/fourslash/unusedMethodInClass1.ts +++ b/tests/cases/fourslash/unusedMethodInClass1.ts @@ -7,6 +7,6 @@ ////} verify.codeFix({ - description: `Remove declaration for: 'function1'`, + description: `Remove unused declaration for: 'function1'`, newFileContent: "class greeter {\n}", }); diff --git a/tests/cases/fourslash/unusedMethodInClass2.ts b/tests/cases/fourslash/unusedMethodInClass2.ts index 0557bedf20352..d0f24d7d62667 100644 --- a/tests/cases/fourslash/unusedMethodInClass2.ts +++ b/tests/cases/fourslash/unusedMethodInClass2.ts @@ -9,7 +9,7 @@ ////} verify.codeFix({ - description: `Remove declaration for: 'function1'`, + description: `Remove unused declaration for: 'function1'`, newFileContent: `class greeter { public function2() { } diff --git a/tests/cases/fourslash/unusedMethodInClass3.ts b/tests/cases/fourslash/unusedMethodInClass3.ts index b41f092de16cd..5ac07e0cbdcf5 100644 --- a/tests/cases/fourslash/unusedMethodInClass3.ts +++ b/tests/cases/fourslash/unusedMethodInClass3.ts @@ -7,6 +7,6 @@ ////} verify.codeFix({ - description: `Remove declaration for: 'function1'`, + description: `Remove unused declaration for: 'function1'`, newFileContent: "class greeter {\n}", }); diff --git a/tests/cases/fourslash/unusedMethodInClass4.ts b/tests/cases/fourslash/unusedMethodInClass4.ts index 096bede27dd53..5fbca2ce424c3 100644 --- a/tests/cases/fourslash/unusedMethodInClass4.ts +++ b/tests/cases/fourslash/unusedMethodInClass4.ts @@ -9,7 +9,7 @@ ////} verify.codeFix({ - description: `Remove declaration for: 'function1'`, + description: `Remove unused declaration for: 'function1'`, newRangeContent: `public function2(){ } `, diff --git a/tests/cases/fourslash/unusedMethodInClass5.ts b/tests/cases/fourslash/unusedMethodInClass5.ts index 01caff131c3ca..4c62962968574 100644 --- a/tests/cases/fourslash/unusedMethodInClass5.ts +++ b/tests/cases/fourslash/unusedMethodInClass5.ts @@ -6,6 +6,6 @@ ////} verify.codeFix({ - description: `Remove declaration for: '["string"]'`, + description: `Remove unused declaration for: '["string"]'`, newFileContent: "class C {\n}", }); diff --git a/tests/cases/fourslash/unusedMethodInClass6.ts b/tests/cases/fourslash/unusedMethodInClass6.ts index 325bf47fb79b0..26134426af6cf 100644 --- a/tests/cases/fourslash/unusedMethodInClass6.ts +++ b/tests/cases/fourslash/unusedMethodInClass6.ts @@ -6,6 +6,6 @@ ////} verify.codeFix({ - description: `Remove declaration for: '"string"'`, + description: `Remove unused declaration for: '"string"'`, newFileContent: "class C {\n}", }); diff --git a/tests/cases/fourslash/unusedNamespaceInNamespace.ts b/tests/cases/fourslash/unusedNamespaceInNamespace.ts index d5a07c4161a54..d50ed5b8ef456 100644 --- a/tests/cases/fourslash/unusedNamespaceInNamespace.ts +++ b/tests/cases/fourslash/unusedNamespaceInNamespace.ts @@ -7,7 +7,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'B'", + description: "Remove unused declaration for: 'B'", newFileContent: `namespace A { }`, }); diff --git a/tests/cases/fourslash/unusedParameterInFunction1.ts b/tests/cases/fourslash/unusedParameterInFunction1.ts index 7c03598c6903c..1b11a0f2bcc58 100644 --- a/tests/cases/fourslash/unusedParameterInFunction1.ts +++ b/tests/cases/fourslash/unusedParameterInFunction1.ts @@ -5,7 +5,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'x'", + description: "Remove unused declaration for: 'x'", index: 0, newRangeContent: "greeter()", }); diff --git a/tests/cases/fourslash/unusedParameterInFunction2.ts b/tests/cases/fourslash/unusedParameterInFunction2.ts index 2d1fa45088abf..96a710df911f0 100644 --- a/tests/cases/fourslash/unusedParameterInFunction2.ts +++ b/tests/cases/fourslash/unusedParameterInFunction2.ts @@ -6,7 +6,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'y'", + description: "Remove unused declaration for: 'y'", index: 0, newRangeContent: "greeter(x)", }); diff --git a/tests/cases/fourslash/unusedParameterInLambda1.ts b/tests/cases/fourslash/unusedParameterInLambda1.ts index 60b7b3a99909d..38ecc2865f3cc 100644 --- a/tests/cases/fourslash/unusedParameterInLambda1.ts +++ b/tests/cases/fourslash/unusedParameterInLambda1.ts @@ -5,7 +5,7 @@ ////[|/*~a*/(/*~b*/x/*~c*/:/*~d*/number/*~e*/)/*~f*/ => /*~g*/{/*~h*/}/*~i*/|] verify.codeFix({ - description: "Remove declaration for: 'x'", + description: "Remove unused declaration for: 'x'", index: 0, newRangeContent: "/*~a*/(/*~e*/)/*~f*/ => /*~g*/{/*~h*/}/*~i*/", }); diff --git a/tests/cases/fourslash/unusedParameterInLambda2.ts b/tests/cases/fourslash/unusedParameterInLambda2.ts index b7c7da6dc2621..81eff0f863f38 100644 --- a/tests/cases/fourslash/unusedParameterInLambda2.ts +++ b/tests/cases/fourslash/unusedParameterInLambda2.ts @@ -5,7 +5,7 @@ ////[|/*~a*/x/*~b*/ /*~c*/=>/*~d*/ {/*~e*/}/*~f*/|] verify.codeFix({ - description: "Remove declaration for: 'x'", + description: "Remove unused declaration for: 'x'", index: 0, newRangeContent: "/*~a*/()/*~b*/ /*~c*/=>/*~d*/ {/*~e*/}/*~f*/", }); diff --git a/tests/cases/fourslash/unusedParameterInLambda3.ts b/tests/cases/fourslash/unusedParameterInLambda3.ts index f95d142d43606..20742f4bd3778 100644 --- a/tests/cases/fourslash/unusedParameterInLambda3.ts +++ b/tests/cases/fourslash/unusedParameterInLambda3.ts @@ -6,7 +6,7 @@ // In a perfect world, /*~c*/ would probably be retained, rather than /*~e*/. verify.codeFix({ - description: "Remove declaration for: 'y'", + description: "Remove unused declaration for: 'y'", index: 0, newRangeContent: "/*~a*/(/*~b*/x/*~e*/)/*~f*/ => /*~g*/x/*~h*/", }); diff --git a/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts b/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts index 2798deaea678c..f0113d6455533 100644 --- a/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts +++ b/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts @@ -7,7 +7,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'hw'", + description: "Remove unused declaration for: 'hw'", newFileContent: `namespace greeter { export type nw = "No" | "Way"; }`, diff --git a/tests/cases/fourslash/unusedTypeParametersInClass2.ts b/tests/cases/fourslash/unusedTypeParametersInClass2.ts index 75518b5e8253b..9ddd69d19d557 100644 --- a/tests/cases/fourslash/unusedTypeParametersInClass2.ts +++ b/tests/cases/fourslash/unusedTypeParametersInClass2.ts @@ -6,7 +6,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'Y'", + description: "Remove unused declaration for: 'Y'", index: 0, newRangeContent: "class greeter ", }); diff --git a/tests/cases/fourslash/unusedTypeParametersInClass3.ts b/tests/cases/fourslash/unusedTypeParametersInClass3.ts index 822d210f671b5..fa6b5007edb7f 100644 --- a/tests/cases/fourslash/unusedTypeParametersInClass3.ts +++ b/tests/cases/fourslash/unusedTypeParametersInClass3.ts @@ -8,7 +8,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'Y'", + description: "Remove unused declaration for: 'Y'", index: 0, newRangeContent: "class greeter ", }); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction2.ts b/tests/cases/fourslash/unusedTypeParametersInFunction2.ts index 69d7075e61300..85b658f6d7395 100644 --- a/tests/cases/fourslash/unusedTypeParametersInFunction2.ts +++ b/tests/cases/fourslash/unusedTypeParametersInFunction2.ts @@ -4,7 +4,7 @@ //// [|function f1(a: X) {a}|] verify.codeFix({ - description: "Remove declaration for: 'Y'", + description: "Remove unused declaration for: 'Y'", index: 0, newRangeContent: "function f1(a: X) {a}", }); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction3.ts b/tests/cases/fourslash/unusedTypeParametersInFunction3.ts index f1139d34c73a6..5957b4883035e 100644 --- a/tests/cases/fourslash/unusedTypeParametersInFunction3.ts +++ b/tests/cases/fourslash/unusedTypeParametersInFunction3.ts @@ -4,7 +4,7 @@ //// [|function f1(a: X) {a;var b:Z;b}|] verify.codeFix({ - description: "Remove declaration for: 'Y'", + description: "Remove unused declaration for: 'Y'", index: 0, newRangeContent: "function f1(a: X) {a;var b:Z;b}", }); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda2.ts b/tests/cases/fourslash/unusedTypeParametersInLambda2.ts index 6c9330cb06e7c..b2f0c440a69ca 100644 --- a/tests/cases/fourslash/unusedTypeParametersInLambda2.ts +++ b/tests/cases/fourslash/unusedTypeParametersInLambda2.ts @@ -7,7 +7,7 @@ //// } verify.codeFix({ - description: "Remove declaration for: 'U'", + description: "Remove unused declaration for: 'U'", index: 0, newRangeContent: "new (a: T): void;", }); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda3.ts b/tests/cases/fourslash/unusedTypeParametersInLambda3.ts index f9dab919c27d4..764e75294b9bb 100644 --- a/tests/cases/fourslash/unusedTypeParametersInLambda3.ts +++ b/tests/cases/fourslash/unusedTypeParametersInLambda3.ts @@ -8,7 +8,7 @@ //// } verify.codeFix({ - description: "Remove declaration for: 'K'", + description: "Remove unused declaration for: 'K'", index: 0, newRangeContent: "new (a: T): A;", }); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda4.ts b/tests/cases/fourslash/unusedTypeParametersInLambda4.ts index 3e7e3288ee449..14bdb64549b51 100644 --- a/tests/cases/fourslash/unusedTypeParametersInLambda4.ts +++ b/tests/cases/fourslash/unusedTypeParametersInLambda4.ts @@ -8,6 +8,6 @@ verify.codeFix({ index: 0, - description: "Remove declaration for: 'U'", + description: "Remove unused declaration for: 'U'", newRangeContent: "var y: new (a:T)=>void;", }); diff --git a/tests/cases/fourslash/unusedTypeParametersInMethod2.ts b/tests/cases/fourslash/unusedTypeParametersInMethod2.ts index c36a7a4f19d8c..4cb6aa8cdb886 100644 --- a/tests/cases/fourslash/unusedTypeParametersInMethod2.ts +++ b/tests/cases/fourslash/unusedTypeParametersInMethod2.ts @@ -7,6 +7,6 @@ verify.codeFix({ index: 0, - description: "Remove declaration for: 'T'", + description: "Remove unused declaration for: 'T'", newRangeContent: "f1(a: U)", }); diff --git a/tests/cases/fourslash/unusedTypeParametersInMethods1.ts b/tests/cases/fourslash/unusedTypeParametersInMethods1.ts index 0ee457f244856..813e2af749412 100644 --- a/tests/cases/fourslash/unusedTypeParametersInMethods1.ts +++ b/tests/cases/fourslash/unusedTypeParametersInMethods1.ts @@ -7,6 +7,6 @@ verify.codeFix({ index: 0, - description: "Remove declaration for: 'Y'", + description: "Remove unused declaration for: 'Y'", newRangeContent: "public f1(a: X)", }); diff --git a/tests/cases/fourslash/unusedVariableInBlocks.ts b/tests/cases/fourslash/unusedVariableInBlocks.ts index 4dac7ae1d9443..fa401f6d0a157 100644 --- a/tests/cases/fourslash/unusedVariableInBlocks.ts +++ b/tests/cases/fourslash/unusedVariableInBlocks.ts @@ -10,7 +10,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'x'", + description: "Remove unused declaration for: 'x'", newRangeContent: `let x = 10; { } diff --git a/tests/cases/fourslash/unusedVariableInClass1.ts b/tests/cases/fourslash/unusedVariableInClass1.ts index d1c3b5c64374c..9e7235841c938 100644 --- a/tests/cases/fourslash/unusedVariableInClass1.ts +++ b/tests/cases/fourslash/unusedVariableInClass1.ts @@ -6,6 +6,6 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'greeting'", + description: "Remove unused declaration for: 'greeting'", newRangeContent: "", }); diff --git a/tests/cases/fourslash/unusedVariableInClass2.ts b/tests/cases/fourslash/unusedVariableInClass2.ts index 1fde857253a83..a4302b4dd535a 100644 --- a/tests/cases/fourslash/unusedVariableInClass2.ts +++ b/tests/cases/fourslash/unusedVariableInClass2.ts @@ -7,7 +7,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'greeting'", + description: "Remove unused declaration for: 'greeting'", index: 0, newRangeContent: "public greeting1;\n", }); diff --git a/tests/cases/fourslash/unusedVariableInClass3.ts b/tests/cases/fourslash/unusedVariableInClass3.ts index bc3527e03aebb..ab9758a7dbcb0 100644 --- a/tests/cases/fourslash/unusedVariableInClass3.ts +++ b/tests/cases/fourslash/unusedVariableInClass3.ts @@ -6,6 +6,6 @@ ////|]} verify.codeFix({ - description: "Remove declaration for: 'X'", + description: "Remove unused declaration for: 'X'", newRangeContent: "\n", }); diff --git a/tests/cases/fourslash/unusedVariableInForLoop1FS.ts b/tests/cases/fourslash/unusedVariableInForLoop1FS.ts index 32c83871da3cd..797d1ca90c7a5 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop1FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop1FS.ts @@ -8,6 +8,6 @@ //// } verify.codeFix({ - description: "Remove declaration for: 'i'", + description: "Remove unused declaration for: 'i'", newRangeContent: "for(; ;) ", }); diff --git a/tests/cases/fourslash/unusedVariableInForLoop2FS.ts b/tests/cases/fourslash/unusedVariableInForLoop2FS.ts index 332f7f7c28a81..c57086cd9813d 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop2FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop2FS.ts @@ -8,6 +8,6 @@ //// } verify.codeFix({ - description: "Remove declaration for: 'j'", + description: "Remove unused declaration for: 'j'", newRangeContent: "for(var i = 0; ;i++)", }); diff --git a/tests/cases/fourslash/unusedVariableInForLoop3FS.ts b/tests/cases/fourslash/unusedVariableInForLoop3FS.ts index de8fa6dd2f005..a596a2b432ea8 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop3FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop3FS.ts @@ -8,6 +8,6 @@ //// } verify.codeFix({ - description: "Remove declaration for: 'j'", + description: "Remove unused declaration for: 'j'", newRangeContent: "for(var i = 0, k=0; ;i++, k++)", }); diff --git a/tests/cases/fourslash/unusedVariableInForLoop4FS.ts b/tests/cases/fourslash/unusedVariableInForLoop4FS.ts index 2203abbe1bb9c..248d729cc9795 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop4FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop4FS.ts @@ -8,6 +8,6 @@ //// } verify.codeFix({ - description: "Remove declaration for: 'i'", + description: "Remove unused declaration for: 'i'", newRangeContent: "for(var j= 0, k=0; ;j++, k++) ", }); diff --git a/tests/cases/fourslash/unusedVariableInForLoop6FS.ts b/tests/cases/fourslash/unusedVariableInForLoop6FS.ts index d2fa0e0757a9b..9ee75ef576f95 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop6FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop6FS.ts @@ -8,7 +8,7 @@ //// } verify.codeFix({ - description: "Remove declaration for: 'elem'", + description: "Remove unused declaration for: 'elem'", index: 0, newRangeContent: "const {} of", }); diff --git a/tests/cases/fourslash/unusedVariableInForLoop7FS.ts b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts index aab6376580a2e..f85c61308e2ec 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop7FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts @@ -10,7 +10,7 @@ //// verify.codeFix({ - description: "Remove declaration for: 'x'", + description: "Remove unused declaration for: 'x'", newRangeContent: `{ for (const elem of ["a", "b", "c"]) { elem; diff --git a/tests/cases/fourslash/unusedVariableInModule1.ts b/tests/cases/fourslash/unusedVariableInModule1.ts index a0b5ebb80c00f..85f2675316c64 100644 --- a/tests/cases/fourslash/unusedVariableInModule1.ts +++ b/tests/cases/fourslash/unusedVariableInModule1.ts @@ -7,6 +7,6 @@ //// export var y: string;|] verify.codeFix({ - description: "Remove declaration for: 'x'", + description: "Remove unused declaration for: 'x'", newRangeContent: "export var y: string;", }); diff --git a/tests/cases/fourslash/unusedVariableInModule2.ts b/tests/cases/fourslash/unusedVariableInModule2.ts index 20a901c5b6c4f..d88338abf8110 100644 --- a/tests/cases/fourslash/unusedVariableInModule2.ts +++ b/tests/cases/fourslash/unusedVariableInModule2.ts @@ -8,6 +8,6 @@ //// export var y: string; verify.codeFix({ - description: "Remove declaration for: 'x'", + description: "Remove unused declaration for: 'x'", newRangeContent: "var z: number;", }); diff --git a/tests/cases/fourslash/unusedVariableInModule3.ts b/tests/cases/fourslash/unusedVariableInModule3.ts index 6a7681c3927c9..e45b58552111c 100644 --- a/tests/cases/fourslash/unusedVariableInModule3.ts +++ b/tests/cases/fourslash/unusedVariableInModule3.ts @@ -7,6 +7,6 @@ //// export var y: string;|] verify.codeFix({ - description: "Remove declaration for: 'x'", + description: "Remove unused declaration for: 'x'", newRangeContent: "export var y: string;", }); diff --git a/tests/cases/fourslash/unusedVariableInModule4.ts b/tests/cases/fourslash/unusedVariableInModule4.ts index 4f8657b30a793..f2e9efb7ec7b2 100644 --- a/tests/cases/fourslash/unusedVariableInModule4.ts +++ b/tests/cases/fourslash/unusedVariableInModule4.ts @@ -8,7 +8,7 @@ //// export var y: string; verify.codeFix({ - description: "Remove declaration for: 'm'", + description: "Remove unused declaration for: 'm'", index: 0, newRangeContent: `var x = function f1() {}`, }); diff --git a/tests/cases/fourslash/unusedVariableInNamespace1.ts b/tests/cases/fourslash/unusedVariableInNamespace1.ts index 33c1c25170ead..e9f2fad077429 100644 --- a/tests/cases/fourslash/unusedVariableInNamespace1.ts +++ b/tests/cases/fourslash/unusedVariableInNamespace1.ts @@ -6,6 +6,6 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'a'", + description: "Remove unused declaration for: 'a'", newRangeContent: "", }); diff --git a/tests/cases/fourslash/unusedVariableInNamespace2.ts b/tests/cases/fourslash/unusedVariableInNamespace2.ts index 6123555fc8a85..6430aca9cda43 100644 --- a/tests/cases/fourslash/unusedVariableInNamespace2.ts +++ b/tests/cases/fourslash/unusedVariableInNamespace2.ts @@ -9,7 +9,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'b'", + description: "Remove unused declaration for: 'b'", index: 0, newRangeContent: 'let a = "dummy entry", c = 0;', }); diff --git a/tests/cases/fourslash/unusedVariableInNamespace3.ts b/tests/cases/fourslash/unusedVariableInNamespace3.ts index 3503bae4e6a34..e79a65cb589da 100644 --- a/tests/cases/fourslash/unusedVariableInNamespace3.ts +++ b/tests/cases/fourslash/unusedVariableInNamespace3.ts @@ -9,7 +9,7 @@ ////} verify.codeFix({ - description: "Remove declaration for: 'c'", + description: "Remove unused declaration for: 'c'", index: 0, newRangeContent: 'let a = "dummy entry", b;', }); From d2c5d54242c69effbed0ebb27033047e0c995589 Mon Sep 17 00:00:00 2001 From: Wenlu Wang Date: Sun, 19 Jan 2020 06:00:53 +0800 Subject: [PATCH 20/28] remove duplicate message (#36125) --- src/compiler/diagnosticMessages.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f9577606a1acd..eccec62f1bd4c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5445,10 +5445,6 @@ "category": "Error", "code": 18007 }, - "'#!' can only be used at the start of a file.": { - "category": "Error", - "code": 18008 - }, "Private identifiers cannot be used as parameters": { "category": "Error", "code": 18009 From f588c78aabb8d8f80b86001bbd2f38f8bee39855 Mon Sep 17 00:00:00 2001 From: Orta Date: Tue, 21 Jan 2020 11:54:48 -0500 Subject: [PATCH 21/28] Remove the compiler diag 1360 after it got missed in #35751 (#36332) --- src/compiler/diagnosticMessages.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index eccec62f1bd4c..d4cd0df8c60bc 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1055,10 +1055,6 @@ "category": "Error", "code": 1359 }, - "Did you mean to parenthesize this function type?": { - "category": "Error", - "code": 1360 - }, "Type-only {0} must reference a type, but '{1}' is a value.": { "category": "Error", "code": 1361 From 4445e1147ce5f07ff74fb893fe2b4764e3b48780 Mon Sep 17 00:00:00 2001 From: Yacine Hmito Date: Tue, 21 Jan 2020 20:26:17 +0100 Subject: [PATCH 22/28] Fix isProgramUpToDate when changing rootFileNames (#36011) --- src/compiler/program.ts | 6 +- .../unittests/reuseProgramStructure.ts | 328 +++++++++++------- 2 files changed, 207 insertions(+), 127 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index fc6b855225082..760e6415cad78 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -571,14 +571,14 @@ namespace ts { return false; } - // If number of files in the program do not match, it is not up-to-date - if (program.getRootFileNames().length !== rootFileNames.length) { + // If root file names don't match + if (!arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) { return false; } let seenResolvedRefs: ResolvedProjectReference[] | undefined; - // If project references dont match + // If project references don't match if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) { return false; } diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index 0f468d76b0129..bcc8a12adf6fb 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -905,20 +905,19 @@ namespace ts { import createTestSystem = TestFSWithWatch.createWatchedSystem; import libFile = TestFSWithWatch.libFile; - describe("unittests:: Reuse program structure:: isProgramUptoDate should return true when there is no change in compiler options and", () => { - function verifyProgramIsUptoDate( + describe("unittests:: Reuse program structure:: isProgramUptoDate", () => { + function getWhetherProgramIsUptoDate( program: Program, newRootFileNames: string[], newOptions: CompilerOptions ) { - const actual = isProgramUptoDate( + return isProgramUptoDate( program, newRootFileNames, newOptions, path => program.getSourceFileByPath(path)!.version, /*fileExists*/ returnFalse, /*hasInvalidatedResolution*/ returnFalse, /*hasChangedAutomaticTypeDirectiveNames*/ false, /*projectReferences*/ undefined ); - assert.isTrue(actual); } function duplicate(options: CompilerOptions): CompilerOptions; @@ -927,134 +926,215 @@ namespace ts { return JSON.parse(JSON.stringify(filesOrOptions)); } - function verifyProgramWithoutConfigFile(system: System, rootFiles: string[], options: CompilerOptions) { - const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, /*watchOptions*/ undefined, system)).getCurrentProgram().getProgram(); - verifyProgramIsUptoDate(program, duplicate(rootFiles), duplicate(options)); - } + describe("should return true when there is no change in compiler options and", () => { + function verifyProgramIsUptoDate( + program: Program, + newRootFileNames: string[], + newOptions: CompilerOptions + ) { + const actual = getWhetherProgramIsUptoDate(program, newRootFileNames, newOptions); + assert.isTrue(actual); + } - function verifyProgramWithConfigFile(system: System, configFileName: string) { - const program = createWatchProgram(createWatchCompilerHostOfConfigFile(configFileName, {}, /*watchOptionsToExtend*/ undefined, system)).getCurrentProgram().getProgram(); - const { fileNames, options } = parseConfigFileWithSystem(configFileName, {}, /*watchOptionsToExtend*/ undefined, system, notImplemented)!; // TODO: GH#18217 - verifyProgramIsUptoDate(program, fileNames, options); - } + function verifyProgramWithoutConfigFile(system: System, rootFiles: string[], options: CompilerOptions) { + const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, /*watchOptions*/ undefined, system)).getCurrentProgram().getProgram(); + verifyProgramIsUptoDate(program, duplicate(rootFiles), duplicate(options)); + } - function verifyProgram(files: File[], rootFiles: string[], options: CompilerOptions, configFile: string) { - const system = createTestSystem(files); - verifyProgramWithoutConfigFile(system, rootFiles, options); - verifyProgramWithConfigFile(system, configFile); - } + function verifyProgramWithConfigFile(system: System, configFileName: string) { + const program = createWatchProgram(createWatchCompilerHostOfConfigFile(configFileName, {}, /*watchOptionsToExtend*/ undefined, system)).getCurrentProgram().getProgram(); + const { fileNames, options } = parseConfigFileWithSystem(configFileName, {}, /*watchOptionsToExtend*/ undefined, system, notImplemented)!; // TODO: GH#18217 + verifyProgramIsUptoDate(program, fileNames, options); + } - it("has empty options", () => { - const file1: File = { - path: "/a/b/file1.ts", - content: "let x = 1" - }; - const file2: File = { - path: "/a/b/file2.ts", - content: "let y = 1" - }; - const configFile: File = { - path: "/a/b/tsconfig.json", - content: "{}" - }; - verifyProgram([file1, file2, libFile, configFile], [file1.path, file2.path], {}, configFile.path); - }); + function verifyProgram(files: File[], rootFiles: string[], options: CompilerOptions, configFile: string) { + const system = createTestSystem(files); + verifyProgramWithoutConfigFile(system, rootFiles, options); + verifyProgramWithConfigFile(system, configFile); + } - it("has lib specified in the options", () => { - const compilerOptions: CompilerOptions = { lib: ["es5", "es2015.promise"] }; - const app: File = { - path: "/src/app.ts", - content: "var x: Promise;" - }; - const configFile: File = { - path: "/src/tsconfig.json", - content: JSON.stringify({ compilerOptions }) - }; - const es5Lib: File = { - path: "/compiler/lib.es5.d.ts", - content: "declare const eval: any" - }; - const es2015Promise: File = { - path: "/compiler/lib.es2015.promise.d.ts", - content: "declare class Promise {}" - }; + it("has empty options", () => { + const file1: File = { + path: "/a/b/file1.ts", + content: "let x = 1" + }; + const file2: File = { + path: "/a/b/file2.ts", + content: "let y = 1" + }; + const configFile: File = { + path: "/a/b/tsconfig.json", + content: "{}" + }; + verifyProgram([file1, file2, libFile, configFile], [file1.path, file2.path], {}, configFile.path); + }); - verifyProgram([app, configFile, es5Lib, es2015Promise], [app.path], compilerOptions, configFile.path); - }); + it("has lib specified in the options", () => { + const compilerOptions: CompilerOptions = { lib: ["es5", "es2015.promise"] }; + const app: File = { + path: "/src/app.ts", + content: "var x: Promise;" + }; + const configFile: File = { + path: "/src/tsconfig.json", + content: JSON.stringify({ compilerOptions }) + }; + const es5Lib: File = { + path: "/compiler/lib.es5.d.ts", + content: "declare const eval: any" + }; + const es2015Promise: File = { + path: "/compiler/lib.es2015.promise.d.ts", + content: "declare class Promise {}" + }; + + verifyProgram([app, configFile, es5Lib, es2015Promise], [app.path], compilerOptions, configFile.path); + }); - it("has paths specified in the options", () => { - const compilerOptions: CompilerOptions = { - baseUrl: ".", - paths: { - "*": [ - "packages/mail/data/*", - "packages/styles/*", - "*" - ] - } - }; - const app: File = { - path: "/src/packages/framework/app.ts", - content: 'import classc from "module1/lib/file1";\ - import classD from "module3/file3";\ - let x = new classc();\ - let y = new classD();' - }; - const module1: File = { - path: "/src/packages/mail/data/module1/lib/file1.ts", - content: 'import classc from "module2/file2";export default classc;', - }; - const module2: File = { - path: "/src/packages/mail/data/module1/lib/module2/file2.ts", - content: 'class classc { method2() { return "hello"; } }\nexport default classc', - }; - const module3: File = { - path: "/src/packages/styles/module3/file3.ts", - content: "class classD { method() { return 10; } }\nexport default classD;" - }; - const configFile: File = { - path: "/src/tsconfig.json", - content: JSON.stringify({ compilerOptions }) - }; + it("has paths specified in the options", () => { + const compilerOptions: CompilerOptions = { + baseUrl: ".", + paths: { + "*": [ + "packages/mail/data/*", + "packages/styles/*", + "*" + ] + } + }; + const app: File = { + path: "/src/packages/framework/app.ts", + content: 'import classc from "module1/lib/file1";\ + import classD from "module3/file3";\ + let x = new classc();\ + let y = new classD();' + }; + const module1: File = { + path: "/src/packages/mail/data/module1/lib/file1.ts", + content: 'import classc from "module2/file2";export default classc;', + }; + const module2: File = { + path: "/src/packages/mail/data/module1/lib/module2/file2.ts", + content: 'class classc { method2() { return "hello"; } }\nexport default classc', + }; + const module3: File = { + path: "/src/packages/styles/module3/file3.ts", + content: "class classD { method() { return 10; } }\nexport default classD;" + }; + const configFile: File = { + path: "/src/tsconfig.json", + content: JSON.stringify({ compilerOptions }) + }; + + verifyProgram([app, module1, module2, module3, libFile, configFile], [app.path], compilerOptions, configFile.path); + }); - verifyProgram([app, module1, module2, module3, libFile, configFile], [app.path], compilerOptions, configFile.path); - }); + it("has include paths specified in tsconfig file", () => { + const compilerOptions: CompilerOptions = { + baseUrl: ".", + paths: { + "*": [ + "packages/mail/data/*", + "packages/styles/*", + "*" + ] + } + }; + const app: File = { + path: "/src/packages/framework/app.ts", + content: 'import classc from "module1/lib/file1";\ + import classD from "module3/file3";\ + let x = new classc();\ + let y = new classD();' + }; + const module1: File = { + path: "/src/packages/mail/data/module1/lib/file1.ts", + content: 'import classc from "module2/file2";export default classc;', + }; + const module2: File = { + path: "/src/packages/mail/data/module1/lib/module2/file2.ts", + content: 'class classc { method2() { return "hello"; } }\nexport default classc', + }; + const module3: File = { + path: "/src/packages/styles/module3/file3.ts", + content: "class classD { method() { return 10; } }\nexport default classD;" + }; + const configFile: File = { + path: "/src/tsconfig.json", + content: JSON.stringify({ compilerOptions, include: ["packages/**/*.ts"] }) + }; + verifyProgramWithConfigFile(createTestSystem([app, module1, module2, module3, libFile, configFile]), configFile.path); + }); + it("has the same root file names", () => { + const module1: File = { + path: "/src/packages/mail/data/module1/lib/file1.ts", + content: 'import classc from "module2/file2";export default classc;', + }; + const module2: File = { + path: "/src/packages/mail/data/module1/lib/module2/file2.ts", + content: 'class classc { method2() { return "hello"; } }\nexport default classc', + }; + const module3: File = { + path: "/src/packages/styles/module3/file3.ts", + content: "class classD { method() { return 10; } }\nexport default classD;" + }; + const rootFiles = [module1.path, module2.path, module3.path]; + const system = createTestSystem([module1, module2, module3]); + const options = {}; + const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, /*watchOptions*/ undefined, system)).getCurrentProgram().getProgram(); + verifyProgramIsUptoDate(program, duplicate(rootFiles), duplicate(options)); + }); - it("has include paths specified in tsconfig file", () => { - const compilerOptions: CompilerOptions = { - baseUrl: ".", - paths: { - "*": [ - "packages/mail/data/*", - "packages/styles/*", - "*" - ] - } - }; - const app: File = { - path: "/src/packages/framework/app.ts", - content: 'import classc from "module1/lib/file1";\ - import classD from "module3/file3";\ - let x = new classc();\ - let y = new classD();' - }; - const module1: File = { - path: "/src/packages/mail/data/module1/lib/file1.ts", - content: 'import classc from "module2/file2";export default classc;', - }; - const module2: File = { - path: "/src/packages/mail/data/module1/lib/module2/file2.ts", - content: 'class classc { method2() { return "hello"; } }\nexport default classc', - }; - const module3: File = { - path: "/src/packages/styles/module3/file3.ts", - content: "class classD { method() { return 10; } }\nexport default classD;" - }; - const configFile: File = { - path: "/src/tsconfig.json", - content: JSON.stringify({ compilerOptions, include: ["packages/**/*.ts"] }) - }; - verifyProgramWithConfigFile(createTestSystem([app, module1, module2, module3, libFile, configFile]), configFile.path); + }); + describe("should return false when there is no change in compiler options but", () => { + function verifyProgramIsNotUptoDate( + program: Program, + newRootFileNames: string[], + newOptions: CompilerOptions + ) { + const actual = getWhetherProgramIsUptoDate(program, newRootFileNames, newOptions); + assert.isFalse(actual); + } + it("has more root file names", () => { + const module1: File = { + path: "/src/packages/mail/data/module1/lib/file1.ts", + content: 'import classc from "module2/file2";export default classc;', + }; + const module2: File = { + path: "/src/packages/mail/data/module1/lib/module2/file2.ts", + content: 'class classc { method2() { return "hello"; } }\nexport default classc', + }; + const module3: File = { + path: "/src/packages/styles/module3/file3.ts", + content: "class classD { method() { return 10; } }\nexport default classD;" + }; + const rootFiles = [module1.path, module2.path]; + const newRootFiles = [module1.path, module2.path, module3.path]; + const system = createTestSystem([module1, module2, module3]); + const options = {}; + const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, /*watchOptions*/ undefined, system)).getCurrentProgram().getProgram(); + verifyProgramIsNotUptoDate(program, duplicate(newRootFiles), duplicate(options)); + }); + it("has one root file replaced by another", () => { + const module1: File = { + path: "/src/packages/mail/data/module1/lib/file1.ts", + content: 'import classc from "module2/file2";export default classc;', + }; + const module2: File = { + path: "/src/packages/mail/data/module1/lib/module2/file2.ts", + content: 'class classc { method2() { return "hello"; } }\nexport default classc', + }; + const module3: File = { + path: "/src/packages/styles/module3/file3.ts", + content: "class classD { method() { return 10; } }\nexport default classD;" + }; + const rootFiles = [module1.path, module2.path]; + const newRootFiles = [module2.path, module3.path]; + const system = createTestSystem([module1, module2, module3]); + const options = {}; + const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, /*watchOptions*/ undefined, system)).getCurrentProgram().getProgram(); + verifyProgramIsNotUptoDate(program, duplicate(newRootFiles), duplicate(options)); + }); }); }); } From 2dd21a08f5a6f2becc1cabfb704427e583cf358d Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Tue, 21 Jan 2020 20:28:04 +0100 Subject: [PATCH 23/28] useDefineForClassFields affects emit (#36308) * useDefineForClassFields affects emit * fix lint --- src/compiler/commandLineParser.ts | 1 + .../unittests/tscWatch/programUpdates.ts | 25 ++++ ...it-when-useDefineForClassFields-changes.js | 128 ++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 tests/baselines/reference/tscWatch/programUpdates/updates-diagnostics-and-emit-when-useDefineForClassFields-changes.js diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 70bd2c29b7aaa..ba62eb16d39c5 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -968,6 +968,7 @@ namespace ts { name: "useDefineForClassFields", type: "boolean", affectsSemanticDiagnostics: true, + affectsEmit: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Emit_class_fields_with_Define_instead_of_Set, }, diff --git a/src/testRunner/unittests/tscWatch/programUpdates.ts b/src/testRunner/unittests/tscWatch/programUpdates.ts index ede0927aa1967..82d61ae255794 100644 --- a/src/testRunner/unittests/tscWatch/programUpdates.ts +++ b/src/testRunner/unittests/tscWatch/programUpdates.ts @@ -1121,6 +1121,31 @@ foo().hello` ] }); + verifyTscWatch({ + scenario, + subScenario: "updates diagnostics and emit when useDefineForClassFields changes", + commandLineArgs: ["-w"], + sys: () => { + const aFile: File = { + path: `/a.ts`, + content: `class C { get prop() { return 1; } } +class D extends C { prop = 1; }` + }; + const config: File = { + path: `/tsconfig.json`, + content: JSON.stringify({ compilerOptions: { target: "es6" } }) + }; + return createWatchedSystem([aFile, config, libFile]); + }, + changes: [ + sys => { + sys.writeFile(`/tsconfig.json`, JSON.stringify({ compilerOptions: { target: "es6", useDefineForClassFields: true } })); + sys.runQueuedTimeoutCallbacks(); + return "Enable useDefineForClassFields"; + }, + ] + }); + verifyTscWatch({ scenario, subScenario: "updates errors and emit when importsNotUsedAsValues changes", diff --git a/tests/baselines/reference/tscWatch/programUpdates/updates-diagnostics-and-emit-when-useDefineForClassFields-changes.js b/tests/baselines/reference/tscWatch/programUpdates/updates-diagnostics-and-emit-when-useDefineForClassFields-changes.js new file mode 100644 index 0000000000000..f5c4d978b177d --- /dev/null +++ b/tests/baselines/reference/tscWatch/programUpdates/updates-diagnostics-and-emit-when-useDefineForClassFields-changes.js @@ -0,0 +1,128 @@ +/a/lib/tsc.js -w +//// [/a.ts] +class C { get prop() { return 1; } } +class D extends C { prop = 1; } + +//// [/tsconfig.json] +{"compilerOptions":{"target":"es6"}} + +//// [/a/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } + +//// [/a.js] +class C { + get prop() { return 1; } +} +class D extends C { + constructor() { + super(...arguments); + this.prop = 1; + } +} + + + +Output:: +>> Screen clear +12:00:13 AM - Starting compilation in watch mode... + + + +12:00:16 AM - Found 0 errors. Watching for file changes. + + +Program root files: ["/a.ts","/a/lib/lib.d.ts"] +Program options: {"target":2,"watch":true,"configFilePath":"/tsconfig.json"} +Program files:: +/a.ts +/a/lib/lib.d.ts + +Semantic diagnostics in builder refreshed for:: +/a.ts +/a/lib/lib.d.ts + +WatchedFiles:: +/tsconfig.json: + {"pollingInterval":250} +/a.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +Change:: Enable useDefineForClassFields + +//// [/tsconfig.json] +{"compilerOptions":{"target":"es6","useDefineForClassFields":true}} + +//// [/a.js] +class C { + get prop() { return 1; } +} +class D extends C { + constructor() { + super(...arguments); + Object.defineProperty(this, "prop", { + enumerable: true, + configurable: true, + writable: true, + value: 1 + }); + } +} + + + +Output:: +>> Screen clear +12:00:20 AM - File change detected. Starting incremental compilation... + + +a.ts(2,21): error TS2610: 'prop' is defined as an accessor in class 'C', but is overridden here in 'D' as an instance property. + + +12:00:24 AM - Found 1 error. Watching for file changes. + + +Program root files: ["/a.ts","/a/lib/lib.d.ts"] +Program options: {"target":2,"useDefineForClassFields":true,"watch":true,"configFilePath":"/tsconfig.json"} +Program files:: +/a.ts +/a/lib/lib.d.ts + +Semantic diagnostics in builder refreshed for:: +/a.ts +/a/lib/lib.d.ts + +WatchedFiles:: +/tsconfig.json: + {"pollingInterval":250} +/a.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined From bc1e7728df93cfbd70ab2966b37952d5978ba677 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Tue, 21 Jan 2020 20:28:55 +0100 Subject: [PATCH 24/28] experimentalDecorators and emitDecoratorMetadata affect builder state (#36297) * experimentalDecorators and emitDecoratorMetadata affect builder state * better test --- src/compiler/commandLineParser.ts | 3 + .../unittests/tscWatch/programUpdates.ts | 43 ++++ ...tes-diagnostics-and-emit-for-decorators.js | 206 ++++++++++++++++++ 3 files changed, 252 insertions(+) create mode 100644 tests/baselines/reference/tscWatch/programUpdates/updates-diagnostics-and-emit-for-decorators.js diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index ba62eb16d39c5..7440358709eda 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -743,12 +743,15 @@ namespace ts { { name: "experimentalDecorators", type: "boolean", + affectsSemanticDiagnostics: true, category: Diagnostics.Experimental_Options, description: Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", + affectsSemanticDiagnostics: true, + affectsEmit: true, category: Diagnostics.Experimental_Options, description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, diff --git a/src/testRunner/unittests/tscWatch/programUpdates.ts b/src/testRunner/unittests/tscWatch/programUpdates.ts index 82d61ae255794..b1074c7b9a288 100644 --- a/src/testRunner/unittests/tscWatch/programUpdates.ts +++ b/src/testRunner/unittests/tscWatch/programUpdates.ts @@ -243,6 +243,49 @@ namespace ts.tscWatch { ] }); + verifyTscWatch({ + scenario, + subScenario: "updates diagnostics and emit for decorators", + commandLineArgs: ["-w"], + sys: () => { + const aTs: File = { + path: "/a.ts", + content: `import {B} from './b' +@((_) => {}) +export class A { + constructor(p: B) {} +}`, + }; + const bTs: File = { + path: "/b.ts", + content: `export class B {}`, + }; + const tsconfig: File = { + path: "/tsconfig.json", + content: JSON.stringify({ + compilerOptions: { target: "es6", importsNotUsedAsValues: "error" } + }) + }; + return createWatchedSystem([libFile, aTs, bTs, tsconfig]); + }, + changes: [ + sys => { + sys.modifyFile("/tsconfig.json", JSON.stringify({ + compilerOptions: { target: "es6", importsNotUsedAsValues: "error", experimentalDecorators: true } + })); + sys.checkTimeoutQueueLengthAndRun(1); + return "Enable experimentalDecorators"; + }, + sys => { + sys.modifyFile("/tsconfig.json", JSON.stringify({ + compilerOptions: { target: "es6", importsNotUsedAsValues: "error", experimentalDecorators: true, emitDecoratorMetadata: true } + })); + sys.checkTimeoutQueueLengthAndRun(1); + return "Enable emitDecoratorMetadata"; + } + ] + }); + verifyTscWatch({ scenario, subScenario: "files explicitly excluded in config file", diff --git a/tests/baselines/reference/tscWatch/programUpdates/updates-diagnostics-and-emit-for-decorators.js b/tests/baselines/reference/tscWatch/programUpdates/updates-diagnostics-and-emit-for-decorators.js new file mode 100644 index 0000000000000..19025658a70c6 --- /dev/null +++ b/tests/baselines/reference/tscWatch/programUpdates/updates-diagnostics-and-emit-for-decorators.js @@ -0,0 +1,206 @@ +/a/lib/tsc.js -w +//// [/a/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } + +//// [/a.ts] +import {B} from './b' +@((_) => {}) +export class A { + constructor(p: B) {} +} + +//// [/b.ts] +export class B {} + +//// [/tsconfig.json] +{"compilerOptions":{"target":"es6","importsNotUsedAsValues":"error"}} + +//// [/b.js] +export class B { +} + + +//// [/a.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +import './b'; +let A = class A { + constructor(p) { } +}; +A = __decorate([ + ((_) => { }) +], A); +export { A }; + + + +Output:: +>> Screen clear +12:00:15 AM - Starting compilation in watch mode... + + +a.ts(1,1): error TS1371: This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'. + +a.ts(3,14): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning. + + +12:00:20 AM - Found 2 errors. Watching for file changes. + + +Program root files: ["/a.ts","/b.ts","/a/lib/lib.d.ts"] +Program options: {"target":2,"importsNotUsedAsValues":2,"watch":true,"configFilePath":"/tsconfig.json"} +Program files:: +/b.ts +/a.ts +/a/lib/lib.d.ts + +Semantic diagnostics in builder refreshed for:: +/b.ts +/a.ts +/a/lib/lib.d.ts + +WatchedFiles:: +/tsconfig.json: + {"pollingInterval":250} +/a.ts: + {"pollingInterval":250} +/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +Change:: Enable experimentalDecorators + +//// [/tsconfig.json] +{"compilerOptions":{"target":"es6","importsNotUsedAsValues":"error","experimentalDecorators":true}} + + +Output:: +>> Screen clear +12:00:23 AM - File change detected. Starting incremental compilation... + + +a.ts(1,1): error TS1371: This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'. + + +12:00:24 AM - Found 1 error. Watching for file changes. + + +Program root files: ["/a.ts","/b.ts","/a/lib/lib.d.ts"] +Program options: {"target":2,"importsNotUsedAsValues":2,"experimentalDecorators":true,"watch":true,"configFilePath":"/tsconfig.json"} +Program files:: +/b.ts +/a.ts +/a/lib/lib.d.ts + +Semantic diagnostics in builder refreshed for:: +/b.ts +/a.ts +/a/lib/lib.d.ts + +WatchedFiles:: +/tsconfig.json: + {"pollingInterval":250} +/a.ts: + {"pollingInterval":250} +/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +Change:: Enable emitDecoratorMetadata + +//// [/tsconfig.json] +{"compilerOptions":{"target":"es6","importsNotUsedAsValues":"error","experimentalDecorators":true,"emitDecoratorMetadata":true}} + +//// [/b.js] file written with same contents +//// [/a.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +import { B } from './b'; +let A = class A { + constructor(p) { } +}; +A = __decorate([ + ((_) => { }), + __metadata("design:paramtypes", [B]) +], A); +export { A }; + + + +Output:: +>> Screen clear +12:00:27 AM - File change detected. Starting incremental compilation... + + + +12:00:34 AM - Found 0 errors. Watching for file changes. + + +Program root files: ["/a.ts","/b.ts","/a/lib/lib.d.ts"] +Program options: {"target":2,"importsNotUsedAsValues":2,"experimentalDecorators":true,"emitDecoratorMetadata":true,"watch":true,"configFilePath":"/tsconfig.json"} +Program files:: +/b.ts +/a.ts +/a/lib/lib.d.ts + +Semantic diagnostics in builder refreshed for:: +/b.ts +/a.ts +/a/lib/lib.d.ts + +WatchedFiles:: +/tsconfig.json: + {"pollingInterval":250} +/a.ts: + {"pollingInterval":250} +/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined From 1fbe20fe75fca9d4787e4281f0a717c0fec1e72f Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Tue, 21 Jan 2020 20:49:38 +0100 Subject: [PATCH 25/28] resolveJsonModule affectsModuleResolution (#36290) * resolveJsonModule affectsModuleResolutionFixes: #36251 * fix lint --- src/compiler/commandLineParser.ts | 1 + .../unittests/tscWatch/programUpdates.ts | 28 ++++ ...solution-when-resolveJsonModule-changes.js | 123 ++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 tests/baselines/reference/tscWatch/programUpdates/updates-moduleResolution-when-resolveJsonModule-changes.js diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7440358709eda..be72b2051312b 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -766,6 +766,7 @@ namespace ts { { name: "resolveJsonModule", type: "boolean", + affectsModuleResolution: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Include_modules_imported_with_json_extension }, diff --git a/src/testRunner/unittests/tscWatch/programUpdates.ts b/src/testRunner/unittests/tscWatch/programUpdates.ts index b1074c7b9a288..163ba1085ead0 100644 --- a/src/testRunner/unittests/tscWatch/programUpdates.ts +++ b/src/testRunner/unittests/tscWatch/programUpdates.ts @@ -1228,6 +1228,34 @@ export function f(p: C) { return p; }` ] }); + verifyTscWatch({ + scenario, + subScenario: "updates moduleResolution when resolveJsonModule changes", + commandLineArgs: ["-w"], + sys: () => { + const aFile: File = { + path: `${projectRoot}/a.ts`, + content: `import * as data from './data.json'` + }; + const jsonFile: File = { + path: `${projectRoot}/data.json`, + content: `{ "foo": 1 }` + }; + const config: File = { + path: `${projectRoot}/tsconfig.json`, + content: JSON.stringify({ compilerOptions: { moduleResolution: "node" } }) + }; + return createWatchedSystem([aFile, jsonFile, config, libFile], { currentDirectory: projectRoot }); + }, + changes: [ + sys => { + sys.writeFile(`${projectRoot}/tsconfig.json`, JSON.stringify({ compilerOptions: { moduleResolution: "node", resolveJsonModule: true } })); + sys.runQueuedTimeoutCallbacks(); + return "Enable resolveJsonModule"; + }, + ] + }); + verifyTscWatch({ scenario, subScenario: "updates errors when ambient modules of program changes", diff --git a/tests/baselines/reference/tscWatch/programUpdates/updates-moduleResolution-when-resolveJsonModule-changes.js b/tests/baselines/reference/tscWatch/programUpdates/updates-moduleResolution-when-resolveJsonModule-changes.js new file mode 100644 index 0000000000000..5db992857c311 --- /dev/null +++ b/tests/baselines/reference/tscWatch/programUpdates/updates-moduleResolution-when-resolveJsonModule-changes.js @@ -0,0 +1,123 @@ +/a/lib/tsc.js -w +//// [/user/username/projects/myproject/a.ts] +import * as data from './data.json' + +//// [/user/username/projects/myproject/data.json] +{ "foo": 1 } + +//// [/user/username/projects/myproject/tsconfig.json] +{"compilerOptions":{"moduleResolution":"node"}} + +//// [/a/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } + +//// [/user/username/projects/myproject/a.js] +"use strict"; +exports.__esModule = true; + + + +Output:: +>> Screen clear +12:00:23 AM - Starting compilation in watch mode... + + +a.ts(1,23): error TS2732: Cannot find module './data.json'. Consider using '--resolveJsonModule' to import module with '.json' extension + + +12:00:26 AM - Found 1 error. Watching for file changes. + + +Program root files: ["/user/username/projects/myproject/a.ts"] +Program options: {"moduleResolution":2,"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"} +Program files:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/user/username/projects/myproject/a.ts + +WatchedFiles:: +/user/username/projects/myproject/tsconfig.json: + {"pollingInterval":250} +/user/username/projects/myproject/a.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: +/user/username/projects/myproject: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +FsWatchesRecursive:: +/user/username/projects/myproject/data.json: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject/node_modules/@types: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +Change:: Enable resolveJsonModule + +//// [/user/username/projects/myproject/tsconfig.json] +{"compilerOptions":{"moduleResolution":"node","resolveJsonModule":true}} + +//// [/user/username/projects/myproject/a.js] file written with same contents + +Output:: +>> Screen clear +12:00:30 AM - File change detected. Starting incremental compilation... + + + +12:00:34 AM - Found 0 errors. Watching for file changes. + + +Program root files: ["/user/username/projects/myproject/a.ts"] +Program options: {"moduleResolution":2,"resolveJsonModule":true,"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"} +Program files:: +/a/lib/lib.d.ts +/user/username/projects/myproject/data.json +/user/username/projects/myproject/a.ts + +Semantic diagnostics in builder refreshed for:: +/a/lib/lib.d.ts +/user/username/projects/myproject/data.json +/user/username/projects/myproject/a.ts + +WatchedFiles:: +/user/username/projects/myproject/tsconfig.json: + {"pollingInterval":250} +/user/username/projects/myproject/a.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} +/user/username/projects/myproject/data.json: + {"pollingInterval":250} + +FsWatches:: +/user/username/projects/myproject: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +FsWatchesRecursive:: +/user/username/projects/myproject: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject/data.json: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} +/user/username/projects/myproject/node_modules/@types: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined From 8976ac96aa5ba0dd9fb34e41cd05531aaea2eef1 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 21 Jan 2020 12:35:42 -0800 Subject: [PATCH 26/28] Update LKG. --- lib/cancellationToken.js | 8 +- lib/ja/diagnosticMessages.generated.json | 2 +- lib/lib.esnext.bigint.d.ts | 650 ++++++++++---------- lib/tsc.js | 132 ++-- lib/tsserver.js | 492 ++++++++++----- lib/tsserverlibrary.js | 492 ++++++++++----- lib/typescript.js | 468 ++++++++++---- lib/typescriptServices.js | 468 ++++++++++---- lib/typingsInstaller.js | 156 +++-- lib/zh-tw/diagnosticMessages.generated.json | 2 +- 10 files changed, 1855 insertions(+), 1015 deletions(-) diff --git a/lib/cancellationToken.js b/lib/cancellationToken.js index d63145f3fc5a0..12a1e5b265b99 100644 --- a/lib/cancellationToken.js +++ b/lib/cancellationToken.js @@ -17,13 +17,7 @@ and limitations under the License. "use strict"; var fs = require("fs"); function pipeExists(name) { - try { - fs.statSync(name); - return true; - } - catch (e) { - return false; - } + return fs.existsSync(name); } function createCancellationToken(args) { var cancellationPipeName; diff --git a/lib/ja/diagnosticMessages.generated.json b/lib/ja/diagnosticMessages.generated.json index 751357dbc01b7..a05d953fe1484 100644 --- a/lib/ja/diagnosticMessages.generated.json +++ b/lib/ja/diagnosticMessages.generated.json @@ -454,7 +454,7 @@ "Generic_type_0_requires_1_type_argument_s_2314": "ジェネリック型 '{0}' には {1} 個の型引数が必要です。", "Generic_type_0_requires_between_1_and_2_type_arguments_2707": "ジェネリック型 '{0}' には、{1} 個から {2} 個までの型引数が必要です。", "Generic_type_instantiation_is_excessively_deep_and_possibly_infinite_2550": "ジェネリック型のインスタンス化は非常に深く、無限である可能性があります。", - "Getter_and_setter_accessors_do_not_agree_in_visibility_2379": "ゲッターおよびセッターで表示が許可されていません。", + "Getter_and_setter_accessors_do_not_agree_in_visibility_2379": "ゲッターおよびセッターでの表示が許可されていません。", "Global_module_exports_may_only_appear_at_top_level_1316": "グローバル モジュールのエクスポートは最上位レベルにのみ出現可能です。", "Global_module_exports_may_only_appear_in_declaration_files_1315": "グローバル モジュールのエクスポートは宣言ファイルにのみ出現可能です。", "Global_module_exports_may_only_appear_in_module_files_1314": "グローバル モジュールのエクスポートはモジュール ファイルにのみ出現可能です。", diff --git a/lib/lib.esnext.bigint.d.ts b/lib/lib.esnext.bigint.d.ts index ba9bae6e85939..50967de98fea7 100644 --- a/lib/lib.esnext.bigint.d.ts +++ b/lib/lib.esnext.bigint.d.ts @@ -20,9 +20,9 @@ and limitations under the License. interface BigInt { /** - * Returns a string representation of an object. - * @param radix Specifies a radix for converting numeric values to strings. - */ + * Returns a string representation of an object. + * @param radix Specifies a radix for converting numeric values to strings. + */ toString(radix?: number): string; /** Returns a string representation appropriate to the host environment's current locale. */ @@ -39,27 +39,27 @@ interface BigIntConstructor { readonly prototype: BigInt; /** - * Interprets the low bits of a BigInt as a 2's-complement signed integer. - * All higher bits are discarded. - * @param bits The number of low bits to use - * @param int The BigInt whose bits to extract - */ + * Interprets the low bits of a BigInt as a 2's-complement signed integer. + * All higher bits are discarded. + * @param bits The number of low bits to use + * @param int The BigInt whose bits to extract + */ asIntN(bits: number, int: bigint): bigint; /** - * Interprets the low bits of a BigInt as an unsigned integer. - * All higher bits are discarded. - * @param bits The number of low bits to use - * @param int The BigInt whose bits to extract - */ + * Interprets the low bits of a BigInt as an unsigned integer. + * All higher bits are discarded. + * @param bits The number of low bits to use + * @param int The BigInt whose bits to extract + */ asUintN(bits: number, int: bigint): bigint; } declare var BigInt: BigIntConstructor; /** - * A typed array of 64-bit signed integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated, an exception is raised. - */ + * A typed array of 64-bit signed integer values. The contents are initialized to 0. If the + * requested number of bytes could not be allocated, an exception is raised. + */ interface BigInt64Array { /** The size in bytes of each element in the array. */ readonly BYTES_PER_ELEMENT: number; @@ -74,213 +74,213 @@ interface BigInt64Array { readonly byteOffset: number; /** - * Returns the this object after copying a section of the array identified by start and end - * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it - * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. - */ + * Returns the this object after copying a section of the array identified by start and end + * to the same array starting at position target + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it + * is treated as length+end. + * @param end If not specified, length of the this object is used as its default value. + */ copyWithin(target: number, start: number, end?: number): this; /** Yields index, value pairs for every entry in the array. */ entries(): IterableIterator<[number, bigint]>; /** - * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in the array until the callbackfn returns false, - * or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Determines whether all the members of an array satisfy the specified test. + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in the array until the callbackfn returns false, + * or until the end of the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ every(callbackfn: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean; /** - * Returns the this object after filling the section identified by start and end with value - * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as - * length+end. - */ + * Returns the this object after filling the section identified by start and end with value + * @param value value to fill array section with + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as + * length+end. + */ fill(value: bigint, start?: number, end?: number): this; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ filter(callbackfn: (value: bigint, index: number, array: BigInt64Array) => any, thisArg?: any): BigInt64Array; /** - * Returns the value of the first element in the array where predicate is true, and undefined - * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find - * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ + * Returns the value of the first element in the array where predicate is true, and undefined + * otherwise. + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find + * immediately returns that element value. Otherwise, find returns undefined. + * @param thisArg If provided, it will be used as the this value for each invocation of + * predicate. If it is not provided, undefined is used instead. + */ find(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): bigint | undefined; /** - * Returns the index of the first element in the array where predicate is true, and -1 - * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, - * findIndex immediately returns that element index. Otherwise, findIndex returns -1. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ + * Returns the index of the first element in the array where predicate is true, and -1 + * otherwise. + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, + * findIndex immediately returns that element index. Otherwise, findIndex returns -1. + * @param thisArg If provided, it will be used as the this value for each invocation of + * predicate. If it is not provided, undefined is used instead. + */ findIndex(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): number; /** - * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Performs the specified action for each element in an array. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ forEach(callbackfn: (value: bigint, index: number, array: BigInt64Array) => void, thisArg?: any): void; /** - * Determines whether an array includes a certain element, returning true or false as appropriate. - * @param searchElement The element to search for. - * @param fromIndex The position in this array at which to begin searching for searchElement. - */ + * Determines whether an array includes a certain element, returning true or false as appropriate. + * @param searchElement The element to search for. + * @param fromIndex The position in this array at which to begin searching for searchElement. + */ includes(searchElement: bigint, fromIndex?: number): boolean; /** - * Returns the index of the first occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ + * Returns the index of the first occurrence of a value in an array. + * @param searchElement The value to locate in the array. + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * search starts at index 0. + */ indexOf(searchElement: bigint, fromIndex?: number): number; /** - * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the - * resulting String. If omitted, the array elements are separated with a comma. - */ + * Adds all the elements of an array separated by the specified separator string. + * @param separator A string used to separate one element of an array from the next in the + * resulting String. If omitted, the array elements are separated with a comma. + */ join(separator?: string): string; /** Yields each index in the array. */ keys(): IterableIterator; /** - * Returns the index of the last occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ + * Returns the index of the last occurrence of a value in an array. + * @param searchElement The value to locate in the array. + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * search starts at index 0. + */ lastIndexOf(searchElement: bigint, fromIndex?: number): number; /** The length of the array. */ readonly length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that - * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Calls a defined callback function on each element of an array, and returns an array that + * contains the results. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ map(callbackfn: (value: bigint, index: number, array: BigInt64Array) => bigint, thisArg?: any): BigInt64Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next + * call to the callback function. + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument + * instead of an array value. + */ reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next + * call to the callback function. + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument + * instead of an array value. + */ reduce(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U; /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an - * argument instead of an array value. - */ + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an + * argument in the next call to the callback function. + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an + * argument instead of an array value. + */ reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint; /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an + * argument in the next call to the callback function. + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument + * instead of an array value. + */ reduceRight(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U; /** Reverses the elements in the array. */ reverse(): this; /** - * Sets a value or an array of values. - * @param array A typed or untyped array of values to set. - * @param offset The index in the current array at which the values are to be written. - */ + * Sets a value or an array of values. + * @param array A typed or untyped array of values to set. + * @param offset The index in the current array at which the values are to be written. + */ set(array: ArrayLike, offset?: number): void; /** - * Returns a section of an array. - * @param start The beginning of the specified portion of the array. - * @param end The end of the specified portion of the array. - */ + * Returns a section of an array. + * @param start The beginning of the specified portion of the array. + * @param end The end of the specified portion of the array. + */ slice(start?: number, end?: number): BigInt64Array; /** - * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in the array until the callbackfn returns true, or until - * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Determines whether the specified callback function returns true for any element of an array. + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in the array until the callbackfn returns true, or until + * the end of the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ some(callbackfn: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean; /** - * Sorts the array. - * @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order. - */ + * Sorts the array. + * @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order. + */ sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this; /** - * Gets a new BigInt64Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. - * @param begin The index of the beginning of the array. - * @param end The index of the end of the array. - */ - subarray(begin?: number, end?: number): BigInt64Array; + * Gets a new BigInt64Array view of the ArrayBuffer store for this array, referencing the elements + * at begin, inclusive, up to end, exclusive. + * @param begin The index of the beginning of the array. + * @param end The index of the end of the array. + */ + subarray(begin: number, end?: number): BigInt64Array; /** Converts the array to a string by using the current locale. */ toLocaleString(): string; @@ -308,17 +308,17 @@ interface BigInt64ArrayConstructor { readonly BYTES_PER_ELEMENT: number; /** - * Returns a new array from a set of elements. - * @param items A set of elements to include in the new array object. - */ + * Returns a new array from a set of elements. + * @param items A set of elements to include in the new array object. + */ of(...items: bigint[]): BigInt64Array; /** - * Creates an array from an array-like or iterable object. - * @param arrayLike An array-like or iterable object to convert to an array. - * @param mapfn A mapping function to call on every element of the array. - * @param thisArg Value of 'this' used to invoke the mapfn. - */ + * Creates an array from an array-like or iterable object. + * @param arrayLike An array-like or iterable object to convert to an array. + * @param mapfn A mapping function to call on every element of the array. + * @param thisArg Value of 'this' used to invoke the mapfn. + */ from(arrayLike: ArrayLike): BigInt64Array; from(arrayLike: ArrayLike, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigInt64Array; } @@ -326,9 +326,9 @@ interface BigInt64ArrayConstructor { declare var BigInt64Array: BigInt64ArrayConstructor; /** - * A typed array of 64-bit unsigned integer values. The contents are initialized to 0. If the - * requested number of bytes could not be allocated, an exception is raised. - */ + * A typed array of 64-bit unsigned integer values. The contents are initialized to 0. If the + * requested number of bytes could not be allocated, an exception is raised. + */ interface BigUint64Array { /** The size in bytes of each element in the array. */ readonly BYTES_PER_ELEMENT: number; @@ -343,213 +343,213 @@ interface BigUint64Array { readonly byteOffset: number; /** - * Returns the this object after copying a section of the array identified by start and end - * to the same array starting at position target - * @param target If target is negative, it is treated as length+target where length is the - * length of the array. - * @param start If start is negative, it is treated as length+start. If end is negative, it - * is treated as length+end. - * @param end If not specified, length of the this object is used as its default value. - */ + * Returns the this object after copying a section of the array identified by start and end + * to the same array starting at position target + * @param target If target is negative, it is treated as length+target where length is the + * length of the array. + * @param start If start is negative, it is treated as length+start. If end is negative, it + * is treated as length+end. + * @param end If not specified, length of the this object is used as its default value. + */ copyWithin(target: number, start: number, end?: number): this; /** Yields index, value pairs for every entry in the array. */ entries(): IterableIterator<[number, bigint]>; /** - * Determines whether all the members of an array satisfy the specified test. - * @param callbackfn A function that accepts up to three arguments. The every method calls - * the callbackfn function for each element in the array until the callbackfn returns false, - * or until the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Determines whether all the members of an array satisfy the specified test. + * @param callbackfn A function that accepts up to three arguments. The every method calls + * the callbackfn function for each element in the array until the callbackfn returns false, + * or until the end of the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ every(callbackfn: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean; /** - * Returns the this object after filling the section identified by start and end with value - * @param value value to fill array section with - * @param start index to start filling the array at. If start is negative, it is treated as - * length+start where length is the length of the array. - * @param end index to stop filling the array at. If end is negative, it is treated as - * length+end. - */ + * Returns the this object after filling the section identified by start and end with value + * @param value value to fill array section with + * @param start index to start filling the array at. If start is negative, it is treated as + * length+start where length is the length of the array. + * @param end index to stop filling the array at. If end is negative, it is treated as + * length+end. + */ fill(value: bigint, start?: number, end?: number): this; /** - * Returns the elements of an array that meet the condition specified in a callback function. - * @param callbackfn A function that accepts up to three arguments. The filter method calls - * the callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Returns the elements of an array that meet the condition specified in a callback function. + * @param callbackfn A function that accepts up to three arguments. The filter method calls + * the callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ filter(callbackfn: (value: bigint, index: number, array: BigUint64Array) => any, thisArg?: any): BigUint64Array; /** - * Returns the value of the first element in the array where predicate is true, and undefined - * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, find - * immediately returns that element value. Otherwise, find returns undefined. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ + * Returns the value of the first element in the array where predicate is true, and undefined + * otherwise. + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, find + * immediately returns that element value. Otherwise, find returns undefined. + * @param thisArg If provided, it will be used as the this value for each invocation of + * predicate. If it is not provided, undefined is used instead. + */ find(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): bigint | undefined; /** - * Returns the index of the first element in the array where predicate is true, and -1 - * otherwise. - * @param predicate find calls predicate once for each element of the array, in ascending - * order, until it finds one where predicate returns true. If such an element is found, - * findIndex immediately returns that element index. Otherwise, findIndex returns -1. - * @param thisArg If provided, it will be used as the this value for each invocation of - * predicate. If it is not provided, undefined is used instead. - */ + * Returns the index of the first element in the array where predicate is true, and -1 + * otherwise. + * @param predicate find calls predicate once for each element of the array, in ascending + * order, until it finds one where predicate returns true. If such an element is found, + * findIndex immediately returns that element index. Otherwise, findIndex returns -1. + * @param thisArg If provided, it will be used as the this value for each invocation of + * predicate. If it is not provided, undefined is used instead. + */ findIndex(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): number; /** - * Performs the specified action for each element in an array. - * @param callbackfn A function that accepts up to three arguments. forEach calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Performs the specified action for each element in an array. + * @param callbackfn A function that accepts up to three arguments. forEach calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ forEach(callbackfn: (value: bigint, index: number, array: BigUint64Array) => void, thisArg?: any): void; /** - * Determines whether an array includes a certain element, returning true or false as appropriate. - * @param searchElement The element to search for. - * @param fromIndex The position in this array at which to begin searching for searchElement. - */ + * Determines whether an array includes a certain element, returning true or false as appropriate. + * @param searchElement The element to search for. + * @param fromIndex The position in this array at which to begin searching for searchElement. + */ includes(searchElement: bigint, fromIndex?: number): boolean; /** - * Returns the index of the first occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ + * Returns the index of the first occurrence of a value in an array. + * @param searchElement The value to locate in the array. + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * search starts at index 0. + */ indexOf(searchElement: bigint, fromIndex?: number): number; /** - * Adds all the elements of an array separated by the specified separator string. - * @param separator A string used to separate one element of an array from the next in the - * resulting String. If omitted, the array elements are separated with a comma. - */ + * Adds all the elements of an array separated by the specified separator string. + * @param separator A string used to separate one element of an array from the next in the + * resulting String. If omitted, the array elements are separated with a comma. + */ join(separator?: string): string; /** Yields each index in the array. */ keys(): IterableIterator; /** - * Returns the index of the last occurrence of a value in an array. - * @param searchElement The value to locate in the array. - * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the - * search starts at index 0. - */ + * Returns the index of the last occurrence of a value in an array. + * @param searchElement The value to locate in the array. + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the + * search starts at index 0. + */ lastIndexOf(searchElement: bigint, fromIndex?: number): number; /** The length of the array. */ readonly length: number; /** - * Calls a defined callback function on each element of an array, and returns an array that - * contains the results. - * @param callbackfn A function that accepts up to three arguments. The map method calls the - * callbackfn function one time for each element in the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Calls a defined callback function on each element of an array, and returns an array that + * contains the results. + * @param callbackfn A function that accepts up to three arguments. The map method calls the + * callbackfn function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ map(callbackfn: (value: bigint, index: number, array: BigUint64Array) => bigint, thisArg?: any): BigUint64Array; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next + * call to the callback function. + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument + * instead of an array value. + */ reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint; /** - * Calls the specified callback function for all the elements in an array. The return value of - * the callback function is the accumulated result, and is provided as an argument in the next - * call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduce method calls the - * callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ + * Calls the specified callback function for all the elements in an array. The return value of + * the callback function is the accumulated result, and is provided as an argument in the next + * call to the callback function. + * @param callbackfn A function that accepts up to four arguments. The reduce method calls the + * callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument + * instead of an array value. + */ reduce(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U; /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an - * argument instead of an array value. - */ + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an + * argument in the next call to the callback function. + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an + * argument instead of an array value. + */ reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint; /** - * Calls the specified callback function for all the elements in an array, in descending order. - * The return value of the callback function is the accumulated result, and is provided as an - * argument in the next call to the callback function. - * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls - * the callbackfn function one time for each element in the array. - * @param initialValue If initialValue is specified, it is used as the initial value to start - * the accumulation. The first call to the callbackfn function provides this value as an argument - * instead of an array value. - */ + * Calls the specified callback function for all the elements in an array, in descending order. + * The return value of the callback function is the accumulated result, and is provided as an + * argument in the next call to the callback function. + * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls + * the callbackfn function one time for each element in the array. + * @param initialValue If initialValue is specified, it is used as the initial value to start + * the accumulation. The first call to the callbackfn function provides this value as an argument + * instead of an array value. + */ reduceRight(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U; /** Reverses the elements in the array. */ reverse(): this; /** - * Sets a value or an array of values. - * @param array A typed or untyped array of values to set. - * @param offset The index in the current array at which the values are to be written. - */ + * Sets a value or an array of values. + * @param array A typed or untyped array of values to set. + * @param offset The index in the current array at which the values are to be written. + */ set(array: ArrayLike, offset?: number): void; /** - * Returns a section of an array. - * @param start The beginning of the specified portion of the array. - * @param end The end of the specified portion of the array. - */ + * Returns a section of an array. + * @param start The beginning of the specified portion of the array. + * @param end The end of the specified portion of the array. + */ slice(start?: number, end?: number): BigUint64Array; /** - * Determines whether the specified callback function returns true for any element of an array. - * @param callbackfn A function that accepts up to three arguments. The some method calls the - * callbackfn function for each element in the array until the callbackfn returns true, or until - * the end of the array. - * @param thisArg An object to which the this keyword can refer in the callbackfn function. - * If thisArg is omitted, undefined is used as the this value. - */ + * Determines whether the specified callback function returns true for any element of an array. + * @param callbackfn A function that accepts up to three arguments. The some method calls the + * callbackfn function for each element in the array until the callbackfn returns true, or until + * the end of the array. + * @param thisArg An object to which the this keyword can refer in the callbackfn function. + * If thisArg is omitted, undefined is used as the this value. + */ some(callbackfn: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean; /** - * Sorts the array. - * @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order. - */ + * Sorts the array. + * @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order. + */ sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this; /** - * Gets a new BigUint64Array view of the ArrayBuffer store for this array, referencing the elements - * at begin, inclusive, up to end, exclusive. - * @param begin The index of the beginning of the array. - * @param end The index of the end of the array. - */ - subarray(begin?: number, end?: number): BigUint64Array; + * Gets a new BigUint64Array view of the ArrayBuffer store for this array, referencing the elements + * at begin, inclusive, up to end, exclusive. + * @param begin The index of the beginning of the array. + * @param end The index of the end of the array. + */ + subarray(begin: number, end?: number): BigUint64Array; /** Converts the array to a string by using the current locale. */ toLocaleString(): string; @@ -577,17 +577,17 @@ interface BigUint64ArrayConstructor { readonly BYTES_PER_ELEMENT: number; /** - * Returns a new array from a set of elements. - * @param items A set of elements to include in the new array object. - */ + * Returns a new array from a set of elements. + * @param items A set of elements to include in the new array object. + */ of(...items: bigint[]): BigUint64Array; /** - * Creates an array from an array-like or iterable object. - * @param arrayLike An array-like or iterable object to convert to an array. - * @param mapfn A mapping function to call on every element of the array. - * @param thisArg Value of 'this' used to invoke the mapfn. - */ + * Creates an array from an array-like or iterable object. + * @param arrayLike An array-like or iterable object to convert to an array. + * @param mapfn A mapping function to call on every element of the array. + * @param thisArg Value of 'this' used to invoke the mapfn. + */ from(arrayLike: ArrayLike): BigUint64Array; from(arrayLike: ArrayLike, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigUint64Array; } @@ -596,34 +596,34 @@ declare var BigUint64Array: BigUint64ArrayConstructor; interface DataView { /** - * Gets the BigInt64 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ + * Gets the BigInt64 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. + * @param byteOffset The place in the buffer at which the value should be retrieved. + */ getBigInt64(byteOffset: number, littleEndian?: boolean): bigint; /** - * Gets the BigUint64 value at the specified byte offset from the start of the view. There is - * no alignment constraint; multi-byte values may be fetched from any offset. - * @param byteOffset The place in the buffer at which the value should be retrieved. - */ + * Gets the BigUint64 value at the specified byte offset from the start of the view. There is + * no alignment constraint; multi-byte values may be fetched from any offset. + * @param byteOffset The place in the buffer at which the value should be retrieved. + */ getBigUint64(byteOffset: number, littleEndian?: boolean): bigint; /** - * Stores a BigInt64 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ + * Stores a BigInt64 value at the specified byte offset from the start of the view. + * @param byteOffset The place in the buffer at which the value should be set. + * @param value The value to set. + * @param littleEndian If false or undefined, a big-endian value should be written, + * otherwise a little-endian value should be written. + */ setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void; /** - * Stores a BigUint64 value at the specified byte offset from the start of the view. - * @param byteOffset The place in the buffer at which the value should be set. - * @param value The value to set. - * @param littleEndian If false or undefined, a big-endian value should be written, - * otherwise a little-endian value should be written. - */ + * Stores a BigUint64 value at the specified byte offset from the start of the view. + * @param byteOffset The place in the buffer at which the value should be set. + * @param value The value to set. + * @param littleEndian If false or undefined, a big-endian value should be written, + * otherwise a little-endian value should be written. + */ setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void; } diff --git a/lib/tsc.js b/lib/tsc.js index 505b3f19af6af..372f8322cace9 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -3411,10 +3411,13 @@ var ts; } } function readFileWorker(fileName, _encoding) { - if (!fileExists(fileName)) { + var buffer; + try { + buffer = _fs.readFileSync(fileName); + } + catch (e) { return undefined; } - var buffer = _fs.readFileSync(fileName); var len = buffer.length; if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) { len &= ~1; @@ -3458,21 +3461,27 @@ var ts; function getAccessibleFileSystemEntries(path) { ts.perfLogger.logEvent("ReadDir: " + (path || ".")); try { - var entries = _fs.readdirSync(path || ".").sort(); + var entries = _fs.readdirSync(path || ".", { withFileTypes: true }); var files = []; var directories = []; for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { - var entry = entries_2[_i]; + var dirent = entries_2[_i]; + var entry = typeof dirent === "string" ? dirent : dirent.name; if (entry === "." || entry === "..") { continue; } - var name = ts.combinePaths(path, entry); var stat = void 0; - try { - stat = _fs.statSync(name); + if (typeof dirent === "string" || dirent.isSymbolicLink()) { + var name = ts.combinePaths(path, entry); + try { + stat = _fs.statSync(name); + } + catch (e) { + continue; + } } - catch (e) { - continue; + else { + stat = dirent; } if (stat.isFile()) { files.push(entry); @@ -3481,6 +3490,8 @@ var ts; directories.push(entry); } } + files.sort(); + directories.sort(); return { files: files, directories: directories }; } catch (e) { @@ -3510,8 +3521,7 @@ var ts; return fileSystemEntryExists(path, 1); } function getDirectories(path) { - ts.perfLogger.logEvent("ReadDir: " + path); - return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1); }); + return getAccessibleFileSystemEntries(path).directories.slice(); } function realpath(path) { try { @@ -4292,7 +4302,7 @@ var ts; Keywords_cannot_contain_escape_characters: diag(1260, ts.DiagnosticCategory.Error, "Keywords_cannot_contain_escape_characters_1260", "Keywords cannot contain escape characters."), Already_included_file_name_0_differs_from_file_name_1_only_in_casing: diag(1261, ts.DiagnosticCategory.Error, "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", "Already included file name '{0}' differs from file name '{1}' only in casing."), with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."), - await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."), + await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules: diag(1308, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", "'await' expressions are only allowed within async functions and at the top levels of modules."), can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."), The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."), Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."), @@ -4340,14 +4350,13 @@ var ts; An_enum_member_name_must_be_followed_by_a_or: diag(1357, ts.DiagnosticCategory.Error, "An_enum_member_name_must_be_followed_by_a_or_1357", "An enum member name must be followed by a ',', '=', or '}'."), Tagged_template_expressions_are_not_permitted_in_an_optional_chain: diag(1358, ts.DiagnosticCategory.Error, "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", "Tagged template expressions are not permitted in an optional chain."), Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here: diag(1359, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", "Identifier expected. '{0}' is a reserved word that cannot be used here."), - Did_you_mean_to_parenthesize_this_function_type: diag(1360, ts.DiagnosticCategory.Error, "Did_you_mean_to_parenthesize_this_function_type_1360", "Did you mean to parenthesize this function type?"), Type_only_0_must_reference_a_type_but_1_is_a_value: diag(1361, ts.DiagnosticCategory.Error, "Type_only_0_must_reference_a_type_but_1_is_a_value_1361", "Type-only {0} must reference a type, but '{1}' is a value."), Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported: diag(1362, ts.DiagnosticCategory.Error, "Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported_1362", "Enum '{0}' cannot be used as a value because only its type has been imported."), A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both: diag(1363, ts.DiagnosticCategory.Error, "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", "A type-only import can specify a default import or named bindings, but not both."), Convert_to_type_only_export: diag(1364, ts.DiagnosticCategory.Message, "Convert_to_type_only_export_1364", "Convert to type-only export"), Convert_all_re_exported_types_to_type_only_exports: diag(1365, ts.DiagnosticCategory.Message, "Convert_all_re_exported_types_to_type_only_exports_1365", "Convert all re-exported types to type-only exports"), Split_into_two_separate_import_declarations: diag(1366, ts.DiagnosticCategory.Message, "Split_into_two_separate_import_declarations_1366", "Split into two separate import declarations"), - Split_all_invalid_type_only_imports: diag(1377, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1377", "Split all invalid type-only imports"), + Split_all_invalid_type_only_imports: diag(1367, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1367", "Split all invalid type-only imports"), Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types: diag(1368, ts.DiagnosticCategory.Message, "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_1368", "Specify emit/checking behavior for imports that are only used for types"), Did_you_mean_0: diag(1369, ts.DiagnosticCategory.Message, "Did_you_mean_0_1369", "Did you mean '{0}'?"), Only_ECMAScript_imports_may_use_import_type: diag(1370, ts.DiagnosticCategory.Error, "Only_ECMAScript_imports_may_use_import_type_1370", "Only ECMAScript imports may use 'import type'."), @@ -4355,7 +4364,8 @@ var ts; This_import_may_be_converted_to_a_type_only_import: diag(1372, ts.DiagnosticCategory.Suggestion, "This_import_may_be_converted_to_a_type_only_import_1372", "This import may be converted to a type-only import."), Convert_to_type_only_import: diag(1373, ts.DiagnosticCategory.Message, "Convert_to_type_only_import_1373", "Convert to type-only import"), Convert_all_imports_not_used_as_a_value_to_type_only_imports: diag(1374, ts.DiagnosticCategory.Message, "Convert_all_imports_not_used_as_a_value_to_type_only_imports_1374", "Convert all imports not used as a value to type-only imports"), - await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher: diag(1375, ts.DiagnosticCategory.Error, "await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnex_1375", "'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher."), + await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module: diag(1375, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."), + Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher: diag(1376, ts.DiagnosticCategory.Error, "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_t_1376", "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher."), The_types_of_0_are_incompatible_between_these_types: diag(2200, ts.DiagnosticCategory.Error, "The_types_of_0_are_incompatible_between_these_types_2200", "The types of '{0}' are incompatible between these types."), The_types_returned_by_0_are_incompatible_between_these_types: diag(2201, ts.DiagnosticCategory.Error, "The_types_returned_by_0_are_incompatible_between_these_types_2201", "The types returned by '{0}' are incompatible between these types."), Call_signature_return_types_0_and_1_are_incompatible: diag(2202, ts.DiagnosticCategory.Error, "Call_signature_return_types_0_and_1_are_incompatible_2202", "Call signature return types '{0}' and '{1}' are incompatible.", undefined, true), @@ -5301,7 +5311,7 @@ var ts; Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"), Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"), Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"), - Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'"), + Remove_unused_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_unused_declaration_for_Colon_0_90004", "Remove unused declaration for: '{0}'"), Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"), Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"), Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"), @@ -5424,10 +5434,12 @@ var ts; Prefix_with_declare: diag(95094, ts.DiagnosticCategory.Message, "Prefix_with_declare_95094", "Prefix with 'declare'"), Prefix_all_incorrect_property_declarations_with_declare: diag(95095, ts.DiagnosticCategory.Message, "Prefix_all_incorrect_property_declarations_with_declare_95095", "Prefix all incorrect property declarations with 'declare'"), Convert_to_template_string: diag(95096, ts.DiagnosticCategory.Message, "Convert_to_template_string_95096", "Convert to template string"), + Add_export_to_make_this_file_into_a_module: diag(95097, ts.DiagnosticCategory.Message, "Add_export_to_make_this_file_into_a_module_95097", "Add 'export {}' to make this file into a module"), + Set_the_target_option_in_your_configuration_file_to_0: diag(95098, ts.DiagnosticCategory.Message, "Set_the_target_option_in_your_configuration_file_to_0_95098", "Set the 'target' option in your configuration file to '{0}'"), + Set_the_module_option_in_your_configuration_file_to_0: diag(95099, ts.DiagnosticCategory.Message, "Set_the_module_option_in_your_configuration_file_to_0_95099", "Set the 'module' option in your configuration file to '{0}'"), No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."), Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."), JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array: diag(18007, ts.DiagnosticCategory.Error, "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", "JSX expressions may not use the comma operator. Did you mean to write an array?"), - can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Private_identifiers_cannot_be_used_as_parameters: diag(18009, ts.DiagnosticCategory.Error, "Private_identifiers_cannot_be_used_as_parameters_18009", "Private identifiers cannot be used as parameters"), An_accessibility_modifier_cannot_be_used_with_a_private_identifier: diag(18010, ts.DiagnosticCategory.Error, "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", "An accessibility modifier cannot be used with a private identifier."), The_operand_of_a_delete_operator_cannot_be_a_private_identifier: diag(18011, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", "The operand of a 'delete' operator cannot be a private identifier."), @@ -5442,6 +5454,7 @@ var ts; A_method_cannot_be_named_with_a_private_identifier: diag(18022, ts.DiagnosticCategory.Error, "A_method_cannot_be_named_with_a_private_identifier_18022", "A method cannot be named with a private identifier."), An_accessor_cannot_be_named_with_a_private_identifier: diag(18023, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_named_with_a_private_identifier_18023", "An accessor cannot be named with a private identifier."), An_enum_member_cannot_be_named_with_a_private_identifier: diag(18024, ts.DiagnosticCategory.Error, "An_enum_member_cannot_be_named_with_a_private_identifier_18024", "An enum member cannot be named with a private identifier."), + can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Compiler_reserves_name_0_when_emitting_private_identifier_downlevel: diag(18027, ts.DiagnosticCategory.Error, "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", "Compiler reserves name '{0}' when emitting private identifier downlevel."), Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher: diag(18028, ts.DiagnosticCategory.Error, "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", "Private identifiers are only available when targeting ECMAScript 2015 and higher."), Private_identifiers_are_not_allowed_in_variable_declarations: diag(18029, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_in_variable_declarations_18029", "Private identifiers are not allowed in variable declarations."), @@ -21067,6 +21080,7 @@ var ts; error: 2 }), affectsEmit: true, + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types }, @@ -21315,12 +21329,15 @@ var ts; { name: "experimentalDecorators", type: "boolean", + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", + affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, @@ -21333,6 +21350,7 @@ var ts; { name: "resolveJsonModule", type: "boolean", + affectsModuleResolution: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Include_modules_imported_with_json_extension }, @@ -21532,6 +21550,7 @@ var ts; name: "useDefineForClassFields", type: "boolean", affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Emit_class_fields_with_Define_instead_of_Set, }, @@ -24790,7 +24809,7 @@ var ts; case 104: case 194: case 195: - return isNarrowableReference(expr); + return containsNarrowableReference(expr); case 196: return hasNarrowableArgument(expr); case 200: @@ -24807,20 +24826,22 @@ var ts; function isNarrowableReference(expr) { return expr.kind === 75 || expr.kind === 104 || expr.kind === 102 || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || - ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) || - ts.isOptionalChain(expr); + ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression); + } + function containsNarrowableReference(expr) { + return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); } function hasNarrowableArgument(expr) { if (expr.arguments) { for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) { var argument = _a[_i]; - if (isNarrowableReference(argument)) { + if (containsNarrowableReference(argument)) { return true; } } } if (expr.expression.kind === 194 && - isNarrowableReference(expr.expression.expression)) { + containsNarrowableReference(expr.expression.expression)) { return true; } return false; @@ -24834,7 +24855,7 @@ var ts; function isNarrowingBinaryExpression(expr) { switch (expr.operatorToken.kind) { case 62: - return isNarrowableReference(expr.left); + return containsNarrowableReference(expr.left); case 34: case 35: case 36: @@ -24862,7 +24883,7 @@ var ts; return isNarrowableOperand(expr.right); } } - return isNarrowableReference(expr); + return containsNarrowableReference(expr); } function createBranchLabel() { return initFlowNode({ flags: 4, antecedents: undefined }); @@ -27667,6 +27688,7 @@ var ts; var currentNode; var emptySymbols = ts.createSymbolTable(); var identityMapper = ts.identity; + var arrayVariances = [1]; var compilerOptions = host.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); @@ -27907,9 +27929,12 @@ var ts; isArrayLikeType: isArrayLikeType, isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant, getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes, - getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); }, + getSuggestedSymbolForNonexistentProperty: getSuggestedSymbolForNonexistentProperty, + getSuggestionForNonexistentProperty: getSuggestionForNonexistentProperty, + getSuggestedSymbolForNonexistentSymbol: function (location, name, meaning) { return getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, - getSuggestionForNonexistentExport: function (node, target) { return getSuggestionForNonexistentExport(node, target); }, + getSuggestedSymbolForNonexistentModule: getSuggestedSymbolForNonexistentModule, + getSuggestionForNonexistentExport: getSuggestionForNonexistentExport, getBaseConstraintOfType: getBaseConstraintOfType, getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 ? getDefaultFromTypeParameter(type) : undefined; }, resolveName: function (name, location, meaning, excludeGlobals) { @@ -29266,8 +29291,11 @@ var ts; } symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias); var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias); - if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default") { - symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + if (symbolFromModule === undefined && name.escapedText === "default") { + var file = ts.find(moduleSymbol.declarations, ts.isSourceFile); + if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) { + symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + } } var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : @@ -37730,8 +37758,9 @@ var ts; return spread; } function isSpreadableProperty(prop) { - return !(prop.flags & (8192 | 32768 | 65536)) || - !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); }); + return !ts.some(prop.declarations, ts.isPrivateIdentifierPropertyDeclaration) && + (!(prop.flags & (8192 | 32768 | 65536)) || + !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); })); } function getSpreadSymbol(prop, readonly) { var isSetonlyAccessor = prop.flags & 65536 && !(prop.flags & 32768); @@ -39776,6 +39805,9 @@ var ts; source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { var variances = getAliasVariances(source.aliasSymbol); + if (variances === ts.emptyArray) { + return 1; + } var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -39945,6 +39977,9 @@ var ts; if (ts.getObjectFlags(source) & 4 && ts.getObjectFlags(target) & 4 && source.target === target.target && !(ts.getObjectFlags(source) & 8192 || ts.getObjectFlags(target) & 8192)) { var variances = getVariances(source.target); + if (variances === ts.emptyArray) { + return 1; + } var varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -40651,7 +40686,7 @@ var ts; } function getVariances(type) { if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8) { - return ts.emptyArray; + return arrayVariances; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); } @@ -43866,19 +43901,7 @@ var ts; } } else if (!assumeInitialized && !(getFalsyFlags(type) & 32768) && getFalsyFlags(flowType) & 32768) { - var diag = error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); - if (type.symbol && type.symbol.declarations.length === 1 && ts.isFunctionTypeNode(type.symbol.declarations[0])) { - var funcTypeNode = type.symbol.declarations[0]; - var returnType = getReturnTypeFromAnnotation(funcTypeNode); - if (returnType && returnType.flags & 1048576) { - var unionTypes_3 = funcTypeNode.type.types; - if (unionTypes_3 && unionTypes_3[unionTypes_3.length - 1].kind === 146) { - var parenedFuncType = ts.getMutableClone(funcTypeNode); - parenedFuncType.end = unionTypes_3[unionTypes_3.length - 2].end; - ts.addRelatedInfo(diag, ts.createDiagnosticForNode(parenedFuncType, ts.Diagnostics.Did_you_mean_to_parenthesize_this_function_type)); - } - } - } + error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); return type; } return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; @@ -48577,12 +48600,17 @@ var ts; if (!(node.flags & 32768)) { if (isTopLevelAwait(node)) { var sourceFile = ts.getSourceFileOfNode(node); - if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || - languageVersion < 4 || - !ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { - if (!hasParseDiagnostics(sourceFile)) { - var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher); + if (!hasParseDiagnostics(sourceFile)) { + var span = void 0; + if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + if (!span) + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); + diagnostics.add(diagnostic); + } + if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || languageVersion < 4) { + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher); diagnostics.add(diagnostic); } } @@ -48591,7 +48619,7 @@ var ts; var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); var func = ts.getContainingFunction(node); if (func && func.kind !== 162 && (ts.getFunctionFlags(func) & 2) === 0) { var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async); @@ -79674,7 +79702,7 @@ var ts; if (!program || hasChangedAutomaticTypeDirectiveNames) { return false; } - if (program.getRootFileNames().length !== rootFileNames.length) { + if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) { return false; } var seenResolvedRefs; diff --git a/lib/tsserver.js b/lib/tsserver.js index e8e55b1446b9a..c9e6eac45e5dc 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -64,6 +64,17 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || @@ -77,17 +88,6 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); -var __rest = (this && this.__rest) || function (s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; -}; var ts; (function (ts) { // WARNING: The script `configurePrerelease.ts` uses a regexp to parse out these values. @@ -1275,6 +1275,11 @@ var ts; return result; } ts.clone = clone; + /** + * Creates a new object by adding the own properties of `second`, then the own properties of `first`. + * + * NOTE: This means that if a property exists in both `first` and `second`, the property in `first` will be chosen. + */ function extend(first, second) { var result = {}; for (var id in second) { @@ -5595,10 +5600,13 @@ var ts; } } function readFileWorker(fileName, _encoding) { - if (!fileExists(fileName)) { + var buffer; + try { + buffer = _fs.readFileSync(fileName); + } + catch (e) { return undefined; } - var buffer = _fs.readFileSync(fileName); var len = buffer.length; if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) { // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js, @@ -5648,23 +5656,30 @@ var ts; function getAccessibleFileSystemEntries(path) { ts.perfLogger.logEvent("ReadDir: " + (path || ".")); try { - var entries = _fs.readdirSync(path || ".").sort(); + var entries = _fs.readdirSync(path || ".", { withFileTypes: true }); var files = []; var directories = []; for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { - var entry = entries_2[_i]; + var dirent = entries_2[_i]; + // withFileTypes is not supported before Node 10.10. + var entry = typeof dirent === "string" ? dirent : dirent.name; // This is necessary because on some file system node fails to exclude // "." and "..". See https://github.com/nodejs/node/issues/4002 if (entry === "." || entry === "..") { continue; } - var name = ts.combinePaths(path, entry); var stat = void 0; - try { - stat = _fs.statSync(name); + if (typeof dirent === "string" || dirent.isSymbolicLink()) { + var name = ts.combinePaths(path, entry); + try { + stat = _fs.statSync(name); + } + catch (e) { + continue; + } } - catch (e) { - continue; + else { + stat = dirent; } if (stat.isFile()) { files.push(entry); @@ -5673,6 +5688,8 @@ var ts; directories.push(entry); } } + files.sort(); + directories.sort(); return { files: files, directories: directories }; } catch (e) { @@ -5702,8 +5719,7 @@ var ts; return fileSystemEntryExists(path, 1 /* Directory */); } function getDirectories(path) { - ts.perfLogger.logEvent("ReadDir: " + path); - return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); }); + return getAccessibleFileSystemEntries(path).directories.slice(); } function realpath(path) { try { @@ -6697,7 +6713,7 @@ var ts; Keywords_cannot_contain_escape_characters: diag(1260, ts.DiagnosticCategory.Error, "Keywords_cannot_contain_escape_characters_1260", "Keywords cannot contain escape characters."), Already_included_file_name_0_differs_from_file_name_1_only_in_casing: diag(1261, ts.DiagnosticCategory.Error, "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", "Already included file name '{0}' differs from file name '{1}' only in casing."), with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."), - await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."), + await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules: diag(1308, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", "'await' expressions are only allowed within async functions and at the top levels of modules."), can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."), The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."), Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."), @@ -6745,14 +6761,13 @@ var ts; An_enum_member_name_must_be_followed_by_a_or: diag(1357, ts.DiagnosticCategory.Error, "An_enum_member_name_must_be_followed_by_a_or_1357", "An enum member name must be followed by a ',', '=', or '}'."), Tagged_template_expressions_are_not_permitted_in_an_optional_chain: diag(1358, ts.DiagnosticCategory.Error, "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", "Tagged template expressions are not permitted in an optional chain."), Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here: diag(1359, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", "Identifier expected. '{0}' is a reserved word that cannot be used here."), - Did_you_mean_to_parenthesize_this_function_type: diag(1360, ts.DiagnosticCategory.Error, "Did_you_mean_to_parenthesize_this_function_type_1360", "Did you mean to parenthesize this function type?"), Type_only_0_must_reference_a_type_but_1_is_a_value: diag(1361, ts.DiagnosticCategory.Error, "Type_only_0_must_reference_a_type_but_1_is_a_value_1361", "Type-only {0} must reference a type, but '{1}' is a value."), Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported: diag(1362, ts.DiagnosticCategory.Error, "Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported_1362", "Enum '{0}' cannot be used as a value because only its type has been imported."), A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both: diag(1363, ts.DiagnosticCategory.Error, "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", "A type-only import can specify a default import or named bindings, but not both."), Convert_to_type_only_export: diag(1364, ts.DiagnosticCategory.Message, "Convert_to_type_only_export_1364", "Convert to type-only export"), Convert_all_re_exported_types_to_type_only_exports: diag(1365, ts.DiagnosticCategory.Message, "Convert_all_re_exported_types_to_type_only_exports_1365", "Convert all re-exported types to type-only exports"), Split_into_two_separate_import_declarations: diag(1366, ts.DiagnosticCategory.Message, "Split_into_two_separate_import_declarations_1366", "Split into two separate import declarations"), - Split_all_invalid_type_only_imports: diag(1377, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1377", "Split all invalid type-only imports"), + Split_all_invalid_type_only_imports: diag(1367, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1367", "Split all invalid type-only imports"), Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types: diag(1368, ts.DiagnosticCategory.Message, "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_1368", "Specify emit/checking behavior for imports that are only used for types"), Did_you_mean_0: diag(1369, ts.DiagnosticCategory.Message, "Did_you_mean_0_1369", "Did you mean '{0}'?"), Only_ECMAScript_imports_may_use_import_type: diag(1370, ts.DiagnosticCategory.Error, "Only_ECMAScript_imports_may_use_import_type_1370", "Only ECMAScript imports may use 'import type'."), @@ -6760,7 +6775,8 @@ var ts; This_import_may_be_converted_to_a_type_only_import: diag(1372, ts.DiagnosticCategory.Suggestion, "This_import_may_be_converted_to_a_type_only_import_1372", "This import may be converted to a type-only import."), Convert_to_type_only_import: diag(1373, ts.DiagnosticCategory.Message, "Convert_to_type_only_import_1373", "Convert to type-only import"), Convert_all_imports_not_used_as_a_value_to_type_only_imports: diag(1374, ts.DiagnosticCategory.Message, "Convert_all_imports_not_used_as_a_value_to_type_only_imports_1374", "Convert all imports not used as a value to type-only imports"), - await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher: diag(1375, ts.DiagnosticCategory.Error, "await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnex_1375", "'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher."), + await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module: diag(1375, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."), + Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher: diag(1376, ts.DiagnosticCategory.Error, "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_t_1376", "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher."), The_types_of_0_are_incompatible_between_these_types: diag(2200, ts.DiagnosticCategory.Error, "The_types_of_0_are_incompatible_between_these_types_2200", "The types of '{0}' are incompatible between these types."), The_types_returned_by_0_are_incompatible_between_these_types: diag(2201, ts.DiagnosticCategory.Error, "The_types_returned_by_0_are_incompatible_between_these_types_2201", "The types returned by '{0}' are incompatible between these types."), Call_signature_return_types_0_and_1_are_incompatible: diag(2202, ts.DiagnosticCategory.Error, "Call_signature_return_types_0_and_1_are_incompatible_2202", "Call signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true), @@ -7706,7 +7722,7 @@ var ts; Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"), Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"), Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"), - Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'"), + Remove_unused_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_unused_declaration_for_Colon_0_90004", "Remove unused declaration for: '{0}'"), Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"), Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"), Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"), @@ -7829,10 +7845,12 @@ var ts; Prefix_with_declare: diag(95094, ts.DiagnosticCategory.Message, "Prefix_with_declare_95094", "Prefix with 'declare'"), Prefix_all_incorrect_property_declarations_with_declare: diag(95095, ts.DiagnosticCategory.Message, "Prefix_all_incorrect_property_declarations_with_declare_95095", "Prefix all incorrect property declarations with 'declare'"), Convert_to_template_string: diag(95096, ts.DiagnosticCategory.Message, "Convert_to_template_string_95096", "Convert to template string"), + Add_export_to_make_this_file_into_a_module: diag(95097, ts.DiagnosticCategory.Message, "Add_export_to_make_this_file_into_a_module_95097", "Add 'export {}' to make this file into a module"), + Set_the_target_option_in_your_configuration_file_to_0: diag(95098, ts.DiagnosticCategory.Message, "Set_the_target_option_in_your_configuration_file_to_0_95098", "Set the 'target' option in your configuration file to '{0}'"), + Set_the_module_option_in_your_configuration_file_to_0: diag(95099, ts.DiagnosticCategory.Message, "Set_the_module_option_in_your_configuration_file_to_0_95099", "Set the 'module' option in your configuration file to '{0}'"), No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."), Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."), JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array: diag(18007, ts.DiagnosticCategory.Error, "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", "JSX expressions may not use the comma operator. Did you mean to write an array?"), - can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Private_identifiers_cannot_be_used_as_parameters: diag(18009, ts.DiagnosticCategory.Error, "Private_identifiers_cannot_be_used_as_parameters_18009", "Private identifiers cannot be used as parameters"), An_accessibility_modifier_cannot_be_used_with_a_private_identifier: diag(18010, ts.DiagnosticCategory.Error, "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", "An accessibility modifier cannot be used with a private identifier."), The_operand_of_a_delete_operator_cannot_be_a_private_identifier: diag(18011, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", "The operand of a 'delete' operator cannot be a private identifier."), @@ -7847,6 +7865,7 @@ var ts; A_method_cannot_be_named_with_a_private_identifier: diag(18022, ts.DiagnosticCategory.Error, "A_method_cannot_be_named_with_a_private_identifier_18022", "A method cannot be named with a private identifier."), An_accessor_cannot_be_named_with_a_private_identifier: diag(18023, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_named_with_a_private_identifier_18023", "An accessor cannot be named with a private identifier."), An_enum_member_cannot_be_named_with_a_private_identifier: diag(18024, ts.DiagnosticCategory.Error, "An_enum_member_cannot_be_named_with_a_private_identifier_18024", "An enum member cannot be named with a private identifier."), + can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Compiler_reserves_name_0_when_emitting_private_identifier_downlevel: diag(18027, ts.DiagnosticCategory.Error, "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", "Compiler reserves name '{0}' when emitting private identifier downlevel."), Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher: diag(18028, ts.DiagnosticCategory.Error, "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", "Private identifiers are only available when targeting ECMAScript 2015 and higher."), Private_identifiers_are_not_allowed_in_variable_declarations: diag(18029, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_in_variable_declarations_18029", "Private identifiers are not allowed in variable declarations."), @@ -26038,6 +26057,7 @@ var ts; error: 2 /* Error */ }), affectsEmit: true, + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types }, @@ -26295,12 +26315,15 @@ var ts; { name: "experimentalDecorators", type: "boolean", + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", + affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, @@ -26314,6 +26337,7 @@ var ts; { name: "resolveJsonModule", type: "boolean", + affectsModuleResolution: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Include_modules_imported_with_json_extension }, @@ -26518,6 +26542,7 @@ var ts; name: "useDefineForClassFields", type: "boolean", affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Emit_class_fields_with_Define_instead_of_Set, }, @@ -30394,7 +30419,7 @@ var ts; case 104 /* ThisKeyword */: case 194 /* PropertyAccessExpression */: case 195 /* ElementAccessExpression */: - return isNarrowableReference(expr); + return containsNarrowableReference(expr); case 196 /* CallExpression */: return hasNarrowableArgument(expr); case 200 /* ParenthesizedExpression */: @@ -30411,20 +30436,22 @@ var ts; function isNarrowableReference(expr) { return expr.kind === 75 /* Identifier */ || expr.kind === 104 /* ThisKeyword */ || expr.kind === 102 /* SuperKeyword */ || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || - ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) || - ts.isOptionalChain(expr); + ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression); + } + function containsNarrowableReference(expr) { + return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); } function hasNarrowableArgument(expr) { if (expr.arguments) { for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) { var argument = _a[_i]; - if (isNarrowableReference(argument)) { + if (containsNarrowableReference(argument)) { return true; } } } if (expr.expression.kind === 194 /* PropertyAccessExpression */ && - isNarrowableReference(expr.expression.expression)) { + containsNarrowableReference(expr.expression.expression)) { return true; } return false; @@ -30438,7 +30465,7 @@ var ts; function isNarrowingBinaryExpression(expr) { switch (expr.operatorToken.kind) { case 62 /* EqualsToken */: - return isNarrowableReference(expr.left); + return containsNarrowableReference(expr.left); case 34 /* EqualsEqualsToken */: case 35 /* ExclamationEqualsToken */: case 36 /* EqualsEqualsEqualsToken */: @@ -30466,7 +30493,7 @@ var ts; return isNarrowableOperand(expr.right); } } - return isNarrowableReference(expr); + return containsNarrowableReference(expr); } function createBranchLabel() { return initFlowNode({ flags: 4 /* BranchLabel */, antecedents: undefined }); @@ -33878,6 +33905,7 @@ var ts; var currentNode; var emptySymbols = ts.createSymbolTable(); var identityMapper = ts.identity; + var arrayVariances = [1 /* Covariant */]; var compilerOptions = host.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); @@ -34126,9 +34154,12 @@ var ts; isArrayLikeType: isArrayLikeType, isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant, getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes, - getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); }, + getSuggestedSymbolForNonexistentProperty: getSuggestedSymbolForNonexistentProperty, + getSuggestionForNonexistentProperty: getSuggestionForNonexistentProperty, + getSuggestedSymbolForNonexistentSymbol: function (location, name, meaning) { return getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, - getSuggestionForNonexistentExport: function (node, target) { return getSuggestionForNonexistentExport(node, target); }, + getSuggestedSymbolForNonexistentModule: getSuggestedSymbolForNonexistentModule, + getSuggestionForNonexistentExport: getSuggestionForNonexistentExport, getBaseConstraintOfType: getBaseConstraintOfType, getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; }, resolveName: function (name, location, meaning, excludeGlobals) { @@ -35720,9 +35751,11 @@ var ts; // if symbolFromVariable is export - get its final target symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias); var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias); - // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default - if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default" /* Default */) { - symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + if (symbolFromModule === undefined && name.escapedText === "default" /* Default */) { + var file = ts.find(moduleSymbol.declarations, ts.isSourceFile); + if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) { + symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + } } var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : @@ -45363,8 +45396,9 @@ var ts; } /** We approximate own properties as non-methods plus methods that are inside the object literal */ function isSpreadableProperty(prop) { - return !(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || - !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); }); + return !ts.some(prop.declarations, ts.isPrivateIdentifierPropertyDeclaration) && + (!(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || + !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); })); } function getSpreadSymbol(prop, readonly) { var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */); @@ -47690,6 +47724,9 @@ var ts; source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { var variances = getAliasVariances(source.aliasSymbol); + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -47884,6 +47921,12 @@ var ts; // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. var variances = getVariances(source.target); + // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This + // effectively means we measure variance only from type parameter occurrences that aren't nested in + // recursive instantiations of the generic type. + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -48669,8 +48712,7 @@ var ts; // a digest of the type comparisons that occur for each type argument when instantiations of the // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function - // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function - // has been invoked recursively for the given generic type. + // returns the emptyArray singleton when invoked recursively for the given generic type. function getVariancesWorker(typeParameters, cache, createMarkerType) { if (typeParameters === void 0) { typeParameters = ts.emptyArray; } var variances = cache.variances; @@ -48717,9 +48759,9 @@ var ts; return variances; } function getVariances(type) { - // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters) + // Arrays and tuples are known to be covariant, no need to spend time computing this. if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8 /* Tuple */) { - return ts.emptyArray; + return arrayVariances; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); } @@ -52425,24 +52467,7 @@ var ts; } } else if (!assumeInitialized && !(getFalsyFlags(type) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) { - var diag = error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); - // See GH:32846 - if the user is using a variable whose type is () => T1 | ... | undefined - // they may have meant to specify the type as (() => T1 | ...) | undefined - // This is assumed if: the type is a FunctionType, the return type is a Union, the last constituent of - // the union is `undefined` - if (type.symbol && type.symbol.declarations.length === 1 && ts.isFunctionTypeNode(type.symbol.declarations[0])) { - var funcTypeNode = type.symbol.declarations[0]; - var returnType = getReturnTypeFromAnnotation(funcTypeNode); - if (returnType && returnType.flags & 1048576 /* Union */) { - var unionTypes_3 = funcTypeNode.type.types; - if (unionTypes_3 && unionTypes_3[unionTypes_3.length - 1].kind === 146 /* UndefinedKeyword */) { - var parenedFuncType = ts.getMutableClone(funcTypeNode); - // Highlight to the end of the second to last constituent of the union - parenedFuncType.end = unionTypes_3[unionTypes_3.length - 2].end; - ts.addRelatedInfo(diag, ts.createDiagnosticForNode(parenedFuncType, ts.Diagnostics.Did_you_mean_to_parenthesize_this_function_type)); - } - } - } + error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; } @@ -58057,12 +58082,17 @@ var ts; if (!(node.flags & 32768 /* AwaitContext */)) { if (isTopLevelAwait(node)) { var sourceFile = ts.getSourceFileOfNode(node); - if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || - languageVersion < 4 /* ES2017 */ || - !ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { - if (!hasParseDiagnostics(sourceFile)) { - var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher); + if (!hasParseDiagnostics(sourceFile)) { + var span = void 0; + if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + if (!span) + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); + diagnostics.add(diagnostic); + } + if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || languageVersion < 4 /* ES2017 */) { + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher); diagnostics.add(diagnostic); } } @@ -58072,7 +58102,7 @@ var ts; var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); var func = ts.getContainingFunction(node); if (func && func.kind !== 162 /* Constructor */ && (ts.getFunctionFlags(func) & 2 /* Async */) === 0) { var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async); @@ -96836,12 +96866,12 @@ var ts; if (!program || hasChangedAutomaticTypeDirectiveNames) { return false; } - // If number of files in the program do not match, it is not up-to-date - if (program.getRootFileNames().length !== rootFileNames.length) { + // If root file names don't match + if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) { return false; } var seenResolvedRefs; - // If project references dont match + // If project references don't match if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) { return false; } @@ -108965,7 +108995,7 @@ var ts; var contextToken = previousToken; // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. - if (contextToken && position <= contextToken.end && (ts.isIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) { + if (contextToken && position <= contextToken.end && (ts.isIdentifierOrPrivateIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) { var start_1 = ts.timestamp(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined); // TODO: GH#18217 log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_1)); @@ -109208,7 +109238,7 @@ var ts; } } } - if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */)) { + if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */) && contextToken === node.getChildAt(1)) { var completion = (node.keywordToken === 99 /* NewKeyword */) ? "target" : "meta"; symbols.push(typeChecker.createSymbol(4 /* Property */, ts.escapeLeadingUnderscores(completion))); return; @@ -110532,6 +110562,8 @@ var ts; if (!contextToken) return undefined; switch (contextToken.kind) { + case 62 /* EqualsToken */: // class c { public prop = | /* global completions */ } + return undefined; case 26 /* SemicolonToken */: // class c {getValue(): number; | } case 19 /* CloseBraceToken */: // class c { method() { } | } // class c { method() { } b| } @@ -110658,8 +110690,12 @@ var ts; case 103 /* SwitchKeyword */: return useParent(node.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); case 78 /* CaseKeyword */: - case 84 /* DefaultKeyword */: - return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + case 84 /* DefaultKeyword */: { + if (ts.isDefaultClause(node.parent) || ts.isCaseClause(node.parent)) { + return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + } + return undefined; + } case 77 /* BreakKeyword */: case 82 /* ContinueKeyword */: return useParent(node.parent, ts.isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences); @@ -112007,9 +112043,7 @@ var ts; return __assign(__assign({}, documentSpan), { isWriteAccess: false, isDefinition: false }); } var kind = entry.kind, node = entry.node; - return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: node.kind === 84 /* DefaultKeyword */ - || !!ts.getDeclarationFromName(node) - || ts.isLiteralComputedPropertyDeclarationName(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined }); + return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: isDefinitionForReference(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined }); } FindAllReferences.toReferenceEntry = toReferenceEntry; function entryToDocumentSpan(entry) { @@ -112117,6 +112151,12 @@ var ts; var decl = ts.getDeclarationFromName(node); return !!decl && declarationIsWriteAccess(decl) || node.kind === 84 /* DefaultKeyword */ || ts.isWriteAccess(node); } + function isDefinitionForReference(node) { + return node.kind === 84 /* DefaultKeyword */ + || !!ts.getDeclarationFromName(node) + || ts.isLiteralComputedPropertyDeclarationName(node) + || (node.kind === 129 /* ConstructorKeyword */ && ts.isConstructorDeclaration(node.parent)); + } /** * True if 'decl' provides a value, as in `function f() {}`; * false if 'decl' is just a location for a future write, as in 'let x;' @@ -122412,27 +122452,62 @@ var ts; this.insertNodeAtStartWorker(sourceFile, obj, newElement); }; ChangeTracker.prototype.insertNodeAtStartWorker = function (sourceFile, cls, newElement) { - var clsStart = cls.getStart(sourceFile); - var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) - + this.formatContext.options.indentSize; - this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, __assign({ indentation: indentation }, this.getInsertNodeAtStartPrefixSuffix(sourceFile, cls))); - }; - ChangeTracker.prototype.getInsertNodeAtStartPrefixSuffix = function (sourceFile, cls) { - var comma = ts.isObjectLiteralExpression(cls) ? "," : ""; - if (getMembersOrProperties(cls).length === 0) { - if (ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile })) { - // For `class C {\n}`, don't add the trailing "\n" - var _a = getClassOrObjectBraceEnds(cls, sourceFile), open = _a[0], close = _a[1]; - var shouldSuffix = open && close && ts.positionsAreOnSameLine(open, close, sourceFile); - return { prefix: this.newLineCharacter, suffix: comma + (shouldSuffix ? this.newLineCharacter : "") }; + var _a; + var indentation = (_a = this.guessIndentationFromExistingMembers(sourceFile, cls)) !== null && _a !== void 0 ? _a : this.computeIndentationForNewMember(sourceFile, cls); + this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, this.getInsertNodeAtStartInsertOptions(sourceFile, cls, indentation)); + }; + /** + * Tries to guess the indentation from the existing members of a class/interface/object. All members must be on + * new lines and must share the same indentation. + */ + ChangeTracker.prototype.guessIndentationFromExistingMembers = function (sourceFile, cls) { + var indentation; + var lastRange = cls; + for (var _i = 0, _a = getMembersOrProperties(cls); _i < _a.length; _i++) { + var member = _a[_i]; + if (ts.rangeStartPositionsAreOnSameLine(lastRange, member, sourceFile)) { + // each indented member must be on a new line + return undefined; } - else { - return { prefix: "", suffix: comma + this.newLineCharacter }; + var memberStart = member.getStart(sourceFile); + var memberIndentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); + if (indentation === undefined) { + indentation = memberIndentation; } + else if (memberIndentation !== indentation) { + // indentation of multiple members is not consistent + return undefined; + } + lastRange = member; } - else { - return { prefix: this.newLineCharacter, suffix: comma }; - } + return indentation; + }; + ChangeTracker.prototype.computeIndentationForNewMember = function (sourceFile, cls) { + var _a; + var clsStart = cls.getStart(sourceFile); + return ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) + + ((_a = this.formatContext.options.indentSize) !== null && _a !== void 0 ? _a : 4); + }; + ChangeTracker.prototype.getInsertNodeAtStartInsertOptions = function (sourceFile, cls, indentation) { + // Rules: + // - Always insert leading newline. + // - For object literals: + // - Add a trailing comma if there are existing members in the node, or the source file is not a JSON file + // (because trailing commas are generally illegal in a JSON file). + // - Add a leading comma if the source file is not a JSON file, there are existing insertions, + // and the node is empty (because we didn't add a trailing comma per the previous rule). + // - Only insert a trailing newline if body is single-line and there are no other insertions for the node. + // NOTE: This is handled in `finishClassesWithNodesInsertedAtStart`. + var members = getMembersOrProperties(cls); + var isEmpty = members.length === 0; + var isFirstInsertion = ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile }); + var insertTrailingComma = ts.isObjectLiteralExpression(cls) && (!ts.isJsonSourceFile(sourceFile) || !isEmpty); + var insertLeadingComma = ts.isObjectLiteralExpression(cls) && ts.isJsonSourceFile(sourceFile) && isEmpty && !isFirstInsertion; + return { + indentation: indentation, + prefix: (insertLeadingComma ? "," : "") + this.newLineCharacter, + suffix: insertTrailingComma ? "," : "" + }; }; ChangeTracker.prototype.insertNodeAfterComma = function (sourceFile, after, newNode) { var endPosition = this.insertNodeAfterWorker(sourceFile, this.nextCommaToken(sourceFile, after) || after, newNode); @@ -122634,9 +122709,16 @@ var ts; this.classesWithNodesInsertedAtStart.forEach(function (_a) { var node = _a.node, sourceFile = _a.sourceFile; var _b = getClassOrObjectBraceEnds(node, sourceFile), openBraceEnd = _b[0], closeBraceEnd = _b[1]; - // For `class C { }` remove the whitespace inside the braces. - if (openBraceEnd && closeBraceEnd && ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) { - _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); + if (openBraceEnd !== undefined && closeBraceEnd !== undefined) { + var isEmpty = getMembersOrProperties(node).length === 0; + var isSingleLine = ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile); + if (isEmpty && isSingleLine && openBraceEnd !== closeBraceEnd - 1) { + // For `class C { }` remove the whitespace inside the braces. + _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); + } + if (isSingleLine) { + _this.insertText(sourceFile, closeBraceEnd - 1, _this.newLineCharacter); + } } }); }; @@ -123212,10 +123294,10 @@ var ts; ? ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag[0]), diag.slice(1)) : ts.getLocaleSpecificMessage(diag); } - function createCodeFixActionNoFixId(fixName, changes, description) { + function createCodeFixActionWithoutFixAll(fixName, changes, description) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined); } - codefix.createCodeFixActionNoFixId = createCodeFixActionNoFixId; + codefix.createCodeFixActionWithoutFixAll = createCodeFixActionWithoutFixAll; function createCodeFixAction(fixName, changes, description, fixId, fixAllDescription, command) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, diagnosticToString(fixAllDescription), command); } @@ -123241,8 +123323,26 @@ var ts; return ts.arrayFrom(errorCodeToFixes.keys()); } codefix.getSupportedErrorCodes = getSupportedErrorCodes; + function removeFixIdIfFixAllUnavailable(registration, diagnostics) { + var errorCodes = registration.errorCodes; + var maybeFixableDiagnostics = 0; + for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { + var diag = diagnostics_1[_i]; + if (ts.contains(errorCodes, diag.code)) + maybeFixableDiagnostics++; + if (maybeFixableDiagnostics > 1) + break; + } + var fixAllUnavailable = maybeFixableDiagnostics < 2; + return function (_a) { + var fixId = _a.fixId, fixAllDescription = _a.fixAllDescription, action = __rest(_a, ["fixId", "fixAllDescription"]); + return fixAllUnavailable ? action : __assign(__assign({}, action), { fixId: fixId, fixAllDescription: fixAllDescription }); + }; + } function getFixes(context) { - return ts.flatMap(errorCodeToFixes.get(String(context.errorCode)) || ts.emptyArray, function (f) { return f.getCodeActions(context); }); + var diagnostics = getDiagnostics(context); + var registrations = errorCodeToFixes.get(String(context.errorCode)); + return ts.flatMap(registrations, function (f) { return ts.map(f.getCodeActions(context), removeFixIdIfFixAllUnavailable(f, diagnostics)); }); } codefix.getFixes = getFixes; function getAllFixes(context) { @@ -123264,16 +123364,19 @@ var ts; return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands); } codefix.codeFixAll = codeFixAll; - function eachDiagnostic(_a, errorCodes, cb) { - var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken; - for (var _i = 0, _b = program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); _i < _b.length; _i++) { - var diag = _b[_i]; + function eachDiagnostic(context, errorCodes, cb) { + for (var _i = 0, _a = getDiagnostics(context); _i < _a.length; _i++) { + var diag = _a[_i]; if (ts.contains(errorCodes, diag.code)) { cb(diag); } } } codefix.eachDiagnostic = eachDiagnostic; + function getDiagnostics(_a) { + var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken; + return program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); + } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ @@ -123330,6 +123433,28 @@ var ts; })(ts || (ts = {})); /* @internal */ var ts; +(function (ts) { + var codefix; + (function (codefix) { + codefix.registerCodeFix({ + errorCodes: [ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code], + getCodeActions: function (context) { + var sourceFile = context.sourceFile; + var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { + var exportDeclaration = ts.createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, ts.createNamedExports([]), + /*moduleSpecifier*/ undefined, + /*isTypeOnly*/ false); + changes.insertNodeAtEndOfScope(sourceFile, sourceFile, exportDeclaration); + }); + return [codefix.createCodeFixActionWithoutFixAll("addEmptyExportDeclaration", changes, ts.Diagnostics.Add_export_to_make_this_file_into_a_module)]; + }, + }); + })(codefix = ts.codefix || (ts.codefix = {})); +})(ts || (ts = {})); +/* @internal */ +var ts; (function (ts) { var codefix; (function (codefix) { @@ -123400,7 +123525,9 @@ var ts; makeChange(t, errorCode, sourceFile, checker, expression, fixedDeclarations); } }); - return codefix.createCodeFixActionNoFixId("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 + // No fix-all because it will already be included once with the use site fix, + // and for simplicity the fix-all doesn‘t let the user choose between use-site and declaration-site fixes. + return codefix.createCodeFixActionWithoutFixAll("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 ? [ts.Diagnostics.Add_await_to_initializer_for_0, awaitableInitializers.initializers[0].declarationSymbol.name] : ts.Diagnostics.Add_await_to_initializers); } @@ -123619,7 +123746,7 @@ var ts; if (forInitializer) return applyChange(changeTracker, forInitializer, sourceFile, fixedNodes); var parent = token.parent; - if (ts.isBinaryExpression(parent) && ts.isExpressionStatement(parent.parent)) { + if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isExpressionStatement(parent.parent)) { return applyChange(changeTracker, token, sourceFile, fixedNodes); } if (ts.isArrayLiteralExpression(parent)) { @@ -123681,7 +123808,9 @@ var ts; if (expression.operatorToken.kind === 27 /* CommaToken */) { return ts.every([expression.left, expression.right], function (expression) { return expressionCouldBeVariableDeclaration(expression, checker); }); } - return ts.isIdentifier(expression.left) && !checker.getSymbolAtLocation(expression.left); + return expression.operatorToken.kind === 62 /* EqualsToken */ + && ts.isIdentifier(expression.left) + && !checker.getSymbolAtLocation(expression.left); } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); @@ -125672,7 +125801,7 @@ var ts; } }); // No support for fix-all since this applies to the whole file at once anyway. - return [codefix.createCodeFixActionNoFixId("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)]; + return [codefix.createCodeFixActionWithoutFixAll("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)]; }, }); function fixImportOfModuleExports(importingFile, exportingFile, changes, quotePreference) { @@ -126271,7 +126400,8 @@ var ts; (function (ts) { var codefix; (function (codefix) { - codefix.importFixId = "fixMissingImport"; + codefix.importFixName = "import"; + var importFixId = "fixMissingImport"; var errorCodes = [ ts.Diagnostics.Cannot_find_name_0.code, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, @@ -126292,7 +126422,7 @@ var ts; var quotePreference = ts.getQuotePreference(sourceFile, preferences); return fixes.map(function (fix) { return codeActionForFix(context, sourceFile, symbolName, fix, quotePreference); }); }, - fixIds: [codefix.importFixId], + fixIds: [importFixId], getAllCodeActions: function (context) { var sourceFile = context.sourceFile, preferences = context.preferences; // Namespace fixes don't conflict, so just build a list. @@ -126724,7 +126854,7 @@ var ts; var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) { diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, quotePreference); }); - return codefix.createCodeFixAction("import", changes, diag, codefix.importFixId, ts.Diagnostics.Add_all_missing_imports); + return codefix.createCodeFixAction(codefix.importFixName, changes, diag, importFixId, ts.Diagnostics.Add_all_missing_imports); } function codeActionForFixWorker(changes, sourceFile, symbolName, fix, quotePreference) { switch (fix.kind) { @@ -127022,17 +127152,17 @@ var ts; var info = getInfo(sourceFile, context.span.start, context); if (!info) return undefined; - var node = info.node, suggestion = info.suggestion; + var node = info.node, suggestedSymbol = info.suggestedSymbol; var target = context.host.getCompilationSettings().target; - var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestion, target); }); - return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, suggestion], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)]; + var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestedSymbol, target); }); + return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, ts.symbolName(suggestedSymbol)], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)]; }, fixIds: [fixId], getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { var info = getInfo(diag.file, diag.start, context); var target = context.host.getCompilationSettings().target; if (info) - doChange(changes, context.sourceFile, info.node, info.suggestion, target); + doChange(changes, context.sourceFile, info.node, info.suggestedSymbol, target); }); }, }); function getInfo(sourceFile, pos, context) { @@ -127041,34 +127171,42 @@ var ts; // ^^^^^^^ var node = ts.getTokenAtPosition(sourceFile, pos); var checker = context.program.getTypeChecker(); - var suggestion; + var suggestedSymbol; if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) { - ts.Debug.assert(node.kind === 75 /* Identifier */, "Expected an identifier for spelling (property access)"); + ts.Debug.assert(ts.isIdentifierOrPrivateIdentifier(node), "Expected an identifier for spelling (property access)"); var containingType = checker.getTypeAtLocation(node.parent.expression); if (node.parent.flags & 32 /* OptionalChain */) { containingType = checker.getNonNullableType(containingType); } - suggestion = checker.getSuggestionForNonexistentProperty(node, containingType); + var name = node; + suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(name, containingType); } else if (ts.isImportSpecifier(node.parent) && node.parent.name === node) { ts.Debug.assert(node.kind === 75 /* Identifier */, "Expected an identifier for spelling (import)"); var importDeclaration = ts.findAncestor(node, ts.isImportDeclaration); var resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration); if (resolvedSourceFile && resolvedSourceFile.symbol) { - suggestion = checker.getSuggestionForNonexistentExport(node, resolvedSourceFile.symbol); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(node, resolvedSourceFile.symbol); } } else { var meaning = ts.getMeaningFromLocation(node); var name = ts.getTextOfNode(node); ts.Debug.assert(name !== undefined, "name should be defined"); - suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); } - return suggestion === undefined ? undefined : { node: node, suggestion: suggestion }; + return suggestedSymbol === undefined ? undefined : { node: node, suggestedSymbol: suggestedSymbol }; } - function doChange(changes, sourceFile, node, suggestion, target) { + function doChange(changes, sourceFile, node, suggestedSymbol, target) { + var suggestion = ts.symbolName(suggestedSymbol); if (!ts.isIdentifierText(suggestion, target) && ts.isPropertyAccessExpression(node.parent)) { - changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion))); + var valDecl = suggestedSymbol.valueDeclaration; + if (ts.isNamedDeclaration(valDecl) && ts.isPrivateIdentifier(valDecl.name)) { + changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion)); + } + else { + changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion))); + } } else { changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion)); @@ -127332,7 +127470,7 @@ var ts; /*modifiers*/ undefined, [indexingParameter], typeNode); var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.insertNodeAtClassStart(declSourceFile, classDeclaration, indexSignature); }); // No fixId here because code-fix-all currently only works on adding individual named properties. - return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]); + return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]); } function getActionForMethodDeclaration(context, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences) { // Private methods are not implemented yet. @@ -127617,7 +127755,7 @@ var ts; return undefined; } var changes = ts.textChanges.ChangeTracker.with(context, function (changeTracker) { return doChange(changeTracker, configFile); }); - return [codefix.createCodeFixActionNoFixId(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; + return [codefix.createCodeFixActionWithoutFixAll(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; }, fixIds: [fixId], getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes) { @@ -127651,7 +127789,7 @@ var ts; return doChange(changeTracker, configFile); }); return [ - codefix.createCodeFixActionNoFixId(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) + codefix.createCodeFixActionWithoutFixAll(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) ]; }, fixIds: [fixID], @@ -127672,6 +127810,49 @@ var ts; })(ts || (ts = {})); /* @internal */ var ts; +(function (ts) { + var codefix; + (function (codefix) { + codefix.registerCodeFix({ + errorCodes: [ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code], + getCodeActions: function (context) { + var compilerOptions = context.program.getCompilerOptions(); + var configFile = compilerOptions.configFile; + if (configFile === undefined) { + return undefined; + } + var codeFixes = []; + var moduleKind = ts.getEmitModuleKind(compilerOptions); + var moduleOutOfRange = moduleKind >= ts.ModuleKind.ES2015 && moduleKind < ts.ModuleKind.ESNext; + if (moduleOutOfRange) { + var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { + codefix.setJsonCompilerOptionValue(changes, configFile, "module", ts.createStringLiteral("esnext")); + }); + codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixModuleOption", changes, [ts.Diagnostics.Set_the_module_option_in_your_configuration_file_to_0, "esnext"])); + } + var target = ts.getEmitScriptTarget(compilerOptions); + var targetOutOfRange = target < 4 /* ES2017 */ || target > 99 /* ESNext */; + if (targetOutOfRange) { + var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) { + var configObject = ts.getTsConfigObjectLiteralExpression(configFile); + if (!configObject) + return; + var options = [["target", ts.createStringLiteral("es2017")]]; + if (moduleKind === ts.ModuleKind.CommonJS) { + // Ensure we preserve the default module kind (commonjs), as targets >= ES2015 have a default module kind of es2015. + options.push(["module", ts.createStringLiteral("commonjs")]); + } + codefix.setJsonCompilerOptionValues(tracker, configFile, options); + }); + codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixTargetOption", changes, [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0, "es2017"])); + } + return codeFixes.length ? codeFixes : undefined; + } + }); + })(codefix = ts.codefix || (ts.codefix = {})); +})(ts || (ts = {})); +/* @internal */ +var ts; (function (ts) { var codefix; (function (codefix) { @@ -127824,7 +128005,7 @@ var ts; }); if (deletion.length) { var name = ts.isComputedPropertyName(token.parent) ? token.parent : token; - result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_declaration_for_Colon_0, name.getText(sourceFile)])); + result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_unused_declaration_for_Colon_0, name.getText(sourceFile)])); } } var prefix = ts.textChanges.ChangeTracker.with(context, function (t) { return tryPrefixDeclaration(t, errorCode, sourceFile, token); }); @@ -128185,7 +128366,7 @@ var ts; (function (codefix) { var fixId = "fixAwaitInSyncFunction"; var errorCodes = [ - ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function.code, + ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code, ]; codefix.registerCodeFix({ @@ -128277,7 +128458,7 @@ var ts; } var fixes = [ // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file. - codefix.createCodeFixActionNoFixId(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [ + codefix.createCodeFixActionWithoutFixAll(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [ ts.createTextChange(sourceFile.checkJsDirective ? ts.createTextSpanFromBounds(sourceFile.checkJsDirective.pos, sourceFile.checkJsDirective.end) : ts.createTextSpan(0, 0), "// @ts-nocheck" + ts.getNewLineOrDefaultFromHost(host, formatContext.options)), @@ -128544,29 +128725,37 @@ var ts; } return undefined; } - function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) { + function setJsonCompilerOptionValues(changeTracker, configFile, options) { var tsconfigObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile); if (!tsconfigObjectLiteral) return undefined; var compilerOptionsProperty = findJsonProperty(tsconfigObjectLiteral, "compilerOptions"); if (compilerOptionsProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral([ - createJsonPropertyAssignment(optionName, optionValue), - ]))); + changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral(options.map(function (_a) { + var optionName = _a[0], optionValue = _a[1]; + return createJsonPropertyAssignment(optionName, optionValue); + }), /*multiLine*/ true))); return; } var compilerOptions = compilerOptionsProperty.initializer; if (!ts.isObjectLiteralExpression(compilerOptions)) { return; } - var optionProperty = findJsonProperty(compilerOptions, optionName); - if (optionProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); - } - else { - changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + for (var _i = 0, options_1 = options; _i < options_1.length; _i++) { + var _a = options_1[_i], optionName = _a[0], optionValue = _a[1]; + var optionProperty = findJsonProperty(compilerOptions, optionName); + if (optionProperty === undefined) { + changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); + } + else { + changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + } } } + codefix.setJsonCompilerOptionValues = setJsonCompilerOptionValues; + function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) { + setJsonCompilerOptionValues(changeTracker, configFile, [[optionName, optionValue]]); + } codefix.setJsonCompilerOptionValue = setJsonCompilerOptionValue; function createJsonPropertyAssignment(name, initializer) { return ts.createPropertyAssignment(ts.createStringLiteral(name), initializer); @@ -128601,7 +128790,7 @@ var ts; } function createAction(context, sourceFile, node, replacement) { var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, node, replacement); }); - return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); + return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); } codefix.registerCodeFix({ errorCodes: [ @@ -128659,7 +128848,7 @@ var ts; if (ts.isExpression(expr) && !(ts.isNamedDeclaration(expr.parent) && expr.parent.name === expr)) { var sourceFile_1 = context.sourceFile; var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile_1, expr, ts.createPropertyAccess(expr, "default"), {}); }); - fixes.push(codefix.createCodeFixActionNoFixId(fixName, changes, ts.Diagnostics.Use_synthetic_default_member)); + fixes.push(codefix.createCodeFixActionWithoutFixAll(fixName, changes, ts.Diagnostics.Use_synthetic_default_member)); } return fixes; } @@ -137184,7 +137373,8 @@ var ts; server.TextStorage = TextStorage; /*@internal*/ function isDynamicFileName(fileName) { - return fileName[0] === "^"; + return fileName[0] === "^" || + (ts.stringContains(fileName, ":^") && !ts.stringContains(fileName, ts.directorySeparator)); } server.isDynamicFileName = isDynamicFileName; var ScriptInfo = /** @class */ (function () { @@ -140277,7 +140467,7 @@ var ts; // Closing file should trigger re-reading the file content from disk. This is // because the user may chose to discard the buffer content before saving // to the disk, and the server's version of the file can be out of sync. - var fileExists = this.host.fileExists(info.fileName); + var fileExists = info.isDynamic ? false : this.host.fileExists(info.fileName); info.close(fileExists); this.stopWatchingConfigFilesForClosedScriptInfo(info); var canonicalFileName = this.toCanonicalFileName(info.fileName); @@ -143277,7 +143467,11 @@ var ts; command: cmdName, request_seq: reqSeq, success: success, - updateGraphDurationMs: this.updateGraphDurationMs, + performanceData: !this.updateGraphDurationMs + ? undefined + : { + updateGraphDurationMs: this.updateGraphDurationMs, + }, }; if (success) { var metadata = void 0; diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index d85e5ebdb0eaf..31d6a57649771 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -63,6 +63,17 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || @@ -76,17 +87,6 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); -var __rest = (this && this.__rest) || function (s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; -}; /* @internal */ var ts; (function (ts) { @@ -1425,6 +1425,11 @@ var ts; return result; } ts.clone = clone; + /** + * Creates a new object by adding the own properties of `second`, then the own properties of `first`. + * + * NOTE: This means that if a property exists in both `first` and `second`, the property in `first` will be chosen. + */ function extend(first, second) { var result = {}; for (var id in second) { @@ -5745,10 +5750,13 @@ var ts; } } function readFileWorker(fileName, _encoding) { - if (!fileExists(fileName)) { + var buffer; + try { + buffer = _fs.readFileSync(fileName); + } + catch (e) { return undefined; } - var buffer = _fs.readFileSync(fileName); var len = buffer.length; if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) { // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js, @@ -5798,23 +5806,30 @@ var ts; function getAccessibleFileSystemEntries(path) { ts.perfLogger.logEvent("ReadDir: " + (path || ".")); try { - var entries = _fs.readdirSync(path || ".").sort(); + var entries = _fs.readdirSync(path || ".", { withFileTypes: true }); var files = []; var directories = []; for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { - var entry = entries_2[_i]; + var dirent = entries_2[_i]; + // withFileTypes is not supported before Node 10.10. + var entry = typeof dirent === "string" ? dirent : dirent.name; // This is necessary because on some file system node fails to exclude // "." and "..". See https://github.com/nodejs/node/issues/4002 if (entry === "." || entry === "..") { continue; } - var name = ts.combinePaths(path, entry); var stat = void 0; - try { - stat = _fs.statSync(name); + if (typeof dirent === "string" || dirent.isSymbolicLink()) { + var name = ts.combinePaths(path, entry); + try { + stat = _fs.statSync(name); + } + catch (e) { + continue; + } } - catch (e) { - continue; + else { + stat = dirent; } if (stat.isFile()) { files.push(entry); @@ -5823,6 +5838,8 @@ var ts; directories.push(entry); } } + files.sort(); + directories.sort(); return { files: files, directories: directories }; } catch (e) { @@ -5852,8 +5869,7 @@ var ts; return fileSystemEntryExists(path, 1 /* Directory */); } function getDirectories(path) { - ts.perfLogger.logEvent("ReadDir: " + path); - return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); }); + return getAccessibleFileSystemEntries(path).directories.slice(); } function realpath(path) { try { @@ -6847,7 +6863,7 @@ var ts; Keywords_cannot_contain_escape_characters: diag(1260, ts.DiagnosticCategory.Error, "Keywords_cannot_contain_escape_characters_1260", "Keywords cannot contain escape characters."), Already_included_file_name_0_differs_from_file_name_1_only_in_casing: diag(1261, ts.DiagnosticCategory.Error, "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", "Already included file name '{0}' differs from file name '{1}' only in casing."), with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."), - await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."), + await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules: diag(1308, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", "'await' expressions are only allowed within async functions and at the top levels of modules."), can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."), The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."), Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."), @@ -6895,14 +6911,13 @@ var ts; An_enum_member_name_must_be_followed_by_a_or: diag(1357, ts.DiagnosticCategory.Error, "An_enum_member_name_must_be_followed_by_a_or_1357", "An enum member name must be followed by a ',', '=', or '}'."), Tagged_template_expressions_are_not_permitted_in_an_optional_chain: diag(1358, ts.DiagnosticCategory.Error, "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", "Tagged template expressions are not permitted in an optional chain."), Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here: diag(1359, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", "Identifier expected. '{0}' is a reserved word that cannot be used here."), - Did_you_mean_to_parenthesize_this_function_type: diag(1360, ts.DiagnosticCategory.Error, "Did_you_mean_to_parenthesize_this_function_type_1360", "Did you mean to parenthesize this function type?"), Type_only_0_must_reference_a_type_but_1_is_a_value: diag(1361, ts.DiagnosticCategory.Error, "Type_only_0_must_reference_a_type_but_1_is_a_value_1361", "Type-only {0} must reference a type, but '{1}' is a value."), Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported: diag(1362, ts.DiagnosticCategory.Error, "Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported_1362", "Enum '{0}' cannot be used as a value because only its type has been imported."), A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both: diag(1363, ts.DiagnosticCategory.Error, "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", "A type-only import can specify a default import or named bindings, but not both."), Convert_to_type_only_export: diag(1364, ts.DiagnosticCategory.Message, "Convert_to_type_only_export_1364", "Convert to type-only export"), Convert_all_re_exported_types_to_type_only_exports: diag(1365, ts.DiagnosticCategory.Message, "Convert_all_re_exported_types_to_type_only_exports_1365", "Convert all re-exported types to type-only exports"), Split_into_two_separate_import_declarations: diag(1366, ts.DiagnosticCategory.Message, "Split_into_two_separate_import_declarations_1366", "Split into two separate import declarations"), - Split_all_invalid_type_only_imports: diag(1377, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1377", "Split all invalid type-only imports"), + Split_all_invalid_type_only_imports: diag(1367, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1367", "Split all invalid type-only imports"), Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types: diag(1368, ts.DiagnosticCategory.Message, "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_1368", "Specify emit/checking behavior for imports that are only used for types"), Did_you_mean_0: diag(1369, ts.DiagnosticCategory.Message, "Did_you_mean_0_1369", "Did you mean '{0}'?"), Only_ECMAScript_imports_may_use_import_type: diag(1370, ts.DiagnosticCategory.Error, "Only_ECMAScript_imports_may_use_import_type_1370", "Only ECMAScript imports may use 'import type'."), @@ -6910,7 +6925,8 @@ var ts; This_import_may_be_converted_to_a_type_only_import: diag(1372, ts.DiagnosticCategory.Suggestion, "This_import_may_be_converted_to_a_type_only_import_1372", "This import may be converted to a type-only import."), Convert_to_type_only_import: diag(1373, ts.DiagnosticCategory.Message, "Convert_to_type_only_import_1373", "Convert to type-only import"), Convert_all_imports_not_used_as_a_value_to_type_only_imports: diag(1374, ts.DiagnosticCategory.Message, "Convert_all_imports_not_used_as_a_value_to_type_only_imports_1374", "Convert all imports not used as a value to type-only imports"), - await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher: diag(1375, ts.DiagnosticCategory.Error, "await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnex_1375", "'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher."), + await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module: diag(1375, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."), + Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher: diag(1376, ts.DiagnosticCategory.Error, "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_t_1376", "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher."), The_types_of_0_are_incompatible_between_these_types: diag(2200, ts.DiagnosticCategory.Error, "The_types_of_0_are_incompatible_between_these_types_2200", "The types of '{0}' are incompatible between these types."), The_types_returned_by_0_are_incompatible_between_these_types: diag(2201, ts.DiagnosticCategory.Error, "The_types_returned_by_0_are_incompatible_between_these_types_2201", "The types returned by '{0}' are incompatible between these types."), Call_signature_return_types_0_and_1_are_incompatible: diag(2202, ts.DiagnosticCategory.Error, "Call_signature_return_types_0_and_1_are_incompatible_2202", "Call signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true), @@ -7856,7 +7872,7 @@ var ts; Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"), Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"), Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"), - Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'"), + Remove_unused_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_unused_declaration_for_Colon_0_90004", "Remove unused declaration for: '{0}'"), Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"), Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"), Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"), @@ -7979,10 +7995,12 @@ var ts; Prefix_with_declare: diag(95094, ts.DiagnosticCategory.Message, "Prefix_with_declare_95094", "Prefix with 'declare'"), Prefix_all_incorrect_property_declarations_with_declare: diag(95095, ts.DiagnosticCategory.Message, "Prefix_all_incorrect_property_declarations_with_declare_95095", "Prefix all incorrect property declarations with 'declare'"), Convert_to_template_string: diag(95096, ts.DiagnosticCategory.Message, "Convert_to_template_string_95096", "Convert to template string"), + Add_export_to_make_this_file_into_a_module: diag(95097, ts.DiagnosticCategory.Message, "Add_export_to_make_this_file_into_a_module_95097", "Add 'export {}' to make this file into a module"), + Set_the_target_option_in_your_configuration_file_to_0: diag(95098, ts.DiagnosticCategory.Message, "Set_the_target_option_in_your_configuration_file_to_0_95098", "Set the 'target' option in your configuration file to '{0}'"), + Set_the_module_option_in_your_configuration_file_to_0: diag(95099, ts.DiagnosticCategory.Message, "Set_the_module_option_in_your_configuration_file_to_0_95099", "Set the 'module' option in your configuration file to '{0}'"), No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."), Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."), JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array: diag(18007, ts.DiagnosticCategory.Error, "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", "JSX expressions may not use the comma operator. Did you mean to write an array?"), - can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Private_identifiers_cannot_be_used_as_parameters: diag(18009, ts.DiagnosticCategory.Error, "Private_identifiers_cannot_be_used_as_parameters_18009", "Private identifiers cannot be used as parameters"), An_accessibility_modifier_cannot_be_used_with_a_private_identifier: diag(18010, ts.DiagnosticCategory.Error, "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", "An accessibility modifier cannot be used with a private identifier."), The_operand_of_a_delete_operator_cannot_be_a_private_identifier: diag(18011, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", "The operand of a 'delete' operator cannot be a private identifier."), @@ -7997,6 +8015,7 @@ var ts; A_method_cannot_be_named_with_a_private_identifier: diag(18022, ts.DiagnosticCategory.Error, "A_method_cannot_be_named_with_a_private_identifier_18022", "A method cannot be named with a private identifier."), An_accessor_cannot_be_named_with_a_private_identifier: diag(18023, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_named_with_a_private_identifier_18023", "An accessor cannot be named with a private identifier."), An_enum_member_cannot_be_named_with_a_private_identifier: diag(18024, ts.DiagnosticCategory.Error, "An_enum_member_cannot_be_named_with_a_private_identifier_18024", "An enum member cannot be named with a private identifier."), + can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Compiler_reserves_name_0_when_emitting_private_identifier_downlevel: diag(18027, ts.DiagnosticCategory.Error, "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", "Compiler reserves name '{0}' when emitting private identifier downlevel."), Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher: diag(18028, ts.DiagnosticCategory.Error, "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", "Private identifiers are only available when targeting ECMAScript 2015 and higher."), Private_identifiers_are_not_allowed_in_variable_declarations: diag(18029, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_in_variable_declarations_18029", "Private identifiers are not allowed in variable declarations."), @@ -26188,6 +26207,7 @@ var ts; error: 2 /* Error */ }), affectsEmit: true, + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types }, @@ -26445,12 +26465,15 @@ var ts; { name: "experimentalDecorators", type: "boolean", + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", + affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, @@ -26464,6 +26487,7 @@ var ts; { name: "resolveJsonModule", type: "boolean", + affectsModuleResolution: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Include_modules_imported_with_json_extension }, @@ -26668,6 +26692,7 @@ var ts; name: "useDefineForClassFields", type: "boolean", affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Emit_class_fields_with_Define_instead_of_Set, }, @@ -30544,7 +30569,7 @@ var ts; case 104 /* ThisKeyword */: case 194 /* PropertyAccessExpression */: case 195 /* ElementAccessExpression */: - return isNarrowableReference(expr); + return containsNarrowableReference(expr); case 196 /* CallExpression */: return hasNarrowableArgument(expr); case 200 /* ParenthesizedExpression */: @@ -30561,20 +30586,22 @@ var ts; function isNarrowableReference(expr) { return expr.kind === 75 /* Identifier */ || expr.kind === 104 /* ThisKeyword */ || expr.kind === 102 /* SuperKeyword */ || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || - ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) || - ts.isOptionalChain(expr); + ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression); + } + function containsNarrowableReference(expr) { + return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); } function hasNarrowableArgument(expr) { if (expr.arguments) { for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) { var argument = _a[_i]; - if (isNarrowableReference(argument)) { + if (containsNarrowableReference(argument)) { return true; } } } if (expr.expression.kind === 194 /* PropertyAccessExpression */ && - isNarrowableReference(expr.expression.expression)) { + containsNarrowableReference(expr.expression.expression)) { return true; } return false; @@ -30588,7 +30615,7 @@ var ts; function isNarrowingBinaryExpression(expr) { switch (expr.operatorToken.kind) { case 62 /* EqualsToken */: - return isNarrowableReference(expr.left); + return containsNarrowableReference(expr.left); case 34 /* EqualsEqualsToken */: case 35 /* ExclamationEqualsToken */: case 36 /* EqualsEqualsEqualsToken */: @@ -30616,7 +30643,7 @@ var ts; return isNarrowableOperand(expr.right); } } - return isNarrowableReference(expr); + return containsNarrowableReference(expr); } function createBranchLabel() { return initFlowNode({ flags: 4 /* BranchLabel */, antecedents: undefined }); @@ -34028,6 +34055,7 @@ var ts; var currentNode; var emptySymbols = ts.createSymbolTable(); var identityMapper = ts.identity; + var arrayVariances = [1 /* Covariant */]; var compilerOptions = host.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); @@ -34276,9 +34304,12 @@ var ts; isArrayLikeType: isArrayLikeType, isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant, getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes, - getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); }, + getSuggestedSymbolForNonexistentProperty: getSuggestedSymbolForNonexistentProperty, + getSuggestionForNonexistentProperty: getSuggestionForNonexistentProperty, + getSuggestedSymbolForNonexistentSymbol: function (location, name, meaning) { return getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, - getSuggestionForNonexistentExport: function (node, target) { return getSuggestionForNonexistentExport(node, target); }, + getSuggestedSymbolForNonexistentModule: getSuggestedSymbolForNonexistentModule, + getSuggestionForNonexistentExport: getSuggestionForNonexistentExport, getBaseConstraintOfType: getBaseConstraintOfType, getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; }, resolveName: function (name, location, meaning, excludeGlobals) { @@ -35870,9 +35901,11 @@ var ts; // if symbolFromVariable is export - get its final target symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias); var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias); - // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default - if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default" /* Default */) { - symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + if (symbolFromModule === undefined && name.escapedText === "default" /* Default */) { + var file = ts.find(moduleSymbol.declarations, ts.isSourceFile); + if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) { + symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + } } var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : @@ -45513,8 +45546,9 @@ var ts; } /** We approximate own properties as non-methods plus methods that are inside the object literal */ function isSpreadableProperty(prop) { - return !(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || - !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); }); + return !ts.some(prop.declarations, ts.isPrivateIdentifierPropertyDeclaration) && + (!(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || + !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); })); } function getSpreadSymbol(prop, readonly) { var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */); @@ -47840,6 +47874,9 @@ var ts; source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { var variances = getAliasVariances(source.aliasSymbol); + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -48034,6 +48071,12 @@ var ts; // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. var variances = getVariances(source.target); + // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This + // effectively means we measure variance only from type parameter occurrences that aren't nested in + // recursive instantiations of the generic type. + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -48819,8 +48862,7 @@ var ts; // a digest of the type comparisons that occur for each type argument when instantiations of the // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function - // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function - // has been invoked recursively for the given generic type. + // returns the emptyArray singleton when invoked recursively for the given generic type. function getVariancesWorker(typeParameters, cache, createMarkerType) { if (typeParameters === void 0) { typeParameters = ts.emptyArray; } var variances = cache.variances; @@ -48867,9 +48909,9 @@ var ts; return variances; } function getVariances(type) { - // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters) + // Arrays and tuples are known to be covariant, no need to spend time computing this. if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8 /* Tuple */) { - return ts.emptyArray; + return arrayVariances; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); } @@ -52575,24 +52617,7 @@ var ts; } } else if (!assumeInitialized && !(getFalsyFlags(type) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) { - var diag = error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); - // See GH:32846 - if the user is using a variable whose type is () => T1 | ... | undefined - // they may have meant to specify the type as (() => T1 | ...) | undefined - // This is assumed if: the type is a FunctionType, the return type is a Union, the last constituent of - // the union is `undefined` - if (type.symbol && type.symbol.declarations.length === 1 && ts.isFunctionTypeNode(type.symbol.declarations[0])) { - var funcTypeNode = type.symbol.declarations[0]; - var returnType = getReturnTypeFromAnnotation(funcTypeNode); - if (returnType && returnType.flags & 1048576 /* Union */) { - var unionTypes_3 = funcTypeNode.type.types; - if (unionTypes_3 && unionTypes_3[unionTypes_3.length - 1].kind === 146 /* UndefinedKeyword */) { - var parenedFuncType = ts.getMutableClone(funcTypeNode); - // Highlight to the end of the second to last constituent of the union - parenedFuncType.end = unionTypes_3[unionTypes_3.length - 2].end; - ts.addRelatedInfo(diag, ts.createDiagnosticForNode(parenedFuncType, ts.Diagnostics.Did_you_mean_to_parenthesize_this_function_type)); - } - } - } + error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; } @@ -58207,12 +58232,17 @@ var ts; if (!(node.flags & 32768 /* AwaitContext */)) { if (isTopLevelAwait(node)) { var sourceFile = ts.getSourceFileOfNode(node); - if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || - languageVersion < 4 /* ES2017 */ || - !ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { - if (!hasParseDiagnostics(sourceFile)) { - var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher); + if (!hasParseDiagnostics(sourceFile)) { + var span = void 0; + if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + if (!span) + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); + diagnostics.add(diagnostic); + } + if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || languageVersion < 4 /* ES2017 */) { + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher); diagnostics.add(diagnostic); } } @@ -58222,7 +58252,7 @@ var ts; var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); var func = ts.getContainingFunction(node); if (func && func.kind !== 162 /* Constructor */ && (ts.getFunctionFlags(func) & 2 /* Async */) === 0) { var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async); @@ -96986,12 +97016,12 @@ var ts; if (!program || hasChangedAutomaticTypeDirectiveNames) { return false; } - // If number of files in the program do not match, it is not up-to-date - if (program.getRootFileNames().length !== rootFileNames.length) { + // If root file names don't match + if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) { return false; } var seenResolvedRefs; - // If project references dont match + // If project references don't match if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) { return false; } @@ -109488,7 +109518,7 @@ var ts; var contextToken = previousToken; // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. - if (contextToken && position <= contextToken.end && (ts.isIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) { + if (contextToken && position <= contextToken.end && (ts.isIdentifierOrPrivateIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) { var start_1 = ts.timestamp(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined); // TODO: GH#18217 log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_1)); @@ -109731,7 +109761,7 @@ var ts; } } } - if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */)) { + if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */) && contextToken === node.getChildAt(1)) { var completion = (node.keywordToken === 99 /* NewKeyword */) ? "target" : "meta"; symbols.push(typeChecker.createSymbol(4 /* Property */, ts.escapeLeadingUnderscores(completion))); return; @@ -111055,6 +111085,8 @@ var ts; if (!contextToken) return undefined; switch (contextToken.kind) { + case 62 /* EqualsToken */: // class c { public prop = | /* global completions */ } + return undefined; case 26 /* SemicolonToken */: // class c {getValue(): number; | } case 19 /* CloseBraceToken */: // class c { method() { } | } // class c { method() { } b| } @@ -111181,8 +111213,12 @@ var ts; case 103 /* SwitchKeyword */: return useParent(node.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); case 78 /* CaseKeyword */: - case 84 /* DefaultKeyword */: - return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + case 84 /* DefaultKeyword */: { + if (ts.isDefaultClause(node.parent) || ts.isCaseClause(node.parent)) { + return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + } + return undefined; + } case 77 /* BreakKeyword */: case 82 /* ContinueKeyword */: return useParent(node.parent, ts.isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences); @@ -112530,9 +112566,7 @@ var ts; return __assign(__assign({}, documentSpan), { isWriteAccess: false, isDefinition: false }); } var kind = entry.kind, node = entry.node; - return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: node.kind === 84 /* DefaultKeyword */ - || !!ts.getDeclarationFromName(node) - || ts.isLiteralComputedPropertyDeclarationName(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined }); + return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: isDefinitionForReference(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined }); } FindAllReferences.toReferenceEntry = toReferenceEntry; function entryToDocumentSpan(entry) { @@ -112640,6 +112674,12 @@ var ts; var decl = ts.getDeclarationFromName(node); return !!decl && declarationIsWriteAccess(decl) || node.kind === 84 /* DefaultKeyword */ || ts.isWriteAccess(node); } + function isDefinitionForReference(node) { + return node.kind === 84 /* DefaultKeyword */ + || !!ts.getDeclarationFromName(node) + || ts.isLiteralComputedPropertyDeclarationName(node) + || (node.kind === 129 /* ConstructorKeyword */ && ts.isConstructorDeclaration(node.parent)); + } /** * True if 'decl' provides a value, as in `function f() {}`; * false if 'decl' is just a location for a future write, as in 'let x;' @@ -122935,27 +122975,62 @@ var ts; this.insertNodeAtStartWorker(sourceFile, obj, newElement); }; ChangeTracker.prototype.insertNodeAtStartWorker = function (sourceFile, cls, newElement) { - var clsStart = cls.getStart(sourceFile); - var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) - + this.formatContext.options.indentSize; - this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, __assign({ indentation: indentation }, this.getInsertNodeAtStartPrefixSuffix(sourceFile, cls))); - }; - ChangeTracker.prototype.getInsertNodeAtStartPrefixSuffix = function (sourceFile, cls) { - var comma = ts.isObjectLiteralExpression(cls) ? "," : ""; - if (getMembersOrProperties(cls).length === 0) { - if (ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile })) { - // For `class C {\n}`, don't add the trailing "\n" - var _a = getClassOrObjectBraceEnds(cls, sourceFile), open = _a[0], close = _a[1]; - var shouldSuffix = open && close && ts.positionsAreOnSameLine(open, close, sourceFile); - return { prefix: this.newLineCharacter, suffix: comma + (shouldSuffix ? this.newLineCharacter : "") }; + var _a; + var indentation = (_a = this.guessIndentationFromExistingMembers(sourceFile, cls)) !== null && _a !== void 0 ? _a : this.computeIndentationForNewMember(sourceFile, cls); + this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, this.getInsertNodeAtStartInsertOptions(sourceFile, cls, indentation)); + }; + /** + * Tries to guess the indentation from the existing members of a class/interface/object. All members must be on + * new lines and must share the same indentation. + */ + ChangeTracker.prototype.guessIndentationFromExistingMembers = function (sourceFile, cls) { + var indentation; + var lastRange = cls; + for (var _i = 0, _a = getMembersOrProperties(cls); _i < _a.length; _i++) { + var member = _a[_i]; + if (ts.rangeStartPositionsAreOnSameLine(lastRange, member, sourceFile)) { + // each indented member must be on a new line + return undefined; } - else { - return { prefix: "", suffix: comma + this.newLineCharacter }; + var memberStart = member.getStart(sourceFile); + var memberIndentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); + if (indentation === undefined) { + indentation = memberIndentation; } + else if (memberIndentation !== indentation) { + // indentation of multiple members is not consistent + return undefined; + } + lastRange = member; } - else { - return { prefix: this.newLineCharacter, suffix: comma }; - } + return indentation; + }; + ChangeTracker.prototype.computeIndentationForNewMember = function (sourceFile, cls) { + var _a; + var clsStart = cls.getStart(sourceFile); + return ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) + + ((_a = this.formatContext.options.indentSize) !== null && _a !== void 0 ? _a : 4); + }; + ChangeTracker.prototype.getInsertNodeAtStartInsertOptions = function (sourceFile, cls, indentation) { + // Rules: + // - Always insert leading newline. + // - For object literals: + // - Add a trailing comma if there are existing members in the node, or the source file is not a JSON file + // (because trailing commas are generally illegal in a JSON file). + // - Add a leading comma if the source file is not a JSON file, there are existing insertions, + // and the node is empty (because we didn't add a trailing comma per the previous rule). + // - Only insert a trailing newline if body is single-line and there are no other insertions for the node. + // NOTE: This is handled in `finishClassesWithNodesInsertedAtStart`. + var members = getMembersOrProperties(cls); + var isEmpty = members.length === 0; + var isFirstInsertion = ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile }); + var insertTrailingComma = ts.isObjectLiteralExpression(cls) && (!ts.isJsonSourceFile(sourceFile) || !isEmpty); + var insertLeadingComma = ts.isObjectLiteralExpression(cls) && ts.isJsonSourceFile(sourceFile) && isEmpty && !isFirstInsertion; + return { + indentation: indentation, + prefix: (insertLeadingComma ? "," : "") + this.newLineCharacter, + suffix: insertTrailingComma ? "," : "" + }; }; ChangeTracker.prototype.insertNodeAfterComma = function (sourceFile, after, newNode) { var endPosition = this.insertNodeAfterWorker(sourceFile, this.nextCommaToken(sourceFile, after) || after, newNode); @@ -123157,9 +123232,16 @@ var ts; this.classesWithNodesInsertedAtStart.forEach(function (_a) { var node = _a.node, sourceFile = _a.sourceFile; var _b = getClassOrObjectBraceEnds(node, sourceFile), openBraceEnd = _b[0], closeBraceEnd = _b[1]; - // For `class C { }` remove the whitespace inside the braces. - if (openBraceEnd && closeBraceEnd && ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) { - _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); + if (openBraceEnd !== undefined && closeBraceEnd !== undefined) { + var isEmpty = getMembersOrProperties(node).length === 0; + var isSingleLine = ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile); + if (isEmpty && isSingleLine && openBraceEnd !== closeBraceEnd - 1) { + // For `class C { }` remove the whitespace inside the braces. + _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); + } + if (isSingleLine) { + _this.insertText(sourceFile, closeBraceEnd - 1, _this.newLineCharacter); + } } }); }; @@ -123735,10 +123817,10 @@ var ts; ? ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag[0]), diag.slice(1)) : ts.getLocaleSpecificMessage(diag); } - function createCodeFixActionNoFixId(fixName, changes, description) { + function createCodeFixActionWithoutFixAll(fixName, changes, description) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined); } - codefix.createCodeFixActionNoFixId = createCodeFixActionNoFixId; + codefix.createCodeFixActionWithoutFixAll = createCodeFixActionWithoutFixAll; function createCodeFixAction(fixName, changes, description, fixId, fixAllDescription, command) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, diagnosticToString(fixAllDescription), command); } @@ -123764,8 +123846,26 @@ var ts; return ts.arrayFrom(errorCodeToFixes.keys()); } codefix.getSupportedErrorCodes = getSupportedErrorCodes; + function removeFixIdIfFixAllUnavailable(registration, diagnostics) { + var errorCodes = registration.errorCodes; + var maybeFixableDiagnostics = 0; + for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { + var diag = diagnostics_1[_i]; + if (ts.contains(errorCodes, diag.code)) + maybeFixableDiagnostics++; + if (maybeFixableDiagnostics > 1) + break; + } + var fixAllUnavailable = maybeFixableDiagnostics < 2; + return function (_a) { + var fixId = _a.fixId, fixAllDescription = _a.fixAllDescription, action = __rest(_a, ["fixId", "fixAllDescription"]); + return fixAllUnavailable ? action : __assign(__assign({}, action), { fixId: fixId, fixAllDescription: fixAllDescription }); + }; + } function getFixes(context) { - return ts.flatMap(errorCodeToFixes.get(String(context.errorCode)) || ts.emptyArray, function (f) { return f.getCodeActions(context); }); + var diagnostics = getDiagnostics(context); + var registrations = errorCodeToFixes.get(String(context.errorCode)); + return ts.flatMap(registrations, function (f) { return ts.map(f.getCodeActions(context), removeFixIdIfFixAllUnavailable(f, diagnostics)); }); } codefix.getFixes = getFixes; function getAllFixes(context) { @@ -123787,16 +123887,19 @@ var ts; return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands); } codefix.codeFixAll = codeFixAll; - function eachDiagnostic(_a, errorCodes, cb) { - var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken; - for (var _i = 0, _b = program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); _i < _b.length; _i++) { - var diag = _b[_i]; + function eachDiagnostic(context, errorCodes, cb) { + for (var _i = 0, _a = getDiagnostics(context); _i < _a.length; _i++) { + var diag = _a[_i]; if (ts.contains(errorCodes, diag.code)) { cb(diag); } } } codefix.eachDiagnostic = eachDiagnostic; + function getDiagnostics(_a) { + var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken; + return program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); + } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ @@ -123853,6 +123956,28 @@ var ts; })(ts || (ts = {})); /* @internal */ var ts; +(function (ts) { + var codefix; + (function (codefix) { + codefix.registerCodeFix({ + errorCodes: [ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code], + getCodeActions: function (context) { + var sourceFile = context.sourceFile; + var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { + var exportDeclaration = ts.createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, ts.createNamedExports([]), + /*moduleSpecifier*/ undefined, + /*isTypeOnly*/ false); + changes.insertNodeAtEndOfScope(sourceFile, sourceFile, exportDeclaration); + }); + return [codefix.createCodeFixActionWithoutFixAll("addEmptyExportDeclaration", changes, ts.Diagnostics.Add_export_to_make_this_file_into_a_module)]; + }, + }); + })(codefix = ts.codefix || (ts.codefix = {})); +})(ts || (ts = {})); +/* @internal */ +var ts; (function (ts) { var codefix; (function (codefix) { @@ -123923,7 +124048,9 @@ var ts; makeChange(t, errorCode, sourceFile, checker, expression, fixedDeclarations); } }); - return codefix.createCodeFixActionNoFixId("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 + // No fix-all because it will already be included once with the use site fix, + // and for simplicity the fix-all doesn‘t let the user choose between use-site and declaration-site fixes. + return codefix.createCodeFixActionWithoutFixAll("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 ? [ts.Diagnostics.Add_await_to_initializer_for_0, awaitableInitializers.initializers[0].declarationSymbol.name] : ts.Diagnostics.Add_await_to_initializers); } @@ -124142,7 +124269,7 @@ var ts; if (forInitializer) return applyChange(changeTracker, forInitializer, sourceFile, fixedNodes); var parent = token.parent; - if (ts.isBinaryExpression(parent) && ts.isExpressionStatement(parent.parent)) { + if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isExpressionStatement(parent.parent)) { return applyChange(changeTracker, token, sourceFile, fixedNodes); } if (ts.isArrayLiteralExpression(parent)) { @@ -124204,7 +124331,9 @@ var ts; if (expression.operatorToken.kind === 27 /* CommaToken */) { return ts.every([expression.left, expression.right], function (expression) { return expressionCouldBeVariableDeclaration(expression, checker); }); } - return ts.isIdentifier(expression.left) && !checker.getSymbolAtLocation(expression.left); + return expression.operatorToken.kind === 62 /* EqualsToken */ + && ts.isIdentifier(expression.left) + && !checker.getSymbolAtLocation(expression.left); } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); @@ -126195,7 +126324,7 @@ var ts; } }); // No support for fix-all since this applies to the whole file at once anyway. - return [codefix.createCodeFixActionNoFixId("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)]; + return [codefix.createCodeFixActionWithoutFixAll("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)]; }, }); function fixImportOfModuleExports(importingFile, exportingFile, changes, quotePreference) { @@ -126794,7 +126923,8 @@ var ts; (function (ts) { var codefix; (function (codefix) { - codefix.importFixId = "fixMissingImport"; + codefix.importFixName = "import"; + var importFixId = "fixMissingImport"; var errorCodes = [ ts.Diagnostics.Cannot_find_name_0.code, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, @@ -126815,7 +126945,7 @@ var ts; var quotePreference = ts.getQuotePreference(sourceFile, preferences); return fixes.map(function (fix) { return codeActionForFix(context, sourceFile, symbolName, fix, quotePreference); }); }, - fixIds: [codefix.importFixId], + fixIds: [importFixId], getAllCodeActions: function (context) { var sourceFile = context.sourceFile, preferences = context.preferences; // Namespace fixes don't conflict, so just build a list. @@ -127247,7 +127377,7 @@ var ts; var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) { diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, quotePreference); }); - return codefix.createCodeFixAction("import", changes, diag, codefix.importFixId, ts.Diagnostics.Add_all_missing_imports); + return codefix.createCodeFixAction(codefix.importFixName, changes, diag, importFixId, ts.Diagnostics.Add_all_missing_imports); } function codeActionForFixWorker(changes, sourceFile, symbolName, fix, quotePreference) { switch (fix.kind) { @@ -127545,17 +127675,17 @@ var ts; var info = getInfo(sourceFile, context.span.start, context); if (!info) return undefined; - var node = info.node, suggestion = info.suggestion; + var node = info.node, suggestedSymbol = info.suggestedSymbol; var target = context.host.getCompilationSettings().target; - var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestion, target); }); - return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, suggestion], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)]; + var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestedSymbol, target); }); + return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, ts.symbolName(suggestedSymbol)], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)]; }, fixIds: [fixId], getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { var info = getInfo(diag.file, diag.start, context); var target = context.host.getCompilationSettings().target; if (info) - doChange(changes, context.sourceFile, info.node, info.suggestion, target); + doChange(changes, context.sourceFile, info.node, info.suggestedSymbol, target); }); }, }); function getInfo(sourceFile, pos, context) { @@ -127564,34 +127694,42 @@ var ts; // ^^^^^^^ var node = ts.getTokenAtPosition(sourceFile, pos); var checker = context.program.getTypeChecker(); - var suggestion; + var suggestedSymbol; if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) { - ts.Debug.assert(node.kind === 75 /* Identifier */, "Expected an identifier for spelling (property access)"); + ts.Debug.assert(ts.isIdentifierOrPrivateIdentifier(node), "Expected an identifier for spelling (property access)"); var containingType = checker.getTypeAtLocation(node.parent.expression); if (node.parent.flags & 32 /* OptionalChain */) { containingType = checker.getNonNullableType(containingType); } - suggestion = checker.getSuggestionForNonexistentProperty(node, containingType); + var name = node; + suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(name, containingType); } else if (ts.isImportSpecifier(node.parent) && node.parent.name === node) { ts.Debug.assert(node.kind === 75 /* Identifier */, "Expected an identifier for spelling (import)"); var importDeclaration = ts.findAncestor(node, ts.isImportDeclaration); var resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration); if (resolvedSourceFile && resolvedSourceFile.symbol) { - suggestion = checker.getSuggestionForNonexistentExport(node, resolvedSourceFile.symbol); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(node, resolvedSourceFile.symbol); } } else { var meaning = ts.getMeaningFromLocation(node); var name = ts.getTextOfNode(node); ts.Debug.assert(name !== undefined, "name should be defined"); - suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); } - return suggestion === undefined ? undefined : { node: node, suggestion: suggestion }; + return suggestedSymbol === undefined ? undefined : { node: node, suggestedSymbol: suggestedSymbol }; } - function doChange(changes, sourceFile, node, suggestion, target) { + function doChange(changes, sourceFile, node, suggestedSymbol, target) { + var suggestion = ts.symbolName(suggestedSymbol); if (!ts.isIdentifierText(suggestion, target) && ts.isPropertyAccessExpression(node.parent)) { - changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion))); + var valDecl = suggestedSymbol.valueDeclaration; + if (ts.isNamedDeclaration(valDecl) && ts.isPrivateIdentifier(valDecl.name)) { + changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion)); + } + else { + changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion))); + } } else { changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion)); @@ -127855,7 +127993,7 @@ var ts; /*modifiers*/ undefined, [indexingParameter], typeNode); var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.insertNodeAtClassStart(declSourceFile, classDeclaration, indexSignature); }); // No fixId here because code-fix-all currently only works on adding individual named properties. - return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]); + return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]); } function getActionForMethodDeclaration(context, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences) { // Private methods are not implemented yet. @@ -128140,7 +128278,7 @@ var ts; return undefined; } var changes = ts.textChanges.ChangeTracker.with(context, function (changeTracker) { return doChange(changeTracker, configFile); }); - return [codefix.createCodeFixActionNoFixId(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; + return [codefix.createCodeFixActionWithoutFixAll(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; }, fixIds: [fixId], getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes) { @@ -128174,7 +128312,7 @@ var ts; return doChange(changeTracker, configFile); }); return [ - codefix.createCodeFixActionNoFixId(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) + codefix.createCodeFixActionWithoutFixAll(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) ]; }, fixIds: [fixID], @@ -128195,6 +128333,49 @@ var ts; })(ts || (ts = {})); /* @internal */ var ts; +(function (ts) { + var codefix; + (function (codefix) { + codefix.registerCodeFix({ + errorCodes: [ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code], + getCodeActions: function (context) { + var compilerOptions = context.program.getCompilerOptions(); + var configFile = compilerOptions.configFile; + if (configFile === undefined) { + return undefined; + } + var codeFixes = []; + var moduleKind = ts.getEmitModuleKind(compilerOptions); + var moduleOutOfRange = moduleKind >= ts.ModuleKind.ES2015 && moduleKind < ts.ModuleKind.ESNext; + if (moduleOutOfRange) { + var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { + codefix.setJsonCompilerOptionValue(changes, configFile, "module", ts.createStringLiteral("esnext")); + }); + codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixModuleOption", changes, [ts.Diagnostics.Set_the_module_option_in_your_configuration_file_to_0, "esnext"])); + } + var target = ts.getEmitScriptTarget(compilerOptions); + var targetOutOfRange = target < 4 /* ES2017 */ || target > 99 /* ESNext */; + if (targetOutOfRange) { + var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) { + var configObject = ts.getTsConfigObjectLiteralExpression(configFile); + if (!configObject) + return; + var options = [["target", ts.createStringLiteral("es2017")]]; + if (moduleKind === ts.ModuleKind.CommonJS) { + // Ensure we preserve the default module kind (commonjs), as targets >= ES2015 have a default module kind of es2015. + options.push(["module", ts.createStringLiteral("commonjs")]); + } + codefix.setJsonCompilerOptionValues(tracker, configFile, options); + }); + codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixTargetOption", changes, [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0, "es2017"])); + } + return codeFixes.length ? codeFixes : undefined; + } + }); + })(codefix = ts.codefix || (ts.codefix = {})); +})(ts || (ts = {})); +/* @internal */ +var ts; (function (ts) { var codefix; (function (codefix) { @@ -128347,7 +128528,7 @@ var ts; }); if (deletion.length) { var name = ts.isComputedPropertyName(token.parent) ? token.parent : token; - result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_declaration_for_Colon_0, name.getText(sourceFile)])); + result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_unused_declaration_for_Colon_0, name.getText(sourceFile)])); } } var prefix = ts.textChanges.ChangeTracker.with(context, function (t) { return tryPrefixDeclaration(t, errorCode, sourceFile, token); }); @@ -128708,7 +128889,7 @@ var ts; (function (codefix) { var fixId = "fixAwaitInSyncFunction"; var errorCodes = [ - ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function.code, + ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code, ]; codefix.registerCodeFix({ @@ -128800,7 +128981,7 @@ var ts; } var fixes = [ // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file. - codefix.createCodeFixActionNoFixId(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [ + codefix.createCodeFixActionWithoutFixAll(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [ ts.createTextChange(sourceFile.checkJsDirective ? ts.createTextSpanFromBounds(sourceFile.checkJsDirective.pos, sourceFile.checkJsDirective.end) : ts.createTextSpan(0, 0), "// @ts-nocheck" + ts.getNewLineOrDefaultFromHost(host, formatContext.options)), @@ -129067,29 +129248,37 @@ var ts; } return undefined; } - function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) { + function setJsonCompilerOptionValues(changeTracker, configFile, options) { var tsconfigObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile); if (!tsconfigObjectLiteral) return undefined; var compilerOptionsProperty = findJsonProperty(tsconfigObjectLiteral, "compilerOptions"); if (compilerOptionsProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral([ - createJsonPropertyAssignment(optionName, optionValue), - ]))); + changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral(options.map(function (_a) { + var optionName = _a[0], optionValue = _a[1]; + return createJsonPropertyAssignment(optionName, optionValue); + }), /*multiLine*/ true))); return; } var compilerOptions = compilerOptionsProperty.initializer; if (!ts.isObjectLiteralExpression(compilerOptions)) { return; } - var optionProperty = findJsonProperty(compilerOptions, optionName); - if (optionProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); - } - else { - changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + for (var _i = 0, options_1 = options; _i < options_1.length; _i++) { + var _a = options_1[_i], optionName = _a[0], optionValue = _a[1]; + var optionProperty = findJsonProperty(compilerOptions, optionName); + if (optionProperty === undefined) { + changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); + } + else { + changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + } } } + codefix.setJsonCompilerOptionValues = setJsonCompilerOptionValues; + function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) { + setJsonCompilerOptionValues(changeTracker, configFile, [[optionName, optionValue]]); + } codefix.setJsonCompilerOptionValue = setJsonCompilerOptionValue; function createJsonPropertyAssignment(name, initializer) { return ts.createPropertyAssignment(ts.createStringLiteral(name), initializer); @@ -129124,7 +129313,7 @@ var ts; } function createAction(context, sourceFile, node, replacement) { var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, node, replacement); }); - return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); + return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); } codefix.registerCodeFix({ errorCodes: [ @@ -129182,7 +129371,7 @@ var ts; if (ts.isExpression(expr) && !(ts.isNamedDeclaration(expr.parent) && expr.parent.name === expr)) { var sourceFile_1 = context.sourceFile; var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile_1, expr, ts.createPropertyAccess(expr, "default"), {}); }); - fixes.push(codefix.createCodeFixActionNoFixId(fixName, changes, ts.Diagnostics.Use_synthetic_default_member)); + fixes.push(codefix.createCodeFixActionWithoutFixAll(fixName, changes, ts.Diagnostics.Use_synthetic_default_member)); } return fixes; } @@ -137334,7 +137523,8 @@ var ts; server.TextStorage = TextStorage; /*@internal*/ function isDynamicFileName(fileName) { - return fileName[0] === "^"; + return fileName[0] === "^" || + (ts.stringContains(fileName, ":^") && !ts.stringContains(fileName, ts.directorySeparator)); } server.isDynamicFileName = isDynamicFileName; var ScriptInfo = /** @class */ (function () { @@ -140427,7 +140617,7 @@ var ts; // Closing file should trigger re-reading the file content from disk. This is // because the user may chose to discard the buffer content before saving // to the disk, and the server's version of the file can be out of sync. - var fileExists = this.host.fileExists(info.fileName); + var fileExists = info.isDynamic ? false : this.host.fileExists(info.fileName); info.close(fileExists); this.stopWatchingConfigFilesForClosedScriptInfo(info); var canonicalFileName = this.toCanonicalFileName(info.fileName); @@ -143427,7 +143617,11 @@ var ts; command: cmdName, request_seq: reqSeq, success: success, - updateGraphDurationMs: this.updateGraphDurationMs, + performanceData: !this.updateGraphDurationMs + ? undefined + : { + updateGraphDurationMs: this.updateGraphDurationMs, + }, }; if (success) { var metadata = void 0; diff --git a/lib/typescript.js b/lib/typescript.js index 382f819640f41..147a6c200bf65 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -63,6 +63,17 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || @@ -1414,6 +1425,11 @@ var ts; return result; } ts.clone = clone; + /** + * Creates a new object by adding the own properties of `second`, then the own properties of `first`. + * + * NOTE: This means that if a property exists in both `first` and `second`, the property in `first` will be chosen. + */ function extend(first, second) { var result = {}; for (var id in second) { @@ -5734,10 +5750,13 @@ var ts; } } function readFileWorker(fileName, _encoding) { - if (!fileExists(fileName)) { + var buffer; + try { + buffer = _fs.readFileSync(fileName); + } + catch (e) { return undefined; } - var buffer = _fs.readFileSync(fileName); var len = buffer.length; if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) { // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js, @@ -5787,23 +5806,30 @@ var ts; function getAccessibleFileSystemEntries(path) { ts.perfLogger.logEvent("ReadDir: " + (path || ".")); try { - var entries = _fs.readdirSync(path || ".").sort(); + var entries = _fs.readdirSync(path || ".", { withFileTypes: true }); var files = []; var directories = []; for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { - var entry = entries_2[_i]; + var dirent = entries_2[_i]; + // withFileTypes is not supported before Node 10.10. + var entry = typeof dirent === "string" ? dirent : dirent.name; // This is necessary because on some file system node fails to exclude // "." and "..". See https://github.com/nodejs/node/issues/4002 if (entry === "." || entry === "..") { continue; } - var name = ts.combinePaths(path, entry); var stat = void 0; - try { - stat = _fs.statSync(name); + if (typeof dirent === "string" || dirent.isSymbolicLink()) { + var name = ts.combinePaths(path, entry); + try { + stat = _fs.statSync(name); + } + catch (e) { + continue; + } } - catch (e) { - continue; + else { + stat = dirent; } if (stat.isFile()) { files.push(entry); @@ -5812,6 +5838,8 @@ var ts; directories.push(entry); } } + files.sort(); + directories.sort(); return { files: files, directories: directories }; } catch (e) { @@ -5841,8 +5869,7 @@ var ts; return fileSystemEntryExists(path, 1 /* Directory */); } function getDirectories(path) { - ts.perfLogger.logEvent("ReadDir: " + path); - return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); }); + return getAccessibleFileSystemEntries(path).directories.slice(); } function realpath(path) { try { @@ -6836,7 +6863,7 @@ var ts; Keywords_cannot_contain_escape_characters: diag(1260, ts.DiagnosticCategory.Error, "Keywords_cannot_contain_escape_characters_1260", "Keywords cannot contain escape characters."), Already_included_file_name_0_differs_from_file_name_1_only_in_casing: diag(1261, ts.DiagnosticCategory.Error, "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", "Already included file name '{0}' differs from file name '{1}' only in casing."), with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."), - await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."), + await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules: diag(1308, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", "'await' expressions are only allowed within async functions and at the top levels of modules."), can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."), The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."), Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."), @@ -6884,14 +6911,13 @@ var ts; An_enum_member_name_must_be_followed_by_a_or: diag(1357, ts.DiagnosticCategory.Error, "An_enum_member_name_must_be_followed_by_a_or_1357", "An enum member name must be followed by a ',', '=', or '}'."), Tagged_template_expressions_are_not_permitted_in_an_optional_chain: diag(1358, ts.DiagnosticCategory.Error, "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", "Tagged template expressions are not permitted in an optional chain."), Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here: diag(1359, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", "Identifier expected. '{0}' is a reserved word that cannot be used here."), - Did_you_mean_to_parenthesize_this_function_type: diag(1360, ts.DiagnosticCategory.Error, "Did_you_mean_to_parenthesize_this_function_type_1360", "Did you mean to parenthesize this function type?"), Type_only_0_must_reference_a_type_but_1_is_a_value: diag(1361, ts.DiagnosticCategory.Error, "Type_only_0_must_reference_a_type_but_1_is_a_value_1361", "Type-only {0} must reference a type, but '{1}' is a value."), Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported: diag(1362, ts.DiagnosticCategory.Error, "Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported_1362", "Enum '{0}' cannot be used as a value because only its type has been imported."), A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both: diag(1363, ts.DiagnosticCategory.Error, "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", "A type-only import can specify a default import or named bindings, but not both."), Convert_to_type_only_export: diag(1364, ts.DiagnosticCategory.Message, "Convert_to_type_only_export_1364", "Convert to type-only export"), Convert_all_re_exported_types_to_type_only_exports: diag(1365, ts.DiagnosticCategory.Message, "Convert_all_re_exported_types_to_type_only_exports_1365", "Convert all re-exported types to type-only exports"), Split_into_two_separate_import_declarations: diag(1366, ts.DiagnosticCategory.Message, "Split_into_two_separate_import_declarations_1366", "Split into two separate import declarations"), - Split_all_invalid_type_only_imports: diag(1377, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1377", "Split all invalid type-only imports"), + Split_all_invalid_type_only_imports: diag(1367, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1367", "Split all invalid type-only imports"), Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types: diag(1368, ts.DiagnosticCategory.Message, "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_1368", "Specify emit/checking behavior for imports that are only used for types"), Did_you_mean_0: diag(1369, ts.DiagnosticCategory.Message, "Did_you_mean_0_1369", "Did you mean '{0}'?"), Only_ECMAScript_imports_may_use_import_type: diag(1370, ts.DiagnosticCategory.Error, "Only_ECMAScript_imports_may_use_import_type_1370", "Only ECMAScript imports may use 'import type'."), @@ -6899,7 +6925,8 @@ var ts; This_import_may_be_converted_to_a_type_only_import: diag(1372, ts.DiagnosticCategory.Suggestion, "This_import_may_be_converted_to_a_type_only_import_1372", "This import may be converted to a type-only import."), Convert_to_type_only_import: diag(1373, ts.DiagnosticCategory.Message, "Convert_to_type_only_import_1373", "Convert to type-only import"), Convert_all_imports_not_used_as_a_value_to_type_only_imports: diag(1374, ts.DiagnosticCategory.Message, "Convert_all_imports_not_used_as_a_value_to_type_only_imports_1374", "Convert all imports not used as a value to type-only imports"), - await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher: diag(1375, ts.DiagnosticCategory.Error, "await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnex_1375", "'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher."), + await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module: diag(1375, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."), + Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher: diag(1376, ts.DiagnosticCategory.Error, "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_t_1376", "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher."), The_types_of_0_are_incompatible_between_these_types: diag(2200, ts.DiagnosticCategory.Error, "The_types_of_0_are_incompatible_between_these_types_2200", "The types of '{0}' are incompatible between these types."), The_types_returned_by_0_are_incompatible_between_these_types: diag(2201, ts.DiagnosticCategory.Error, "The_types_returned_by_0_are_incompatible_between_these_types_2201", "The types returned by '{0}' are incompatible between these types."), Call_signature_return_types_0_and_1_are_incompatible: diag(2202, ts.DiagnosticCategory.Error, "Call_signature_return_types_0_and_1_are_incompatible_2202", "Call signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true), @@ -7845,7 +7872,7 @@ var ts; Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"), Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"), Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"), - Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'"), + Remove_unused_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_unused_declaration_for_Colon_0_90004", "Remove unused declaration for: '{0}'"), Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"), Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"), Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"), @@ -7968,10 +7995,12 @@ var ts; Prefix_with_declare: diag(95094, ts.DiagnosticCategory.Message, "Prefix_with_declare_95094", "Prefix with 'declare'"), Prefix_all_incorrect_property_declarations_with_declare: diag(95095, ts.DiagnosticCategory.Message, "Prefix_all_incorrect_property_declarations_with_declare_95095", "Prefix all incorrect property declarations with 'declare'"), Convert_to_template_string: diag(95096, ts.DiagnosticCategory.Message, "Convert_to_template_string_95096", "Convert to template string"), + Add_export_to_make_this_file_into_a_module: diag(95097, ts.DiagnosticCategory.Message, "Add_export_to_make_this_file_into_a_module_95097", "Add 'export {}' to make this file into a module"), + Set_the_target_option_in_your_configuration_file_to_0: diag(95098, ts.DiagnosticCategory.Message, "Set_the_target_option_in_your_configuration_file_to_0_95098", "Set the 'target' option in your configuration file to '{0}'"), + Set_the_module_option_in_your_configuration_file_to_0: diag(95099, ts.DiagnosticCategory.Message, "Set_the_module_option_in_your_configuration_file_to_0_95099", "Set the 'module' option in your configuration file to '{0}'"), No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."), Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."), JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array: diag(18007, ts.DiagnosticCategory.Error, "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", "JSX expressions may not use the comma operator. Did you mean to write an array?"), - can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Private_identifiers_cannot_be_used_as_parameters: diag(18009, ts.DiagnosticCategory.Error, "Private_identifiers_cannot_be_used_as_parameters_18009", "Private identifiers cannot be used as parameters"), An_accessibility_modifier_cannot_be_used_with_a_private_identifier: diag(18010, ts.DiagnosticCategory.Error, "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", "An accessibility modifier cannot be used with a private identifier."), The_operand_of_a_delete_operator_cannot_be_a_private_identifier: diag(18011, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", "The operand of a 'delete' operator cannot be a private identifier."), @@ -7986,6 +8015,7 @@ var ts; A_method_cannot_be_named_with_a_private_identifier: diag(18022, ts.DiagnosticCategory.Error, "A_method_cannot_be_named_with_a_private_identifier_18022", "A method cannot be named with a private identifier."), An_accessor_cannot_be_named_with_a_private_identifier: diag(18023, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_named_with_a_private_identifier_18023", "An accessor cannot be named with a private identifier."), An_enum_member_cannot_be_named_with_a_private_identifier: diag(18024, ts.DiagnosticCategory.Error, "An_enum_member_cannot_be_named_with_a_private_identifier_18024", "An enum member cannot be named with a private identifier."), + can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Compiler_reserves_name_0_when_emitting_private_identifier_downlevel: diag(18027, ts.DiagnosticCategory.Error, "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", "Compiler reserves name '{0}' when emitting private identifier downlevel."), Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher: diag(18028, ts.DiagnosticCategory.Error, "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", "Private identifiers are only available when targeting ECMAScript 2015 and higher."), Private_identifiers_are_not_allowed_in_variable_declarations: diag(18029, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_in_variable_declarations_18029", "Private identifiers are not allowed in variable declarations."), @@ -26177,6 +26207,7 @@ var ts; error: 2 /* Error */ }), affectsEmit: true, + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types }, @@ -26434,12 +26465,15 @@ var ts; { name: "experimentalDecorators", type: "boolean", + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", + affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, @@ -26453,6 +26487,7 @@ var ts; { name: "resolveJsonModule", type: "boolean", + affectsModuleResolution: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Include_modules_imported_with_json_extension }, @@ -26657,6 +26692,7 @@ var ts; name: "useDefineForClassFields", type: "boolean", affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Emit_class_fields_with_Define_instead_of_Set, }, @@ -30533,7 +30569,7 @@ var ts; case 104 /* ThisKeyword */: case 194 /* PropertyAccessExpression */: case 195 /* ElementAccessExpression */: - return isNarrowableReference(expr); + return containsNarrowableReference(expr); case 196 /* CallExpression */: return hasNarrowableArgument(expr); case 200 /* ParenthesizedExpression */: @@ -30550,20 +30586,22 @@ var ts; function isNarrowableReference(expr) { return expr.kind === 75 /* Identifier */ || expr.kind === 104 /* ThisKeyword */ || expr.kind === 102 /* SuperKeyword */ || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || - ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) || - ts.isOptionalChain(expr); + ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression); + } + function containsNarrowableReference(expr) { + return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); } function hasNarrowableArgument(expr) { if (expr.arguments) { for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) { var argument = _a[_i]; - if (isNarrowableReference(argument)) { + if (containsNarrowableReference(argument)) { return true; } } } if (expr.expression.kind === 194 /* PropertyAccessExpression */ && - isNarrowableReference(expr.expression.expression)) { + containsNarrowableReference(expr.expression.expression)) { return true; } return false; @@ -30577,7 +30615,7 @@ var ts; function isNarrowingBinaryExpression(expr) { switch (expr.operatorToken.kind) { case 62 /* EqualsToken */: - return isNarrowableReference(expr.left); + return containsNarrowableReference(expr.left); case 34 /* EqualsEqualsToken */: case 35 /* ExclamationEqualsToken */: case 36 /* EqualsEqualsEqualsToken */: @@ -30605,7 +30643,7 @@ var ts; return isNarrowableOperand(expr.right); } } - return isNarrowableReference(expr); + return containsNarrowableReference(expr); } function createBranchLabel() { return initFlowNode({ flags: 4 /* BranchLabel */, antecedents: undefined }); @@ -34017,6 +34055,7 @@ var ts; var currentNode; var emptySymbols = ts.createSymbolTable(); var identityMapper = ts.identity; + var arrayVariances = [1 /* Covariant */]; var compilerOptions = host.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); @@ -34265,9 +34304,12 @@ var ts; isArrayLikeType: isArrayLikeType, isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant, getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes, - getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); }, + getSuggestedSymbolForNonexistentProperty: getSuggestedSymbolForNonexistentProperty, + getSuggestionForNonexistentProperty: getSuggestionForNonexistentProperty, + getSuggestedSymbolForNonexistentSymbol: function (location, name, meaning) { return getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, - getSuggestionForNonexistentExport: function (node, target) { return getSuggestionForNonexistentExport(node, target); }, + getSuggestedSymbolForNonexistentModule: getSuggestedSymbolForNonexistentModule, + getSuggestionForNonexistentExport: getSuggestionForNonexistentExport, getBaseConstraintOfType: getBaseConstraintOfType, getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; }, resolveName: function (name, location, meaning, excludeGlobals) { @@ -35859,9 +35901,11 @@ var ts; // if symbolFromVariable is export - get its final target symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias); var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias); - // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default - if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default" /* Default */) { - symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + if (symbolFromModule === undefined && name.escapedText === "default" /* Default */) { + var file = ts.find(moduleSymbol.declarations, ts.isSourceFile); + if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) { + symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + } } var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : @@ -45502,8 +45546,9 @@ var ts; } /** We approximate own properties as non-methods plus methods that are inside the object literal */ function isSpreadableProperty(prop) { - return !(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || - !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); }); + return !ts.some(prop.declarations, ts.isPrivateIdentifierPropertyDeclaration) && + (!(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || + !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); })); } function getSpreadSymbol(prop, readonly) { var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */); @@ -47829,6 +47874,9 @@ var ts; source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { var variances = getAliasVariances(source.aliasSymbol); + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -48023,6 +48071,12 @@ var ts; // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. var variances = getVariances(source.target); + // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This + // effectively means we measure variance only from type parameter occurrences that aren't nested in + // recursive instantiations of the generic type. + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -48808,8 +48862,7 @@ var ts; // a digest of the type comparisons that occur for each type argument when instantiations of the // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function - // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function - // has been invoked recursively for the given generic type. + // returns the emptyArray singleton when invoked recursively for the given generic type. function getVariancesWorker(typeParameters, cache, createMarkerType) { if (typeParameters === void 0) { typeParameters = ts.emptyArray; } var variances = cache.variances; @@ -48856,9 +48909,9 @@ var ts; return variances; } function getVariances(type) { - // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters) + // Arrays and tuples are known to be covariant, no need to spend time computing this. if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8 /* Tuple */) { - return ts.emptyArray; + return arrayVariances; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); } @@ -52564,24 +52617,7 @@ var ts; } } else if (!assumeInitialized && !(getFalsyFlags(type) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) { - var diag = error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); - // See GH:32846 - if the user is using a variable whose type is () => T1 | ... | undefined - // they may have meant to specify the type as (() => T1 | ...) | undefined - // This is assumed if: the type is a FunctionType, the return type is a Union, the last constituent of - // the union is `undefined` - if (type.symbol && type.symbol.declarations.length === 1 && ts.isFunctionTypeNode(type.symbol.declarations[0])) { - var funcTypeNode = type.symbol.declarations[0]; - var returnType = getReturnTypeFromAnnotation(funcTypeNode); - if (returnType && returnType.flags & 1048576 /* Union */) { - var unionTypes_3 = funcTypeNode.type.types; - if (unionTypes_3 && unionTypes_3[unionTypes_3.length - 1].kind === 146 /* UndefinedKeyword */) { - var parenedFuncType = ts.getMutableClone(funcTypeNode); - // Highlight to the end of the second to last constituent of the union - parenedFuncType.end = unionTypes_3[unionTypes_3.length - 2].end; - ts.addRelatedInfo(diag, ts.createDiagnosticForNode(parenedFuncType, ts.Diagnostics.Did_you_mean_to_parenthesize_this_function_type)); - } - } - } + error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; } @@ -58196,12 +58232,17 @@ var ts; if (!(node.flags & 32768 /* AwaitContext */)) { if (isTopLevelAwait(node)) { var sourceFile = ts.getSourceFileOfNode(node); - if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || - languageVersion < 4 /* ES2017 */ || - !ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { - if (!hasParseDiagnostics(sourceFile)) { - var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher); + if (!hasParseDiagnostics(sourceFile)) { + var span = void 0; + if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + if (!span) + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); + diagnostics.add(diagnostic); + } + if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || languageVersion < 4 /* ES2017 */) { + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher); diagnostics.add(diagnostic); } } @@ -58211,7 +58252,7 @@ var ts; var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); var func = ts.getContainingFunction(node); if (func && func.kind !== 162 /* Constructor */ && (ts.getFunctionFlags(func) & 2 /* Async */) === 0) { var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async); @@ -96975,12 +97016,12 @@ var ts; if (!program || hasChangedAutomaticTypeDirectiveNames) { return false; } - // If number of files in the program do not match, it is not up-to-date - if (program.getRootFileNames().length !== rootFileNames.length) { + // If root file names don't match + if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) { return false; } var seenResolvedRefs; - // If project references dont match + // If project references don't match if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) { return false; } @@ -109477,7 +109518,7 @@ var ts; var contextToken = previousToken; // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. - if (contextToken && position <= contextToken.end && (ts.isIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) { + if (contextToken && position <= contextToken.end && (ts.isIdentifierOrPrivateIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) { var start_1 = ts.timestamp(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined); // TODO: GH#18217 log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_1)); @@ -109720,7 +109761,7 @@ var ts; } } } - if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */)) { + if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */) && contextToken === node.getChildAt(1)) { var completion = (node.keywordToken === 99 /* NewKeyword */) ? "target" : "meta"; symbols.push(typeChecker.createSymbol(4 /* Property */, ts.escapeLeadingUnderscores(completion))); return; @@ -111044,6 +111085,8 @@ var ts; if (!contextToken) return undefined; switch (contextToken.kind) { + case 62 /* EqualsToken */: // class c { public prop = | /* global completions */ } + return undefined; case 26 /* SemicolonToken */: // class c {getValue(): number; | } case 19 /* CloseBraceToken */: // class c { method() { } | } // class c { method() { } b| } @@ -111170,8 +111213,12 @@ var ts; case 103 /* SwitchKeyword */: return useParent(node.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); case 78 /* CaseKeyword */: - case 84 /* DefaultKeyword */: - return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + case 84 /* DefaultKeyword */: { + if (ts.isDefaultClause(node.parent) || ts.isCaseClause(node.parent)) { + return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + } + return undefined; + } case 77 /* BreakKeyword */: case 82 /* ContinueKeyword */: return useParent(node.parent, ts.isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences); @@ -112519,9 +112566,7 @@ var ts; return __assign(__assign({}, documentSpan), { isWriteAccess: false, isDefinition: false }); } var kind = entry.kind, node = entry.node; - return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: node.kind === 84 /* DefaultKeyword */ - || !!ts.getDeclarationFromName(node) - || ts.isLiteralComputedPropertyDeclarationName(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined }); + return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: isDefinitionForReference(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined }); } FindAllReferences.toReferenceEntry = toReferenceEntry; function entryToDocumentSpan(entry) { @@ -112629,6 +112674,12 @@ var ts; var decl = ts.getDeclarationFromName(node); return !!decl && declarationIsWriteAccess(decl) || node.kind === 84 /* DefaultKeyword */ || ts.isWriteAccess(node); } + function isDefinitionForReference(node) { + return node.kind === 84 /* DefaultKeyword */ + || !!ts.getDeclarationFromName(node) + || ts.isLiteralComputedPropertyDeclarationName(node) + || (node.kind === 129 /* ConstructorKeyword */ && ts.isConstructorDeclaration(node.parent)); + } /** * True if 'decl' provides a value, as in `function f() {}`; * false if 'decl' is just a location for a future write, as in 'let x;' @@ -122924,27 +122975,62 @@ var ts; this.insertNodeAtStartWorker(sourceFile, obj, newElement); }; ChangeTracker.prototype.insertNodeAtStartWorker = function (sourceFile, cls, newElement) { - var clsStart = cls.getStart(sourceFile); - var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) - + this.formatContext.options.indentSize; - this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, __assign({ indentation: indentation }, this.getInsertNodeAtStartPrefixSuffix(sourceFile, cls))); + var _a; + var indentation = (_a = this.guessIndentationFromExistingMembers(sourceFile, cls)) !== null && _a !== void 0 ? _a : this.computeIndentationForNewMember(sourceFile, cls); + this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, this.getInsertNodeAtStartInsertOptions(sourceFile, cls, indentation)); }; - ChangeTracker.prototype.getInsertNodeAtStartPrefixSuffix = function (sourceFile, cls) { - var comma = ts.isObjectLiteralExpression(cls) ? "," : ""; - if (getMembersOrProperties(cls).length === 0) { - if (ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile })) { - // For `class C {\n}`, don't add the trailing "\n" - var _a = getClassOrObjectBraceEnds(cls, sourceFile), open = _a[0], close = _a[1]; - var shouldSuffix = open && close && ts.positionsAreOnSameLine(open, close, sourceFile); - return { prefix: this.newLineCharacter, suffix: comma + (shouldSuffix ? this.newLineCharacter : "") }; + /** + * Tries to guess the indentation from the existing members of a class/interface/object. All members must be on + * new lines and must share the same indentation. + */ + ChangeTracker.prototype.guessIndentationFromExistingMembers = function (sourceFile, cls) { + var indentation; + var lastRange = cls; + for (var _i = 0, _a = getMembersOrProperties(cls); _i < _a.length; _i++) { + var member = _a[_i]; + if (ts.rangeStartPositionsAreOnSameLine(lastRange, member, sourceFile)) { + // each indented member must be on a new line + return undefined; } - else { - return { prefix: "", suffix: comma + this.newLineCharacter }; + var memberStart = member.getStart(sourceFile); + var memberIndentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); + if (indentation === undefined) { + indentation = memberIndentation; } + else if (memberIndentation !== indentation) { + // indentation of multiple members is not consistent + return undefined; + } + lastRange = member; } - else { - return { prefix: this.newLineCharacter, suffix: comma }; - } + return indentation; + }; + ChangeTracker.prototype.computeIndentationForNewMember = function (sourceFile, cls) { + var _a; + var clsStart = cls.getStart(sourceFile); + return ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) + + ((_a = this.formatContext.options.indentSize) !== null && _a !== void 0 ? _a : 4); + }; + ChangeTracker.prototype.getInsertNodeAtStartInsertOptions = function (sourceFile, cls, indentation) { + // Rules: + // - Always insert leading newline. + // - For object literals: + // - Add a trailing comma if there are existing members in the node, or the source file is not a JSON file + // (because trailing commas are generally illegal in a JSON file). + // - Add a leading comma if the source file is not a JSON file, there are existing insertions, + // and the node is empty (because we didn't add a trailing comma per the previous rule). + // - Only insert a trailing newline if body is single-line and there are no other insertions for the node. + // NOTE: This is handled in `finishClassesWithNodesInsertedAtStart`. + var members = getMembersOrProperties(cls); + var isEmpty = members.length === 0; + var isFirstInsertion = ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile }); + var insertTrailingComma = ts.isObjectLiteralExpression(cls) && (!ts.isJsonSourceFile(sourceFile) || !isEmpty); + var insertLeadingComma = ts.isObjectLiteralExpression(cls) && ts.isJsonSourceFile(sourceFile) && isEmpty && !isFirstInsertion; + return { + indentation: indentation, + prefix: (insertLeadingComma ? "," : "") + this.newLineCharacter, + suffix: insertTrailingComma ? "," : "" + }; }; ChangeTracker.prototype.insertNodeAfterComma = function (sourceFile, after, newNode) { var endPosition = this.insertNodeAfterWorker(sourceFile, this.nextCommaToken(sourceFile, after) || after, newNode); @@ -123146,9 +123232,16 @@ var ts; this.classesWithNodesInsertedAtStart.forEach(function (_a) { var node = _a.node, sourceFile = _a.sourceFile; var _b = getClassOrObjectBraceEnds(node, sourceFile), openBraceEnd = _b[0], closeBraceEnd = _b[1]; - // For `class C { }` remove the whitespace inside the braces. - if (openBraceEnd && closeBraceEnd && ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) { - _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); + if (openBraceEnd !== undefined && closeBraceEnd !== undefined) { + var isEmpty = getMembersOrProperties(node).length === 0; + var isSingleLine = ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile); + if (isEmpty && isSingleLine && openBraceEnd !== closeBraceEnd - 1) { + // For `class C { }` remove the whitespace inside the braces. + _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); + } + if (isSingleLine) { + _this.insertText(sourceFile, closeBraceEnd - 1, _this.newLineCharacter); + } } }); }; @@ -123724,10 +123817,10 @@ var ts; ? ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag[0]), diag.slice(1)) : ts.getLocaleSpecificMessage(diag); } - function createCodeFixActionNoFixId(fixName, changes, description) { + function createCodeFixActionWithoutFixAll(fixName, changes, description) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined); } - codefix.createCodeFixActionNoFixId = createCodeFixActionNoFixId; + codefix.createCodeFixActionWithoutFixAll = createCodeFixActionWithoutFixAll; function createCodeFixAction(fixName, changes, description, fixId, fixAllDescription, command) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, diagnosticToString(fixAllDescription), command); } @@ -123753,8 +123846,26 @@ var ts; return ts.arrayFrom(errorCodeToFixes.keys()); } codefix.getSupportedErrorCodes = getSupportedErrorCodes; + function removeFixIdIfFixAllUnavailable(registration, diagnostics) { + var errorCodes = registration.errorCodes; + var maybeFixableDiagnostics = 0; + for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { + var diag = diagnostics_1[_i]; + if (ts.contains(errorCodes, diag.code)) + maybeFixableDiagnostics++; + if (maybeFixableDiagnostics > 1) + break; + } + var fixAllUnavailable = maybeFixableDiagnostics < 2; + return function (_a) { + var fixId = _a.fixId, fixAllDescription = _a.fixAllDescription, action = __rest(_a, ["fixId", "fixAllDescription"]); + return fixAllUnavailable ? action : __assign(__assign({}, action), { fixId: fixId, fixAllDescription: fixAllDescription }); + }; + } function getFixes(context) { - return ts.flatMap(errorCodeToFixes.get(String(context.errorCode)) || ts.emptyArray, function (f) { return f.getCodeActions(context); }); + var diagnostics = getDiagnostics(context); + var registrations = errorCodeToFixes.get(String(context.errorCode)); + return ts.flatMap(registrations, function (f) { return ts.map(f.getCodeActions(context), removeFixIdIfFixAllUnavailable(f, diagnostics)); }); } codefix.getFixes = getFixes; function getAllFixes(context) { @@ -123776,16 +123887,19 @@ var ts; return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands); } codefix.codeFixAll = codeFixAll; - function eachDiagnostic(_a, errorCodes, cb) { - var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken; - for (var _i = 0, _b = program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); _i < _b.length; _i++) { - var diag = _b[_i]; + function eachDiagnostic(context, errorCodes, cb) { + for (var _i = 0, _a = getDiagnostics(context); _i < _a.length; _i++) { + var diag = _a[_i]; if (ts.contains(errorCodes, diag.code)) { cb(diag); } } } codefix.eachDiagnostic = eachDiagnostic; + function getDiagnostics(_a) { + var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken; + return program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); + } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ @@ -123842,6 +123956,28 @@ var ts; })(ts || (ts = {})); /* @internal */ var ts; +(function (ts) { + var codefix; + (function (codefix) { + codefix.registerCodeFix({ + errorCodes: [ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code], + getCodeActions: function (context) { + var sourceFile = context.sourceFile; + var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { + var exportDeclaration = ts.createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, ts.createNamedExports([]), + /*moduleSpecifier*/ undefined, + /*isTypeOnly*/ false); + changes.insertNodeAtEndOfScope(sourceFile, sourceFile, exportDeclaration); + }); + return [codefix.createCodeFixActionWithoutFixAll("addEmptyExportDeclaration", changes, ts.Diagnostics.Add_export_to_make_this_file_into_a_module)]; + }, + }); + })(codefix = ts.codefix || (ts.codefix = {})); +})(ts || (ts = {})); +/* @internal */ +var ts; (function (ts) { var codefix; (function (codefix) { @@ -123912,7 +124048,9 @@ var ts; makeChange(t, errorCode, sourceFile, checker, expression, fixedDeclarations); } }); - return codefix.createCodeFixActionNoFixId("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 + // No fix-all because it will already be included once with the use site fix, + // and for simplicity the fix-all doesn‘t let the user choose between use-site and declaration-site fixes. + return codefix.createCodeFixActionWithoutFixAll("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 ? [ts.Diagnostics.Add_await_to_initializer_for_0, awaitableInitializers.initializers[0].declarationSymbol.name] : ts.Diagnostics.Add_await_to_initializers); } @@ -124131,7 +124269,7 @@ var ts; if (forInitializer) return applyChange(changeTracker, forInitializer, sourceFile, fixedNodes); var parent = token.parent; - if (ts.isBinaryExpression(parent) && ts.isExpressionStatement(parent.parent)) { + if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isExpressionStatement(parent.parent)) { return applyChange(changeTracker, token, sourceFile, fixedNodes); } if (ts.isArrayLiteralExpression(parent)) { @@ -124193,7 +124331,9 @@ var ts; if (expression.operatorToken.kind === 27 /* CommaToken */) { return ts.every([expression.left, expression.right], function (expression) { return expressionCouldBeVariableDeclaration(expression, checker); }); } - return ts.isIdentifier(expression.left) && !checker.getSymbolAtLocation(expression.left); + return expression.operatorToken.kind === 62 /* EqualsToken */ + && ts.isIdentifier(expression.left) + && !checker.getSymbolAtLocation(expression.left); } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); @@ -126184,7 +126324,7 @@ var ts; } }); // No support for fix-all since this applies to the whole file at once anyway. - return [codefix.createCodeFixActionNoFixId("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)]; + return [codefix.createCodeFixActionWithoutFixAll("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)]; }, }); function fixImportOfModuleExports(importingFile, exportingFile, changes, quotePreference) { @@ -126783,7 +126923,8 @@ var ts; (function (ts) { var codefix; (function (codefix) { - codefix.importFixId = "fixMissingImport"; + codefix.importFixName = "import"; + var importFixId = "fixMissingImport"; var errorCodes = [ ts.Diagnostics.Cannot_find_name_0.code, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, @@ -126804,7 +126945,7 @@ var ts; var quotePreference = ts.getQuotePreference(sourceFile, preferences); return fixes.map(function (fix) { return codeActionForFix(context, sourceFile, symbolName, fix, quotePreference); }); }, - fixIds: [codefix.importFixId], + fixIds: [importFixId], getAllCodeActions: function (context) { var sourceFile = context.sourceFile, preferences = context.preferences; // Namespace fixes don't conflict, so just build a list. @@ -127236,7 +127377,7 @@ var ts; var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) { diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, quotePreference); }); - return codefix.createCodeFixAction("import", changes, diag, codefix.importFixId, ts.Diagnostics.Add_all_missing_imports); + return codefix.createCodeFixAction(codefix.importFixName, changes, diag, importFixId, ts.Diagnostics.Add_all_missing_imports); } function codeActionForFixWorker(changes, sourceFile, symbolName, fix, quotePreference) { switch (fix.kind) { @@ -127534,17 +127675,17 @@ var ts; var info = getInfo(sourceFile, context.span.start, context); if (!info) return undefined; - var node = info.node, suggestion = info.suggestion; + var node = info.node, suggestedSymbol = info.suggestedSymbol; var target = context.host.getCompilationSettings().target; - var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestion, target); }); - return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, suggestion], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)]; + var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestedSymbol, target); }); + return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, ts.symbolName(suggestedSymbol)], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)]; }, fixIds: [fixId], getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { var info = getInfo(diag.file, diag.start, context); var target = context.host.getCompilationSettings().target; if (info) - doChange(changes, context.sourceFile, info.node, info.suggestion, target); + doChange(changes, context.sourceFile, info.node, info.suggestedSymbol, target); }); }, }); function getInfo(sourceFile, pos, context) { @@ -127553,34 +127694,42 @@ var ts; // ^^^^^^^ var node = ts.getTokenAtPosition(sourceFile, pos); var checker = context.program.getTypeChecker(); - var suggestion; + var suggestedSymbol; if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) { - ts.Debug.assert(node.kind === 75 /* Identifier */, "Expected an identifier for spelling (property access)"); + ts.Debug.assert(ts.isIdentifierOrPrivateIdentifier(node), "Expected an identifier for spelling (property access)"); var containingType = checker.getTypeAtLocation(node.parent.expression); if (node.parent.flags & 32 /* OptionalChain */) { containingType = checker.getNonNullableType(containingType); } - suggestion = checker.getSuggestionForNonexistentProperty(node, containingType); + var name = node; + suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(name, containingType); } else if (ts.isImportSpecifier(node.parent) && node.parent.name === node) { ts.Debug.assert(node.kind === 75 /* Identifier */, "Expected an identifier for spelling (import)"); var importDeclaration = ts.findAncestor(node, ts.isImportDeclaration); var resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration); if (resolvedSourceFile && resolvedSourceFile.symbol) { - suggestion = checker.getSuggestionForNonexistentExport(node, resolvedSourceFile.symbol); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(node, resolvedSourceFile.symbol); } } else { var meaning = ts.getMeaningFromLocation(node); var name = ts.getTextOfNode(node); ts.Debug.assert(name !== undefined, "name should be defined"); - suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); } - return suggestion === undefined ? undefined : { node: node, suggestion: suggestion }; + return suggestedSymbol === undefined ? undefined : { node: node, suggestedSymbol: suggestedSymbol }; } - function doChange(changes, sourceFile, node, suggestion, target) { + function doChange(changes, sourceFile, node, suggestedSymbol, target) { + var suggestion = ts.symbolName(suggestedSymbol); if (!ts.isIdentifierText(suggestion, target) && ts.isPropertyAccessExpression(node.parent)) { - changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion))); + var valDecl = suggestedSymbol.valueDeclaration; + if (ts.isNamedDeclaration(valDecl) && ts.isPrivateIdentifier(valDecl.name)) { + changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion)); + } + else { + changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion))); + } } else { changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion)); @@ -127844,7 +127993,7 @@ var ts; /*modifiers*/ undefined, [indexingParameter], typeNode); var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.insertNodeAtClassStart(declSourceFile, classDeclaration, indexSignature); }); // No fixId here because code-fix-all currently only works on adding individual named properties. - return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]); + return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]); } function getActionForMethodDeclaration(context, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences) { // Private methods are not implemented yet. @@ -128129,7 +128278,7 @@ var ts; return undefined; } var changes = ts.textChanges.ChangeTracker.with(context, function (changeTracker) { return doChange(changeTracker, configFile); }); - return [codefix.createCodeFixActionNoFixId(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; + return [codefix.createCodeFixActionWithoutFixAll(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; }, fixIds: [fixId], getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes) { @@ -128163,7 +128312,7 @@ var ts; return doChange(changeTracker, configFile); }); return [ - codefix.createCodeFixActionNoFixId(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) + codefix.createCodeFixActionWithoutFixAll(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) ]; }, fixIds: [fixID], @@ -128184,6 +128333,49 @@ var ts; })(ts || (ts = {})); /* @internal */ var ts; +(function (ts) { + var codefix; + (function (codefix) { + codefix.registerCodeFix({ + errorCodes: [ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code], + getCodeActions: function (context) { + var compilerOptions = context.program.getCompilerOptions(); + var configFile = compilerOptions.configFile; + if (configFile === undefined) { + return undefined; + } + var codeFixes = []; + var moduleKind = ts.getEmitModuleKind(compilerOptions); + var moduleOutOfRange = moduleKind >= ts.ModuleKind.ES2015 && moduleKind < ts.ModuleKind.ESNext; + if (moduleOutOfRange) { + var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { + codefix.setJsonCompilerOptionValue(changes, configFile, "module", ts.createStringLiteral("esnext")); + }); + codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixModuleOption", changes, [ts.Diagnostics.Set_the_module_option_in_your_configuration_file_to_0, "esnext"])); + } + var target = ts.getEmitScriptTarget(compilerOptions); + var targetOutOfRange = target < 4 /* ES2017 */ || target > 99 /* ESNext */; + if (targetOutOfRange) { + var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) { + var configObject = ts.getTsConfigObjectLiteralExpression(configFile); + if (!configObject) + return; + var options = [["target", ts.createStringLiteral("es2017")]]; + if (moduleKind === ts.ModuleKind.CommonJS) { + // Ensure we preserve the default module kind (commonjs), as targets >= ES2015 have a default module kind of es2015. + options.push(["module", ts.createStringLiteral("commonjs")]); + } + codefix.setJsonCompilerOptionValues(tracker, configFile, options); + }); + codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixTargetOption", changes, [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0, "es2017"])); + } + return codeFixes.length ? codeFixes : undefined; + } + }); + })(codefix = ts.codefix || (ts.codefix = {})); +})(ts || (ts = {})); +/* @internal */ +var ts; (function (ts) { var codefix; (function (codefix) { @@ -128336,7 +128528,7 @@ var ts; }); if (deletion.length) { var name = ts.isComputedPropertyName(token.parent) ? token.parent : token; - result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_declaration_for_Colon_0, name.getText(sourceFile)])); + result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_unused_declaration_for_Colon_0, name.getText(sourceFile)])); } } var prefix = ts.textChanges.ChangeTracker.with(context, function (t) { return tryPrefixDeclaration(t, errorCode, sourceFile, token); }); @@ -128697,7 +128889,7 @@ var ts; (function (codefix) { var fixId = "fixAwaitInSyncFunction"; var errorCodes = [ - ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function.code, + ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code, ]; codefix.registerCodeFix({ @@ -128789,7 +128981,7 @@ var ts; } var fixes = [ // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file. - codefix.createCodeFixActionNoFixId(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [ + codefix.createCodeFixActionWithoutFixAll(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [ ts.createTextChange(sourceFile.checkJsDirective ? ts.createTextSpanFromBounds(sourceFile.checkJsDirective.pos, sourceFile.checkJsDirective.end) : ts.createTextSpan(0, 0), "// @ts-nocheck" + ts.getNewLineOrDefaultFromHost(host, formatContext.options)), @@ -129056,29 +129248,37 @@ var ts; } return undefined; } - function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) { + function setJsonCompilerOptionValues(changeTracker, configFile, options) { var tsconfigObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile); if (!tsconfigObjectLiteral) return undefined; var compilerOptionsProperty = findJsonProperty(tsconfigObjectLiteral, "compilerOptions"); if (compilerOptionsProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral([ - createJsonPropertyAssignment(optionName, optionValue), - ]))); + changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral(options.map(function (_a) { + var optionName = _a[0], optionValue = _a[1]; + return createJsonPropertyAssignment(optionName, optionValue); + }), /*multiLine*/ true))); return; } var compilerOptions = compilerOptionsProperty.initializer; if (!ts.isObjectLiteralExpression(compilerOptions)) { return; } - var optionProperty = findJsonProperty(compilerOptions, optionName); - if (optionProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); - } - else { - changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + for (var _i = 0, options_1 = options; _i < options_1.length; _i++) { + var _a = options_1[_i], optionName = _a[0], optionValue = _a[1]; + var optionProperty = findJsonProperty(compilerOptions, optionName); + if (optionProperty === undefined) { + changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); + } + else { + changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + } } } + codefix.setJsonCompilerOptionValues = setJsonCompilerOptionValues; + function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) { + setJsonCompilerOptionValues(changeTracker, configFile, [[optionName, optionValue]]); + } codefix.setJsonCompilerOptionValue = setJsonCompilerOptionValue; function createJsonPropertyAssignment(name, initializer) { return ts.createPropertyAssignment(ts.createStringLiteral(name), initializer); @@ -129113,7 +129313,7 @@ var ts; } function createAction(context, sourceFile, node, replacement) { var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, node, replacement); }); - return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); + return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); } codefix.registerCodeFix({ errorCodes: [ @@ -129171,7 +129371,7 @@ var ts; if (ts.isExpression(expr) && !(ts.isNamedDeclaration(expr.parent) && expr.parent.name === expr)) { var sourceFile_1 = context.sourceFile; var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile_1, expr, ts.createPropertyAccess(expr, "default"), {}); }); - fixes.push(codefix.createCodeFixActionNoFixId(fixName, changes, ts.Diagnostics.Use_synthetic_default_member)); + fixes.push(codefix.createCodeFixActionWithoutFixAll(fixName, changes, ts.Diagnostics.Use_synthetic_default_member)); } return fixes; } diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index c271b332e67be..d434587d9d587 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -63,6 +63,17 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || @@ -1414,6 +1425,11 @@ var ts; return result; } ts.clone = clone; + /** + * Creates a new object by adding the own properties of `second`, then the own properties of `first`. + * + * NOTE: This means that if a property exists in both `first` and `second`, the property in `first` will be chosen. + */ function extend(first, second) { var result = {}; for (var id in second) { @@ -5734,10 +5750,13 @@ var ts; } } function readFileWorker(fileName, _encoding) { - if (!fileExists(fileName)) { + var buffer; + try { + buffer = _fs.readFileSync(fileName); + } + catch (e) { return undefined; } - var buffer = _fs.readFileSync(fileName); var len = buffer.length; if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) { // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js, @@ -5787,23 +5806,30 @@ var ts; function getAccessibleFileSystemEntries(path) { ts.perfLogger.logEvent("ReadDir: " + (path || ".")); try { - var entries = _fs.readdirSync(path || ".").sort(); + var entries = _fs.readdirSync(path || ".", { withFileTypes: true }); var files = []; var directories = []; for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { - var entry = entries_2[_i]; + var dirent = entries_2[_i]; + // withFileTypes is not supported before Node 10.10. + var entry = typeof dirent === "string" ? dirent : dirent.name; // This is necessary because on some file system node fails to exclude // "." and "..". See https://github.com/nodejs/node/issues/4002 if (entry === "." || entry === "..") { continue; } - var name = ts.combinePaths(path, entry); var stat = void 0; - try { - stat = _fs.statSync(name); + if (typeof dirent === "string" || dirent.isSymbolicLink()) { + var name = ts.combinePaths(path, entry); + try { + stat = _fs.statSync(name); + } + catch (e) { + continue; + } } - catch (e) { - continue; + else { + stat = dirent; } if (stat.isFile()) { files.push(entry); @@ -5812,6 +5838,8 @@ var ts; directories.push(entry); } } + files.sort(); + directories.sort(); return { files: files, directories: directories }; } catch (e) { @@ -5841,8 +5869,7 @@ var ts; return fileSystemEntryExists(path, 1 /* Directory */); } function getDirectories(path) { - ts.perfLogger.logEvent("ReadDir: " + path); - return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); }); + return getAccessibleFileSystemEntries(path).directories.slice(); } function realpath(path) { try { @@ -6836,7 +6863,7 @@ var ts; Keywords_cannot_contain_escape_characters: diag(1260, ts.DiagnosticCategory.Error, "Keywords_cannot_contain_escape_characters_1260", "Keywords cannot contain escape characters."), Already_included_file_name_0_differs_from_file_name_1_only_in_casing: diag(1261, ts.DiagnosticCategory.Error, "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", "Already included file name '{0}' differs from file name '{1}' only in casing."), with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."), - await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."), + await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules: diag(1308, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", "'await' expressions are only allowed within async functions and at the top levels of modules."), can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."), The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."), Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."), @@ -6884,14 +6911,13 @@ var ts; An_enum_member_name_must_be_followed_by_a_or: diag(1357, ts.DiagnosticCategory.Error, "An_enum_member_name_must_be_followed_by_a_or_1357", "An enum member name must be followed by a ',', '=', or '}'."), Tagged_template_expressions_are_not_permitted_in_an_optional_chain: diag(1358, ts.DiagnosticCategory.Error, "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", "Tagged template expressions are not permitted in an optional chain."), Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here: diag(1359, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", "Identifier expected. '{0}' is a reserved word that cannot be used here."), - Did_you_mean_to_parenthesize_this_function_type: diag(1360, ts.DiagnosticCategory.Error, "Did_you_mean_to_parenthesize_this_function_type_1360", "Did you mean to parenthesize this function type?"), Type_only_0_must_reference_a_type_but_1_is_a_value: diag(1361, ts.DiagnosticCategory.Error, "Type_only_0_must_reference_a_type_but_1_is_a_value_1361", "Type-only {0} must reference a type, but '{1}' is a value."), Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported: diag(1362, ts.DiagnosticCategory.Error, "Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported_1362", "Enum '{0}' cannot be used as a value because only its type has been imported."), A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both: diag(1363, ts.DiagnosticCategory.Error, "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", "A type-only import can specify a default import or named bindings, but not both."), Convert_to_type_only_export: diag(1364, ts.DiagnosticCategory.Message, "Convert_to_type_only_export_1364", "Convert to type-only export"), Convert_all_re_exported_types_to_type_only_exports: diag(1365, ts.DiagnosticCategory.Message, "Convert_all_re_exported_types_to_type_only_exports_1365", "Convert all re-exported types to type-only exports"), Split_into_two_separate_import_declarations: diag(1366, ts.DiagnosticCategory.Message, "Split_into_two_separate_import_declarations_1366", "Split into two separate import declarations"), - Split_all_invalid_type_only_imports: diag(1377, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1377", "Split all invalid type-only imports"), + Split_all_invalid_type_only_imports: diag(1367, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1367", "Split all invalid type-only imports"), Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types: diag(1368, ts.DiagnosticCategory.Message, "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_1368", "Specify emit/checking behavior for imports that are only used for types"), Did_you_mean_0: diag(1369, ts.DiagnosticCategory.Message, "Did_you_mean_0_1369", "Did you mean '{0}'?"), Only_ECMAScript_imports_may_use_import_type: diag(1370, ts.DiagnosticCategory.Error, "Only_ECMAScript_imports_may_use_import_type_1370", "Only ECMAScript imports may use 'import type'."), @@ -6899,7 +6925,8 @@ var ts; This_import_may_be_converted_to_a_type_only_import: diag(1372, ts.DiagnosticCategory.Suggestion, "This_import_may_be_converted_to_a_type_only_import_1372", "This import may be converted to a type-only import."), Convert_to_type_only_import: diag(1373, ts.DiagnosticCategory.Message, "Convert_to_type_only_import_1373", "Convert to type-only import"), Convert_all_imports_not_used_as_a_value_to_type_only_imports: diag(1374, ts.DiagnosticCategory.Message, "Convert_all_imports_not_used_as_a_value_to_type_only_imports_1374", "Convert all imports not used as a value to type-only imports"), - await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher: diag(1375, ts.DiagnosticCategory.Error, "await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnex_1375", "'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher."), + await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module: diag(1375, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."), + Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher: diag(1376, ts.DiagnosticCategory.Error, "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_t_1376", "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher."), The_types_of_0_are_incompatible_between_these_types: diag(2200, ts.DiagnosticCategory.Error, "The_types_of_0_are_incompatible_between_these_types_2200", "The types of '{0}' are incompatible between these types."), The_types_returned_by_0_are_incompatible_between_these_types: diag(2201, ts.DiagnosticCategory.Error, "The_types_returned_by_0_are_incompatible_between_these_types_2201", "The types returned by '{0}' are incompatible between these types."), Call_signature_return_types_0_and_1_are_incompatible: diag(2202, ts.DiagnosticCategory.Error, "Call_signature_return_types_0_and_1_are_incompatible_2202", "Call signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true), @@ -7845,7 +7872,7 @@ var ts; Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"), Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"), Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"), - Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'"), + Remove_unused_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_unused_declaration_for_Colon_0_90004", "Remove unused declaration for: '{0}'"), Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"), Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"), Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"), @@ -7968,10 +7995,12 @@ var ts; Prefix_with_declare: diag(95094, ts.DiagnosticCategory.Message, "Prefix_with_declare_95094", "Prefix with 'declare'"), Prefix_all_incorrect_property_declarations_with_declare: diag(95095, ts.DiagnosticCategory.Message, "Prefix_all_incorrect_property_declarations_with_declare_95095", "Prefix all incorrect property declarations with 'declare'"), Convert_to_template_string: diag(95096, ts.DiagnosticCategory.Message, "Convert_to_template_string_95096", "Convert to template string"), + Add_export_to_make_this_file_into_a_module: diag(95097, ts.DiagnosticCategory.Message, "Add_export_to_make_this_file_into_a_module_95097", "Add 'export {}' to make this file into a module"), + Set_the_target_option_in_your_configuration_file_to_0: diag(95098, ts.DiagnosticCategory.Message, "Set_the_target_option_in_your_configuration_file_to_0_95098", "Set the 'target' option in your configuration file to '{0}'"), + Set_the_module_option_in_your_configuration_file_to_0: diag(95099, ts.DiagnosticCategory.Message, "Set_the_module_option_in_your_configuration_file_to_0_95099", "Set the 'module' option in your configuration file to '{0}'"), No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."), Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."), JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array: diag(18007, ts.DiagnosticCategory.Error, "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", "JSX expressions may not use the comma operator. Did you mean to write an array?"), - can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Private_identifiers_cannot_be_used_as_parameters: diag(18009, ts.DiagnosticCategory.Error, "Private_identifiers_cannot_be_used_as_parameters_18009", "Private identifiers cannot be used as parameters"), An_accessibility_modifier_cannot_be_used_with_a_private_identifier: diag(18010, ts.DiagnosticCategory.Error, "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", "An accessibility modifier cannot be used with a private identifier."), The_operand_of_a_delete_operator_cannot_be_a_private_identifier: diag(18011, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", "The operand of a 'delete' operator cannot be a private identifier."), @@ -7986,6 +8015,7 @@ var ts; A_method_cannot_be_named_with_a_private_identifier: diag(18022, ts.DiagnosticCategory.Error, "A_method_cannot_be_named_with_a_private_identifier_18022", "A method cannot be named with a private identifier."), An_accessor_cannot_be_named_with_a_private_identifier: diag(18023, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_named_with_a_private_identifier_18023", "An accessor cannot be named with a private identifier."), An_enum_member_cannot_be_named_with_a_private_identifier: diag(18024, ts.DiagnosticCategory.Error, "An_enum_member_cannot_be_named_with_a_private_identifier_18024", "An enum member cannot be named with a private identifier."), + can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Compiler_reserves_name_0_when_emitting_private_identifier_downlevel: diag(18027, ts.DiagnosticCategory.Error, "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", "Compiler reserves name '{0}' when emitting private identifier downlevel."), Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher: diag(18028, ts.DiagnosticCategory.Error, "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", "Private identifiers are only available when targeting ECMAScript 2015 and higher."), Private_identifiers_are_not_allowed_in_variable_declarations: diag(18029, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_in_variable_declarations_18029", "Private identifiers are not allowed in variable declarations."), @@ -26177,6 +26207,7 @@ var ts; error: 2 /* Error */ }), affectsEmit: true, + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types }, @@ -26434,12 +26465,15 @@ var ts; { name: "experimentalDecorators", type: "boolean", + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", + affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, @@ -26453,6 +26487,7 @@ var ts; { name: "resolveJsonModule", type: "boolean", + affectsModuleResolution: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Include_modules_imported_with_json_extension }, @@ -26657,6 +26692,7 @@ var ts; name: "useDefineForClassFields", type: "boolean", affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Emit_class_fields_with_Define_instead_of_Set, }, @@ -30533,7 +30569,7 @@ var ts; case 104 /* ThisKeyword */: case 194 /* PropertyAccessExpression */: case 195 /* ElementAccessExpression */: - return isNarrowableReference(expr); + return containsNarrowableReference(expr); case 196 /* CallExpression */: return hasNarrowableArgument(expr); case 200 /* ParenthesizedExpression */: @@ -30550,20 +30586,22 @@ var ts; function isNarrowableReference(expr) { return expr.kind === 75 /* Identifier */ || expr.kind === 104 /* ThisKeyword */ || expr.kind === 102 /* SuperKeyword */ || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || - ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) || - ts.isOptionalChain(expr); + ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression); + } + function containsNarrowableReference(expr) { + return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); } function hasNarrowableArgument(expr) { if (expr.arguments) { for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) { var argument = _a[_i]; - if (isNarrowableReference(argument)) { + if (containsNarrowableReference(argument)) { return true; } } } if (expr.expression.kind === 194 /* PropertyAccessExpression */ && - isNarrowableReference(expr.expression.expression)) { + containsNarrowableReference(expr.expression.expression)) { return true; } return false; @@ -30577,7 +30615,7 @@ var ts; function isNarrowingBinaryExpression(expr) { switch (expr.operatorToken.kind) { case 62 /* EqualsToken */: - return isNarrowableReference(expr.left); + return containsNarrowableReference(expr.left); case 34 /* EqualsEqualsToken */: case 35 /* ExclamationEqualsToken */: case 36 /* EqualsEqualsEqualsToken */: @@ -30605,7 +30643,7 @@ var ts; return isNarrowableOperand(expr.right); } } - return isNarrowableReference(expr); + return containsNarrowableReference(expr); } function createBranchLabel() { return initFlowNode({ flags: 4 /* BranchLabel */, antecedents: undefined }); @@ -34017,6 +34055,7 @@ var ts; var currentNode; var emptySymbols = ts.createSymbolTable(); var identityMapper = ts.identity; + var arrayVariances = [1 /* Covariant */]; var compilerOptions = host.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); @@ -34265,9 +34304,12 @@ var ts; isArrayLikeType: isArrayLikeType, isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant, getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes, - getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); }, + getSuggestedSymbolForNonexistentProperty: getSuggestedSymbolForNonexistentProperty, + getSuggestionForNonexistentProperty: getSuggestionForNonexistentProperty, + getSuggestedSymbolForNonexistentSymbol: function (location, name, meaning) { return getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, - getSuggestionForNonexistentExport: function (node, target) { return getSuggestionForNonexistentExport(node, target); }, + getSuggestedSymbolForNonexistentModule: getSuggestedSymbolForNonexistentModule, + getSuggestionForNonexistentExport: getSuggestionForNonexistentExport, getBaseConstraintOfType: getBaseConstraintOfType, getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; }, resolveName: function (name, location, meaning, excludeGlobals) { @@ -35859,9 +35901,11 @@ var ts; // if symbolFromVariable is export - get its final target symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias); var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias); - // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default - if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default" /* Default */) { - symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + if (symbolFromModule === undefined && name.escapedText === "default" /* Default */) { + var file = ts.find(moduleSymbol.declarations, ts.isSourceFile); + if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) { + symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + } } var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : @@ -45502,8 +45546,9 @@ var ts; } /** We approximate own properties as non-methods plus methods that are inside the object literal */ function isSpreadableProperty(prop) { - return !(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || - !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); }); + return !ts.some(prop.declarations, ts.isPrivateIdentifierPropertyDeclaration) && + (!(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || + !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); })); } function getSpreadSymbol(prop, readonly) { var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */); @@ -47829,6 +47874,9 @@ var ts; source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { var variances = getAliasVariances(source.aliasSymbol); + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -48023,6 +48071,12 @@ var ts; // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. var variances = getVariances(source.target); + // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This + // effectively means we measure variance only from type parameter occurrences that aren't nested in + // recursive instantiations of the generic type. + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -48808,8 +48862,7 @@ var ts; // a digest of the type comparisons that occur for each type argument when instantiations of the // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function - // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function - // has been invoked recursively for the given generic type. + // returns the emptyArray singleton when invoked recursively for the given generic type. function getVariancesWorker(typeParameters, cache, createMarkerType) { if (typeParameters === void 0) { typeParameters = ts.emptyArray; } var variances = cache.variances; @@ -48856,9 +48909,9 @@ var ts; return variances; } function getVariances(type) { - // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters) + // Arrays and tuples are known to be covariant, no need to spend time computing this. if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8 /* Tuple */) { - return ts.emptyArray; + return arrayVariances; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); } @@ -52564,24 +52617,7 @@ var ts; } } else if (!assumeInitialized && !(getFalsyFlags(type) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) { - var diag = error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); - // See GH:32846 - if the user is using a variable whose type is () => T1 | ... | undefined - // they may have meant to specify the type as (() => T1 | ...) | undefined - // This is assumed if: the type is a FunctionType, the return type is a Union, the last constituent of - // the union is `undefined` - if (type.symbol && type.symbol.declarations.length === 1 && ts.isFunctionTypeNode(type.symbol.declarations[0])) { - var funcTypeNode = type.symbol.declarations[0]; - var returnType = getReturnTypeFromAnnotation(funcTypeNode); - if (returnType && returnType.flags & 1048576 /* Union */) { - var unionTypes_3 = funcTypeNode.type.types; - if (unionTypes_3 && unionTypes_3[unionTypes_3.length - 1].kind === 146 /* UndefinedKeyword */) { - var parenedFuncType = ts.getMutableClone(funcTypeNode); - // Highlight to the end of the second to last constituent of the union - parenedFuncType.end = unionTypes_3[unionTypes_3.length - 2].end; - ts.addRelatedInfo(diag, ts.createDiagnosticForNode(parenedFuncType, ts.Diagnostics.Did_you_mean_to_parenthesize_this_function_type)); - } - } - } + error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; } @@ -58196,12 +58232,17 @@ var ts; if (!(node.flags & 32768 /* AwaitContext */)) { if (isTopLevelAwait(node)) { var sourceFile = ts.getSourceFileOfNode(node); - if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || - languageVersion < 4 /* ES2017 */ || - !ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { - if (!hasParseDiagnostics(sourceFile)) { - var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher); + if (!hasParseDiagnostics(sourceFile)) { + var span = void 0; + if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + if (!span) + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); + diagnostics.add(diagnostic); + } + if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || languageVersion < 4 /* ES2017 */) { + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher); diagnostics.add(diagnostic); } } @@ -58211,7 +58252,7 @@ var ts; var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); var func = ts.getContainingFunction(node); if (func && func.kind !== 162 /* Constructor */ && (ts.getFunctionFlags(func) & 2 /* Async */) === 0) { var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async); @@ -96975,12 +97016,12 @@ var ts; if (!program || hasChangedAutomaticTypeDirectiveNames) { return false; } - // If number of files in the program do not match, it is not up-to-date - if (program.getRootFileNames().length !== rootFileNames.length) { + // If root file names don't match + if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) { return false; } var seenResolvedRefs; - // If project references dont match + // If project references don't match if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) { return false; } @@ -109477,7 +109518,7 @@ var ts; var contextToken = previousToken; // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. - if (contextToken && position <= contextToken.end && (ts.isIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) { + if (contextToken && position <= contextToken.end && (ts.isIdentifierOrPrivateIdentifier(contextToken) || ts.isKeyword(contextToken.kind))) { var start_1 = ts.timestamp(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined); // TODO: GH#18217 log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_1)); @@ -109720,7 +109761,7 @@ var ts; } } } - if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */)) { + if (ts.isMetaProperty(node) && (node.keywordToken === 99 /* NewKeyword */ || node.keywordToken === 96 /* ImportKeyword */) && contextToken === node.getChildAt(1)) { var completion = (node.keywordToken === 99 /* NewKeyword */) ? "target" : "meta"; symbols.push(typeChecker.createSymbol(4 /* Property */, ts.escapeLeadingUnderscores(completion))); return; @@ -111044,6 +111085,8 @@ var ts; if (!contextToken) return undefined; switch (contextToken.kind) { + case 62 /* EqualsToken */: // class c { public prop = | /* global completions */ } + return undefined; case 26 /* SemicolonToken */: // class c {getValue(): number; | } case 19 /* CloseBraceToken */: // class c { method() { } | } // class c { method() { } b| } @@ -111170,8 +111213,12 @@ var ts; case 103 /* SwitchKeyword */: return useParent(node.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); case 78 /* CaseKeyword */: - case 84 /* DefaultKeyword */: - return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + case 84 /* DefaultKeyword */: { + if (ts.isDefaultClause(node.parent) || ts.isCaseClause(node.parent)) { + return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); + } + return undefined; + } case 77 /* BreakKeyword */: case 82 /* ContinueKeyword */: return useParent(node.parent, ts.isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences); @@ -112519,9 +112566,7 @@ var ts; return __assign(__assign({}, documentSpan), { isWriteAccess: false, isDefinition: false }); } var kind = entry.kind, node = entry.node; - return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: node.kind === 84 /* DefaultKeyword */ - || !!ts.getDeclarationFromName(node) - || ts.isLiteralComputedPropertyDeclarationName(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined }); + return __assign(__assign({}, documentSpan), { isWriteAccess: isWriteAccessForReference(node), isDefinition: isDefinitionForReference(node), isInString: kind === 2 /* StringLiteral */ ? true : undefined }); } FindAllReferences.toReferenceEntry = toReferenceEntry; function entryToDocumentSpan(entry) { @@ -112629,6 +112674,12 @@ var ts; var decl = ts.getDeclarationFromName(node); return !!decl && declarationIsWriteAccess(decl) || node.kind === 84 /* DefaultKeyword */ || ts.isWriteAccess(node); } + function isDefinitionForReference(node) { + return node.kind === 84 /* DefaultKeyword */ + || !!ts.getDeclarationFromName(node) + || ts.isLiteralComputedPropertyDeclarationName(node) + || (node.kind === 129 /* ConstructorKeyword */ && ts.isConstructorDeclaration(node.parent)); + } /** * True if 'decl' provides a value, as in `function f() {}`; * false if 'decl' is just a location for a future write, as in 'let x;' @@ -122924,27 +122975,62 @@ var ts; this.insertNodeAtStartWorker(sourceFile, obj, newElement); }; ChangeTracker.prototype.insertNodeAtStartWorker = function (sourceFile, cls, newElement) { - var clsStart = cls.getStart(sourceFile); - var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) - + this.formatContext.options.indentSize; - this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, __assign({ indentation: indentation }, this.getInsertNodeAtStartPrefixSuffix(sourceFile, cls))); + var _a; + var indentation = (_a = this.guessIndentationFromExistingMembers(sourceFile, cls)) !== null && _a !== void 0 ? _a : this.computeIndentationForNewMember(sourceFile, cls); + this.insertNodeAt(sourceFile, getMembersOrProperties(cls).pos, newElement, this.getInsertNodeAtStartInsertOptions(sourceFile, cls, indentation)); }; - ChangeTracker.prototype.getInsertNodeAtStartPrefixSuffix = function (sourceFile, cls) { - var comma = ts.isObjectLiteralExpression(cls) ? "," : ""; - if (getMembersOrProperties(cls).length === 0) { - if (ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile })) { - // For `class C {\n}`, don't add the trailing "\n" - var _a = getClassOrObjectBraceEnds(cls, sourceFile), open = _a[0], close = _a[1]; - var shouldSuffix = open && close && ts.positionsAreOnSameLine(open, close, sourceFile); - return { prefix: this.newLineCharacter, suffix: comma + (shouldSuffix ? this.newLineCharacter : "") }; + /** + * Tries to guess the indentation from the existing members of a class/interface/object. All members must be on + * new lines and must share the same indentation. + */ + ChangeTracker.prototype.guessIndentationFromExistingMembers = function (sourceFile, cls) { + var indentation; + var lastRange = cls; + for (var _i = 0, _a = getMembersOrProperties(cls); _i < _a.length; _i++) { + var member = _a[_i]; + if (ts.rangeStartPositionsAreOnSameLine(lastRange, member, sourceFile)) { + // each indented member must be on a new line + return undefined; } - else { - return { prefix: "", suffix: comma + this.newLineCharacter }; + var memberStart = member.getStart(sourceFile); + var memberIndentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(memberStart, sourceFile), memberStart, sourceFile, this.formatContext.options); + if (indentation === undefined) { + indentation = memberIndentation; } + else if (memberIndentation !== indentation) { + // indentation of multiple members is not consistent + return undefined; + } + lastRange = member; } - else { - return { prefix: this.newLineCharacter, suffix: comma }; - } + return indentation; + }; + ChangeTracker.prototype.computeIndentationForNewMember = function (sourceFile, cls) { + var _a; + var clsStart = cls.getStart(sourceFile); + return ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(ts.getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) + + ((_a = this.formatContext.options.indentSize) !== null && _a !== void 0 ? _a : 4); + }; + ChangeTracker.prototype.getInsertNodeAtStartInsertOptions = function (sourceFile, cls, indentation) { + // Rules: + // - Always insert leading newline. + // - For object literals: + // - Add a trailing comma if there are existing members in the node, or the source file is not a JSON file + // (because trailing commas are generally illegal in a JSON file). + // - Add a leading comma if the source file is not a JSON file, there are existing insertions, + // and the node is empty (because we didn't add a trailing comma per the previous rule). + // - Only insert a trailing newline if body is single-line and there are no other insertions for the node. + // NOTE: This is handled in `finishClassesWithNodesInsertedAtStart`. + var members = getMembersOrProperties(cls); + var isEmpty = members.length === 0; + var isFirstInsertion = ts.addToSeen(this.classesWithNodesInsertedAtStart, ts.getNodeId(cls), { node: cls, sourceFile: sourceFile }); + var insertTrailingComma = ts.isObjectLiteralExpression(cls) && (!ts.isJsonSourceFile(sourceFile) || !isEmpty); + var insertLeadingComma = ts.isObjectLiteralExpression(cls) && ts.isJsonSourceFile(sourceFile) && isEmpty && !isFirstInsertion; + return { + indentation: indentation, + prefix: (insertLeadingComma ? "," : "") + this.newLineCharacter, + suffix: insertTrailingComma ? "," : "" + }; }; ChangeTracker.prototype.insertNodeAfterComma = function (sourceFile, after, newNode) { var endPosition = this.insertNodeAfterWorker(sourceFile, this.nextCommaToken(sourceFile, after) || after, newNode); @@ -123146,9 +123232,16 @@ var ts; this.classesWithNodesInsertedAtStart.forEach(function (_a) { var node = _a.node, sourceFile = _a.sourceFile; var _b = getClassOrObjectBraceEnds(node, sourceFile), openBraceEnd = _b[0], closeBraceEnd = _b[1]; - // For `class C { }` remove the whitespace inside the braces. - if (openBraceEnd && closeBraceEnd && ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) { - _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); + if (openBraceEnd !== undefined && closeBraceEnd !== undefined) { + var isEmpty = getMembersOrProperties(node).length === 0; + var isSingleLine = ts.positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile); + if (isEmpty && isSingleLine && openBraceEnd !== closeBraceEnd - 1) { + // For `class C { }` remove the whitespace inside the braces. + _this.deleteRange(sourceFile, ts.createRange(openBraceEnd, closeBraceEnd - 1)); + } + if (isSingleLine) { + _this.insertText(sourceFile, closeBraceEnd - 1, _this.newLineCharacter); + } } }); }; @@ -123724,10 +123817,10 @@ var ts; ? ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag[0]), diag.slice(1)) : ts.getLocaleSpecificMessage(diag); } - function createCodeFixActionNoFixId(fixName, changes, description) { + function createCodeFixActionWithoutFixAll(fixName, changes, description) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined); } - codefix.createCodeFixActionNoFixId = createCodeFixActionNoFixId; + codefix.createCodeFixActionWithoutFixAll = createCodeFixActionWithoutFixAll; function createCodeFixAction(fixName, changes, description, fixId, fixAllDescription, command) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, diagnosticToString(fixAllDescription), command); } @@ -123753,8 +123846,26 @@ var ts; return ts.arrayFrom(errorCodeToFixes.keys()); } codefix.getSupportedErrorCodes = getSupportedErrorCodes; + function removeFixIdIfFixAllUnavailable(registration, diagnostics) { + var errorCodes = registration.errorCodes; + var maybeFixableDiagnostics = 0; + for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { + var diag = diagnostics_1[_i]; + if (ts.contains(errorCodes, diag.code)) + maybeFixableDiagnostics++; + if (maybeFixableDiagnostics > 1) + break; + } + var fixAllUnavailable = maybeFixableDiagnostics < 2; + return function (_a) { + var fixId = _a.fixId, fixAllDescription = _a.fixAllDescription, action = __rest(_a, ["fixId", "fixAllDescription"]); + return fixAllUnavailable ? action : __assign(__assign({}, action), { fixId: fixId, fixAllDescription: fixAllDescription }); + }; + } function getFixes(context) { - return ts.flatMap(errorCodeToFixes.get(String(context.errorCode)) || ts.emptyArray, function (f) { return f.getCodeActions(context); }); + var diagnostics = getDiagnostics(context); + var registrations = errorCodeToFixes.get(String(context.errorCode)); + return ts.flatMap(registrations, function (f) { return ts.map(f.getCodeActions(context), removeFixIdIfFixAllUnavailable(f, diagnostics)); }); } codefix.getFixes = getFixes; function getAllFixes(context) { @@ -123776,16 +123887,19 @@ var ts; return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands); } codefix.codeFixAll = codeFixAll; - function eachDiagnostic(_a, errorCodes, cb) { - var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken; - for (var _i = 0, _b = program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); _i < _b.length; _i++) { - var diag = _b[_i]; + function eachDiagnostic(context, errorCodes, cb) { + for (var _i = 0, _a = getDiagnostics(context); _i < _a.length; _i++) { + var diag = _a[_i]; if (ts.contains(errorCodes, diag.code)) { cb(diag); } } } codefix.eachDiagnostic = eachDiagnostic; + function getDiagnostics(_a) { + var program = _a.program, sourceFile = _a.sourceFile, cancellationToken = _a.cancellationToken; + return program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(ts.computeSuggestionDiagnostics(sourceFile, program, cancellationToken)); + } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ @@ -123842,6 +123956,28 @@ var ts; })(ts || (ts = {})); /* @internal */ var ts; +(function (ts) { + var codefix; + (function (codefix) { + codefix.registerCodeFix({ + errorCodes: [ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code], + getCodeActions: function (context) { + var sourceFile = context.sourceFile; + var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { + var exportDeclaration = ts.createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, ts.createNamedExports([]), + /*moduleSpecifier*/ undefined, + /*isTypeOnly*/ false); + changes.insertNodeAtEndOfScope(sourceFile, sourceFile, exportDeclaration); + }); + return [codefix.createCodeFixActionWithoutFixAll("addEmptyExportDeclaration", changes, ts.Diagnostics.Add_export_to_make_this_file_into_a_module)]; + }, + }); + })(codefix = ts.codefix || (ts.codefix = {})); +})(ts || (ts = {})); +/* @internal */ +var ts; (function (ts) { var codefix; (function (codefix) { @@ -123912,7 +124048,9 @@ var ts; makeChange(t, errorCode, sourceFile, checker, expression, fixedDeclarations); } }); - return codefix.createCodeFixActionNoFixId("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 + // No fix-all because it will already be included once with the use site fix, + // and for simplicity the fix-all doesn‘t let the user choose between use-site and declaration-site fixes. + return codefix.createCodeFixActionWithoutFixAll("addMissingAwaitToInitializer", initializerChanges, awaitableInitializers.initializers.length === 1 ? [ts.Diagnostics.Add_await_to_initializer_for_0, awaitableInitializers.initializers[0].declarationSymbol.name] : ts.Diagnostics.Add_await_to_initializers); } @@ -124131,7 +124269,7 @@ var ts; if (forInitializer) return applyChange(changeTracker, forInitializer, sourceFile, fixedNodes); var parent = token.parent; - if (ts.isBinaryExpression(parent) && ts.isExpressionStatement(parent.parent)) { + if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isExpressionStatement(parent.parent)) { return applyChange(changeTracker, token, sourceFile, fixedNodes); } if (ts.isArrayLiteralExpression(parent)) { @@ -124193,7 +124331,9 @@ var ts; if (expression.operatorToken.kind === 27 /* CommaToken */) { return ts.every([expression.left, expression.right], function (expression) { return expressionCouldBeVariableDeclaration(expression, checker); }); } - return ts.isIdentifier(expression.left) && !checker.getSymbolAtLocation(expression.left); + return expression.operatorToken.kind === 62 /* EqualsToken */ + && ts.isIdentifier(expression.left) + && !checker.getSymbolAtLocation(expression.left); } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); @@ -126184,7 +126324,7 @@ var ts; } }); // No support for fix-all since this applies to the whole file at once anyway. - return [codefix.createCodeFixActionNoFixId("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)]; + return [codefix.createCodeFixActionWithoutFixAll("convertToEs6Module", changes, ts.Diagnostics.Convert_to_ES6_module)]; }, }); function fixImportOfModuleExports(importingFile, exportingFile, changes, quotePreference) { @@ -126783,7 +126923,8 @@ var ts; (function (ts) { var codefix; (function (codefix) { - codefix.importFixId = "fixMissingImport"; + codefix.importFixName = "import"; + var importFixId = "fixMissingImport"; var errorCodes = [ ts.Diagnostics.Cannot_find_name_0.code, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, @@ -126804,7 +126945,7 @@ var ts; var quotePreference = ts.getQuotePreference(sourceFile, preferences); return fixes.map(function (fix) { return codeActionForFix(context, sourceFile, symbolName, fix, quotePreference); }); }, - fixIds: [codefix.importFixId], + fixIds: [importFixId], getAllCodeActions: function (context) { var sourceFile = context.sourceFile, preferences = context.preferences; // Namespace fixes don't conflict, so just build a list. @@ -127236,7 +127377,7 @@ var ts; var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) { diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, quotePreference); }); - return codefix.createCodeFixAction("import", changes, diag, codefix.importFixId, ts.Diagnostics.Add_all_missing_imports); + return codefix.createCodeFixAction(codefix.importFixName, changes, diag, importFixId, ts.Diagnostics.Add_all_missing_imports); } function codeActionForFixWorker(changes, sourceFile, symbolName, fix, quotePreference) { switch (fix.kind) { @@ -127534,17 +127675,17 @@ var ts; var info = getInfo(sourceFile, context.span.start, context); if (!info) return undefined; - var node = info.node, suggestion = info.suggestion; + var node = info.node, suggestedSymbol = info.suggestedSymbol; var target = context.host.getCompilationSettings().target; - var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestion, target); }); - return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, suggestion], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)]; + var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return doChange(t, sourceFile, node, suggestedSymbol, target); }); + return [codefix.createCodeFixAction("spelling", changes, [ts.Diagnostics.Change_spelling_to_0, ts.symbolName(suggestedSymbol)], fixId, ts.Diagnostics.Fix_all_detected_spelling_errors)]; }, fixIds: [fixId], getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes, diag) { var info = getInfo(diag.file, diag.start, context); var target = context.host.getCompilationSettings().target; if (info) - doChange(changes, context.sourceFile, info.node, info.suggestion, target); + doChange(changes, context.sourceFile, info.node, info.suggestedSymbol, target); }); }, }); function getInfo(sourceFile, pos, context) { @@ -127553,34 +127694,42 @@ var ts; // ^^^^^^^ var node = ts.getTokenAtPosition(sourceFile, pos); var checker = context.program.getTypeChecker(); - var suggestion; + var suggestedSymbol; if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) { - ts.Debug.assert(node.kind === 75 /* Identifier */, "Expected an identifier for spelling (property access)"); + ts.Debug.assert(ts.isIdentifierOrPrivateIdentifier(node), "Expected an identifier for spelling (property access)"); var containingType = checker.getTypeAtLocation(node.parent.expression); if (node.parent.flags & 32 /* OptionalChain */) { containingType = checker.getNonNullableType(containingType); } - suggestion = checker.getSuggestionForNonexistentProperty(node, containingType); + var name = node; + suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(name, containingType); } else if (ts.isImportSpecifier(node.parent) && node.parent.name === node) { ts.Debug.assert(node.kind === 75 /* Identifier */, "Expected an identifier for spelling (import)"); var importDeclaration = ts.findAncestor(node, ts.isImportDeclaration); var resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration); if (resolvedSourceFile && resolvedSourceFile.symbol) { - suggestion = checker.getSuggestionForNonexistentExport(node, resolvedSourceFile.symbol); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(node, resolvedSourceFile.symbol); } } else { var meaning = ts.getMeaningFromLocation(node); var name = ts.getTextOfNode(node); ts.Debug.assert(name !== undefined, "name should be defined"); - suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); + suggestedSymbol = checker.getSuggestedSymbolForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); } - return suggestion === undefined ? undefined : { node: node, suggestion: suggestion }; + return suggestedSymbol === undefined ? undefined : { node: node, suggestedSymbol: suggestedSymbol }; } - function doChange(changes, sourceFile, node, suggestion, target) { + function doChange(changes, sourceFile, node, suggestedSymbol, target) { + var suggestion = ts.symbolName(suggestedSymbol); if (!ts.isIdentifierText(suggestion, target) && ts.isPropertyAccessExpression(node.parent)) { - changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion))); + var valDecl = suggestedSymbol.valueDeclaration; + if (ts.isNamedDeclaration(valDecl) && ts.isPrivateIdentifier(valDecl.name)) { + changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion)); + } + else { + changes.replaceNode(sourceFile, node.parent, ts.createElementAccess(node.parent.expression, ts.createLiteral(suggestion))); + } } else { changes.replaceNode(sourceFile, node, ts.createIdentifier(suggestion)); @@ -127844,7 +127993,7 @@ var ts; /*modifiers*/ undefined, [indexingParameter], typeNode); var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.insertNodeAtClassStart(declSourceFile, classDeclaration, indexSignature); }); // No fixId here because code-fix-all currently only works on adding individual named properties. - return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]); + return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Add_index_signature_for_property_0, tokenName]); } function getActionForMethodDeclaration(context, declSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences) { // Private methods are not implemented yet. @@ -128129,7 +128278,7 @@ var ts; return undefined; } var changes = ts.textChanges.ChangeTracker.with(context, function (changeTracker) { return doChange(changeTracker, configFile); }); - return [codefix.createCodeFixActionNoFixId(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; + return [codefix.createCodeFixActionWithoutFixAll(fixId, changes, ts.Diagnostics.Enable_the_experimentalDecorators_option_in_your_configuration_file)]; }, fixIds: [fixId], getAllCodeActions: function (context) { return codefix.codeFixAll(context, errorCodes, function (changes) { @@ -128163,7 +128312,7 @@ var ts; return doChange(changeTracker, configFile); }); return [ - codefix.createCodeFixActionNoFixId(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) + codefix.createCodeFixActionWithoutFixAll(fixID, changes, ts.Diagnostics.Enable_the_jsx_flag_in_your_configuration_file) ]; }, fixIds: [fixID], @@ -128184,6 +128333,49 @@ var ts; })(ts || (ts = {})); /* @internal */ var ts; +(function (ts) { + var codefix; + (function (codefix) { + codefix.registerCodeFix({ + errorCodes: [ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code], + getCodeActions: function (context) { + var compilerOptions = context.program.getCompilerOptions(); + var configFile = compilerOptions.configFile; + if (configFile === undefined) { + return undefined; + } + var codeFixes = []; + var moduleKind = ts.getEmitModuleKind(compilerOptions); + var moduleOutOfRange = moduleKind >= ts.ModuleKind.ES2015 && moduleKind < ts.ModuleKind.ESNext; + if (moduleOutOfRange) { + var changes = ts.textChanges.ChangeTracker.with(context, function (changes) { + codefix.setJsonCompilerOptionValue(changes, configFile, "module", ts.createStringLiteral("esnext")); + }); + codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixModuleOption", changes, [ts.Diagnostics.Set_the_module_option_in_your_configuration_file_to_0, "esnext"])); + } + var target = ts.getEmitScriptTarget(compilerOptions); + var targetOutOfRange = target < 4 /* ES2017 */ || target > 99 /* ESNext */; + if (targetOutOfRange) { + var changes = ts.textChanges.ChangeTracker.with(context, function (tracker) { + var configObject = ts.getTsConfigObjectLiteralExpression(configFile); + if (!configObject) + return; + var options = [["target", ts.createStringLiteral("es2017")]]; + if (moduleKind === ts.ModuleKind.CommonJS) { + // Ensure we preserve the default module kind (commonjs), as targets >= ES2015 have a default module kind of es2015. + options.push(["module", ts.createStringLiteral("commonjs")]); + } + codefix.setJsonCompilerOptionValues(tracker, configFile, options); + }); + codeFixes.push(codefix.createCodeFixActionWithoutFixAll("fixTargetOption", changes, [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0, "es2017"])); + } + return codeFixes.length ? codeFixes : undefined; + } + }); + })(codefix = ts.codefix || (ts.codefix = {})); +})(ts || (ts = {})); +/* @internal */ +var ts; (function (ts) { var codefix; (function (codefix) { @@ -128336,7 +128528,7 @@ var ts; }); if (deletion.length) { var name = ts.isComputedPropertyName(token.parent) ? token.parent : token; - result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_declaration_for_Colon_0, name.getText(sourceFile)])); + result.push(createDeleteFix(deletion, [ts.Diagnostics.Remove_unused_declaration_for_Colon_0, name.getText(sourceFile)])); } } var prefix = ts.textChanges.ChangeTracker.with(context, function (t) { return tryPrefixDeclaration(t, errorCode, sourceFile, token); }); @@ -128697,7 +128889,7 @@ var ts; (function (codefix) { var fixId = "fixAwaitInSyncFunction"; var errorCodes = [ - ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function.code, + ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code, ]; codefix.registerCodeFix({ @@ -128789,7 +128981,7 @@ var ts; } var fixes = [ // fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file. - codefix.createCodeFixActionNoFixId(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [ + codefix.createCodeFixActionWithoutFixAll(fixName, [codefix.createFileTextChanges(sourceFile.fileName, [ ts.createTextChange(sourceFile.checkJsDirective ? ts.createTextSpanFromBounds(sourceFile.checkJsDirective.pos, sourceFile.checkJsDirective.end) : ts.createTextSpan(0, 0), "// @ts-nocheck" + ts.getNewLineOrDefaultFromHost(host, formatContext.options)), @@ -129056,29 +129248,37 @@ var ts; } return undefined; } - function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) { + function setJsonCompilerOptionValues(changeTracker, configFile, options) { var tsconfigObjectLiteral = ts.getTsConfigObjectLiteralExpression(configFile); if (!tsconfigObjectLiteral) return undefined; var compilerOptionsProperty = findJsonProperty(tsconfigObjectLiteral, "compilerOptions"); if (compilerOptionsProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral([ - createJsonPropertyAssignment(optionName, optionValue), - ]))); + changeTracker.insertNodeAtObjectStart(configFile, tsconfigObjectLiteral, createJsonPropertyAssignment("compilerOptions", ts.createObjectLiteral(options.map(function (_a) { + var optionName = _a[0], optionValue = _a[1]; + return createJsonPropertyAssignment(optionName, optionValue); + }), /*multiLine*/ true))); return; } var compilerOptions = compilerOptionsProperty.initializer; if (!ts.isObjectLiteralExpression(compilerOptions)) { return; } - var optionProperty = findJsonProperty(compilerOptions, optionName); - if (optionProperty === undefined) { - changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); - } - else { - changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + for (var _i = 0, options_1 = options; _i < options_1.length; _i++) { + var _a = options_1[_i], optionName = _a[0], optionValue = _a[1]; + var optionProperty = findJsonProperty(compilerOptions, optionName); + if (optionProperty === undefined) { + changeTracker.insertNodeAtObjectStart(configFile, compilerOptions, createJsonPropertyAssignment(optionName, optionValue)); + } + else { + changeTracker.replaceNode(configFile, optionProperty.initializer, optionValue); + } } } + codefix.setJsonCompilerOptionValues = setJsonCompilerOptionValues; + function setJsonCompilerOptionValue(changeTracker, configFile, optionName, optionValue) { + setJsonCompilerOptionValues(changeTracker, configFile, [[optionName, optionValue]]); + } codefix.setJsonCompilerOptionValue = setJsonCompilerOptionValue; function createJsonPropertyAssignment(name, initializer) { return ts.createPropertyAssignment(ts.createStringLiteral(name), initializer); @@ -129113,7 +129313,7 @@ var ts; } function createAction(context, sourceFile, node, replacement) { var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, node, replacement); }); - return codefix.createCodeFixActionNoFixId(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); + return codefix.createCodeFixActionWithoutFixAll(fixName, changes, [ts.Diagnostics.Replace_import_with_0, changes[0].textChanges[0].newText]); } codefix.registerCodeFix({ errorCodes: [ @@ -129171,7 +129371,7 @@ var ts; if (ts.isExpression(expr) && !(ts.isNamedDeclaration(expr.parent) && expr.parent.name === expr)) { var sourceFile_1 = context.sourceFile; var changes = ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile_1, expr, ts.createPropertyAccess(expr, "default"), {}); }); - fixes.push(codefix.createCodeFixActionNoFixId(fixName, changes, ts.Diagnostics.Use_synthetic_default_member)); + fixes.push(codefix.createCodeFixActionWithoutFixAll(fixName, changes, ts.Diagnostics.Use_synthetic_default_member)); } return fixes; } diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 068bc5dba19db..c4ee140de7483 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -1264,6 +1264,11 @@ var ts; return result; } ts.clone = clone; + /** + * Creates a new object by adding the own properties of `second`, then the own properties of `first`. + * + * NOTE: This means that if a property exists in both `first` and `second`, the property in `first` will be chosen. + */ function extend(first, second) { var result = {}; for (var id in second) { @@ -5584,10 +5589,13 @@ var ts; } } function readFileWorker(fileName, _encoding) { - if (!fileExists(fileName)) { + var buffer; + try { + buffer = _fs.readFileSync(fileName); + } + catch (e) { return undefined; } - var buffer = _fs.readFileSync(fileName); var len = buffer.length; if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) { // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js, @@ -5637,23 +5645,30 @@ var ts; function getAccessibleFileSystemEntries(path) { ts.perfLogger.logEvent("ReadDir: " + (path || ".")); try { - var entries = _fs.readdirSync(path || ".").sort(); + var entries = _fs.readdirSync(path || ".", { withFileTypes: true }); var files = []; var directories = []; for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { - var entry = entries_2[_i]; + var dirent = entries_2[_i]; + // withFileTypes is not supported before Node 10.10. + var entry = typeof dirent === "string" ? dirent : dirent.name; // This is necessary because on some file system node fails to exclude // "." and "..". See https://github.com/nodejs/node/issues/4002 if (entry === "." || entry === "..") { continue; } - var name = ts.combinePaths(path, entry); var stat = void 0; - try { - stat = _fs.statSync(name); + if (typeof dirent === "string" || dirent.isSymbolicLink()) { + var name = ts.combinePaths(path, entry); + try { + stat = _fs.statSync(name); + } + catch (e) { + continue; + } } - catch (e) { - continue; + else { + stat = dirent; } if (stat.isFile()) { files.push(entry); @@ -5662,6 +5677,8 @@ var ts; directories.push(entry); } } + files.sort(); + directories.sort(); return { files: files, directories: directories }; } catch (e) { @@ -5691,8 +5708,7 @@ var ts; return fileSystemEntryExists(path, 1 /* Directory */); } function getDirectories(path) { - ts.perfLogger.logEvent("ReadDir: " + path); - return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); }); + return getAccessibleFileSystemEntries(path).directories.slice(); } function realpath(path) { try { @@ -6686,7 +6702,7 @@ var ts; Keywords_cannot_contain_escape_characters: diag(1260, ts.DiagnosticCategory.Error, "Keywords_cannot_contain_escape_characters_1260", "Keywords cannot contain escape characters."), Already_included_file_name_0_differs_from_file_name_1_only_in_casing: diag(1261, ts.DiagnosticCategory.Error, "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", "Already included file name '{0}' differs from file name '{1}' only in casing."), with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."), - await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."), + await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules: diag(1308, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", "'await' expressions are only allowed within async functions and at the top levels of modules."), can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."), The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."), Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."), @@ -6734,14 +6750,13 @@ var ts; An_enum_member_name_must_be_followed_by_a_or: diag(1357, ts.DiagnosticCategory.Error, "An_enum_member_name_must_be_followed_by_a_or_1357", "An enum member name must be followed by a ',', '=', or '}'."), Tagged_template_expressions_are_not_permitted_in_an_optional_chain: diag(1358, ts.DiagnosticCategory.Error, "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", "Tagged template expressions are not permitted in an optional chain."), Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here: diag(1359, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", "Identifier expected. '{0}' is a reserved word that cannot be used here."), - Did_you_mean_to_parenthesize_this_function_type: diag(1360, ts.DiagnosticCategory.Error, "Did_you_mean_to_parenthesize_this_function_type_1360", "Did you mean to parenthesize this function type?"), Type_only_0_must_reference_a_type_but_1_is_a_value: diag(1361, ts.DiagnosticCategory.Error, "Type_only_0_must_reference_a_type_but_1_is_a_value_1361", "Type-only {0} must reference a type, but '{1}' is a value."), Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported: diag(1362, ts.DiagnosticCategory.Error, "Enum_0_cannot_be_used_as_a_value_because_only_its_type_has_been_imported_1362", "Enum '{0}' cannot be used as a value because only its type has been imported."), A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both: diag(1363, ts.DiagnosticCategory.Error, "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", "A type-only import can specify a default import or named bindings, but not both."), Convert_to_type_only_export: diag(1364, ts.DiagnosticCategory.Message, "Convert_to_type_only_export_1364", "Convert to type-only export"), Convert_all_re_exported_types_to_type_only_exports: diag(1365, ts.DiagnosticCategory.Message, "Convert_all_re_exported_types_to_type_only_exports_1365", "Convert all re-exported types to type-only exports"), Split_into_two_separate_import_declarations: diag(1366, ts.DiagnosticCategory.Message, "Split_into_two_separate_import_declarations_1366", "Split into two separate import declarations"), - Split_all_invalid_type_only_imports: diag(1377, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1377", "Split all invalid type-only imports"), + Split_all_invalid_type_only_imports: diag(1367, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1367", "Split all invalid type-only imports"), Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types: diag(1368, ts.DiagnosticCategory.Message, "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_1368", "Specify emit/checking behavior for imports that are only used for types"), Did_you_mean_0: diag(1369, ts.DiagnosticCategory.Message, "Did_you_mean_0_1369", "Did you mean '{0}'?"), Only_ECMAScript_imports_may_use_import_type: diag(1370, ts.DiagnosticCategory.Error, "Only_ECMAScript_imports_may_use_import_type_1370", "Only ECMAScript imports may use 'import type'."), @@ -6749,7 +6764,8 @@ var ts; This_import_may_be_converted_to_a_type_only_import: diag(1372, ts.DiagnosticCategory.Suggestion, "This_import_may_be_converted_to_a_type_only_import_1372", "This import may be converted to a type-only import."), Convert_to_type_only_import: diag(1373, ts.DiagnosticCategory.Message, "Convert_to_type_only_import_1373", "Convert to type-only import"), Convert_all_imports_not_used_as_a_value_to_type_only_imports: diag(1374, ts.DiagnosticCategory.Message, "Convert_all_imports_not_used_as_a_value_to_type_only_imports_1374", "Convert all imports not used as a value to type-only imports"), - await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher: diag(1375, ts.DiagnosticCategory.Error, "await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnex_1375", "'await' outside of an async function is only allowed at the top level of a module when '--module' is 'esnext' or 'system' and '--target' is 'es2017' or higher."), + await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module: diag(1375, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."), + Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher: diag(1376, ts.DiagnosticCategory.Error, "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_t_1376", "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher."), The_types_of_0_are_incompatible_between_these_types: diag(2200, ts.DiagnosticCategory.Error, "The_types_of_0_are_incompatible_between_these_types_2200", "The types of '{0}' are incompatible between these types."), The_types_returned_by_0_are_incompatible_between_these_types: diag(2201, ts.DiagnosticCategory.Error, "The_types_returned_by_0_are_incompatible_between_these_types_2201", "The types returned by '{0}' are incompatible between these types."), Call_signature_return_types_0_and_1_are_incompatible: diag(2202, ts.DiagnosticCategory.Error, "Call_signature_return_types_0_and_1_are_incompatible_2202", "Call signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true), @@ -7695,7 +7711,7 @@ var ts; Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"), Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"), Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"), - Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'"), + Remove_unused_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_unused_declaration_for_Colon_0_90004", "Remove unused declaration for: '{0}'"), Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"), Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"), Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"), @@ -7818,10 +7834,12 @@ var ts; Prefix_with_declare: diag(95094, ts.DiagnosticCategory.Message, "Prefix_with_declare_95094", "Prefix with 'declare'"), Prefix_all_incorrect_property_declarations_with_declare: diag(95095, ts.DiagnosticCategory.Message, "Prefix_all_incorrect_property_declarations_with_declare_95095", "Prefix all incorrect property declarations with 'declare'"), Convert_to_template_string: diag(95096, ts.DiagnosticCategory.Message, "Convert_to_template_string_95096", "Convert to template string"), + Add_export_to_make_this_file_into_a_module: diag(95097, ts.DiagnosticCategory.Message, "Add_export_to_make_this_file_into_a_module_95097", "Add 'export {}' to make this file into a module"), + Set_the_target_option_in_your_configuration_file_to_0: diag(95098, ts.DiagnosticCategory.Message, "Set_the_target_option_in_your_configuration_file_to_0_95098", "Set the 'target' option in your configuration file to '{0}'"), + Set_the_module_option_in_your_configuration_file_to_0: diag(95099, ts.DiagnosticCategory.Message, "Set_the_module_option_in_your_configuration_file_to_0_95099", "Set the 'module' option in your configuration file to '{0}'"), No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."), Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."), JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array: diag(18007, ts.DiagnosticCategory.Error, "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", "JSX expressions may not use the comma operator. Did you mean to write an array?"), - can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Private_identifiers_cannot_be_used_as_parameters: diag(18009, ts.DiagnosticCategory.Error, "Private_identifiers_cannot_be_used_as_parameters_18009", "Private identifiers cannot be used as parameters"), An_accessibility_modifier_cannot_be_used_with_a_private_identifier: diag(18010, ts.DiagnosticCategory.Error, "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", "An accessibility modifier cannot be used with a private identifier."), The_operand_of_a_delete_operator_cannot_be_a_private_identifier: diag(18011, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", "The operand of a 'delete' operator cannot be a private identifier."), @@ -7836,6 +7854,7 @@ var ts; A_method_cannot_be_named_with_a_private_identifier: diag(18022, ts.DiagnosticCategory.Error, "A_method_cannot_be_named_with_a_private_identifier_18022", "A method cannot be named with a private identifier."), An_accessor_cannot_be_named_with_a_private_identifier: diag(18023, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_named_with_a_private_identifier_18023", "An accessor cannot be named with a private identifier."), An_enum_member_cannot_be_named_with_a_private_identifier: diag(18024, ts.DiagnosticCategory.Error, "An_enum_member_cannot_be_named_with_a_private_identifier_18024", "An enum member cannot be named with a private identifier."), + can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."), Compiler_reserves_name_0_when_emitting_private_identifier_downlevel: diag(18027, ts.DiagnosticCategory.Error, "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", "Compiler reserves name '{0}' when emitting private identifier downlevel."), Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher: diag(18028, ts.DiagnosticCategory.Error, "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", "Private identifiers are only available when targeting ECMAScript 2015 and higher."), Private_identifiers_are_not_allowed_in_variable_declarations: diag(18029, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_in_variable_declarations_18029", "Private identifiers are not allowed in variable declarations."), @@ -26027,6 +26046,7 @@ var ts; error: 2 /* Error */ }), affectsEmit: true, + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types }, @@ -26284,12 +26304,15 @@ var ts; { name: "experimentalDecorators", type: "boolean", + affectsSemanticDiagnostics: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", + affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, @@ -26303,6 +26326,7 @@ var ts; { name: "resolveJsonModule", type: "boolean", + affectsModuleResolution: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Include_modules_imported_with_json_extension }, @@ -26507,6 +26531,7 @@ var ts; name: "useDefineForClassFields", type: "boolean", affectsSemanticDiagnostics: true, + affectsEmit: true, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Emit_class_fields_with_Define_instead_of_Set, }, @@ -30383,7 +30408,7 @@ var ts; case 104 /* ThisKeyword */: case 194 /* PropertyAccessExpression */: case 195 /* ElementAccessExpression */: - return isNarrowableReference(expr); + return containsNarrowableReference(expr); case 196 /* CallExpression */: return hasNarrowableArgument(expr); case 200 /* ParenthesizedExpression */: @@ -30400,20 +30425,22 @@ var ts; function isNarrowableReference(expr) { return expr.kind === 75 /* Identifier */ || expr.kind === 104 /* ThisKeyword */ || expr.kind === 102 /* SuperKeyword */ || (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || - ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) || - ts.isOptionalChain(expr); + ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression); + } + function containsNarrowableReference(expr) { + return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression); } function hasNarrowableArgument(expr) { if (expr.arguments) { for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) { var argument = _a[_i]; - if (isNarrowableReference(argument)) { + if (containsNarrowableReference(argument)) { return true; } } } if (expr.expression.kind === 194 /* PropertyAccessExpression */ && - isNarrowableReference(expr.expression.expression)) { + containsNarrowableReference(expr.expression.expression)) { return true; } return false; @@ -30427,7 +30454,7 @@ var ts; function isNarrowingBinaryExpression(expr) { switch (expr.operatorToken.kind) { case 62 /* EqualsToken */: - return isNarrowableReference(expr.left); + return containsNarrowableReference(expr.left); case 34 /* EqualsEqualsToken */: case 35 /* ExclamationEqualsToken */: case 36 /* EqualsEqualsEqualsToken */: @@ -30455,7 +30482,7 @@ var ts; return isNarrowableOperand(expr.right); } } - return isNarrowableReference(expr); + return containsNarrowableReference(expr); } function createBranchLabel() { return initFlowNode({ flags: 4 /* BranchLabel */, antecedents: undefined }); @@ -33867,6 +33894,7 @@ var ts; var currentNode; var emptySymbols = ts.createSymbolTable(); var identityMapper = ts.identity; + var arrayVariances = [1 /* Covariant */]; var compilerOptions = host.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); @@ -34115,9 +34143,12 @@ var ts; isArrayLikeType: isArrayLikeType, isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant, getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes, - getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); }, + getSuggestedSymbolForNonexistentProperty: getSuggestedSymbolForNonexistentProperty, + getSuggestionForNonexistentProperty: getSuggestionForNonexistentProperty, + getSuggestedSymbolForNonexistentSymbol: function (location, name, meaning) { return getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, - getSuggestionForNonexistentExport: function (node, target) { return getSuggestionForNonexistentExport(node, target); }, + getSuggestedSymbolForNonexistentModule: getSuggestedSymbolForNonexistentModule, + getSuggestionForNonexistentExport: getSuggestionForNonexistentExport, getBaseConstraintOfType: getBaseConstraintOfType, getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; }, resolveName: function (name, location, meaning, excludeGlobals) { @@ -35709,9 +35740,11 @@ var ts; // if symbolFromVariable is export - get its final target symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias); var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias); - // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default - if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default" /* Default */) { - symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + if (symbolFromModule === undefined && name.escapedText === "default" /* Default */) { + var file = ts.find(moduleSymbol.declarations, ts.isSourceFile); + if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) { + symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + } } var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : @@ -45352,8 +45385,9 @@ var ts; } /** We approximate own properties as non-methods plus methods that are inside the object literal */ function isSpreadableProperty(prop) { - return !(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || - !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); }); + return !ts.some(prop.declarations, ts.isPrivateIdentifierPropertyDeclaration) && + (!(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) || + !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); })); } function getSpreadSymbol(prop, readonly) { var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */); @@ -47679,6 +47713,9 @@ var ts; source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { var variances = getAliasVariances(source.aliasSymbol); + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -47873,6 +47910,12 @@ var ts; // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. var variances = getVariances(source.target); + // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This + // effectively means we measure variance only from type parameter occurrences that aren't nested in + // recursive instantiations of the generic type. + if (variances === ts.emptyArray) { + return 1 /* Maybe */; + } var varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState); if (varianceResult !== undefined) { return varianceResult; @@ -48658,8 +48701,7 @@ var ts; // a digest of the type comparisons that occur for each type argument when instantiations of the // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function - // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function - // has been invoked recursively for the given generic type. + // returns the emptyArray singleton when invoked recursively for the given generic type. function getVariancesWorker(typeParameters, cache, createMarkerType) { if (typeParameters === void 0) { typeParameters = ts.emptyArray; } var variances = cache.variances; @@ -48706,9 +48748,9 @@ var ts; return variances; } function getVariances(type) { - // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters) + // Arrays and tuples are known to be covariant, no need to spend time computing this. if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8 /* Tuple */) { - return ts.emptyArray; + return arrayVariances; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); } @@ -52414,24 +52456,7 @@ var ts; } } else if (!assumeInitialized && !(getFalsyFlags(type) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) { - var diag = error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); - // See GH:32846 - if the user is using a variable whose type is () => T1 | ... | undefined - // they may have meant to specify the type as (() => T1 | ...) | undefined - // This is assumed if: the type is a FunctionType, the return type is a Union, the last constituent of - // the union is `undefined` - if (type.symbol && type.symbol.declarations.length === 1 && ts.isFunctionTypeNode(type.symbol.declarations[0])) { - var funcTypeNode = type.symbol.declarations[0]; - var returnType = getReturnTypeFromAnnotation(funcTypeNode); - if (returnType && returnType.flags & 1048576 /* Union */) { - var unionTypes_3 = funcTypeNode.type.types; - if (unionTypes_3 && unionTypes_3[unionTypes_3.length - 1].kind === 146 /* UndefinedKeyword */) { - var parenedFuncType = ts.getMutableClone(funcTypeNode); - // Highlight to the end of the second to last constituent of the union - parenedFuncType.end = unionTypes_3[unionTypes_3.length - 2].end; - ts.addRelatedInfo(diag, ts.createDiagnosticForNode(parenedFuncType, ts.Diagnostics.Did_you_mean_to_parenthesize_this_function_type)); - } - } - } + error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; } @@ -58046,12 +58071,17 @@ var ts; if (!(node.flags & 32768 /* AwaitContext */)) { if (isTopLevelAwait(node)) { var sourceFile = ts.getSourceFileOfNode(node); - if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || - languageVersion < 4 /* ES2017 */ || - !ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { - if (!hasParseDiagnostics(sourceFile)) { - var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_outside_of_an_async_function_is_only_allowed_at_the_top_level_of_a_module_when_module_is_esnext_or_system_and_target_is_es2017_or_higher); + if (!hasParseDiagnostics(sourceFile)) { + var span = void 0; + if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) { + if (!span) + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module); + diagnostics.add(diagnostic); + } + if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || languageVersion < 4 /* ES2017 */) { + span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher); diagnostics.add(diagnostic); } } @@ -58061,7 +58091,7 @@ var ts; var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); - var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function); + var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules); var func = ts.getContainingFunction(node); if (func && func.kind !== 162 /* Constructor */ && (ts.getFunctionFlags(func) & 2 /* Async */) === 0) { var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async); @@ -96825,12 +96855,12 @@ var ts; if (!program || hasChangedAutomaticTypeDirectiveNames) { return false; } - // If number of files in the program do not match, it is not up-to-date - if (program.getRootFileNames().length !== rootFileNames.length) { + // If root file names don't match + if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) { return false; } var seenResolvedRefs; - // If project references dont match + // If project references don't match if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) { return false; } diff --git a/lib/zh-tw/diagnosticMessages.generated.json b/lib/zh-tw/diagnosticMessages.generated.json index 6496c4afa54ed..44e599285ae31 100644 --- a/lib/zh-tw/diagnosticMessages.generated.json +++ b/lib/zh-tw/diagnosticMessages.generated.json @@ -454,7 +454,7 @@ "Generic_type_0_requires_1_type_argument_s_2314": "泛型類型 '{0}' 需要 {1} 個型別引數。", "Generic_type_0_requires_between_1_and_2_type_arguments_2707": "泛型型別 '{0}' 需要介於 {1} 和 {2} 之間的型別引數。", "Generic_type_instantiation_is_excessively_deep_and_possibly_infinite_2550": "泛型類型具現化的深度過深,而且可能是無限深。", - "Getter_and_setter_accessors_do_not_agree_in_visibility_2379": "getter 和 setter 存取子的可視性不符。", + "Getter_and_setter_accessors_do_not_agree_in_visibility_2379": "getter 和 setter 存取子的可見度不符。", "Global_module_exports_may_only_appear_at_top_level_1316": "全域模組匯出只能顯示在最上層。", "Global_module_exports_may_only_appear_in_declaration_files_1315": "全域模組匯出只能顯示在宣告檔案中。", "Global_module_exports_may_only_appear_in_module_files_1314": "全域模組匯出只能顯示在模組檔案中。", From 342f4c0b54cee93bc9bb19463c22ce14a8e1f8f8 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Tue, 21 Jan 2020 21:45:13 +0100 Subject: [PATCH 27/28] forceConsistentCasingInFileNames affects module resolution (#36334) --- src/compiler/commandLineParser.ts | 1 + .../unittests/tscWatch/programUpdates.ts | 29 +++++ ...orceConsistentCasingInFileNames-changes.js | 122 ++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 tests/baselines/reference/tscWatch/programUpdates/updates-errors-when-forceConsistentCasingInFileNames-changes.js diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index be72b2051312b..2eb261499d50f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -951,6 +951,7 @@ namespace ts { { name: "forceConsistentCasingInFileNames", type: "boolean", + affectsModuleResolution: true, category: Diagnostics.Advanced_Options, description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file }, diff --git a/src/testRunner/unittests/tscWatch/programUpdates.ts b/src/testRunner/unittests/tscWatch/programUpdates.ts index 163ba1085ead0..ce3292693a2dc 100644 --- a/src/testRunner/unittests/tscWatch/programUpdates.ts +++ b/src/testRunner/unittests/tscWatch/programUpdates.ts @@ -1228,6 +1228,35 @@ export function f(p: C) { return p; }` ] }); + + verifyTscWatch({ + scenario, + subScenario: "updates errors when forceConsistentCasingInFileNames changes", + commandLineArgs: ["-w"], + sys: () => { + const aFile: File = { + path: `/a.ts`, + content: `export class C {}` + }; + const bFile: File = { + path: `/b.ts`, + content: `import {C} from './a'; import * as A from './A';` + }; + const config: File = { + path: `/tsconfig.json`, + content: JSON.stringify({ compilerOptions: {} }) + }; + return createWatchedSystem([aFile, bFile, config, libFile], { useCaseSensitiveFileNames: false }); + }, + changes: [ + sys => { + sys.writeFile(`/tsconfig.json`, JSON.stringify({ compilerOptions: { forceConsistentCasingInFileNames: true } })); + sys.runQueuedTimeoutCallbacks(); + return "Enable forceConsistentCasingInFileNames"; + }, + ] + }); + verifyTscWatch({ scenario, subScenario: "updates moduleResolution when resolveJsonModule changes", diff --git a/tests/baselines/reference/tscWatch/programUpdates/updates-errors-when-forceConsistentCasingInFileNames-changes.js b/tests/baselines/reference/tscWatch/programUpdates/updates-errors-when-forceConsistentCasingInFileNames-changes.js new file mode 100644 index 0000000000000..f29845f27a0cd --- /dev/null +++ b/tests/baselines/reference/tscWatch/programUpdates/updates-errors-when-forceConsistentCasingInFileNames-changes.js @@ -0,0 +1,122 @@ +/a/lib/tsc.js -w +//// [/a.ts] +export class C {} + +//// [/b.ts] +import {C} from './a'; import * as A from './A'; + +//// [/tsconfig.json] +{"compilerOptions":{}} + +//// [/a/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } + +//// [/a.js] +"use strict"; +exports.__esModule = true; +var C = /** @class */ (function () { + function C() { + } + return C; +}()); +exports.C = C; + + +//// [/b.js] +"use strict"; +exports.__esModule = true; + + + +Output:: +>> Screen clear +12:00:15 AM - Starting compilation in watch mode... + + + +12:00:20 AM - Found 0 errors. Watching for file changes. + + +Program root files: ["/a.ts","/b.ts","/a/lib/lib.d.ts"] +Program options: {"watch":true,"configFilePath":"/tsconfig.json"} +Program files:: +/a.ts +/b.ts +/a/lib/lib.d.ts + +Semantic diagnostics in builder refreshed for:: +/a.ts +/b.ts +/a/lib/lib.d.ts + +WatchedFiles:: +/tsconfig.json: + {"pollingInterval":250} +/a.ts: + {"pollingInterval":250} +/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined + +Change:: Enable forceConsistentCasingInFileNames + +//// [/tsconfig.json] +{"compilerOptions":{"forceConsistentCasingInFileNames":true}} + + +Output:: +>> Screen clear +12:00:24 AM - File change detected. Starting incremental compilation... + + +b.ts(1,43): error TS1149: File name '/A.ts' differs from already included file name '/a.ts' only in casing. + + +12:00:25 AM - Found 1 error. Watching for file changes. + + +Program root files: ["/a.ts","/b.ts","/a/lib/lib.d.ts"] +Program options: {"forceConsistentCasingInFileNames":true,"watch":true,"configFilePath":"/tsconfig.json"} +Program files:: +/a.ts +/b.ts +/a/lib/lib.d.ts + +Semantic diagnostics in builder refreshed for:: + +WatchedFiles:: +/tsconfig.json: + {"pollingInterval":250} +/a.ts: + {"pollingInterval":250} +/b.ts: + {"pollingInterval":250} +/a/lib/lib.d.ts: + {"pollingInterval":250} + +FsWatches:: + +FsWatchesRecursive:: +/: + {"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}} + +exitCode:: ExitStatus.undefined From 38eccbab2a000a568cfeee3e1c59dade6bd4e601 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Tue, 21 Jan 2020 23:03:22 +0200 Subject: [PATCH 28/28] feat(29624): better errors for non-exported types (#36187) --- src/compiler/checker.ts | 25 +++++++++++++++++-- src/compiler/diagnosticMessages.json | 8 ++++++ ...ImportNamedImportNoNamedExports.errors.txt | 10 +++++--- .../importNonExportedMember.errors.txt | 14 +++++++++++ .../reference/importNonExportedMember.js | 17 +++++++++++++ .../reference/importNonExportedMember.symbols | 17 +++++++++++++ .../reference/importNonExportedMember.types | 17 +++++++++++++ .../importNonExportedMember1.errors.txt | 14 +++++++++++ .../reference/importNonExportedMember1.js | 17 +++++++++++++ .../importNonExportedMember1.symbols | 14 +++++++++++ .../reference/importNonExportedMember1.types | 14 +++++++++++ .../cases/compiler/importNonExportedMember.ts | 7 ++++++ .../compiler/importNonExportedMember1.ts | 7 ++++++ 13 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/importNonExportedMember.errors.txt create mode 100644 tests/baselines/reference/importNonExportedMember.js create mode 100644 tests/baselines/reference/importNonExportedMember.symbols create mode 100644 tests/baselines/reference/importNonExportedMember.types create mode 100644 tests/baselines/reference/importNonExportedMember1.errors.txt create mode 100644 tests/baselines/reference/importNonExportedMember1.js create mode 100644 tests/baselines/reference/importNonExportedMember1.symbols create mode 100644 tests/baselines/reference/importNonExportedMember1.types create mode 100644 tests/cases/compiler/importNonExportedMember.ts create mode 100644 tests/cases/compiler/importNonExportedMember1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0150d5236bdef..92ba8cb9fb56a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2355,7 +2355,7 @@ namespace ts { } } else { - if (moduleSymbol.exports && moduleSymbol.exports.has(InternalSymbolName.Default)) { + if (moduleSymbol.exports?.has(InternalSymbolName.Default)) { error( name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, @@ -2364,7 +2364,7 @@ namespace ts { ); } else { - error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName); + reportNonExportedMember(name, declarationName, moduleSymbol, moduleName); } } } @@ -2373,6 +2373,27 @@ namespace ts { } } + function reportNonExportedMember(name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void { + const localSymbol = moduleSymbol.valueDeclaration.locals?.get(name.escapedText); + const exports = moduleSymbol.exports; + + if (localSymbol) { + const exportedSymbol = exports && !exports.has(InternalSymbolName.ExportEquals) + ? find(symbolsToArray(exports), symbol => !!getSymbolIfSameReference(symbol, localSymbol)) + : undefined; + const diagnostic = exportedSymbol + ? error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol)) + : error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName); + + addRelatedInfo(diagnostic, + createDiagnosticForNode(localSymbol.valueDeclaration, Diagnostics._0_is_declared_here, declarationName) + ); + } + else { + error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName); + } + } + function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol | undefined { const resolved = getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias); if (resolved && node.parent.parent.isTypeOnly) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d4cd0df8c60bc..b4d6bea4fcae8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1764,6 +1764,14 @@ "category": "Error", "code": 2458 }, + "Module '{0}' declares '{1}' locally, but it is not exported.": { + "category": "Error", + "code": 2459 + }, + "Module '{0}' declares '{1}' locally, but it is exported as '{2}'.": { + "category": "Error", + "code": 2460 + }, "Type '{0}' is not an array type.": { "category": "Error", "code": 2461 diff --git a/tests/baselines/reference/es6ImportNamedImportNoNamedExports.errors.txt b/tests/baselines/reference/es6ImportNamedImportNoNamedExports.errors.txt index aed703af0fc25..1219ff6255186 100644 --- a/tests/baselines/reference/es6ImportNamedImportNoNamedExports.errors.txt +++ b/tests/baselines/reference/es6ImportNamedImportNoNamedExports.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(1,10): error TS2305: Module '"./es6ImportNamedImportNoNamedExports_0"' has no exported member 'a'. -tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2305: Module '"./es6ImportNamedImportNoNamedExports_0"' has no exported member 'a'. +tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(1,10): error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported. +tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported. ==== tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts (0 errors) ==== @@ -9,7 +9,9 @@ tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2305 ==== tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts (2 errors) ==== import { a } from "./es6ImportNamedImportNoNamedExports_0"; ~ -!!! error TS2305: Module '"./es6ImportNamedImportNoNamedExports_0"' has no exported member 'a'. +!!! error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported. +!!! related TS2728 tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts:1:5: 'a' is declared here. import { a as x } from "./es6ImportNamedImportNoNamedExports_0"; ~ -!!! error TS2305: Module '"./es6ImportNamedImportNoNamedExports_0"' has no exported member 'a'. \ No newline at end of file +!!! error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported. +!!! related TS2728 tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts:1:5: 'a' is declared here. \ No newline at end of file diff --git a/tests/baselines/reference/importNonExportedMember.errors.txt b/tests/baselines/reference/importNonExportedMember.errors.txt new file mode 100644 index 0000000000000..abb9d6281b360 --- /dev/null +++ b/tests/baselines/reference/importNonExportedMember.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/b.ts(1,15): error TS2460: Module '"./a"' declares 'bar' locally, but it is exported as 'baz'. + + +==== tests/cases/compiler/a.ts (0 errors) ==== + declare function foo(): any + declare function bar(): any; + export { foo, bar as baz }; + +==== tests/cases/compiler/b.ts (1 errors) ==== + import { foo, bar } from "./a"; + ~~~ +!!! error TS2460: Module '"./a"' declares 'bar' locally, but it is exported as 'baz'. +!!! related TS2728 tests/cases/compiler/a.ts:2:18: 'bar' is declared here. + \ No newline at end of file diff --git a/tests/baselines/reference/importNonExportedMember.js b/tests/baselines/reference/importNonExportedMember.js new file mode 100644 index 0000000000000..3aff52e723d92 --- /dev/null +++ b/tests/baselines/reference/importNonExportedMember.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/importNonExportedMember.ts] //// + +//// [a.ts] +declare function foo(): any +declare function bar(): any; +export { foo, bar as baz }; + +//// [b.ts] +import { foo, bar } from "./a"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; +//// [b.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/importNonExportedMember.symbols b/tests/baselines/reference/importNonExportedMember.symbols new file mode 100644 index 0000000000000..2c5d85bf48a65 --- /dev/null +++ b/tests/baselines/reference/importNonExportedMember.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/a.ts === +declare function foo(): any +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +declare function bar(): any; +>bar : Symbol(bar, Decl(a.ts, 0, 27)) + +export { foo, bar as baz }; +>foo : Symbol(foo, Decl(a.ts, 2, 8)) +>bar : Symbol(bar, Decl(a.ts, 0, 27)) +>baz : Symbol(baz, Decl(a.ts, 2, 13)) + +=== tests/cases/compiler/b.ts === +import { foo, bar } from "./a"; +>foo : Symbol(foo, Decl(b.ts, 0, 8)) +>bar : Symbol(bar, Decl(b.ts, 0, 13)) + diff --git a/tests/baselines/reference/importNonExportedMember.types b/tests/baselines/reference/importNonExportedMember.types new file mode 100644 index 0000000000000..dbf49aeb96c93 --- /dev/null +++ b/tests/baselines/reference/importNonExportedMember.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/a.ts === +declare function foo(): any +>foo : () => any + +declare function bar(): any; +>bar : () => any + +export { foo, bar as baz }; +>foo : () => any +>bar : () => any +>baz : () => any + +=== tests/cases/compiler/b.ts === +import { foo, bar } from "./a"; +>foo : () => any +>bar : any + diff --git a/tests/baselines/reference/importNonExportedMember1.errors.txt b/tests/baselines/reference/importNonExportedMember1.errors.txt new file mode 100644 index 0000000000000..80cae4d278425 --- /dev/null +++ b/tests/baselines/reference/importNonExportedMember1.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/b.ts(1,10): error TS2459: Module '"./a"' declares 'bar' locally, but it is not exported. + + +==== tests/cases/compiler/a.ts (0 errors) ==== + declare function foo(): any + declare function bar(): any; + export { foo }; + +==== tests/cases/compiler/b.ts (1 errors) ==== + import { bar } from "./a"; + ~~~ +!!! error TS2459: Module '"./a"' declares 'bar' locally, but it is not exported. +!!! related TS2728 tests/cases/compiler/a.ts:2:18: 'bar' is declared here. + \ No newline at end of file diff --git a/tests/baselines/reference/importNonExportedMember1.js b/tests/baselines/reference/importNonExportedMember1.js new file mode 100644 index 0000000000000..5309080c4a997 --- /dev/null +++ b/tests/baselines/reference/importNonExportedMember1.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/importNonExportedMember1.ts] //// + +//// [a.ts] +declare function foo(): any +declare function bar(): any; +export { foo }; + +//// [b.ts] +import { bar } from "./a"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; +//// [b.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/importNonExportedMember1.symbols b/tests/baselines/reference/importNonExportedMember1.symbols new file mode 100644 index 0000000000000..1fb7b5418c55e --- /dev/null +++ b/tests/baselines/reference/importNonExportedMember1.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/a.ts === +declare function foo(): any +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +declare function bar(): any; +>bar : Symbol(bar, Decl(a.ts, 0, 27)) + +export { foo }; +>foo : Symbol(foo, Decl(a.ts, 2, 8)) + +=== tests/cases/compiler/b.ts === +import { bar } from "./a"; +>bar : Symbol(bar, Decl(b.ts, 0, 8)) + diff --git a/tests/baselines/reference/importNonExportedMember1.types b/tests/baselines/reference/importNonExportedMember1.types new file mode 100644 index 0000000000000..e4ec51b4b7676 --- /dev/null +++ b/tests/baselines/reference/importNonExportedMember1.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/a.ts === +declare function foo(): any +>foo : () => any + +declare function bar(): any; +>bar : () => any + +export { foo }; +>foo : () => any + +=== tests/cases/compiler/b.ts === +import { bar } from "./a"; +>bar : any + diff --git a/tests/cases/compiler/importNonExportedMember.ts b/tests/cases/compiler/importNonExportedMember.ts new file mode 100644 index 0000000000000..103210edc8321 --- /dev/null +++ b/tests/cases/compiler/importNonExportedMember.ts @@ -0,0 +1,7 @@ +// @filename: a.ts +declare function foo(): any +declare function bar(): any; +export { foo, bar as baz }; + +// @filename: b.ts +import { foo, bar } from "./a"; diff --git a/tests/cases/compiler/importNonExportedMember1.ts b/tests/cases/compiler/importNonExportedMember1.ts new file mode 100644 index 0000000000000..e3242ce60043d --- /dev/null +++ b/tests/cases/compiler/importNonExportedMember1.ts @@ -0,0 +1,7 @@ +// @filename: a.ts +declare function foo(): any +declare function bar(): any; +export { foo }; + +// @filename: b.ts +import { bar } from "./a";