From acee628a31068d0b3fa22af77733cab831b34b56 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 30 Apr 2018 15:42:52 -0700 Subject: [PATCH 01/21] Fix discriminant checking in contextual types to avoid infinite recursion --- src/compiler/checker.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9bd940e547e..2070cf84e50 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15036,6 +15036,26 @@ namespace ts { } } + // Return true if the given expression is possibly a discriminant value. We limit the kinds of + // expressions we check to those that don't depend on their contextual type in order not to cause + // recursive (and possibly infinite) invocations of getContextualType. + function isPossiblyDiscriminantValue(node: Expression): boolean { + switch (node.kind) { + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: + case SyntaxKind.NullKeyword: + case SyntaxKind.Identifier: + return true; + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ParenthesizedExpression: + return isPossiblyDiscriminantValue((node).expression); + } + return false; + } + // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. function getApparentTypeOfContextualType(node: Expression): Type { @@ -15049,8 +15069,8 @@ namespace ts { propLoop: for (const prop of node.properties) { if (!prop.symbol) continue; if (prop.kind !== SyntaxKind.PropertyAssignment) continue; - if (isDiscriminantProperty(contextualType, prop.symbol.escapedName)) { - const discriminatingType = getTypeOfNode(prop.initializer); + if (isPossiblyDiscriminantValue(prop.initializer) && isDiscriminantProperty(contextualType, prop.symbol.escapedName)) { + const discriminatingType = checkExpression(prop.initializer); for (const type of (contextualType as UnionType).types) { const targetType = getTypeOfPropertyOfType(type, prop.symbol.escapedName); if (targetType && checkTypeAssignableTo(discriminatingType, targetType, /*errorNode*/ undefined)) { From 0ab3c1fe9652ab0e3537adcd0b45e246f0262a12 Mon Sep 17 00:00:00 2001 From: Mine Starks Date: Tue, 15 May 2018 13:35:24 -0700 Subject: [PATCH 02/21] Normalize this.currentDirectory --- src/server/editorServices.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 459b4b12d83..dd27130ea72 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -403,7 +403,7 @@ namespace ts.server { /* @internal */ pendingEnsureProjectForOpenFiles: boolean; - readonly currentDirectory: string; + readonly currentDirectory: NormalizedPath; readonly toCanonicalFileName: (f: string) => string; public readonly host: ServerHost; @@ -450,7 +450,7 @@ namespace ts.server { if (this.host.realpath) { this.realpathToScriptInfos = createMultiMap(); } - this.currentDirectory = this.host.getCurrentDirectory(); + this.currentDirectory = toNormalizedPath(this.host.getCurrentDirectory()); this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation && ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation)); From dff5809c68564891d39f44be1342b782eece3e11 Mon Sep 17 00:00:00 2001 From: Mine Starks Date: Wed, 16 May 2018 09:27:14 -0700 Subject: [PATCH 03/21] Accept new baseline --- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6c3e0c9b7a1..5ea9484aaf8 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8154,7 +8154,7 @@ declare namespace ts.server { private safelist; private legacySafelist; private pendingProjectUpdates; - readonly currentDirectory: string; + readonly currentDirectory: NormalizedPath; readonly toCanonicalFileName: (f: string) => string; readonly host: ServerHost; readonly logger: Logger; From d55837175c450073130ab72e41ed37403347d35d Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 16 May 2018 13:50:48 -0700 Subject: [PATCH 04/21] Update version --- package.json | 2 +- src/compiler/core.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 48179f02e10..a7eb0dfd389 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "2.9.0", + "version": "3.0.0", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3e8e33e3017..d23aa681422 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,7 +1,7 @@ namespace ts { // WARNING: The script `configureNightly.ts` uses a regexp to parse out these values. // If changing the text in this section, be sure to test `configureNightly` too. - export const versionMajorMinor = "2.9"; + export const versionMajorMinor = "3.0"; /** The version of the TypeScript compiler release */ export const version = `${versionMajorMinor}.0-dev`; } From 6f041e9379562a9fc08521bf55b2b3f431f3107a Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 16 May 2018 14:26:34 -0700 Subject: [PATCH 05/21] Accept baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 67bd6cbe980..0a32d866569 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2938,7 +2938,7 @@ declare namespace ts { } } declare namespace ts { - const versionMajorMinor = "2.9"; + const versionMajorMinor = "3.0"; /** The version of the TypeScript compiler release */ const version: string; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index ef435632a36..3c2e5d27038 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2938,7 +2938,7 @@ declare namespace ts { } } declare namespace ts { - const versionMajorMinor = "2.9"; + const versionMajorMinor = "3.0"; /** The version of the TypeScript compiler release */ const version: string; } From 59d19251cfcb20083222f7882adfca0204c5aada Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 15 May 2018 16:11:25 -0700 Subject: [PATCH 06/21] Add test to verify the document is released from source file when info is orphan --- .../unittests/tsserverProjectSystem.ts | 43 +++++++++++++++++++ src/server/editorServices.ts | 3 +- src/services/documentRegistry.ts | 8 ++++ .../reference/api/tsserverlibrary.d.ts | 1 - 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 8524d46e094..10bd2f2ac72 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -8383,4 +8383,47 @@ new C();` verifyCompletionListWithNewFileInSubFolder(TestFSWithWatch.Tsc_WatchDirectory.DynamicPolling); }); }); + + describe("document registry in project service", () => { + it("Caches the source file if script info is orphan", () => { + const projectRootPath = "/user/username/projects/project"; + const importModuleContent = `import {a} from "./module1"`; + const file: File = { + path: `${projectRootPath}/index.ts`, + content: importModuleContent + }; + const moduleFile: File = { + path: `${projectRootPath}/module1.d.ts`, + content: "export const a: number;" + }; + const configFile: File = { + path: `${projectRootPath}/tsconfig.json`, + content: JSON.stringify({ files: ["index.ts"] }) + }; + const host = createServerHost([file, moduleFile, libFile, configFile]); + const service = createProjectService(host); + service.openClientFile(file.path); + const project = service.configuredProjects.get(configFile.path); + checkProject(/*moduleIsOrphan*/ false); + + // edit file + const info = service.getScriptInfo(file.path); + service.applyChangesToFile(info, [{ span: { start: 0, length: importModuleContent.length }, newText: "" }]); + checkProject(/*moduleIsOrphan*/ true); + + // write content back + service.applyChangesToFile(info, [{ span: { start: 0, length: 0 }, newText: importModuleContent }]); + checkProject(/*moduleIsOrphan*/ false); + + function checkProject(moduleIsOrphan: boolean) { + // Update the project + project.getLanguageService(); + checkProjectActualFiles(project, [file.path, libFile.path, configFile.path, ...(moduleIsOrphan ? [] : [moduleFile.path])]); + const moduleInfo = service.getScriptInfo(moduleFile.path); + assert.isDefined(moduleInfo); + assert.equal(moduleInfo.isOrphan(), moduleIsOrphan); + assert.equal(service.documentRegistry.hasDocument(moduleInfo.path), !moduleIsOrphan); + } + }); + }); } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index bb3560cbde5..f3fb198e68a 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -339,7 +339,8 @@ namespace ts.server { /*@internal*/ readonly typingsCache: TypingsCache; - private readonly documentRegistry: DocumentRegistry; + /*@internal*/ + readonly documentRegistry: DocumentRegistry; /** * Container of all known scripts diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index d464f7a408a..b49f0d5c2c1 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -87,6 +87,9 @@ namespace ts { releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey): void; + /*@internal*/ + hasDocument(path: Path): boolean; + reportStats(): string; } @@ -225,6 +228,10 @@ namespace ts { } } + function hasDocument(path: Path) { + return !!forEachEntry(buckets, bucket => bucket.has(path)); + } + return { acquireDocument, acquireDocumentWithKey, @@ -232,6 +239,7 @@ namespace ts { updateDocumentWithKey, releaseDocument, releaseDocumentWithKey, + hasDocument, reportStats, getKeyForCompilationSettings }; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1cf0b12522b..ef51c004480 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8124,7 +8124,6 @@ declare namespace ts.server { syntaxOnly?: boolean; } class ProjectService { - private readonly documentRegistry; /** * Container of all known scripts */ From 81ca6502ea1344879f77ae784841adc7281dd57b Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 15 May 2018 17:10:40 -0700 Subject: [PATCH 07/21] Cache the latest source file from document registry so we can keep it alive when script info is orphan --- .../unittests/tsserverProjectSystem.ts | 6 +++ src/server/editorServices.ts | 15 +++++++- src/server/scriptInfo.ts | 9 +++++ src/services/documentRegistry.ts | 38 +++++++++++++++---- 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 10bd2f2ac72..c09dbde2b57 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -8405,15 +8405,21 @@ new C();` service.openClientFile(file.path); const project = service.configuredProjects.get(configFile.path); checkProject(/*moduleIsOrphan*/ false); + const moduleInfo = service.getScriptInfo(moduleFile.path); + const sourceFile = moduleInfo.cacheSourceFile.sourceFile; + assert.equal(project.getSourceFile(moduleInfo.path), sourceFile); // edit file const info = service.getScriptInfo(file.path); service.applyChangesToFile(info, [{ span: { start: 0, length: importModuleContent.length }, newText: "" }]); checkProject(/*moduleIsOrphan*/ true); + assert.equal(moduleInfo.cacheSourceFile.sourceFile, sourceFile); // write content back service.applyChangesToFile(info, [{ span: { start: 0, length: 0 }, newText: importModuleContent }]); checkProject(/*moduleIsOrphan*/ false); + assert.equal(moduleInfo.cacheSourceFile.sourceFile, sourceFile); + assert.equal(project.getSourceFile(moduleInfo.path), sourceFile); function checkProject(moduleIsOrphan: boolean) { // Update the project diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index f3fb198e68a..b8a94a98889 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -475,7 +475,7 @@ namespace ts.server { extraFileExtensions: [] }; - this.documentRegistry = createDocumentRegistry(this.host.useCaseSensitiveFileNames, this.currentDirectory); + this.documentRegistry = createDocumentRegistryInternal(this.host.useCaseSensitiveFileNames, this.currentDirectory, this); const watchLogLevel = this.logger.hasLevel(LogLevel.verbose) ? WatchLogLevel.Verbose : this.logger.loggingEnabled() ? WatchLogLevel.TriggerOnly : WatchLogLevel.None; const log: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? (s => this.logger.info(s)) : noop; @@ -496,6 +496,19 @@ namespace ts.server { return getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory()); } + /*@internal*/ + setDocument(key: DocumentRegistryBucketKey, path: Path, sourceFile: SourceFile) { + const info = this.getScriptInfoForPath(path); + Debug.assert(!!info); + info.cacheSourceFile = { key, sourceFile }; + } + + /*@internal*/ + getDocument(key: DocumentRegistryBucketKey, path: Path) { + const info = this.getScriptInfoForPath(path); + return info && info.cacheSourceFile && info.cacheSourceFile.key === key && info.cacheSourceFile.sourceFile; + } + /* @internal */ ensureInferredProjectsUpToDate_TestOnly() { this.ensureProjectStructuresUptoDate(); diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index efae3a5faa6..c47f3daecb9 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -202,6 +202,12 @@ namespace ts.server { return fileName[0] === "^" || getBaseFileName(fileName)[0] === "^"; } + /*@internal*/ + export interface DocumentRegistrySourceFileCache { + key: DocumentRegistryBucketKey; + sourceFile: SourceFile; + } + export class ScriptInfo { /** * All projects that include this file @@ -221,6 +227,9 @@ namespace ts.server { /** Set to real path if path is different from info.path */ private realpath: Path | undefined; + /*@internal*/ + cacheSourceFile: DocumentRegistrySourceFileCache; + constructor( private readonly host: ServerHost, readonly fileName: NormalizedPath, diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index b49f0d5c2c1..a51cf82daad 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -93,6 +93,12 @@ namespace ts { reportStats(): string; } + /*@internal*/ + export interface ExternalDocumentCache { + setDocument(key: DocumentRegistryBucketKey, path: Path, sourceFile: SourceFile): void; + getDocument(key: DocumentRegistryBucketKey, path: Path): SourceFile | undefined; + } + export type DocumentRegistryBucketKey = string & { __bucketKey: any }; interface DocumentRegistryEntry { @@ -102,10 +108,14 @@ namespace ts { // language services are referencing the file, then the file can be removed from the // registry. languageServiceRefCount: number; - owners: string[]; } - export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry { + export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry { + return createDocumentRegistryInternal(useCaseSensitiveFileNames, currentDirectory); + } + + /*@internal*/ + export function createDocumentRegistryInternal(useCaseSensitiveFileNames?: boolean, currentDirectory = "", externalCache?: ExternalDocumentCache): DocumentRegistry { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. const buckets = createMap>(); @@ -126,12 +136,11 @@ namespace ts { function reportStats() { const bucketInfoArray = arrayFrom(buckets.keys()).filter(name => name && name.charAt(0) === "_").map(name => { const entries = buckets.get(name); - const sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; + const sourceFiles: { name: string; refCount: number; }[] = []; entries.forEach((entry, name) => { sourceFiles.push({ name, - refCount: entry.languageServiceRefCount, - references: entry.owners.slice(0) + refCount: entry.languageServiceRefCount }); }); sourceFiles.sort((x, y) => y.refCount - x.refCount); @@ -176,14 +185,26 @@ namespace ts { const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true); let entry = bucket.get(path); const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target; + if (!entry && externalCache) { + const sourceFile = externalCache.getDocument(key, path); + if (sourceFile) { + entry = { + sourceFile, + languageServiceRefCount: 1 + }; + bucket.set(path, entry); + } + } + if (!entry) { // Have never seen this file with these settings. Create a new source file for it. const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, /*setNodeParents*/ false, scriptKind); - + if (externalCache) { + externalCache.setDocument(key, path, sourceFile); + } entry = { sourceFile, languageServiceRefCount: 1, - owners: [] }; bucket.set(path, entry); } @@ -194,6 +215,9 @@ namespace ts { if (entry.sourceFile.version !== version) { entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); + if (externalCache) { + externalCache.setDocument(key, path, entry.sourceFile); + } } // If we're acquiring, then this is the first time this LS is asking for this document. From f1acbc93efd8f834469b7f00c9e412d281a5a7a6 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 21 May 2018 12:19:48 -0700 Subject: [PATCH 08/21] Add noGetErrOnBackgroundUpdate session option to not queue diagnostics check for open files This will ensure that the getErr will be queued in by host and hence would make sure that it is cancellable. Handles one of the scenario delaying completions in #19458 --- src/harness/unittests/tsserverProjectSystem.ts | 17 ++++++++++++++--- src/server/server.ts | 2 ++ src/server/session.ts | 5 ++++- .../reference/api/tsserverlibrary.d.ts | 2 ++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 7a5f97b06d5..bda8f1d09a5 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -7445,10 +7445,17 @@ namespace ts.projectSystem { }); describe("when event handler is not set but session is created with canUseEvents = true", () => { - verifyProjectsUpdatedInBackgroundEvent(createSessionThatUsesEvents); + describe("without noGetErrOnBackgroundUpdate, diagnostics for open files are queued", () => { + verifyProjectsUpdatedInBackgroundEvent(createSessionThatUsesEvents); + }); - function createSessionThatUsesEvents(host: TestServerHost): ProjectsUpdatedInBackgroundEventVerifier { - const session = createSession(host, { canUseEvents: true }); + describe("with noGetErrOnBackgroundUpdate, diagnostics for open file are not queued", () => { + verifyProjectsUpdatedInBackgroundEvent(host => createSessionThatUsesEvents(host, /*noGetErrOnBackgroundUpdate*/ true)); + }); + + + function createSessionThatUsesEvents(host: TestServerHost, noGetErrOnBackgroundUpdate?: boolean): ProjectsUpdatedInBackgroundEventVerifier { + const session = createSession(host, { canUseEvents: true, noGetErrOnBackgroundUpdate }); return { session, @@ -7480,6 +7487,10 @@ namespace ts.projectSystem { // Verified the events, reset them session.clearMessages(); + + if (events.length) { + host.checkTimeoutQueueLength(noGetErrOnBackgroundUpdate ? 0 : 1); // Error checking queued only if not noGetErrOnBackgroundUpdate + } } } }); diff --git a/src/server/server.ts b/src/server/server.ts index 6eff3256349..706a47a0aa5 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -505,6 +505,7 @@ namespace ts.server { canUseEvents: true, suppressDiagnosticEvents, syntaxOnly, + noGetErrOnBackgroundUpdate, globalPlugins, pluginProbeLocations, allowLocalPluginLoads, @@ -939,6 +940,7 @@ namespace ts.server { const suppressDiagnosticEvents = hasArgument("--suppressDiagnosticEvents"); const syntaxOnly = hasArgument("--syntaxOnly"); const telemetryEnabled = hasArgument(Arguments.EnableTelemetry); + const noGetErrOnBackgroundUpdate = hasArgument("--noGetErrOnBackgroundUpdate"); logger.info(`Starting TS Server`); logger.info(`Version: ${version}`); diff --git a/src/server/session.ts b/src/server/session.ts index 40f26785113..ccedad18aac 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -295,6 +295,7 @@ namespace ts.server { suppressDiagnosticEvents?: boolean; syntaxOnly?: boolean; throttleWaitMilliseconds?: number; + noGetErrOnBackgroundUpdate?: boolean; globalPlugins?: ReadonlyArray; pluginProbeLocations?: ReadonlyArray; @@ -319,6 +320,7 @@ namespace ts.server { protected canUseEvents: boolean; private suppressDiagnosticEvents?: boolean; private eventHandler: ProjectServiceEventHandler; + private readonly noGetErrOnBackgroundUpdate?: boolean; constructor(opts: SessionOptions) { this.host = opts.host; @@ -329,6 +331,7 @@ namespace ts.server { this.logger = opts.logger; this.canUseEvents = opts.canUseEvents; this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents; + this.noGetErrOnBackgroundUpdate = opts.noGetErrOnBackgroundUpdate; const { throttleWaitMilliseconds } = opts; @@ -404,7 +407,7 @@ namespace ts.server { private projectsUpdatedInBackgroundEvent(openFiles: string[]): void { this.projectService.logger.info(`got projects updated in background, updating diagnostics for ${openFiles}`); if (openFiles.length) { - if (!this.suppressDiagnosticEvents) { + if (!this.suppressDiagnosticEvents && !this.noGetErrOnBackgroundUpdate) { const checkList = this.createCheckList(openFiles); // For now only queue error checking for open files. We can change this to include non open files as well diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index cbf39a2a48f..52568993f3e 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8391,6 +8391,7 @@ declare namespace ts.server { suppressDiagnosticEvents?: boolean; syntaxOnly?: boolean; throttleWaitMilliseconds?: number; + noGetErrOnBackgroundUpdate?: boolean; globalPlugins?: ReadonlyArray; pluginProbeLocations?: ReadonlyArray; allowLocalPluginLoads?: boolean; @@ -8410,6 +8411,7 @@ declare namespace ts.server { protected canUseEvents: boolean; private suppressDiagnosticEvents?; private eventHandler; + private readonly noGetErrOnBackgroundUpdate?; constructor(opts: SessionOptions); private sendRequestCompletedEvent; private defaultEventHandler; From c8ac08549838c0dad0389e27ddf95bcc56760ad6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 21 May 2018 15:28:51 -0700 Subject: [PATCH 09/21] Infer non-widening literal types when type parameter constraint includes primitive types --- src/compiler/checker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9f3c8fa6fd7..fb2e2ba3413 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12777,7 +12777,9 @@ namespace ts { const widenLiteralTypes = inference.topLevel && !hasPrimitiveConstraint(inference.typeParameter) && (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); - const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates; + const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : + hasPrimitiveConstraint(inference.typeParameter) ? sameMap(candidates, getRegularTypeOfLiteralType) : + candidates; // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if // union types were requested or if all inferences were made from the return type position, infer a // union type. Otherwise, infer a common supertype. From 8528dbee763e096e6cec72b38e5014b1ffb9ffd0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 21 May 2018 16:17:56 -0700 Subject: [PATCH 10/21] Handle union types in getRegularTypeOfLiteralType --- src/compiler/checker.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fb2e2ba3413..c36e5075a0e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9286,8 +9286,10 @@ namespace ts { return type; } - function getRegularTypeOfLiteralType(type: Type) { - return type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral ? (type).regularType : type; + function getRegularTypeOfLiteralType(type: Type): Type { + return type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral ? (type).regularType : + type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getRegularTypeOfLiteralType)) : + type; } function getLiteralType(value: string | number, enumId?: number, symbol?: Symbol) { @@ -12774,11 +12776,11 @@ namespace ts { // all inferences were made to top-level occurrences of the type parameter, and // the type parameter has no constraint or its constraint includes no primitive or literal types, and // the type parameter was fixed during inference or does not occur at top-level in the return type. - const widenLiteralTypes = inference.topLevel && - !hasPrimitiveConstraint(inference.typeParameter) && + const primitiveConstraint = hasPrimitiveConstraint(inference.typeParameter); + const widenLiteralTypes = !primitiveConstraint && inference.topLevel && (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); - const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : - hasPrimitiveConstraint(inference.typeParameter) ? sameMap(candidates, getRegularTypeOfLiteralType) : + const baseCandidates = primitiveConstraint ? sameMap(candidates, getRegularTypeOfLiteralType) : + widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates; // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if // union types were requested or if all inferences were made from the return type position, infer a From 5bbadb66ab01aaf4a95a8e33bf8f7285963b2c1a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 21 May 2018 16:43:46 -0700 Subject: [PATCH 11/21] Accept new baselines --- .../reference/bestCommonTypeOfConditionalExpressions2.types | 2 +- ...onWithTypeParameterConstrainedToOuterTypeParameter.types | 2 +- tests/baselines/reference/conditionalExpression1.types | 4 ++-- tests/baselines/reference/conditionalExpressions2.types | 2 +- .../reference/conditionalOperatorWithIdenticalBCT.types | 2 +- tests/baselines/reference/conditionalTypes1.types | 4 ++-- .../reference/declFileTypeAnnotationParenType.types | 2 +- tests/baselines/reference/literalTypes2.types | 2 +- tests/baselines/reference/literalTypes3.types | 4 ++-- ...onWithTypeParameterConstrainedToOuterTypeParameter.types | 2 +- tests/baselines/reference/parserArgumentList1.types | 2 +- tests/baselines/reference/subtypesOfTypeParameter.types | 4 ++-- .../reference/subtypesOfTypeParameterWithConstraints2.types | 4 ++-- tests/baselines/reference/uniqueSymbols.types | 6 +++--- tests/baselines/reference/uniqueSymbolsDeclarations.types | 6 +++--- 15 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/baselines/reference/bestCommonTypeOfConditionalExpressions2.types b/tests/baselines/reference/bestCommonTypeOfConditionalExpressions2.types index 997f4ea5249..ad09c274c9b 100644 --- a/tests/baselines/reference/bestCommonTypeOfConditionalExpressions2.types +++ b/tests/baselines/reference/bestCommonTypeOfConditionalExpressions2.types @@ -30,7 +30,7 @@ var derived2: Derived2; var r2 = true ? 1 : ''; >r2 : string | number ->true ? 1 : '' : 1 | "" +>true ? 1 : '' : "" | 1 >true : true >1 : 1 >'' : "" diff --git a/tests/baselines/reference/callExpressionWithTypeParameterConstrainedToOuterTypeParameter.types b/tests/baselines/reference/callExpressionWithTypeParameterConstrainedToOuterTypeParameter.types index 69188eacd1a..76b8a513702 100644 --- a/tests/baselines/reference/callExpressionWithTypeParameterConstrainedToOuterTypeParameter.types +++ b/tests/baselines/reference/callExpressionWithTypeParameterConstrainedToOuterTypeParameter.types @@ -15,7 +15,7 @@ var i: I; >I : I var y = i(""); // y should be string ->y : string +>y : "" >i("") : "" >i : I >"" : "" diff --git a/tests/baselines/reference/conditionalExpression1.types b/tests/baselines/reference/conditionalExpression1.types index d5695b64c38..b5e177b4c78 100644 --- a/tests/baselines/reference/conditionalExpression1.types +++ b/tests/baselines/reference/conditionalExpression1.types @@ -1,8 +1,8 @@ === tests/cases/compiler/conditionalExpression1.ts === var x: boolean = (true ? 1 : ""); // should be an error >x : boolean ->(true ? 1 : "") : 1 | "" ->true ? 1 : "" : 1 | "" +>(true ? 1 : "") : "" | 1 +>true ? 1 : "" : "" | 1 >true : true >1 : 1 >"" : "" diff --git a/tests/baselines/reference/conditionalExpressions2.types b/tests/baselines/reference/conditionalExpressions2.types index 325a281738f..3067f212f3c 100644 --- a/tests/baselines/reference/conditionalExpressions2.types +++ b/tests/baselines/reference/conditionalExpressions2.types @@ -15,7 +15,7 @@ var b = false ? undefined : 0; var c = false ? 1 : 0; >c : number ->false ? 1 : 0 : 1 | 0 +>false ? 1 : 0 : 0 | 1 >false : false >1 : 1 >0 : 0 diff --git a/tests/baselines/reference/conditionalOperatorWithIdenticalBCT.types b/tests/baselines/reference/conditionalOperatorWithIdenticalBCT.types index a9767c72fc7..6f7a4db20e2 100644 --- a/tests/baselines/reference/conditionalOperatorWithIdenticalBCT.types +++ b/tests/baselines/reference/conditionalOperatorWithIdenticalBCT.types @@ -218,7 +218,7 @@ var result10: (t: X) => any = true ? (m) => m.propertyX1 : (n) => n.propertyX2; //Expr1 and Expr2 are literals var result11: any = true ? 1 : 'string'; >result11 : any ->true ? 1 : 'string' : 1 | "string" +>true ? 1 : 'string' : "string" | 1 >true : true >1 : 1 >'string' : "string" diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index 699808c1f78..5b0cb6dd838 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -589,8 +589,8 @@ function zeroOf(value: T) { >>(typeof value === "number" ? 0 : typeof value === "string" ? "" : false) : ZeroOf >ZeroOf : ZeroOf >T : T ->(typeof value === "number" ? 0 : typeof value === "string" ? "" : false) : false | 0 | "" ->typeof value === "number" ? 0 : typeof value === "string" ? "" : false : false | 0 | "" +>(typeof value === "number" ? 0 : typeof value === "string" ? "" : false) : false | "" | 0 +>typeof value === "number" ? 0 : typeof value === "string" ? "" : false : false | "" | 0 >typeof value === "number" : boolean >typeof value : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" >value : T diff --git a/tests/baselines/reference/declFileTypeAnnotationParenType.types b/tests/baselines/reference/declFileTypeAnnotationParenType.types index a73c9bba0a9..9d8fddb0559 100644 --- a/tests/baselines/reference/declFileTypeAnnotationParenType.types +++ b/tests/baselines/reference/declFileTypeAnnotationParenType.types @@ -24,7 +24,7 @@ var y = [() => new c()]; var k: (() => c) | string = (() => new c()) || ""; >k : string | (() => c) >c : c ->(() => new c()) || "" : (() => c) | "" +>(() => new c()) || "" : "" | (() => c) >(() => new c()) : () => c >() => new c() : () => c >new c() : c diff --git a/tests/baselines/reference/literalTypes2.types b/tests/baselines/reference/literalTypes2.types index 429a1457c4e..e4e33445790 100644 --- a/tests/baselines/reference/literalTypes2.types +++ b/tests/baselines/reference/literalTypes2.types @@ -555,7 +555,7 @@ class C2 { >bar : () => 1 | 0 return cond ? 0 : 1; ->cond ? 0 : 1 : 1 | 0 +>cond ? 0 : 1 : 0 | 1 >cond : boolean >0 : 0 >1 : 1 diff --git a/tests/baselines/reference/literalTypes3.types b/tests/baselines/reference/literalTypes3.types index 059e2777e54..c0623dd6523 100644 --- a/tests/baselines/reference/literalTypes3.types +++ b/tests/baselines/reference/literalTypes3.types @@ -107,7 +107,7 @@ function f5(x: number, y: 1 | 2) { >y : 1 | 2 x; // 0 | 1 | 2 ->x : 1 | 2 | 0 +>x : 0 | 1 | 2 } } @@ -126,7 +126,7 @@ function f6(x: number, y: 1 | 2) { >x : number x; // 0 | 1 | 2 ->x : 1 | 2 | 0 +>x : 0 | 1 | 2 } } diff --git a/tests/baselines/reference/newExpressionWithTypeParameterConstrainedToOuterTypeParameter.types b/tests/baselines/reference/newExpressionWithTypeParameterConstrainedToOuterTypeParameter.types index badd17765b8..6d541198802 100644 --- a/tests/baselines/reference/newExpressionWithTypeParameterConstrainedToOuterTypeParameter.types +++ b/tests/baselines/reference/newExpressionWithTypeParameterConstrainedToOuterTypeParameter.types @@ -15,7 +15,7 @@ var i: I; >I : I var y = new i(""); // y should be string ->y : string +>y : "" >new i("") : "" >i : I >"" : "" diff --git a/tests/baselines/reference/parserArgumentList1.types b/tests/baselines/reference/parserArgumentList1.types index ddf00ee8750..3e210b80890 100644 --- a/tests/baselines/reference/parserArgumentList1.types +++ b/tests/baselines/reference/parserArgumentList1.types @@ -26,7 +26,7 @@ export function removeClass (node:HTMLElement, className:string) { >rightDelimiter : any return leftDelimiter.length + rightDelimiter.length === 2 ? ' ' : ''; ->leftDelimiter.length + rightDelimiter.length === 2 ? ' ' : '' : " " | "" +>leftDelimiter.length + rightDelimiter.length === 2 ? ' ' : '' : "" | " " >leftDelimiter.length + rightDelimiter.length === 2 : boolean >leftDelimiter.length + rightDelimiter.length : any >leftDelimiter.length : any diff --git a/tests/baselines/reference/subtypesOfTypeParameter.types b/tests/baselines/reference/subtypesOfTypeParameter.types index 58af856e150..b703292fb4f 100644 --- a/tests/baselines/reference/subtypesOfTypeParameter.types +++ b/tests/baselines/reference/subtypesOfTypeParameter.types @@ -144,14 +144,14 @@ function f2(x: T, y: U) { var r2 = true ? '' : x; >r2 : string | T ->true ? '' : x : T | "" +>true ? '' : x : "" | T >true : true >'' : "" >x : T var r2 = true ? x : ''; >r2 : string | T ->true ? x : '' : T | "" +>true ? x : '' : "" | T >true : true >x : T >'' : "" diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints2.types b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints2.types index e2f294343a5..34ef257609b 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints2.types +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints2.types @@ -259,14 +259,14 @@ function f6(x: T) { var r2 = true ? '' : x; // ok >r2 : string | T ->true ? '' : x : T | "" +>true ? '' : x : "" | T >true : true >'' : "" >x : T var r2 = true ? x : ''; // ok >r2 : string | T ->true ? x : '' : T | "" +>true ? x : '' : "" | T >true : true >x : T >'' : "" diff --git a/tests/baselines/reference/uniqueSymbols.types b/tests/baselines/reference/uniqueSymbols.types index 55ce8d9c87e..3cae76bd782 100644 --- a/tests/baselines/reference/uniqueSymbols.types +++ b/tests/baselines/reference/uniqueSymbols.types @@ -699,19 +699,19 @@ g(N["s"]); // falsy expressions s || ""; ->s || "" : unique symbol | "" +>s || "" : "" | unique symbol >s : unique symbol >"" : "" N.s || ""; ->N.s || "" : unique symbol | "" +>N.s || "" : "" | unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol >"" : "" N["s"] || ""; ->N["s"] || "" : unique symbol | "" +>N["s"] || "" : "" | unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" diff --git a/tests/baselines/reference/uniqueSymbolsDeclarations.types b/tests/baselines/reference/uniqueSymbolsDeclarations.types index 6bfee5a0403..792a27f5182 100644 --- a/tests/baselines/reference/uniqueSymbolsDeclarations.types +++ b/tests/baselines/reference/uniqueSymbolsDeclarations.types @@ -699,19 +699,19 @@ g(N["s"]); // falsy expressions s || ""; ->s || "" : unique symbol | "" +>s || "" : "" | unique symbol >s : unique symbol >"" : "" N.s || ""; ->N.s || "" : unique symbol | "" +>N.s || "" : "" | unique symbol >N.s : unique symbol >N : typeof N >s : unique symbol >"" : "" N["s"] || ""; ->N["s"] || "" : unique symbol | "" +>N["s"] || "" : "" | unique symbol >N["s"] : unique symbol >N : typeof N >"s" : "s" From 9d4096f9c4d320e294e25d9810c82022a4b1a4e6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 21 May 2018 16:43:55 -0700 Subject: [PATCH 12/21] Add tests --- .../types/literal/literalTypeWidening.ts | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/cases/conformance/types/literal/literalTypeWidening.ts b/tests/cases/conformance/types/literal/literalTypeWidening.ts index 98ed328f0d2..4c818793142 100644 --- a/tests/cases/conformance/types/literal/literalTypeWidening.ts +++ b/tests/cases/conformance/types/literal/literalTypeWidening.ts @@ -59,6 +59,18 @@ function f5() { let v4 = c4; } +declare function widening(x: T): T; +declare function nonWidening(x: T): T; + +function f6(cond: boolean) { + let x1 = widening('a'); + let x2 = widening(10); + let x3 = widening(cond ? 'a' : 10); + let y1 = nonWidening('a'); + let y2 = nonWidening(10); + let y3 = nonWidening(cond ? 'a' : 10); +} + // Repro from #10898 type FAILURE = "FAILURE"; @@ -94,4 +106,24 @@ type TestEvent = "onmouseover" | "onmouseout"; function onMouseOver(): TestEvent { return "onmouseover"; } -let x = onMouseOver(); \ No newline at end of file +let x = onMouseOver(); + +// Repro from #23649 + +export function Set(...keys: K[]): Record { + const result = {} as Record + keys.forEach(key => result[key] = true) + return result +} + +export function keys(obj: Record): K[] { + return Object.keys(obj) as K[] +} + +type Obj = { code: LangCode } + +const langCodeSet = Set('fr', 'en', 'es', 'it', 'nl') +export type LangCode = keyof typeof langCodeSet +export const langCodes = keys(langCodeSet) + +const arr: Obj[] = langCodes.map(code => ({ code })) From b31c414a31e7f55ef5b8dce8fffef693d02edd66 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 21 May 2018 16:44:03 -0700 Subject: [PATCH 13/21] Accept new baselines --- .../reference/literalTypeWidening.js | 63 +++++- .../reference/literalTypeWidening.symbols | 203 ++++++++++++++---- .../reference/literalTypeWidening.types | 155 +++++++++++++ 3 files changed, 377 insertions(+), 44 deletions(-) diff --git a/tests/baselines/reference/literalTypeWidening.js b/tests/baselines/reference/literalTypeWidening.js index 58002123557..fc805ac6706 100644 --- a/tests/baselines/reference/literalTypeWidening.js +++ b/tests/baselines/reference/literalTypeWidening.js @@ -60,6 +60,18 @@ function f5() { let v4 = c4; } +declare function widening(x: T): T; +declare function nonWidening(x: T): T; + +function f6(cond: boolean) { + let x1 = widening('a'); + let x2 = widening(10); + let x3 = widening(cond ? 'a' : 10); + let y1 = nonWidening('a'); + let y2 = nonWidening(10); + let y3 = nonWidening(cond ? 'a' : 10); +} + // Repro from #10898 type FAILURE = "FAILURE"; @@ -95,10 +107,33 @@ type TestEvent = "onmouseover" | "onmouseout"; function onMouseOver(): TestEvent { return "onmouseover"; } -let x = onMouseOver(); +let x = onMouseOver(); + +// Repro from #23649 + +export function Set(...keys: K[]): Record { + const result = {} as Record + keys.forEach(key => result[key] = true) + return result +} + +export function keys(obj: Record): K[] { + return Object.keys(obj) as K[] +} + +type Obj = { code: LangCode } + +const langCodeSet = Set('fr', 'en', 'es', 'it', 'nl') +export type LangCode = keyof typeof langCodeSet +export const langCodes = keys(langCodeSet) + +const arr: Obj[] = langCodes.map(code => ({ code })) + //// [literalTypeWidening.js] +"use strict"; // Widening vs. non-widening literal types +exports.__esModule = true; function f1() { var c1 = "hello"; // Widening type "hello" var v1 = c1; // Type string @@ -153,6 +188,14 @@ function f5() { var c4 = "foo"; var v4 = c4; } +function f6(cond) { + var x1 = widening('a'); + var x2 = widening(10); + var x3 = widening(cond ? 'a' : 10); + var y1 = nonWidening('a'); + var y2 = nonWidening(10); + var y3 = nonWidening(cond ? 'a' : 10); +} var FAILURE = "FAILURE"; function doWork() { return FAILURE; @@ -172,3 +215,21 @@ if (isSuccess(result)) { } function onMouseOver() { return "onmouseover"; } var x = onMouseOver(); +// Repro from #23649 +function Set() { + var keys = []; + for (var _i = 0; _i < arguments.length; _i++) { + keys[_i] = arguments[_i]; + } + var result = {}; + keys.forEach(function (key) { return result[key] = true; }); + return result; +} +exports.Set = Set; +function keys(obj) { + return Object.keys(obj); +} +exports.keys = keys; +var langCodeSet = Set('fr', 'en', 'es', 'it', 'nl'); +exports.langCodes = keys(langCodeSet); +var arr = exports.langCodes.map(function (code) { return ({ code: code }); }); diff --git a/tests/baselines/reference/literalTypeWidening.symbols b/tests/baselines/reference/literalTypeWidening.symbols index e0da630180e..bb5a27026c2 100644 --- a/tests/baselines/reference/literalTypeWidening.symbols +++ b/tests/baselines/reference/literalTypeWidening.symbols @@ -197,89 +197,206 @@ function f5() { >c4 : Symbol(c4, Decl(literalTypeWidening.ts, 57, 9)) } +declare function widening(x: T): T; +>widening : Symbol(widening, Decl(literalTypeWidening.ts, 59, 1)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 61, 26)) +>x : Symbol(x, Decl(literalTypeWidening.ts, 61, 29)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 61, 26)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 61, 26)) + +declare function nonWidening(x: T): T; +>nonWidening : Symbol(nonWidening, Decl(literalTypeWidening.ts, 61, 38)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 62, 29)) +>x : Symbol(x, Decl(literalTypeWidening.ts, 62, 65)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 62, 29)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 62, 29)) + +function f6(cond: boolean) { +>f6 : Symbol(f6, Decl(literalTypeWidening.ts, 62, 74)) +>cond : Symbol(cond, Decl(literalTypeWidening.ts, 64, 12)) + + let x1 = widening('a'); +>x1 : Symbol(x1, Decl(literalTypeWidening.ts, 65, 7)) +>widening : Symbol(widening, Decl(literalTypeWidening.ts, 59, 1)) + + let x2 = widening(10); +>x2 : Symbol(x2, Decl(literalTypeWidening.ts, 66, 7)) +>widening : Symbol(widening, Decl(literalTypeWidening.ts, 59, 1)) + + let x3 = widening(cond ? 'a' : 10); +>x3 : Symbol(x3, Decl(literalTypeWidening.ts, 67, 7)) +>widening : Symbol(widening, Decl(literalTypeWidening.ts, 59, 1)) +>cond : Symbol(cond, Decl(literalTypeWidening.ts, 64, 12)) + + let y1 = nonWidening('a'); +>y1 : Symbol(y1, Decl(literalTypeWidening.ts, 68, 7)) +>nonWidening : Symbol(nonWidening, Decl(literalTypeWidening.ts, 61, 38)) + + let y2 = nonWidening(10); +>y2 : Symbol(y2, Decl(literalTypeWidening.ts, 69, 7)) +>nonWidening : Symbol(nonWidening, Decl(literalTypeWidening.ts, 61, 38)) + + let y3 = nonWidening(cond ? 'a' : 10); +>y3 : Symbol(y3, Decl(literalTypeWidening.ts, 70, 7)) +>nonWidening : Symbol(nonWidening, Decl(literalTypeWidening.ts, 61, 38)) +>cond : Symbol(cond, Decl(literalTypeWidening.ts, 64, 12)) +} + // Repro from #10898 type FAILURE = "FAILURE"; ->FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5)) +>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5)) const FAILURE = "FAILURE"; ->FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5)) +>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5)) type Result = T | FAILURE; ->Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 66, 12)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 66, 12)) ->FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5)) +>Result : Symbol(Result, Decl(literalTypeWidening.ts, 76, 26)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 78, 12)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 78, 12)) +>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5)) function doWork(): Result { ->doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 66, 29)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 68, 16)) ->Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 68, 16)) +>doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 78, 29)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 80, 16)) +>Result : Symbol(Result, Decl(literalTypeWidening.ts, 76, 26)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 80, 16)) return FAILURE; ->FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5)) +>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5)) } function isSuccess(result: Result): result is T { ->isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 70, 1)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19)) ->result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22)) ->Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19)) ->result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19)) +>isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 82, 1)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 84, 19)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 22)) +>Result : Symbol(Result, Decl(literalTypeWidening.ts, 76, 26)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 84, 19)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 22)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 84, 19)) return !isFailure(result); ->isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 74, 1)) ->result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22)) +>isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 86, 1)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 22)) } function isFailure(result: Result): result is FAILURE { ->isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 74, 1)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 76, 19)) ->result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22)) ->Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26)) ->T : Symbol(T, Decl(literalTypeWidening.ts, 76, 19)) ->result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22)) ->FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5)) +>isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 86, 1)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 88, 19)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 88, 22)) +>Result : Symbol(Result, Decl(literalTypeWidening.ts, 76, 26)) +>T : Symbol(T, Decl(literalTypeWidening.ts, 88, 19)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 88, 22)) +>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5)) return result === FAILURE; ->result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22)) ->FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 88, 22)) +>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5)) } function increment(x: number): number { ->increment : Symbol(increment, Decl(literalTypeWidening.ts, 78, 1)) ->x : Symbol(x, Decl(literalTypeWidening.ts, 80, 19)) +>increment : Symbol(increment, Decl(literalTypeWidening.ts, 90, 1)) +>x : Symbol(x, Decl(literalTypeWidening.ts, 92, 19)) return x + 1; ->x : Symbol(x, Decl(literalTypeWidening.ts, 80, 19)) +>x : Symbol(x, Decl(literalTypeWidening.ts, 92, 19)) } let result = doWork(); ->result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3)) ->doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 66, 29)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 96, 3)) +>doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 78, 29)) if (isSuccess(result)) { ->isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 70, 1)) ->result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3)) +>isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 82, 1)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 96, 3)) increment(result); ->increment : Symbol(increment, Decl(literalTypeWidening.ts, 78, 1)) ->result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3)) +>increment : Symbol(increment, Decl(literalTypeWidening.ts, 90, 1)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 96, 3)) } // Repro from #10898 type TestEvent = "onmouseover" | "onmouseout"; ->TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 88, 1)) +>TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 100, 1)) function onMouseOver(): TestEvent { return "onmouseover"; } ->onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 92, 46)) ->TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 88, 1)) +>onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 104, 46)) +>TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 100, 1)) let x = onMouseOver(); ->x : Symbol(x, Decl(literalTypeWidening.ts, 96, 3)) ->onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 92, 46)) +>x : Symbol(x, Decl(literalTypeWidening.ts, 108, 3)) +>onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 104, 46)) + +// Repro from #23649 + +export function Set(...keys: K[]): Record { +>Set : Symbol(Set, Decl(literalTypeWidening.ts, 108, 22)) +>K : Symbol(K, Decl(literalTypeWidening.ts, 112, 20)) +>keys : Symbol(keys, Decl(literalTypeWidening.ts, 112, 38)) +>K : Symbol(K, Decl(literalTypeWidening.ts, 112, 20)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(literalTypeWidening.ts, 112, 20)) + + const result = {} as Record +>result : Symbol(result, Decl(literalTypeWidening.ts, 113, 7)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(literalTypeWidening.ts, 112, 20)) + + keys.forEach(key => result[key] = true) +>keys.forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --)) +>keys : Symbol(keys, Decl(literalTypeWidening.ts, 112, 38)) +>forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --)) +>key : Symbol(key, Decl(literalTypeWidening.ts, 114, 15)) +>result : Symbol(result, Decl(literalTypeWidening.ts, 113, 7)) +>key : Symbol(key, Decl(literalTypeWidening.ts, 114, 15)) + + return result +>result : Symbol(result, Decl(literalTypeWidening.ts, 113, 7)) +} + +export function keys(obj: Record): K[] { +>keys : Symbol(keys, Decl(literalTypeWidening.ts, 116, 1)) +>K : Symbol(K, Decl(literalTypeWidening.ts, 118, 21)) +>V : Symbol(V, Decl(literalTypeWidening.ts, 118, 38)) +>obj : Symbol(obj, Decl(literalTypeWidening.ts, 118, 42)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(literalTypeWidening.ts, 118, 21)) +>V : Symbol(V, Decl(literalTypeWidening.ts, 118, 38)) +>K : Symbol(K, Decl(literalTypeWidening.ts, 118, 21)) + + return Object.keys(obj) as K[] +>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>keys : Symbol(ObjectConstructor.keys, Decl(lib.d.ts, --, --)) +>obj : Symbol(obj, Decl(literalTypeWidening.ts, 118, 42)) +>K : Symbol(K, Decl(literalTypeWidening.ts, 118, 21)) +} + +type Obj = { code: LangCode } +>Obj : Symbol(Obj, Decl(literalTypeWidening.ts, 120, 1)) +>code : Symbol(code, Decl(literalTypeWidening.ts, 122, 12)) +>LangCode : Symbol(LangCode, Decl(literalTypeWidening.ts, 124, 53)) + +const langCodeSet = Set('fr', 'en', 'es', 'it', 'nl') +>langCodeSet : Symbol(langCodeSet, Decl(literalTypeWidening.ts, 124, 5)) +>Set : Symbol(Set, Decl(literalTypeWidening.ts, 108, 22)) + +export type LangCode = keyof typeof langCodeSet +>LangCode : Symbol(LangCode, Decl(literalTypeWidening.ts, 124, 53)) +>langCodeSet : Symbol(langCodeSet, Decl(literalTypeWidening.ts, 124, 5)) + +export const langCodes = keys(langCodeSet) +>langCodes : Symbol(langCodes, Decl(literalTypeWidening.ts, 126, 12)) +>keys : Symbol(keys, Decl(literalTypeWidening.ts, 116, 1)) +>langCodeSet : Symbol(langCodeSet, Decl(literalTypeWidening.ts, 124, 5)) + +const arr: Obj[] = langCodes.map(code => ({ code })) +>arr : Symbol(arr, Decl(literalTypeWidening.ts, 128, 5)) +>Obj : Symbol(Obj, Decl(literalTypeWidening.ts, 120, 1)) +>langCodes.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>langCodes : Symbol(langCodes, Decl(literalTypeWidening.ts, 126, 12)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>code : Symbol(code, Decl(literalTypeWidening.ts, 128, 33)) +>code : Symbol(code, Decl(literalTypeWidening.ts, 128, 43)) diff --git a/tests/baselines/reference/literalTypeWidening.types b/tests/baselines/reference/literalTypeWidening.types index db5df6ba90c..7d41472496a 100644 --- a/tests/baselines/reference/literalTypeWidening.types +++ b/tests/baselines/reference/literalTypeWidening.types @@ -219,6 +219,67 @@ function f5() { >c4 : "foo" } +declare function widening(x: T): T; +>widening : (x: T) => T +>T : T +>x : T +>T : T +>T : T + +declare function nonWidening(x: T): T; +>nonWidening : (x: T) => T +>T : T +>x : T +>T : T +>T : T + +function f6(cond: boolean) { +>f6 : (cond: boolean) => void +>cond : boolean + + let x1 = widening('a'); +>x1 : string +>widening('a') : "a" +>widening : (x: T) => T +>'a' : "a" + + let x2 = widening(10); +>x2 : number +>widening(10) : 10 +>widening : (x: T) => T +>10 : 10 + + let x3 = widening(cond ? 'a' : 10); +>x3 : string | number +>widening(cond ? 'a' : 10) : "a" | 10 +>widening : (x: T) => T +>cond ? 'a' : 10 : "a" | 10 +>cond : boolean +>'a' : "a" +>10 : 10 + + let y1 = nonWidening('a'); +>y1 : "a" +>nonWidening('a') : "a" +>nonWidening : (x: T) => T +>'a' : "a" + + let y2 = nonWidening(10); +>y2 : 10 +>nonWidening(10) : 10 +>nonWidening : (x: T) => T +>10 : 10 + + let y3 = nonWidening(cond ? 'a' : 10); +>y3 : "a" | 10 +>nonWidening(cond ? 'a' : 10) : "a" | 10 +>nonWidening : (x: T) => T +>cond ? 'a' : 10 : "a" | 10 +>cond : boolean +>'a' : "a" +>10 : 10 +} + // Repro from #10898 type FAILURE = "FAILURE"; @@ -316,3 +377,97 @@ let x = onMouseOver(); >onMouseOver() : TestEvent >onMouseOver : () => TestEvent +// Repro from #23649 + +export function Set(...keys: K[]): Record { +>Set : (...keys: K[]) => Record +>K : K +>keys : K[] +>K : K +>Record : Record +>K : K +>true : true + + const result = {} as Record +>result : Record +>{} as Record : Record +>{} : {} +>Record : Record +>K : K +>true : true + + keys.forEach(key => result[key] = true) +>keys.forEach(key => result[key] = true) : void +>keys.forEach : (callbackfn: (value: K, index: number, array: K[]) => void, thisArg?: any) => void +>keys : K[] +>forEach : (callbackfn: (value: K, index: number, array: K[]) => void, thisArg?: any) => void +>key => result[key] = true : (key: K) => boolean +>key : K +>result[key] = true : true +>result[key] : Record[K] +>result : Record +>key : K +>true : true + + return result +>result : Record +} + +export function keys(obj: Record): K[] { +>keys : (obj: Record) => K[] +>K : K +>V : V +>obj : Record +>Record : Record +>K : K +>V : V +>K : K + + return Object.keys(obj) as K[] +>Object.keys(obj) as K[] : K[] +>Object.keys(obj) : string[] +>Object.keys : (o: {}) => string[] +>Object : ObjectConstructor +>keys : (o: {}) => string[] +>obj : Record +>K : K +} + +type Obj = { code: LangCode } +>Obj : Obj +>code : "fr" | "en" | "es" | "it" | "nl" +>LangCode : "fr" | "en" | "es" | "it" | "nl" + +const langCodeSet = Set('fr', 'en', 'es', 'it', 'nl') +>langCodeSet : Record<"fr" | "en" | "es" | "it" | "nl", true> +>Set('fr', 'en', 'es', 'it', 'nl') : Record<"fr" | "en" | "es" | "it" | "nl", true> +>Set : (...keys: K[]) => Record +>'fr' : "fr" +>'en' : "en" +>'es' : "es" +>'it' : "it" +>'nl' : "nl" + +export type LangCode = keyof typeof langCodeSet +>LangCode : "fr" | "en" | "es" | "it" | "nl" +>langCodeSet : Record<"fr" | "en" | "es" | "it" | "nl", true> + +export const langCodes = keys(langCodeSet) +>langCodes : ("fr" | "en" | "es" | "it" | "nl")[] +>keys(langCodeSet) : ("fr" | "en" | "es" | "it" | "nl")[] +>keys : (obj: Record) => K[] +>langCodeSet : Record<"fr" | "en" | "es" | "it" | "nl", true> + +const arr: Obj[] = langCodes.map(code => ({ code })) +>arr : Obj[] +>Obj : Obj +>langCodes.map(code => ({ code })) : { code: "fr" | "en" | "es" | "it" | "nl"; }[] +>langCodes.map : (callbackfn: (value: "fr" | "en" | "es" | "it" | "nl", index: number, array: ("fr" | "en" | "es" | "it" | "nl")[]) => U, thisArg?: any) => U[] +>langCodes : ("fr" | "en" | "es" | "it" | "nl")[] +>map : (callbackfn: (value: "fr" | "en" | "es" | "it" | "nl", index: number, array: ("fr" | "en" | "es" | "it" | "nl")[]) => U, thisArg?: any) => U[] +>code => ({ code }) : (code: "fr" | "en" | "es" | "it" | "nl") => { code: "fr" | "en" | "es" | "it" | "nl"; } +>code : "fr" | "en" | "es" | "it" | "nl" +>({ code }) : { code: "fr" | "en" | "es" | "it" | "nl"; } +>{ code } : { code: "fr" | "en" | "es" | "it" | "nl"; } +>code : "fr" | "en" | "es" | "it" | "nl" + From edd31a15056d85f2ee175770e00e971ac806f855 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Mon, 21 May 2018 16:57:18 -0700 Subject: [PATCH 14/21] Preserver jsx imports even when the compiler option is not set ...based on feedback from VS Code users. Fixes #23287 --- src/harness/unittests/organizeImports.ts | 20 +++++++++++++++++++ src/services/organizeImports.ts | 2 +- .../organizeImports/JsxFactoryUnusedJs.ts | 7 +++++++ .../organizeImports/JsxFactoryUnusedJsx.ts | 7 +++++++ 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/organizeImports/JsxFactoryUnusedJs.ts create mode 100644 tests/baselines/reference/organizeImports/JsxFactoryUnusedJsx.ts diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts index 94f99856777..61b4e240d9b 100644 --- a/src/harness/unittests/organizeImports.ts +++ b/src/harness/unittests/organizeImports.ts @@ -513,6 +513,26 @@ D(); import { React, Other } from "react";
; +`, + }, + reactLibFile); + + testOrganizeImports("JsxFactoryUnusedJsx", + { + path: "/test.jsx", + content: ` +import { React, Other } from "react"; +`, + }, + reactLibFile); + + // Note: Since the file extension does not end with "x", the jsx compiler option + // will not be enabled. The import should be retained regardless. + testOrganizeImports("JsxFactoryUnusedJs", + { + path: "/test.js", + content: ` +import { React, Other } from "react"; `, }, reactLibFile); diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 99bac64973f..30f7f1584a4 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -92,7 +92,7 @@ namespace ts.OrganizeImports { function removeUnusedImports(oldImports: ReadonlyArray, sourceFile: SourceFile, program: Program) { const typeChecker = program.getTypeChecker(); const jsxNamespace = typeChecker.getJsxNamespace(); - const jsxContext = sourceFile.languageVariant === LanguageVariant.JSX && program.getCompilerOptions().jsx; + const jsxContext = sourceFile.languageVariant === LanguageVariant.JSX; const usedImports: ImportDeclaration[] = []; diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUnusedJs.ts b/tests/baselines/reference/organizeImports/JsxFactoryUnusedJs.ts new file mode 100644 index 00000000000..6a97e7f660a --- /dev/null +++ b/tests/baselines/reference/organizeImports/JsxFactoryUnusedJs.ts @@ -0,0 +1,7 @@ +// ==ORIGINAL== + +import { React, Other } from "react"; + +// ==ORGANIZED== + +import { React } from "react"; diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUnusedJsx.ts b/tests/baselines/reference/organizeImports/JsxFactoryUnusedJsx.ts new file mode 100644 index 00000000000..6a97e7f660a --- /dev/null +++ b/tests/baselines/reference/organizeImports/JsxFactoryUnusedJsx.ts @@ -0,0 +1,7 @@ +// ==ORIGINAL== + +import { React, Other } from "react"; + +// ==ORGANIZED== + +import { React } from "react"; From 4b47c0cb825bcd70a65a33ed24744d67c9b06f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Tue, 22 May 2018 14:01:04 +0800 Subject: [PATCH 15/21] fix wrong formatting with multiline type literals with IntersectionType and UnionType --- src/services/formatting/smartIndenter.ts | 6 +++ ...matLiteralTypeInUnionOrIntersectionType.ts | 37 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/cases/fourslash/formatLiteralTypeInUnionOrIntersectionType.ts diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index a75781b8da0..4c93d7816e7 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -569,6 +569,12 @@ namespace ts.formatting { return childKind !== SyntaxKind.JsxClosingElement; case SyntaxKind.JsxFragment: return childKind !== SyntaxKind.JsxClosingFragment; + case SyntaxKind.IntersectionType: + case SyntaxKind.UnionType: + if (childKind === SyntaxKind.TypeLiteral) { + return false; + } + // falls through } // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; diff --git a/tests/cases/fourslash/formatLiteralTypeInUnionOrIntersectionType.ts b/tests/cases/fourslash/formatLiteralTypeInUnionOrIntersectionType.ts new file mode 100644 index 00000000000..81bba56adf2 --- /dev/null +++ b/tests/cases/fourslash/formatLiteralTypeInUnionOrIntersectionType.ts @@ -0,0 +1,37 @@ +/// + +//// type NumberAndString = { +//// a: number +//// } & { +//// b: string +//// }; +//// +//// type NumberOrString = { +//// a: number +//// } | { +//// b: string +//// }; +//// +//// type Complexed = +//// Foo & +//// Bar | +//// Baz; + + +format.document(); +verify.currentFileContentIs(`type NumberAndString = { + a: number +} & { + b: string +}; + +type NumberOrString = { + a: number +} | { + b: string +}; + +type Complexed = + Foo & + Bar | + Baz;`); From 982c8d0af94e721bef2054a3180866c168ffa23b Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 22 May 2018 07:56:29 -0700 Subject: [PATCH 16/21] Add suggestion diagnostics for unused label and unreachable code (#24261) * Add suggestion diagnostics for unused label and unreachable code * Always error on unused left hand side of comma --- src/compiler/binder.ts | 51 ++++++---- src/compiler/core.ts | 8 ++ src/compiler/diagnosticMessages.json | 6 +- src/compiler/factory.ts | 1 + src/compiler/parser.ts | 1 + src/compiler/types.ts | 1 + src/harness/fourslash.ts | 16 +++- src/services/services.ts | 1 + src/services/shims.ts | 5 +- src/services/suggestionDiagnostics.ts | 1 + .../reference/assignmentLHSIsValue.errors.txt | 5 +- ...blockScopedBindingUsedBeforeDef.errors.txt | 5 +- tests/baselines/reference/cf.errors.txt | 2 +- tests/baselines/reference/cf.js | 2 +- tests/baselines/reference/cf.symbols | 2 +- tests/baselines/reference/cf.types | 2 +- ...onentiationAssignmentLHSIsValue.errors.txt | 5 +- .../constDeclarations-scopes.errors.txt | 8 +- .../declarationEmitInvalidExport.errors.txt | 5 +- ...perCallsInNonConstructorMembers.errors.txt | 5 +- ...invalidContinueInDownlevelAsync.errors.txt | 5 +- .../invalidWhileBreakStatements.errors.txt | 8 +- .../nestedBlockScopedBindings13.errors.txt | 18 ---- .../nestedBlockScopedBindings14.errors.txt | 20 ---- .../nestedBlockScopedBindings15.errors.txt | 46 ---------- .../nestedBlockScopedBindings16.errors.txt | 50 ---------- .../nestedBlockScopedBindings5.errors.txt | 92 ------------------- .../nestedBlockScopedBindings7.errors.txt | 16 ---- .../nestedBlockScopedBindings8.errors.txt | 18 ---- ...serErrorRecovery_ModuleElement1.errors.txt | 5 +- .../parserLabeledStatement1.d.errors.txt | 5 +- .../reference/parser_breakTarget5.errors.txt | 5 +- ...ontinueNotInIterationStatement4.errors.txt | 5 +- .../parser_continueTarget5.errors.txt | 5 +- .../parser_duplicateLabel1.errors.txt | 8 +- .../parser_duplicateLabel2.errors.txt | 8 +- .../reference/recursiveLetConst.errors.txt | 5 +- .../recursiveNamedLambdaCall.errors.txt | 5 +- .../reference/reservedWords2.errors.txt | 5 +- .../reference/scanner10.1.1-8gs.errors.txt | 5 +- .../reference/setterWithReturn.errors.txt | 5 +- .../sourceMapValidationFor.errors.txt | 5 +- .../thisTypeInFunctionsNegative.errors.txt | 5 +- .../reference/throwWithoutNewLine2.errors.txt | 7 +- .../typeGuardFunctionErrors.errors.txt | 5 +- .../typeofOperatorWithAnyOtherType.errors.txt | 25 +---- .../typeofOperatorWithStringType.errors.txt | 25 +---- .../reference/undeclaredVarEmit.errors.txt | 5 +- ...lidMultipleVariableDeclarations.errors.txt | 45 --------- .../whileContinueStatements.errors.txt | 59 ------------ tests/cases/compiler/cf.ts | 3 +- tests/cases/compiler/commaOperator1.ts | 1 + .../compiler/commaOperatorLeftSideUnused.ts | 1 + tests/cases/compiler/evalAfter0.ts | 1 + .../compiler/jsFileCompilationBindErrors.ts | 2 + ...jsFileCompilationBindReachabilityErrors.ts | 5 +- .../compiler/unreachableJavascriptChecked.ts | 1 + ...poundExponentiationAssignmentLHSIsValue.ts | 1 + .../commaOperatorWithoutOperand.ts | 1 + .../cases/fourslash/codeFixUnreachableCode.ts | 17 +++- ...xUnreachableCode_noSuggestionIfDisabled.ts | 7 ++ .../codeFixUnusedIdentifier_suggestion.ts | 4 +- tests/cases/fourslash/codeFixUnusedLabel.ts | 8 +- ...deFixUnusedLabel_noSuggestionIfDisabled.ts | 7 ++ tests/cases/fourslash/fourslash.ts | 2 +- ...stionOfUnusedVariableWithExternalModule.ts | 31 ++++--- 66 files changed, 163 insertions(+), 581 deletions(-) delete mode 100644 tests/baselines/reference/nestedBlockScopedBindings13.errors.txt delete mode 100644 tests/baselines/reference/nestedBlockScopedBindings14.errors.txt delete mode 100644 tests/baselines/reference/nestedBlockScopedBindings15.errors.txt delete mode 100644 tests/baselines/reference/nestedBlockScopedBindings16.errors.txt delete mode 100644 tests/baselines/reference/nestedBlockScopedBindings5.errors.txt delete mode 100644 tests/baselines/reference/nestedBlockScopedBindings7.errors.txt delete mode 100644 tests/baselines/reference/nestedBlockScopedBindings8.errors.txt delete mode 100644 tests/baselines/reference/validMultipleVariableDeclarations.errors.txt delete mode 100644 tests/baselines/reference/whileContinueStatements.errors.txt create mode 100644 tests/cases/fourslash/codeFixUnreachableCode_noSuggestionIfDisabled.ts create mode 100644 tests/cases/fourslash/codeFixUnusedLabel_noSuggestionIfDisabled.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d95001b1041..73ef6339552 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1208,7 +1208,7 @@ namespace ts { bind(node.statement); popActiveLabel(); if (!activeLabel.referenced && !options.allowUnusedLabels) { - file.bindDiagnostics.push(createDiagnosticForNode(node.label, Diagnostics.Unused_label)); + errorOrSuggestionOnFirstToken(unusedLabelIsError(options), node, Diagnostics.Unused_label); } if (!node.statement || node.statement.kind !== SyntaxKind.DoStatement) { // do statement sets current flow inside bindDoStatement @@ -1914,6 +1914,17 @@ namespace ts { file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2)); } + function errorOrSuggestionOnFirstToken(isError: boolean, node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) { + const span = getSpanOfTokenAtPosition(file, node.pos); + const diag = createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2); + if (isError) { + file.bindDiagnostics.push(diag); + } + else { + file.bindSuggestionDiagnostics = append(file.bindSuggestionDiagnostics, { ...diag, category: DiagnosticCategory.Suggestion }); + } + } + function bind(node: Node): void { if (!node) { return; @@ -2730,26 +2741,26 @@ namespace ts { if (reportError) { currentFlow = reportedUnreachableFlow; - // unreachable code is reported if - // - user has explicitly asked about it AND - // - statement is in not ambient context (statements in ambient context is already an error - // so we should not report extras) AND - // - node is not variable statement OR - // - node is block scoped variable statement OR - // - node is not block scoped variable statement and at least one variable declaration has initializer - // Rationale: we don't want to report errors on non-initialized var's since they are hoisted - // On the other side we do want to report errors on non-initialized 'lets' because of TDZ - const reportUnreachableCode = - !options.allowUnreachableCode && - !(node.flags & NodeFlags.Ambient) && - ( - node.kind !== SyntaxKind.VariableStatement || - getCombinedNodeFlags((node).declarationList) & NodeFlags.BlockScoped || - forEach((node).declarationList.declarations, d => d.initializer) - ); + if (!options.allowUnreachableCode) { + // unreachable code is reported if + // - user has explicitly asked about it AND + // - statement is in not ambient context (statements in ambient context is already an error + // so we should not report extras) AND + // - node is not variable statement OR + // - node is block scoped variable statement OR + // - node is not block scoped variable statement and at least one variable declaration has initializer + // Rationale: we don't want to report errors on non-initialized var's since they are hoisted + // On the other side we do want to report errors on non-initialized 'lets' because of TDZ + const isError = + unreachableCodeIsError(options) && + !(node.flags & NodeFlags.Ambient) && + ( + !isVariableStatement(node) || + !!(getCombinedNodeFlags(node.declarationList) & NodeFlags.BlockScoped) || + node.declarationList.declarations.some(d => !!d.initializer) + ); - if (reportUnreachableCode) { - errorOnFirstToken(node, Diagnostics.Unreachable_code_detected); + errorOrSuggestionOnFirstToken(isError, node, Diagnostics.Unreachable_code_detected); } } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 4dd0fd0358a..7f03ba06b11 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1991,6 +1991,14 @@ namespace ts { return moduleResolution; } + export function unreachableCodeIsError(options: CompilerOptions): boolean { + return options.allowUnreachableCode === false; + } + + export function unusedLabelIsError(options: CompilerOptions): boolean { + return options.allowUnusedLabels === false; + } + export function getAreDeclarationMapsEnabled(options: CompilerOptions) { return !!(options.declaration && options.declarationMap); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 761e89ae645..59007e610b4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2238,7 +2238,8 @@ }, "Left side of comma operator is unused and has no side effects.": { "category": "Error", - "code": 2695 + "code": 2695, + "reportsUnnecessary": true }, "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?": { "category": "Error", @@ -3673,7 +3674,8 @@ }, "Unreachable code detected.": { "category": "Error", - "code": 7027 + "code": 7027, + "reportsUnnecessary": true }, "Unused label.": { "category": "Error", diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index a286c9fae35..489bc72db62 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2463,6 +2463,7 @@ namespace ts { if (node.symbolCount !== undefined) updated.symbolCount = node.symbolCount; if (node.parseDiagnostics !== undefined) updated.parseDiagnostics = node.parseDiagnostics; if (node.bindDiagnostics !== undefined) updated.bindDiagnostics = node.bindDiagnostics; + if (node.bindSuggestionDiagnostics !== undefined) updated.bindSuggestionDiagnostics = node.bindSuggestionDiagnostics; if (node.lineMap !== undefined) updated.lineMap = node.lineMap; if (node.classifiableNames !== undefined) updated.classifiableNames = node.classifiableNames; if (node.resolvedModules !== undefined) updated.resolvedModules = node.resolvedModules; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3a7adbc2609..e9c0ca66f1d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -912,6 +912,7 @@ namespace ts { sourceFile.text = sourceText; sourceFile.bindDiagnostics = []; + sourceFile.bindSuggestionDiagnostics = undefined; sourceFile.languageVersion = languageVersion; sourceFile.fileName = normalizePath(fileName); sourceFile.languageVariant = getLanguageVariant(scriptKind); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 19e526ba056..23e990d913e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2603,6 +2603,7 @@ namespace ts { // File-level diagnostics reported by the binder. /* @internal */ bindDiagnostics: Diagnostic[]; + /* @internal */ bindSuggestionDiagnostics?: Diagnostic[]; // File-level JSDoc diagnostics reported by the JSDoc parser /* @internal */ jsDocDiagnostics?: Diagnostic[]; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 47f0a91b286..46df7fc0980 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1317,8 +1317,13 @@ Actual: ${stringify(fullActual)}`); } private testDiagnostics(expected: ReadonlyArray, diagnostics: ReadonlyArray, category: string) { - assert.deepEqual(ts.realizeDiagnostics(diagnostics, ts.newLineCharacter), expected.map(e => ( - { message: e.message, category, code: e.code, ...ts.createTextSpanFromRange(e.range || this.getRanges()[0]) }))); + assert.deepEqual(ts.realizeDiagnostics(diagnostics, ts.newLineCharacter), expected.map((e): ts.RealizedDiagnostic => ({ + message: e.message, + category, + code: e.code, + ...ts.createTextSpanFromRange(e.range || this.getRanges()[0]), + reportsUnnecessary: e.reportsUnnecessary, + }))); } public verifyQuickInfoAt(markerName: string, expectedText: string, expectedDocumentation?: string) { @@ -4422,15 +4427,15 @@ namespace FourSlashInterface { this.state.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation, tags); } - public getSyntacticDiagnostics(expected: ReadonlyArray) { + public getSyntacticDiagnostics(expected: ReadonlyArray) { this.state.getSyntacticDiagnostics(expected); } - public getSemanticDiagnostics(expected: ReadonlyArray) { + public getSemanticDiagnostics(expected: ReadonlyArray) { this.state.getSemanticDiagnostics(expected); } - public getSuggestionDiagnostics(expected: ReadonlyArray) { + public getSuggestionDiagnostics(expected: ReadonlyArray) { this.state.getSuggestionDiagnostics(expected); } @@ -4837,6 +4842,7 @@ namespace FourSlashInterface { message: string; range?: FourSlash.Range; code: number; + reportsUnnecessary?: true; } export interface GetEditsForFileRenameOptions { diff --git a/src/services/services.ts b/src/services/services.ts index 3fcd4e8e151..9b8d0e04648 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -548,6 +548,7 @@ namespace ts { public syntacticDiagnostics: Diagnostic[]; public parseDiagnostics: Diagnostic[]; public bindDiagnostics: Diagnostic[]; + public bindSuggestionDiagnostics?: Diagnostic[]; public isDeclarationFile: boolean; public isDefaultLib: boolean; diff --git a/src/services/shims.ts b/src/services/shims.ts index d0735cc1717..c371533da0c 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -586,7 +586,7 @@ namespace ts { length: number; category: string; code: number; - unused?: {}; + reportsUnnecessary?: {}; } export function realizeDiagnostics(diagnostics: ReadonlyArray, newLine: string): RealizedDiagnostic[] { return diagnostics.map(d => realizeDiagnostic(d, newLine)); @@ -598,7 +598,8 @@ namespace ts { start: diagnostic.start, length: diagnostic.length, category: diagnosticCategoryName(diagnostic), - code: diagnostic.code + code: diagnostic.code, + reportsUnnecessary: diagnostic.reportsUnnecessary, }; } diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 3135fdc368b..40ed7719c9f 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -60,6 +60,7 @@ namespace ts { } } + addRange(diags, sourceFile.bindSuggestionDiagnostics); return diags.concat(checker.getSuggestionDiagnostics(sourceFile)).sort((d1, d2) => d1.start - d2.start); } diff --git a/tests/baselines/reference/assignmentLHSIsValue.errors.txt b/tests/baselines/reference/assignmentLHSIsValue.errors.txt index 01de8d33441..3064d713a12 100644 --- a/tests/baselines/reference/assignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/assignmentLHSIsValue.errors.txt @@ -13,7 +13,6 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(2 tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(30,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(31,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(32,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. -tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,3): error TS7028: Unused label. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,9): error TS1128: Declaration or statement expected. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,2): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,6): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. @@ -39,7 +38,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(6 tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(70,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. -==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (39 errors) ==== +==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (38 errors) ==== // expected error for all the LHS of assignments var value: any; @@ -105,8 +104,6 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7 // object literals { a: 0} = value; - ~ -!!! error TS7028: Unused label. ~ !!! error TS1128: Declaration or statement expected. diff --git a/tests/baselines/reference/blockScopedBindingUsedBeforeDef.errors.txt b/tests/baselines/reference/blockScopedBindingUsedBeforeDef.errors.txt index 55b5c9dab2d..3a55ebbfded 100644 --- a/tests/baselines/reference/blockScopedBindingUsedBeforeDef.errors.txt +++ b/tests/baselines/reference/blockScopedBindingUsedBeforeDef.errors.txt @@ -1,10 +1,9 @@ tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(2,12): error TS2448: Block-scoped variable 'a' used before its declaration. tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,12): error TS2448: Block-scoped variable 'a' used before its declaration. -tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,35): error TS7027: Unreachable code detected. tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Block-scoped variable 'b' used before its declaration. -==== tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts (4 errors) ==== +==== tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts (3 errors) ==== // 1: for (let {[a]: a} of [{ }]) continue; ~ @@ -14,8 +13,6 @@ tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Bloc for (let {[a]: a} = { }; false; ) continue; ~ !!! error TS2448: Block-scoped variable 'a' used before its declaration. - ~~~~~~~~ -!!! error TS7027: Unreachable code detected. // 3: let {[b]: b} = { }; diff --git a/tests/baselines/reference/cf.errors.txt b/tests/baselines/reference/cf.errors.txt index 75b285c37c6..8f5f82f8169 100644 --- a/tests/baselines/reference/cf.errors.txt +++ b/tests/baselines/reference/cf.errors.txt @@ -53,7 +53,7 @@ tests/cases/compiler/cf.ts(36,13): error TS7027: Unreachable code detected. } catch (e) { x++; - } + } finally { x+=3; } diff --git a/tests/baselines/reference/cf.js b/tests/baselines/reference/cf.js index bc7e43a371a..7e95dca1944 100644 --- a/tests/baselines/reference/cf.js +++ b/tests/baselines/reference/cf.js @@ -39,7 +39,7 @@ function f() { } catch (e) { x++; - } + } finally { x+=3; } diff --git a/tests/baselines/reference/cf.symbols b/tests/baselines/reference/cf.symbols index 9c2d73f5134..d1f1c8392d1 100644 --- a/tests/baselines/reference/cf.symbols +++ b/tests/baselines/reference/cf.symbols @@ -77,7 +77,7 @@ function f() { x++; >x : Symbol(x, Decl(cf.ts, 2, 7)) - } + } finally { x+=3; >x : Symbol(x, Decl(cf.ts, 2, 7)) diff --git a/tests/baselines/reference/cf.types b/tests/baselines/reference/cf.types index b1b5b74c2f6..ba71e388dbd 100644 --- a/tests/baselines/reference/cf.types +++ b/tests/baselines/reference/cf.types @@ -121,7 +121,7 @@ function f() { x++; >x++ : number >x : number - } + } finally { x+=3; >x+=3 : number diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt index 51b69f81620..3f806e2c1fd 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.errors.txt @@ -14,7 +14,6 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(38,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(39,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(40,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(43,3): error TS7028: Unused label. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(43,10): error TS1128: Declaration or statement expected. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(46,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(52,15): error TS1034: 'super' must be followed by an argument list or member access. @@ -40,7 +39,7 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(85,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts (40 errors) ==== +==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts (39 errors) ==== // expected error for all the LHS of compound assignments (arithmetic and addition) var value: any; @@ -116,8 +115,6 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm // object literals { a: 0 } **= value; - ~ -!!! error TS7028: Unused label. ~~~ !!! error TS1128: Declaration or statement expected. diff --git a/tests/baselines/reference/constDeclarations-scopes.errors.txt b/tests/baselines/reference/constDeclarations-scopes.errors.txt index 064ad9aaaf8..647807a6a3d 100644 --- a/tests/baselines/reference/constDeclarations-scopes.errors.txt +++ b/tests/baselines/reference/constDeclarations-scopes.errors.txt @@ -1,9 +1,7 @@ -tests/cases/compiler/constDeclarations-scopes.ts(12,5): error TS7027: Unreachable code detected. -tests/cases/compiler/constDeclarations-scopes.ts(21,1): error TS7027: Unreachable code detected. tests/cases/compiler/constDeclarations-scopes.ts(27,1): error TS2410: The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'. -==== tests/cases/compiler/constDeclarations-scopes.ts (3 errors) ==== +==== tests/cases/compiler/constDeclarations-scopes.ts (1 errors) ==== // global const c = "string"; @@ -16,8 +14,6 @@ tests/cases/compiler/constDeclarations-scopes.ts(27,1): error TS2410: The 'with' } else { const c = 0; - ~~~~~ -!!! error TS7027: Unreachable code detected. n = c; } @@ -27,8 +23,6 @@ tests/cases/compiler/constDeclarations-scopes.ts(27,1): error TS2410: The 'with' } do { - ~~ -!!! error TS7027: Unreachable code detected. const c = 0; n = c; } while (true); diff --git a/tests/baselines/reference/declarationEmitInvalidExport.errors.txt b/tests/baselines/reference/declarationEmitInvalidExport.errors.txt index 74c8fc6b0a5..45612eb4eb4 100644 --- a/tests/baselines/reference/declarationEmitInvalidExport.errors.txt +++ b/tests/baselines/reference/declarationEmitInvalidExport.errors.txt @@ -1,13 +1,10 @@ -tests/cases/compiler/declarationEmitInvalidExport.ts(2,3): error TS7027: Unreachable code detected. tests/cases/compiler/declarationEmitInvalidExport.ts(4,30): error TS4081: Exported type alias 'MyClass' has or is using private name 'myClass'. tests/cases/compiler/declarationEmitInvalidExport.ts(5,1): error TS1128: Declaration or statement expected. -==== tests/cases/compiler/declarationEmitInvalidExport.ts (3 errors) ==== +==== tests/cases/compiler/declarationEmitInvalidExport.ts (2 errors) ==== if (false) { export var myClass = 0; - ~~~~~~ -!!! error TS7027: Unreachable code detected. } export type MyClass = typeof myClass; ~~~~~~~ diff --git a/tests/baselines/reference/derivedClassSuperCallsInNonConstructorMembers.errors.txt b/tests/baselines/reference/derivedClassSuperCallsInNonConstructorMembers.errors.txt index 1e471f9970c..fbf03bd2f23 100644 --- a/tests/baselines/reference/derivedClassSuperCallsInNonConstructorMembers.errors.txt +++ b/tests/baselines/reference/derivedClassSuperCallsInNonConstructorMembers.errors.txt @@ -10,7 +10,6 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassS tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(12,13): error TS1005: ';' expected. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(13,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,5): error TS2304: Cannot find name 'set'. -tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,5): error TS7027: Unreachable code detected. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,9): error TS1005: ';' expected. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,9): error TS2304: Cannot find name 'C'. tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,11): error TS2304: Cannot find name 'v'. @@ -38,7 +37,7 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassS tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(31,1): error TS1128: Declaration or statement expected. -==== tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts (38 errors) ==== +==== tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts (37 errors) ==== // error to use super calls outside a constructor class Base { @@ -79,8 +78,6 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassS set C(v) { ~~~ !!! error TS2304: Cannot find name 'set'. - ~~~ -!!! error TS7027: Unreachable code detected. ~ !!! error TS1005: ';' expected. ~ diff --git a/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt b/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt index ffdfee20090..f22d84f3779 100644 --- a/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt +++ b/tests/baselines/reference/invalidContinueInDownlevelAsync.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/invalidContinueInDownlevelAsync.ts(3,9): error TS1107: Jump target cannot cross function boundary. -tests/cases/compiler/invalidContinueInDownlevelAsync.ts(6,9): error TS7027: Unreachable code detected. -==== tests/cases/compiler/invalidContinueInDownlevelAsync.ts (2 errors) ==== +==== tests/cases/compiler/invalidContinueInDownlevelAsync.ts (1 errors) ==== async function func() { if (true) { continue; @@ -11,7 +10,5 @@ tests/cases/compiler/invalidContinueInDownlevelAsync.ts(6,9): error TS7027: Unre } else { await 1; - ~~~~~ -!!! error TS7027: Unreachable code detected. } } \ No newline at end of file diff --git a/tests/baselines/reference/invalidWhileBreakStatements.errors.txt b/tests/baselines/reference/invalidWhileBreakStatements.errors.txt index 7d4f86b3e9d..54adc2856d7 100644 --- a/tests/baselines/reference/invalidWhileBreakStatements.errors.txt +++ b/tests/baselines/reference/invalidWhileBreakStatements.errors.txt @@ -1,14 +1,12 @@ tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(4,1): error TS1105: A 'break' statement can only be used within an enclosing iteration or switch statement. -tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(7,1): error TS7028: Unused label. tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(8,14): error TS1116: A 'break' statement can only jump to a label of an enclosing statement. -tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(11,1): error TS7027: Unreachable code detected. tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(14,9): error TS1107: Jump target cannot cross function boundary. tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(21,9): error TS1107: Jump target cannot cross function boundary. tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(27,5): error TS1116: A 'break' statement can only jump to a label of an enclosing statement. tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(37,5): error TS1116: A 'break' statement can only jump to a label of an enclosing statement. -==== tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts (8 errors) ==== +==== tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts (6 errors) ==== // All errors // naked break not allowed @@ -18,16 +16,12 @@ tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.t // non-existent label ONE: - ~~~ -!!! error TS7028: Unused label. while (true) break TWO; ~~~~~~~~~~ !!! error TS1116: A 'break' statement can only jump to a label of an enclosing statement. // break from inside function TWO: - ~~~ -!!! error TS7027: Unreachable code detected. while (true){ var x = () => { break TWO; diff --git a/tests/baselines/reference/nestedBlockScopedBindings13.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings13.errors.txt deleted file mode 100644 index 0421583cff9..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings13.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -tests/cases/compiler/nestedBlockScopedBindings13.ts(2,5): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings13.ts(7,5): error TS7027: Unreachable code detected. - - -==== tests/cases/compiler/nestedBlockScopedBindings13.ts (2 errors) ==== - for (; false;) { - let x; - ~~~ -!!! error TS7027: Unreachable code detected. - () => x; - } - - for (; false;) { - let y; - ~~~ -!!! error TS7027: Unreachable code detected. - y = 1; - } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings14.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings14.errors.txt deleted file mode 100644 index 1b5babb4c25..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings14.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/compiler/nestedBlockScopedBindings14.ts(3,5): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings14.ts(9,5): error TS7027: Unreachable code detected. - - -==== tests/cases/compiler/nestedBlockScopedBindings14.ts (2 errors) ==== - var x; - for (; false;) { - let x; - ~~~ -!!! error TS7027: Unreachable code detected. - () => x; - } - - var y; - for (; false;) { - let y; - ~~~ -!!! error TS7027: Unreachable code detected. - y = 1; - } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings15.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings15.errors.txt deleted file mode 100644 index b60a502b528..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings15.errors.txt +++ /dev/null @@ -1,46 +0,0 @@ -tests/cases/compiler/nestedBlockScopedBindings15.ts(3,9): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings15.ts(10,9): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings15.ts(16,5): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings15.ts(25,5): error TS7027: Unreachable code detected. - - -==== tests/cases/compiler/nestedBlockScopedBindings15.ts (4 errors) ==== - for (; false;) { - { - let x; - ~~~ -!!! error TS7027: Unreachable code detected. - () => x; - } - } - - for (; false;) { - { - let y; - ~~~ -!!! error TS7027: Unreachable code detected. - y = 1; - } - } - - for (; false;) { - switch (1){ - ~~~~~~ -!!! error TS7027: Unreachable code detected. - case 1: - let z0; - () => z0; - break; - } - } - - for (; false;) { - switch (1){ - ~~~~~~ -!!! error TS7027: Unreachable code detected. - case 1: - let z; - z = 1; - break; - } - } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings16.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings16.errors.txt deleted file mode 100644 index 806f58231a0..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings16.errors.txt +++ /dev/null @@ -1,50 +0,0 @@ -tests/cases/compiler/nestedBlockScopedBindings16.ts(4,9): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings16.ts(12,9): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings16.ts(19,5): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings16.ts(29,5): error TS7027: Unreachable code detected. - - -==== tests/cases/compiler/nestedBlockScopedBindings16.ts (4 errors) ==== - var x; - for (; false;) { - { - let x; - ~~~ -!!! error TS7027: Unreachable code detected. - () => x; - } - } - - var y; - for (; false;) { - { - let y; - ~~~ -!!! error TS7027: Unreachable code detected. - y = 1; - } - } - - var z0; - for (; false;) { - switch (1){ - ~~~~~~ -!!! error TS7027: Unreachable code detected. - case 1: - let z0; - () => z0; - break; - } - } - - var z; - for (; false;) { - switch (1){ - ~~~~~~ -!!! error TS7027: Unreachable code detected. - case 1: - let z; - z = 1; - break; - } - } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings5.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings5.errors.txt deleted file mode 100644 index a40f6a29aea..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings5.errors.txt +++ /dev/null @@ -1,92 +0,0 @@ -tests/cases/compiler/nestedBlockScopedBindings5.ts(37,9): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings5.ts(54,9): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings5.ts(71,9): error TS7027: Unreachable code detected. - - -==== tests/cases/compiler/nestedBlockScopedBindings5.ts (3 errors) ==== - function a0() { - for (let x in []) { - x = x + 1; - } - for (let x;;) { - x = x + 2; - } - } - - function a1() { - for (let x in []) { - x = x + 1; - () => x; - } - for (let x;;) { - x = x + 2; - } - } - - function a2() { - for (let x in []) { - x = x + 1; - } - for (let x;;) { - x = x + 2; - () => x; - } - } - - - function a3() { - for (let x in []) { - x = x + 1; - () => x; - } - for (let x;false;) { - x = x + 2; - ~ -!!! error TS7027: Unreachable code detected. - () => x; - } - switch (1) { - case 1: - let x; - () => x; - break; - } - - } - - function a4() { - for (let x in []) { - x = x + 1; - } - for (let x;false;) { - x = x + 2; - ~ -!!! error TS7027: Unreachable code detected. - } - switch (1) { - case 1: - let x; - () => x; - break; - } - - } - - function a5() { - let y; - for (let x in []) { - x = x + 1; - } - for (let x;false;) { - x = x + 2; - ~ -!!! error TS7027: Unreachable code detected. - () => x; - } - switch (1) { - case 1: - let x; - break; - } - - } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings7.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings7.errors.txt deleted file mode 100644 index 274ef8bf6c3..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings7.errors.txt +++ /dev/null @@ -1,16 +0,0 @@ -tests/cases/compiler/nestedBlockScopedBindings7.ts(2,5): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings7.ts(6,5): error TS7027: Unreachable code detected. - - -==== tests/cases/compiler/nestedBlockScopedBindings7.ts (2 errors) ==== - for (let x; false;) { - () => x; - ~ -!!! error TS7027: Unreachable code detected. - } - - for (let y; false;) { - y = 1; - ~ -!!! error TS7027: Unreachable code detected. - } \ No newline at end of file diff --git a/tests/baselines/reference/nestedBlockScopedBindings8.errors.txt b/tests/baselines/reference/nestedBlockScopedBindings8.errors.txt deleted file mode 100644 index 73f580ae3cb..00000000000 --- a/tests/baselines/reference/nestedBlockScopedBindings8.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -tests/cases/compiler/nestedBlockScopedBindings8.ts(3,5): error TS7027: Unreachable code detected. -tests/cases/compiler/nestedBlockScopedBindings8.ts(8,5): error TS7027: Unreachable code detected. - - -==== tests/cases/compiler/nestedBlockScopedBindings8.ts (2 errors) ==== - var x; - for (let x; false; ) { - () => x; - ~ -!!! error TS7027: Unreachable code detected. - } - - var y; - for (let y; false; ) { - y = 1; - ~ -!!! error TS7027: Unreachable code detected. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ModuleElement1.errors.txt b/tests/baselines/reference/parserErrorRecovery_ModuleElement1.errors.txt index 05b31b7af8e..4b8be3e17ad 100644 --- a/tests/baselines/reference/parserErrorRecovery_ModuleElement1.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ModuleElement1.errors.txt @@ -1,16 +1,13 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts(2,1): error TS1128: Declaration or statement expected. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts(3,1): error TS7027: Unreachable code detected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts(4,1): error TS1128: Declaration or statement expected. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts (2 errors) ==== return foo; } ~ !!! error TS1128: Declaration or statement expected. return bar; - ~~~~~~ -!!! error TS7027: Unreachable code detected. } ~ !!! error TS1128: Declaration or statement expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserLabeledStatement1.d.errors.txt b/tests/baselines/reference/parserLabeledStatement1.d.errors.txt index 2ce51b0bb4c..11de61548a3 100644 --- a/tests/baselines/reference/parserLabeledStatement1.d.errors.txt +++ b/tests/baselines/reference/parserLabeledStatement1.d.errors.txt @@ -1,14 +1,11 @@ tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts(1,1): error TS1036: Statements are not allowed in ambient contexts. -tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts(1,1): error TS7028: Unused label. tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts(2,3): error TS2304: Cannot find name 'bar'. -==== tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts (2 errors) ==== foo: ~~~ !!! error TS1036: Statements are not allowed in ambient contexts. - ~~~ -!!! error TS7028: Unused label. bar(); ~~~ !!! error TS2304: Cannot find name 'bar'. \ No newline at end of file diff --git a/tests/baselines/reference/parser_breakTarget5.errors.txt b/tests/baselines/reference/parser_breakTarget5.errors.txt index 5943649c97b..8221cbebb4c 100644 --- a/tests/baselines/reference/parser_breakTarget5.errors.txt +++ b/tests/baselines/reference/parser_breakTarget5.errors.txt @@ -1,11 +1,8 @@ -tests/cases/conformance/parser/ecmascript5/Statements/BreakStatements/parser_breakTarget5.ts(1,1): error TS7028: Unused label. tests/cases/conformance/parser/ecmascript5/Statements/BreakStatements/parser_breakTarget5.ts(5,7): error TS1107: Jump target cannot cross function boundary. -==== tests/cases/conformance/parser/ecmascript5/Statements/BreakStatements/parser_breakTarget5.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/BreakStatements/parser_breakTarget5.ts (1 errors) ==== target: - ~~~~~~ -!!! error TS7028: Unused label. while (true) { function f() { while (true) { diff --git a/tests/baselines/reference/parser_continueNotInIterationStatement4.errors.txt b/tests/baselines/reference/parser_continueNotInIterationStatement4.errors.txt index 94392259568..efade17a52a 100644 --- a/tests/baselines/reference/parser_continueNotInIterationStatement4.errors.txt +++ b/tests/baselines/reference/parser_continueNotInIterationStatement4.errors.txt @@ -1,11 +1,8 @@ -tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueNotInIterationStatement4.ts(1,1): error TS7028: Unused label. tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueNotInIterationStatement4.ts(4,5): error TS1107: Jump target cannot cross function boundary. -==== tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueNotInIterationStatement4.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueNotInIterationStatement4.ts (1 errors) ==== TWO: - ~~~ -!!! error TS7028: Unused label. while (true){ var x = () => { continue TWO; diff --git a/tests/baselines/reference/parser_continueTarget5.errors.txt b/tests/baselines/reference/parser_continueTarget5.errors.txt index b9b1f2edb94..ffeee7a07b3 100644 --- a/tests/baselines/reference/parser_continueTarget5.errors.txt +++ b/tests/baselines/reference/parser_continueTarget5.errors.txt @@ -1,11 +1,8 @@ -tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget5.ts(1,1): error TS7028: Unused label. tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget5.ts(5,7): error TS1107: Jump target cannot cross function boundary. -==== tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget5.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget5.ts (1 errors) ==== target: - ~~~~~~ -!!! error TS7028: Unused label. while (true) { function f() { while (true) { diff --git a/tests/baselines/reference/parser_duplicateLabel1.errors.txt b/tests/baselines/reference/parser_duplicateLabel1.errors.txt index 95c0ad9a290..dee0d5d40e6 100644 --- a/tests/baselines/reference/parser_duplicateLabel1.errors.txt +++ b/tests/baselines/reference/parser_duplicateLabel1.errors.txt @@ -1,16 +1,10 @@ -tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(1,1): error TS7028: Unused label. tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(2,1): error TS1114: Duplicate label 'target'. -tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(2,1): error TS7028: Unused label. -==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts (1 errors) ==== target: - ~~~~~~ -!!! error TS7028: Unused label. target: ~~~~~~ !!! error TS1114: Duplicate label 'target'. - ~~~~~~ -!!! error TS7028: Unused label. while (true) { } \ No newline at end of file diff --git a/tests/baselines/reference/parser_duplicateLabel2.errors.txt b/tests/baselines/reference/parser_duplicateLabel2.errors.txt index 6d42b8c34fe..60a2c2659c3 100644 --- a/tests/baselines/reference/parser_duplicateLabel2.errors.txt +++ b/tests/baselines/reference/parser_duplicateLabel2.errors.txt @@ -1,18 +1,12 @@ -tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(1,1): error TS7028: Unused label. tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(3,3): error TS1114: Duplicate label 'target'. -tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(3,3): error TS7028: Unused label. -==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts (1 errors) ==== target: - ~~~~~~ -!!! error TS7028: Unused label. while (true) { target: ~~~~~~ !!! error TS1114: Duplicate label 'target'. - ~~~~~~ -!!! error TS7028: Unused label. while (true) { } } \ No newline at end of file diff --git a/tests/baselines/reference/recursiveLetConst.errors.txt b/tests/baselines/reference/recursiveLetConst.errors.txt index 88ecb379e5e..b02d0819a3f 100644 --- a/tests/baselines/reference/recursiveLetConst.errors.txt +++ b/tests/baselines/reference/recursiveLetConst.errors.txt @@ -3,7 +3,6 @@ tests/cases/compiler/recursiveLetConst.ts(3,12): error TS2448: Block-scoped vari tests/cases/compiler/recursiveLetConst.ts(4,11): error TS2448: Block-scoped variable 'y' used before its declaration. tests/cases/compiler/recursiveLetConst.ts(5,14): error TS2448: Block-scoped variable 'y1' used before its declaration. tests/cases/compiler/recursiveLetConst.ts(6,14): error TS2448: Block-scoped variable 'v' used before its declaration. -tests/cases/compiler/recursiveLetConst.ts(7,1): error TS7027: Unreachable code detected. tests/cases/compiler/recursiveLetConst.ts(7,16): error TS2448: Block-scoped variable 'v' used before its declaration. tests/cases/compiler/recursiveLetConst.ts(8,15): error TS2448: Block-scoped variable 'v' used before its declaration. tests/cases/compiler/recursiveLetConst.ts(9,15): error TS2448: Block-scoped variable 'v' used before its declaration. @@ -11,7 +10,7 @@ tests/cases/compiler/recursiveLetConst.ts(10,17): error TS2448: Block-scoped var tests/cases/compiler/recursiveLetConst.ts(11,11): error TS2448: Block-scoped variable 'x2' used before its declaration. -==== tests/cases/compiler/recursiveLetConst.ts (11 errors) ==== +==== tests/cases/compiler/recursiveLetConst.ts (10 errors) ==== 'use strict' let x = x + 1; ~ @@ -29,8 +28,6 @@ tests/cases/compiler/recursiveLetConst.ts(11,11): error TS2448: Block-scoped var ~ !!! error TS2448: Block-scoped variable 'v' used before its declaration. for (let [v] = v; ;) { } - ~~~ -!!! error TS7027: Unreachable code detected. ~ !!! error TS2448: Block-scoped variable 'v' used before its declaration. for (let v in v) { } diff --git a/tests/baselines/reference/recursiveNamedLambdaCall.errors.txt b/tests/baselines/reference/recursiveNamedLambdaCall.errors.txt index 04ddc371ac7..7729d1e780f 100644 --- a/tests/baselines/reference/recursiveNamedLambdaCall.errors.txt +++ b/tests/baselines/reference/recursiveNamedLambdaCall.errors.txt @@ -1,12 +1,11 @@ tests/cases/compiler/recursiveNamedLambdaCall.ts(3,8): error TS2304: Cannot find name 'top'. tests/cases/compiler/recursiveNamedLambdaCall.ts(3,15): error TS2304: Cannot find name 'top'. -tests/cases/compiler/recursiveNamedLambdaCall.ts(7,6): error TS7027: Unreachable code detected. tests/cases/compiler/recursiveNamedLambdaCall.ts(8,7): error TS2304: Cannot find name 'top'. tests/cases/compiler/recursiveNamedLambdaCall.ts(10,14): error TS2304: Cannot find name 'setTimeout'. tests/cases/compiler/recursiveNamedLambdaCall.ts(14,6): error TS2304: Cannot find name 'detach'. -==== tests/cases/compiler/recursiveNamedLambdaCall.ts (6 errors) ==== +==== tests/cases/compiler/recursiveNamedLambdaCall.ts (5 errors) ==== var promise = function( obj ) { if ( top && top.doScroll ) { @@ -18,8 +17,6 @@ tests/cases/compiler/recursiveNamedLambdaCall.ts(14,6): error TS2304: Cannot fin if ( false ) { try { - ~~~ -!!! error TS7027: Unreachable code detected. top.doScroll("left"); ~~~ !!! error TS2304: Cannot find name 'top'. diff --git a/tests/baselines/reference/reservedWords2.errors.txt b/tests/baselines/reference/reservedWords2.errors.txt index f1d781ed59e..0760e1e2566 100644 --- a/tests/baselines/reference/reservedWords2.errors.txt +++ b/tests/baselines/reference/reservedWords2.errors.txt @@ -15,7 +15,6 @@ tests/cases/compiler/reservedWords2.ts(5,9): error TS2567: Enum declarations can tests/cases/compiler/reservedWords2.ts(5,10): error TS1003: Identifier expected. tests/cases/compiler/reservedWords2.ts(5,18): error TS1005: '=>' expected. tests/cases/compiler/reservedWords2.ts(6,1): error TS2304: Cannot find name 'module'. -tests/cases/compiler/reservedWords2.ts(6,1): error TS7027: Unreachable code detected. tests/cases/compiler/reservedWords2.ts(6,8): error TS1005: ';' expected. tests/cases/compiler/reservedWords2.ts(7,11): error TS2300: Duplicate identifier '(Missing)'. tests/cases/compiler/reservedWords2.ts(7,11): error TS1005: ':' expected. @@ -33,7 +32,7 @@ tests/cases/compiler/reservedWords2.ts(10,5): error TS2567: Enum declarations ca tests/cases/compiler/reservedWords2.ts(10,6): error TS1003: Identifier expected. -==== tests/cases/compiler/reservedWords2.ts (33 errors) ==== +==== tests/cases/compiler/reservedWords2.ts (32 errors) ==== import while = require("dfdf"); ~~~~~ !!! error TS1109: Expression expected. @@ -74,8 +73,6 @@ tests/cases/compiler/reservedWords2.ts(10,6): error TS1003: Identifier expected. module void {} ~~~~~~ !!! error TS2304: Cannot find name 'module'. - ~~~~~~ -!!! error TS7027: Unreachable code detected. ~~~~ !!! error TS1005: ';' expected. var {while, return} = { while: 1, return: 2 }; diff --git a/tests/baselines/reference/scanner10.1.1-8gs.errors.txt b/tests/baselines/reference/scanner10.1.1-8gs.errors.txt index 6e75f195c26..512da965486 100644 --- a/tests/baselines/reference/scanner10.1.1-8gs.errors.txt +++ b/tests/baselines/reference/scanner10.1.1-8gs.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts(16,7): error TS2304: Cannot find name 'NotEarlyError'. -tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts(17,1): error TS7027: Unreachable code detected. tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts(17,5): error TS1212: Identifier expected. 'public' is a reserved word in strict mode. -==== tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts (3 errors) ==== +==== tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts (2 errors) ==== /// Copyright (c) 2012 Ecma International. All rights reserved. /// Ecma International makes this code available under the terms and conditions set /// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the @@ -23,8 +22,6 @@ tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts(17,5): error TS ~~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'NotEarlyError'. var public = 1; - ~~~ -!!! error TS7027: Unreachable code detected. ~~~~~~ !!! error TS1212: Identifier expected. 'public' is a reserved word in strict mode. \ No newline at end of file diff --git a/tests/baselines/reference/setterWithReturn.errors.txt b/tests/baselines/reference/setterWithReturn.errors.txt index a0f04506a71..deb0fa6fc32 100644 --- a/tests/baselines/reference/setterWithReturn.errors.txt +++ b/tests/baselines/reference/setterWithReturn.errors.txt @@ -1,10 +1,9 @@ tests/cases/compiler/setterWithReturn.ts(2,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/compiler/setterWithReturn.ts(4,13): error TS2408: Setters cannot return a value. -tests/cases/compiler/setterWithReturn.ts(7,13): error TS7027: Unreachable code detected. tests/cases/compiler/setterWithReturn.ts(7,13): error TS2408: Setters cannot return a value. -==== tests/cases/compiler/setterWithReturn.ts (4 errors) ==== +==== tests/cases/compiler/setterWithReturn.ts (3 errors) ==== class C234 { public set p1(arg1) { ~~ @@ -16,8 +15,6 @@ tests/cases/compiler/setterWithReturn.ts(7,13): error TS2408: Setters cannot ret } else { return 0; - ~~~~~~ -!!! error TS7027: Unreachable code detected. ~~~~~~~~~ !!! error TS2408: Setters cannot return a value. } diff --git a/tests/baselines/reference/sourceMapValidationFor.errors.txt b/tests/baselines/reference/sourceMapValidationFor.errors.txt index ffc981648d6..75139bcb12d 100644 --- a/tests/baselines/reference/sourceMapValidationFor.errors.txt +++ b/tests/baselines/reference/sourceMapValidationFor.errors.txt @@ -1,8 +1,7 @@ -tests/cases/compiler/sourceMapValidationFor.ts(20,1): error TS7027: Unreachable code detected. tests/cases/compiler/sourceMapValidationFor.ts(32,21): error TS2695: Left side of comma operator is unused and has no side effects. -==== tests/cases/compiler/sourceMapValidationFor.ts (2 errors) ==== +==== tests/cases/compiler/sourceMapValidationFor.ts (1 errors) ==== for (var i = 0; i < 10; i++) { WScript.Echo("i: " + i); } @@ -23,8 +22,6 @@ tests/cases/compiler/sourceMapValidationFor.ts(32,21): error TS2695: Left side o for (var k = 0;; k++) { } for (k = 0;; k++) - ~~~ -!!! error TS7027: Unreachable code detected. { } for (; k < 10; k++) { diff --git a/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt b/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt index 56ac090c02c..797c6877e21 100644 --- a/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt +++ b/tests/baselines/reference/thisTypeInFunctionsNegative.errors.txt @@ -93,13 +93,12 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,39): e tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,40): error TS1128: Declaration or statement expected. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,42): error TS2693: 'number' only refers to a type, but is being used as a value here. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,49): error TS1005: ';' expected. -tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,1): error TS7027: Unreachable code detected. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,29): error TS2304: Cannot find name 'm'. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,32): error TS1005: ';' expected. tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,35): error TS2304: Cannot find name 'm'. -==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (65 errors) ==== +==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (64 errors) ==== class C { n: number; explicitThis(this: this, m: number): number { @@ -431,8 +430,6 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(175,35): e // can't name parameters 'this' in a lambda. c.explicitProperty = (this, m) => m + this.n; - ~ -!!! error TS7027: Unreachable code detected. ~ !!! error TS2304: Cannot find name 'm'. ~~ diff --git a/tests/baselines/reference/throwWithoutNewLine2.errors.txt b/tests/baselines/reference/throwWithoutNewLine2.errors.txt index 83f4e4cc246..6930d240e7b 100644 --- a/tests/baselines/reference/throwWithoutNewLine2.errors.txt +++ b/tests/baselines/reference/throwWithoutNewLine2.errors.txt @@ -1,14 +1,11 @@ tests/cases/compiler/throwWithoutNewLine2.ts(1,6): error TS1142: Line break not permitted here. tests/cases/compiler/throwWithoutNewLine2.ts(2,1): error TS2304: Cannot find name 'a'. -tests/cases/compiler/throwWithoutNewLine2.ts(2,1): error TS7027: Unreachable code detected. -==== tests/cases/compiler/throwWithoutNewLine2.ts (3 errors) ==== +==== tests/cases/compiler/throwWithoutNewLine2.ts (2 errors) ==== throw !!! error TS1142: Line break not permitted here. a; ~ -!!! error TS2304: Cannot find name 'a'. - ~ -!!! error TS7027: Unreachable code detected. \ No newline at end of file +!!! error TS2304: Cannot find name 'a'. \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt index 52e8b3bf81b..4be44cc799a 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -8,7 +8,6 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(21,33) tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(25,33): error TS1225: Cannot find parameter 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(29,10): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,5): error TS1131: Property or signature expected. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,5): error TS7027: Unreachable code detected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(31,1): error TS1128: Declaration or statement expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(33,38): error TS1225: Cannot find parameter 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(37,51): error TS2677: A type predicate's type must be assignable to its parameter's type. @@ -71,7 +70,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,45 tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54): error TS2344: Type 'number' does not satisfy the constraint 'Foo'. -==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (57 errors) ==== +==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (56 errors) ==== class A { ~ !!! error TS2300: Duplicate identifier 'A'. @@ -122,8 +121,6 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 return true; ~~~~~~ !!! error TS1131: Property or signature expected. - ~~~~~~ -!!! error TS7027: Unreachable code detected. } ~ !!! error TS1128: Declaration or statement expected. diff --git a/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt b/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt index 9357cf4e4cc..4251ce08ad9 100644 --- a/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt +++ b/tests/baselines/reference/typeofOperatorWithAnyOtherType.errors.txt @@ -2,16 +2,9 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperator tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(47,32): error TS2365: Operator '+' cannot be applied to types 'null' and 'null'. tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(48,32): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'undefined'. tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(58,1): error TS2695: Left side of comma operator is unused and has no side effects. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(68,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(69,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(70,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(71,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(72,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(73,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts(74,1): error TS7028: Unused label. -==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts (11 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithAnyOtherType.ts (4 errors) ==== // typeof operator on any type var ANY: any; @@ -88,23 +81,9 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperator var x: any[]; var r: () => any; z: typeof ANY; - ~ -!!! error TS7028: Unused label. x: typeof ANY2; - ~ -!!! error TS7028: Unused label. r: typeof foo; - ~ -!!! error TS7028: Unused label. z: typeof objA.a; - ~ -!!! error TS7028: Unused label. z: typeof A.foo; - ~ -!!! error TS7028: Unused label. z: typeof M.n; - ~ -!!! error TS7028: Unused label. - z: typeof obj1.x; - ~ -!!! error TS7028: Unused label. \ No newline at end of file + z: typeof obj1.x; \ No newline at end of file diff --git a/tests/baselines/reference/typeofOperatorWithStringType.errors.txt b/tests/baselines/reference/typeofOperatorWithStringType.errors.txt index 6d01d397ab6..1aa3905d149 100644 --- a/tests/baselines/reference/typeofOperatorWithStringType.errors.txt +++ b/tests/baselines/reference/typeofOperatorWithStringType.errors.txt @@ -1,14 +1,7 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(44,1): error TS2695: Left side of comma operator is unused and has no side effects. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(50,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(51,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(52,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(54,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(55,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(56,1): error TS7028: Unused label. -tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts(57,1): error TS7028: Unused label. -==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts (8 errors) ==== +==== tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperatorWithStringType.ts (1 errors) ==== // typeof operator on string type var STRING: string; var STRING1: string[] = ["", "abc"]; @@ -61,24 +54,10 @@ tests/cases/conformance/expressions/unaryOperators/typeofOperator/typeofOperator var x: string[]; var r: () => string; z: typeof STRING; - ~ -!!! error TS7028: Unused label. x: typeof STRING1; - ~ -!!! error TS7028: Unused label. r: typeof foo; - ~ -!!! error TS7028: Unused label. var y = { a: "", b: "" }; z: typeof y.a; - ~ -!!! error TS7028: Unused label. z: typeof objA.a; - ~ -!!! error TS7028: Unused label. z: typeof A.foo; - ~ -!!! error TS7028: Unused label. - z: typeof M.n; - ~ -!!! error TS7028: Unused label. \ No newline at end of file + z: typeof M.n; \ No newline at end of file diff --git a/tests/baselines/reference/undeclaredVarEmit.errors.txt b/tests/baselines/reference/undeclaredVarEmit.errors.txt index bbf508ab005..ff5d2ef7e9e 100644 --- a/tests/baselines/reference/undeclaredVarEmit.errors.txt +++ b/tests/baselines/reference/undeclaredVarEmit.errors.txt @@ -1,10 +1,7 @@ -tests/cases/compiler/undeclaredVarEmit.ts(1,1): error TS7028: Unused label. tests/cases/compiler/undeclaredVarEmit.ts(1,4): error TS2693: 'number' only refers to a type, but is being used as a value here. -==== tests/cases/compiler/undeclaredVarEmit.ts (2 errors) ==== +==== tests/cases/compiler/undeclaredVarEmit.ts (1 errors) ==== f: number; - ~ -!!! error TS7028: Unused label. ~~~~~~ !!! error TS2693: 'number' only refers to a type, but is being used as a value here. \ No newline at end of file diff --git a/tests/baselines/reference/validMultipleVariableDeclarations.errors.txt b/tests/baselines/reference/validMultipleVariableDeclarations.errors.txt deleted file mode 100644 index 8f751e9efee..00000000000 --- a/tests/baselines/reference/validMultipleVariableDeclarations.errors.txt +++ /dev/null @@ -1,45 +0,0 @@ -tests/cases/conformance/statements/VariableStatements/validMultipleVariableDeclarations.ts(9,1): error TS7027: Unreachable code detected. - - -==== tests/cases/conformance/statements/VariableStatements/validMultipleVariableDeclarations.ts (1 errors) ==== - // all expected to be valid - - var x: number; - var x = 2; - if (true) { - var x = 3; - for (var x = 0; ;) { } - } - var x = undefined; - ~~~ -!!! error TS7027: Unreachable code detected. - - // new declaration space, making redeclaring x as a string valid - function declSpace() { - var x = 'this is a string'; - } - - interface Point { x: number; y: number; } - - var p: Point; - var p = { x: 1, y: 2 }; - var p: Point = { x: 0, y: undefined }; - var p = { x: 1, y: undefined }; - var p: { x: number; y: number; } = { x: 1, y: 2 }; - var p = <{ x: number; y: number; }>{ x: 0, y: undefined }; - var p: typeof p; - - var fn = function (s: string) { return 42; } - var fn = (s: string) => 3; - var fn: (s: string) => number; - var fn: { (s: string): number }; - var fn = <(s: string) => number> null; - var fn: typeof fn; - - var a: string[]; - var a = ['a', 'b'] - var a = []; - var a: string[] = []; - var a = new Array(); - var a: typeof a; - \ No newline at end of file diff --git a/tests/baselines/reference/whileContinueStatements.errors.txt b/tests/baselines/reference/whileContinueStatements.errors.txt deleted file mode 100644 index c2009b02600..00000000000 --- a/tests/baselines/reference/whileContinueStatements.errors.txt +++ /dev/null @@ -1,59 +0,0 @@ -tests/cases/conformance/statements/continueStatements/whileContinueStatements.ts(5,1): error TS7027: Unreachable code detected. - - -==== tests/cases/conformance/statements/continueStatements/whileContinueStatements.ts (1 errors) ==== - while(true) { - continue; - } - - while (true) { - ~~~~~ -!!! error TS7027: Unreachable code detected. - if (true) { - continue; - } - } - - ONE: - - while (true) { - continue ONE; - } - - TWO: - THREE: - while (true) { - continue THREE; - } - - FOUR: - while (true) { - FIVE: - while (true) { - continue FOUR; - } - } - - while (true) { - SIX: - while (true) - continue SIX; - } - - SEVEN: - while (true) - while (true) - while (true) - continue SEVEN; - - EIGHT: - while (true) { - var fn = function () { } - continue EIGHT; - } - - NINE: - while (true) { - if (true) { continue NINE; } - } - \ No newline at end of file diff --git a/tests/cases/compiler/cf.ts b/tests/cases/compiler/cf.ts index a37f626cd89..4b1afcbf000 100644 --- a/tests/cases/compiler/cf.ts +++ b/tests/cases/compiler/cf.ts @@ -1,3 +1,4 @@ +// @allowUnreachableCode: false function f() { var z; var x=10; @@ -38,7 +39,7 @@ function f() { } catch (e) { x++; - } + } finally { x+=3; } diff --git a/tests/cases/compiler/commaOperator1.ts b/tests/cases/compiler/commaOperator1.ts index 0cba7f1cd53..2a51e06eadc 100644 --- a/tests/cases/compiler/commaOperator1.ts +++ b/tests/cases/compiler/commaOperator1.ts @@ -1,3 +1,4 @@ +// @allowUnreachableCode: false var v1 = ((1, 2, 3), 4, 5, (6, 7)); function f1() { var a = 1; diff --git a/tests/cases/compiler/commaOperatorLeftSideUnused.ts b/tests/cases/compiler/commaOperatorLeftSideUnused.ts index b4ac6ac1a17..e5bab897afa 100644 --- a/tests/cases/compiler/commaOperatorLeftSideUnused.ts +++ b/tests/cases/compiler/commaOperatorLeftSideUnused.ts @@ -1,3 +1,4 @@ +// @allowUnreachableCode: false var xx: any; var yy: any; diff --git a/tests/cases/compiler/evalAfter0.ts b/tests/cases/compiler/evalAfter0.ts index 2245150ce6a..8b9ac51d5d4 100644 --- a/tests/cases/compiler/evalAfter0.ts +++ b/tests/cases/compiler/evalAfter0.ts @@ -1,3 +1,4 @@ +// @allowUnreachableCode: false (0,eval)("10"); // fine: special case for eval declare var eva; diff --git a/tests/cases/compiler/jsFileCompilationBindErrors.ts b/tests/cases/compiler/jsFileCompilationBindErrors.ts index 7c43b329a47..dc34a38afff 100644 --- a/tests/cases/compiler/jsFileCompilationBindErrors.ts +++ b/tests/cases/compiler/jsFileCompilationBindErrors.ts @@ -1,6 +1,8 @@ // @allowJs: true // @checkJs: true // @noEmit: true +// @allowUnreachableCode: false + // @filename: a.js let C = "sss"; let C = 0; // Error: Cannot redeclare block-scoped variable 'C'. diff --git a/tests/cases/compiler/jsFileCompilationBindReachabilityErrors.ts b/tests/cases/compiler/jsFileCompilationBindReachabilityErrors.ts index e9273231316..29dfd68bb04 100644 --- a/tests/cases/compiler/jsFileCompilationBindReachabilityErrors.ts +++ b/tests/cases/compiler/jsFileCompilationBindReachabilityErrors.ts @@ -1,8 +1,11 @@ // @allowJs: true // @checkJs: true // @noEmit: true -// @filename: a.js // @noFallthroughCasesInSwitch: true +// @allowUnreachableCode: false +// @allowUnusedLabels: false + +// @filename: a.js function foo(a, b) { switch (a) { case 10: diff --git a/tests/cases/compiler/unreachableJavascriptChecked.ts b/tests/cases/compiler/unreachableJavascriptChecked.ts index 4db98c4c8c4..afddcba6a23 100644 --- a/tests/cases/compiler/unreachableJavascriptChecked.ts +++ b/tests/cases/compiler/unreachableJavascriptChecked.ts @@ -2,6 +2,7 @@ // @allowJs: true // @checkJs: true // @outDir: out +// @allowUnreachableCode: false function unreachable() { return 1; return 2; diff --git a/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts b/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts index 176c2043344..2964561dc63 100644 --- a/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts +++ b/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts @@ -1,3 +1,4 @@ +// @allowUnreachableCode: false // expected error for all the LHS of compound assignments (arithmetic and addition) var value: any; diff --git a/tests/cases/conformance/expressions/commaOperator/commaOperatorWithoutOperand.ts b/tests/cases/conformance/expressions/commaOperator/commaOperatorWithoutOperand.ts index e52e6e30bfa..dce2222c967 100644 --- a/tests/cases/conformance/expressions/commaOperator/commaOperatorWithoutOperand.ts +++ b/tests/cases/conformance/expressions/commaOperator/commaOperatorWithoutOperand.ts @@ -1,3 +1,4 @@ +// @allowUnreachableCode: false var ANY: any; var BOOLEAN: boolean; var NUMBER: number; diff --git a/tests/cases/fourslash/codeFixUnreachableCode.ts b/tests/cases/fourslash/codeFixUnreachableCode.ts index bbe716e792e..5f70d51c1ee 100644 --- a/tests/cases/fourslash/codeFixUnreachableCode.ts +++ b/tests/cases/fourslash/codeFixUnreachableCode.ts @@ -2,7 +2,7 @@ ////function f() { //// return f(); -//// return 1; +//// [|return|] 1; //// function f() {} //// return 2; //// type T = number; @@ -10,11 +10,18 @@ //// const enum E {} //// enum E {} //// namespace N { export type T = number; } -//// namespace N { export const x = 0; } -//// var x; -//// var y = 0; +//// namespace N { export const x: T = 0; } +//// var x: I; +//// var y: T = 0; +//// E; N; x; y; ////} +verify.getSuggestionDiagnostics([{ + message: "Unreachable code detected.", + code: 7027, + reportsUnnecessary: true, +}]); + verify.codeFix({ description: "Remove unreachable code", index: 0, @@ -26,6 +33,6 @@ verify.codeFix({ interface I {} const enum E {} namespace N { export type T = number; } - var x; + var x: I; }`, }); diff --git a/tests/cases/fourslash/codeFixUnreachableCode_noSuggestionIfDisabled.ts b/tests/cases/fourslash/codeFixUnreachableCode_noSuggestionIfDisabled.ts new file mode 100644 index 00000000000..35ad3c430a3 --- /dev/null +++ b/tests/cases/fourslash/codeFixUnreachableCode_noSuggestionIfDisabled.ts @@ -0,0 +1,7 @@ +/// + +// @allowUnreachableCode: true + +////if (false) 0; + +verify.getSuggestionDiagnostics([]); diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts index de671de1e5d..b830ccad746 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_suggestion.ts @@ -10,13 +10,13 @@ verify.getSuggestionDiagnostics([ message: "'p' is declared but its value is never read.", range: r0, code: 6133, - unused: true, + reportsUnnecessary: true, }, { message: "'x' is declared but its value is never read.", range: r1, code: 6133, - unused: true, + reportsUnnecessary: true, } ]); diff --git a/tests/cases/fourslash/codeFixUnusedLabel.ts b/tests/cases/fourslash/codeFixUnusedLabel.ts index 0feea173b0c..38265aa818e 100644 --- a/tests/cases/fourslash/codeFixUnusedLabel.ts +++ b/tests/cases/fourslash/codeFixUnusedLabel.ts @@ -1,8 +1,12 @@ /// -// @noUnusedLocals: true +/////* a */[|label|]/* b */:/* c */while (1) {} -/////* a */label/* b */:/* c */while (1) {} +verify.getSuggestionDiagnostics([{ + message: "Unused label.", + code: 7028, + reportsUnnecessary: true, +}]); verify.codeFix({ description: "Remove unused label", diff --git a/tests/cases/fourslash/codeFixUnusedLabel_noSuggestionIfDisabled.ts b/tests/cases/fourslash/codeFixUnusedLabel_noSuggestionIfDisabled.ts new file mode 100644 index 00000000000..a7e504d2f66 --- /dev/null +++ b/tests/cases/fourslash/codeFixUnusedLabel_noSuggestionIfDisabled.ts @@ -0,0 +1,7 @@ +/// + +// @allowUnusedLabels: true + +////foo: while (true) {} + +verify.getSuggestionDiagnostics([]); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b8b06edca15..57eda1e0947 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -516,7 +516,7 @@ declare namespace FourSlashInterface { /** @default `test.ranges()[0]` */ range?: Range; code: number; - unused?: true; + reportsUnnecessary?: true; } interface VerifyDocumentHighlightsOptions { filesToSearch?: ReadonlyArray; diff --git a/tests/cases/fourslash/suggestionOfUnusedVariableWithExternalModule.ts b/tests/cases/fourslash/suggestionOfUnusedVariableWithExternalModule.ts index b86f79a8e49..77d0b6157fd 100644 --- a/tests/cases/fourslash/suggestionOfUnusedVariableWithExternalModule.ts +++ b/tests/cases/fourslash/suggestionOfUnusedVariableWithExternalModule.ts @@ -3,15 +3,15 @@ //@allowJs: true // @Filename: /mymodule.js -////(function ([|root|], factory) { -//// module.exports = factory(); -////}(this, function () { -//// var [|unusedVar|] = "something"; -//// return {}; +////(function ([|root|], factory) { +//// module.exports = factory(); +////}(this, function () { +//// var [|unusedVar|] = "something"; +//// return {}; ////})); // @Filename: /app.js -//////@ts-check +//////@ts-check ////require("./mymodule"); const [range0, range1] = test.ranges(); @@ -20,12 +20,17 @@ goTo.file("/app.js"); verify.getSuggestionDiagnostics([]); goTo.file("/mymodule.js"); -verify.getSuggestionDiagnostics([{ - message: "'root' is declared but its value is never read.", - code: 6133, - range: range0 -}, { +verify.getSuggestionDiagnostics([ + { + message: "'root' is declared but its value is never read.", + code: 6133, + range: range0, + reportsUnnecessary: true, + }, + { message: "'unusedVar' is declared but its value is never read.", code: 6133, - range: range1 -}]); + range: range1, + reportsUnnecessary: true, + }, +]); From a8715d0c1021f8e5b66e9e35c5db3f12d3bcedf9 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 22 May 2018 09:52:58 -0700 Subject: [PATCH 17/21] Update user baselines (#24289) --- tests/baselines/reference/user/async.log | 168 +++++++++--------- .../reference/user/follow-redirects.log | 10 +- tests/baselines/reference/user/puppeteer.log | 2 +- tests/baselines/reference/user/uglify-js.log | 104 +++++------ 4 files changed, 142 insertions(+), 142 deletions(-) diff --git a/tests/baselines/reference/user/async.log b/tests/baselines/reference/user/async.log index c78c122343c..5c1efc71f02 100644 --- a/tests/baselines/reference/user/async.log +++ b/tests/baselines/reference/user/async.log @@ -94,101 +94,101 @@ node_modules/async/dist/async.js(298,7): error TS2454: Variable 'unmasked' is us node_modules/async/dist/async.js(480,35): error TS2538: Type 'true' cannot be used as an index type. node_modules/async/dist/async.js(480,59): error TS2538: Type 'true' cannot be used as an index type. node_modules/async/dist/async.js(622,80): error TS2339: Property 'nodeType' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(745,84): error TS2339: Property 'nodeType' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(751,49): error TS2339: Property 'process' does not exist on type 'false | Global'. +node_modules/async/dist/async.js(748,84): error TS2339: Property 'nodeType' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(754,49): error TS2339: Property 'process' does not exist on type 'false | Global'. Property 'process' does not exist on type 'false'. -node_modules/async/dist/async.js(912,32): error TS2554: Expected 2 arguments, but got 1. -node_modules/async/dist/async.js(1285,18): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1289,3): error TS2322: Type 'any[] | undefined' is not assignable to type 'any[]'. +node_modules/async/dist/async.js(923,32): error TS2554: Expected 2 arguments, but got 1. +node_modules/async/dist/async.js(1299,18): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1303,3): error TS2322: Type 'any[] | undefined' is not assignable to type 'any[]'. Type 'undefined' is not assignable to type 'any[]'. -node_modules/async/dist/async.js(1495,9): error TS2322: Type 'null' is not assignable to type 'number | undefined'. -node_modules/async/dist/async.js(1564,20): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(1566,51): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1608,17): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(1673,30): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1747,7): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1748,14): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1748,45): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1750,9): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1751,7): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1752,5): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1754,12): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1754,20): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1754,32): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1754,38): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1755,3): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1759,35): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(1937,10): error TS1003: Identifier expected. -node_modules/async/dist/async.js(1937,10): error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name. -node_modules/async/dist/async.js(1976,16): error TS2554: Expected 3 arguments, but got 1. -node_modules/async/dist/async.js(2102,20): error TS2345: Argument of type 'Function | undefined' is not assignable to parameter of type 'number | undefined'. +node_modules/async/dist/async.js(1509,9): error TS2322: Type 'null' is not assignable to type 'number | undefined'. +node_modules/async/dist/async.js(1578,20): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(1580,51): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1622,17): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(1687,30): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1761,7): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1762,14): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1762,45): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1764,9): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1765,7): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1766,5): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1768,12): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1768,20): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1768,32): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1768,38): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1769,3): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1773,35): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(1951,10): error TS1003: Identifier expected. +node_modules/async/dist/async.js(1951,10): error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name. +node_modules/async/dist/async.js(1990,16): error TS2554: Expected 3 arguments, but got 1. +node_modules/async/dist/async.js(2116,20): error TS2345: Argument of type 'Function | undefined' is not assignable to parameter of type 'number | undefined'. Type 'Function' is not assignable to type 'number | undefined'. Type 'Function' is not assignable to type 'number'. -node_modules/async/dist/async.js(2260,21): error TS2554: Expected 0 arguments, but got 2. -node_modules/async/dist/async.js(2411,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(2436,5): error TS2322: Type '{ [x: string]: any; _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturat...' is not assignable to type 'NodeModule'. +node_modules/async/dist/async.js(2274,21): error TS2554: Expected 0 arguments, but got 2. +node_modules/async/dist/async.js(2425,20): error TS1005: '}' expected. +node_modules/async/dist/async.js(2450,5): error TS2322: Type '{ [x: string]: any; _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturat...' is not assignable to type 'NodeModule'. Property 'exports' is missing in type '{ [x: string]: any; _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturat...'. -node_modules/async/dist/async.js(2507,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(2550,31): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type 'any[] | undefined'. +node_modules/async/dist/async.js(2521,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(2564,31): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type 'any[] | undefined'. Type 'IArguments' is not assignable to type 'any[]'. Property 'flatMap' is missing in type 'IArguments'. -node_modules/async/dist/async.js(2649,16): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(2668,31): error TS1005: ']' expected. -node_modules/async/dist/async.js(2693,31): error TS1005: ']' expected. -node_modules/async/dist/async.js(2710,28): error TS1003: Identifier expected. -node_modules/async/dist/async.js(2710,29): error TS1003: Identifier expected. -node_modules/async/dist/async.js(2710,30): error TS1003: Identifier expected. -node_modules/async/dist/async.js(2921,28): error TS1003: Identifier expected. -node_modules/async/dist/async.js(2921,29): error TS1003: Identifier expected. -node_modules/async/dist/async.js(2921,30): error TS1003: Identifier expected. -node_modules/async/dist/async.js(2963,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(2970,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(2971,28): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(3005,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(3008,9): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(3008,9): error TS2684: The 'this' context of type 'Function | undefined' is not assignable to method's 'this' of type 'Function'. +node_modules/async/dist/async.js(2663,16): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(2682,31): error TS1005: ']' expected. +node_modules/async/dist/async.js(2707,31): error TS1005: ']' expected. +node_modules/async/dist/async.js(2724,28): error TS1003: Identifier expected. +node_modules/async/dist/async.js(2724,29): error TS1003: Identifier expected. +node_modules/async/dist/async.js(2724,30): error TS1003: Identifier expected. +node_modules/async/dist/async.js(2935,28): error TS1003: Identifier expected. +node_modules/async/dist/async.js(2935,29): error TS1003: Identifier expected. +node_modules/async/dist/async.js(2935,30): error TS1003: Identifier expected. +node_modules/async/dist/async.js(2977,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(2984,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(2985,28): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(3019,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(3022,9): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(3022,9): error TS2684: The 'this' context of type 'Function | undefined' is not assignable to method's 'this' of type 'Function'. Type 'undefined' is not assignable to type 'Function'. -node_modules/async/dist/async.js(3081,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(3086,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(3087,28): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(3550,16): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(3626,28): error TS1003: Identifier expected. -node_modules/async/dist/async.js(3626,29): error TS1003: Identifier expected. -node_modules/async/dist/async.js(3626,30): error TS1003: Identifier expected. -node_modules/async/dist/async.js(3674,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(3813,14): error TS2339: Property 'memo' does not exist on type '(...args: any[]) => void'. -node_modules/async/dist/async.js(3814,14): error TS2339: Property 'unmemoized' does not exist on type '(...args: any[]) => void'. -node_modules/async/dist/async.js(3834,23): error TS1003: Identifier expected. -node_modules/async/dist/async.js(3834,24): error TS1003: Identifier expected. -node_modules/async/dist/async.js(3834,25): error TS1003: Identifier expected. -node_modules/async/dist/async.js(4045,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(4081,5): error TS2322: Type '{ [x: string]: any; _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturat...' is not assignable to type 'NodeModule'. -node_modules/async/dist/async.js(4103,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(4114,7): error TS2339: Property 'push' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4119,11): error TS2339: Property 'started' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4126,19): error TS2339: Property 'drain' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4131,26): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4144,19): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4146,19): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4149,26): error TS2339: Property 'process' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4153,14): error TS2339: Property 'unshift' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4367,5): error TS2322: Type 'any[] | {}' is not assignable to type 'any[]'. +node_modules/async/dist/async.js(3095,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(3100,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(3101,28): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(3564,16): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(3640,28): error TS1003: Identifier expected. +node_modules/async/dist/async.js(3640,29): error TS1003: Identifier expected. +node_modules/async/dist/async.js(3640,30): error TS1003: Identifier expected. +node_modules/async/dist/async.js(3688,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(3827,14): error TS2339: Property 'memo' does not exist on type '(...args: any[]) => void'. +node_modules/async/dist/async.js(3828,14): error TS2339: Property 'unmemoized' does not exist on type '(...args: any[]) => void'. +node_modules/async/dist/async.js(3848,23): error TS1003: Identifier expected. +node_modules/async/dist/async.js(3848,24): error TS1003: Identifier expected. +node_modules/async/dist/async.js(3848,25): error TS1003: Identifier expected. +node_modules/async/dist/async.js(4059,20): error TS1005: '}' expected. +node_modules/async/dist/async.js(4095,5): error TS2322: Type '{ [x: string]: any; _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturat...' is not assignable to type 'NodeModule'. +node_modules/async/dist/async.js(4117,20): error TS1005: '}' expected. +node_modules/async/dist/async.js(4128,7): error TS2339: Property 'push' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(4133,11): error TS2339: Property 'started' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(4140,19): error TS2339: Property 'drain' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(4145,26): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(4158,19): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(4160,19): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(4163,26): error TS2339: Property 'process' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(4167,14): error TS2339: Property 'unshift' does not exist on type 'NodeModule'. +node_modules/async/dist/async.js(4381,5): error TS2322: Type 'any[] | {}' is not assignable to type 'any[]'. Type '{}' is not assignable to type 'any[]'. Property 'flatMap' is missing in type '{}'. -node_modules/async/dist/async.js(4603,17): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(4603,17): error TS2684: The 'this' context of type 'Function | undefined' is not assignable to method's 'this' of type 'Function'. +node_modules/async/dist/async.js(4617,17): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(4617,17): error TS2684: The 'this' context of type 'Function | undefined' is not assignable to method's 'this' of type 'Function'. Type 'undefined' is not assignable to type 'Function'. -node_modules/async/dist/async.js(4917,19): error TS2339: Property 'code' does not exist on type 'Error'. -node_modules/async/dist/async.js(4919,23): error TS2339: Property 'info' does not exist on type 'Error'. -node_modules/async/dist/async.js(5090,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(5146,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(5165,20): error TS2339: Property 'unmemoized' does not exist on type 'Function'. -node_modules/async/dist/async.js(5208,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. -node_modules/async/dist/async.js(5211,9): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(5211,9): error TS2684: The 'this' context of type 'Function | undefined' is not assignable to method's 'this' of type 'Function'. +node_modules/async/dist/async.js(4931,19): error TS2339: Property 'code' does not exist on type 'Error'. +node_modules/async/dist/async.js(4933,23): error TS2339: Property 'info' does not exist on type 'Error'. +node_modules/async/dist/async.js(5104,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(5160,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(5179,20): error TS2339: Property 'unmemoized' does not exist on type 'Function'. +node_modules/async/dist/async.js(5222,25): error TS2722: Cannot invoke an object which is possibly 'undefined'. +node_modules/async/dist/async.js(5225,9): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(5225,9): error TS2684: The 'this' context of type 'Function | undefined' is not assignable to method's 'this' of type 'Function'. Type 'undefined' is not assignable to type 'Function'. -node_modules/async/dist/async.js(5315,20): error TS2532: Object is possibly 'undefined'. -node_modules/async/dist/async.js(5315,20): error TS2684: The 'this' context of type 'Function | undefined' is not assignable to method's 'this' of type 'Function'. +node_modules/async/dist/async.js(5329,20): error TS2532: Object is possibly 'undefined'. +node_modules/async/dist/async.js(5329,20): error TS2684: The 'this' context of type 'Function | undefined' is not assignable to method's 'this' of type 'Function'. Type 'undefined' is not assignable to type 'Function'. node_modules/async/doDuring.js(37,12): error TS2304: Cannot find name 'AsyncFunction'. node_modules/async/doDuring.js(39,12): error TS2304: Cannot find name 'AsyncFunction'. @@ -519,7 +519,7 @@ node_modules/async/internal/doParallelLimit.js(20,20): error TS2695: Left side o node_modules/async/internal/doParallelLimit.js(20,60): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/internal/eachOfLimit.js(32,21): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/internal/eachOfLimit.js(36,25): error TS2695: Left side of comma operator is unused and has no side effects. -node_modules/async/internal/eachOfLimit.js(64,49): error TS2695: Left side of comma operator is unused and has no side effects. +node_modules/async/internal/eachOfLimit.js(66,49): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/internal/filter.js(64,29): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/internal/filter.js(66,18): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/internal/filter.js(72,19): error TS2695: Left side of comma operator is unused and has no side effects. diff --git a/tests/baselines/reference/user/follow-redirects.log b/tests/baselines/reference/user/follow-redirects.log index d169f8a97c9..625b739fd43 100644 --- a/tests/baselines/reference/user/follow-redirects.log +++ b/tests/baselines/reference/user/follow-redirects.log @@ -1,11 +1,11 @@ Exit Code: 1 Standard output: -node_modules/follow-redirects/index.js(66,10): error TS2339: Property 'emit' does not exist on type 'RedirectableRequest'. -node_modules/follow-redirects/index.js(67,10): error TS2339: Property 'abort' does not exist on type 'RedirectableRequest'. -node_modules/follow-redirects/index.js(171,12): error TS2339: Property 'emit' does not exist on type 'RedirectableRequest'. -node_modules/follow-redirects/index.js(205,35): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. +node_modules/follow-redirects/index.js(70,10): error TS2339: Property 'emit' does not exist on type 'RedirectableRequest'. +node_modules/follow-redirects/index.js(71,10): error TS2339: Property 'abort' does not exist on type 'RedirectableRequest'. +node_modules/follow-redirects/index.js(184,12): error TS2339: Property 'emit' does not exist on type 'RedirectableRequest'. +node_modules/follow-redirects/index.js(218,35): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'. -node_modules/follow-redirects/index.js(214,10): error TS2339: Property 'emit' does not exist on type 'RedirectableRequest'. +node_modules/follow-redirects/index.js(228,10): error TS2339: Property 'emit' does not exist on type 'RedirectableRequest'. diff --git a/tests/baselines/reference/user/puppeteer.log b/tests/baselines/reference/user/puppeteer.log index 86623a0aafc..f05a564517c 100644 --- a/tests/baselines/reference/user/puppeteer.log +++ b/tests/baselines/reference/user/puppeteer.log @@ -62,7 +62,7 @@ lib/externs.d.ts(17,121): error TS2503: Cannot find namespace 'Protocol'. lib/helper.js(59,15): error TS2503: Cannot find namespace 'Protocol'. lib/helper.js(77,15): error TS2503: Cannot find namespace 'Protocol'. lib/helper.js(101,15): error TS2503: Cannot find namespace 'Protocol'. -node_modules/@types/node/index.d.ts(911,22): error TS2300: Duplicate identifier 'EventEmitter'. +node_modules/@types/node/index.d.ts(912,22): error TS2300: Duplicate identifier 'EventEmitter'. diff --git a/tests/baselines/reference/user/uglify-js.log b/tests/baselines/reference/user/uglify-js.log index 6857fedda3f..8d4125a3a47 100644 --- a/tests/baselines/reference/user/uglify-js.log +++ b/tests/baselines/reference/user/uglify-js.log @@ -14,58 +14,58 @@ node_modules/uglify-js/lib/compress.js(1195,112): error TS2532: Object is possib node_modules/uglify-js/lib/compress.js(1196,29): error TS2532: Object is possibly 'undefined'. node_modules/uglify-js/lib/compress.js(1205,87): error TS2322: Type 'false' is not assignable to type 'number'. node_modules/uglify-js/lib/compress.js(1213,29): error TS2322: Type 'false' is not assignable to type 'never'. -node_modules/uglify-js/lib/compress.js(1311,38): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1404,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1501,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1533,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1947,44): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(2139,19): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(2399,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3139,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3152,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. -node_modules/uglify-js/lib/compress.js(3289,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3299,33): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3303,32): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3309,40): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3318,41): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3335,14): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3337,40): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3345,33): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3419,63): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3608,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3625,36): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3631,38): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3635,40): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3660,22): error TS2339: Property 'each' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3665,30): error TS2339: Property 'del' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3670,30): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3681,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3683,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3695,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3697,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3803,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(3805,36): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3834,22): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3854,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. -node_modules/uglify-js/lib/compress.js(3879,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4017,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4316,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(4400,22): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4748,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4755,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ [x: string]: any; get: () => string; toString: () => string; indent: () => void; indentation: (...'. -node_modules/uglify-js/lib/compress.js(4759,36): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(4764,41): error TS2339: Property 'get' does not exist on type 'string'. -node_modules/uglify-js/lib/compress.js(5251,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. -node_modules/uglify-js/lib/compress.js(5690,25): error TS2365: Operator '==' cannot be applied to types 'boolean' and '"f"'. -node_modules/uglify-js/lib/compress.js(5717,32): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5777,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5849,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5855,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(6205,43): error TS2454: Variable 'property' is used before being assigned. -node_modules/uglify-js/lib/compress.js(6219,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6222,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. -node_modules/uglify-js/lib/compress.js(6229,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6282,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1313,38): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1406,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1503,27): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1535,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1949,44): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(2141,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(2401,27): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3141,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3154,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. +node_modules/uglify-js/lib/compress.js(3291,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3301,33): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3305,32): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3311,40): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3320,41): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3337,14): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3339,40): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3347,33): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3421,63): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3610,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3627,36): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3633,38): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3637,40): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3662,22): error TS2339: Property 'each' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3667,30): error TS2339: Property 'del' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3672,30): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3683,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3685,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3697,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3699,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3805,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(3807,36): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3836,22): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3856,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. +node_modules/uglify-js/lib/compress.js(3881,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4019,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4318,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(4402,22): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4750,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4757,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ [x: string]: any; get: () => string; toString: () => string; indent: () => void; indentation: (...'. +node_modules/uglify-js/lib/compress.js(4761,36): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(4766,41): error TS2339: Property 'get' does not exist on type 'string'. +node_modules/uglify-js/lib/compress.js(5253,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. +node_modules/uglify-js/lib/compress.js(5692,25): error TS2365: Operator '==' cannot be applied to types 'boolean' and '"f"'. +node_modules/uglify-js/lib/compress.js(5719,32): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5779,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5851,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5857,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(6207,43): error TS2454: Variable 'property' is used before being assigned. +node_modules/uglify-js/lib/compress.js(6221,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6224,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. +node_modules/uglify-js/lib/compress.js(6231,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6284,19): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/minify.js(166,75): error TS2339: Property 'compress' does not exist on type 'Compressor'. node_modules/uglify-js/lib/mozilla-ast.js(569,18): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/output.js(481,22): error TS2554: Expected 0 arguments, but got 1. From 2e0cc63067cdb72d290c0b3a8de99027d152e5d5 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 22 May 2018 10:51:19 -0700 Subject: [PATCH 18/21] Check TransformFlags.ContainsJsx, rather than LanguageVariant.JSX --- src/harness/unittests/organizeImports.ts | 38 ++++++++++++++++++- src/services/organizeImports.ts | 6 +-- .../organizeImports/JsxFactoryUnusedJs.ts | 1 - .../organizeImports/JsxFactoryUnusedJsx.ts | 1 - .../organizeImports/JsxFactoryUnusedTsx.ts | 1 - ...{JsxFactoryUsed.ts => JsxFactoryUsedJs.ts} | 0 .../organizeImports/JsxFactoryUsedJsx.ts | 11 ++++++ .../organizeImports/JsxFactoryUsedTs.ts | 10 +++++ .../organizeImports/JsxFactoryUsedTsx.ts | 11 ++++++ 9 files changed, 71 insertions(+), 8 deletions(-) rename tests/baselines/reference/organizeImports/{JsxFactoryUsed.ts => JsxFactoryUsedJs.ts} (100%) create mode 100644 tests/baselines/reference/organizeImports/JsxFactoryUsedJsx.ts create mode 100644 tests/baselines/reference/organizeImports/JsxFactoryUsedTs.ts create mode 100644 tests/baselines/reference/organizeImports/JsxFactoryUsedTsx.ts diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts index 61b4e240d9b..9dea2d0d51e 100644 --- a/src/harness/unittests/organizeImports.ts +++ b/src/harness/unittests/organizeImports.ts @@ -506,12 +506,47 @@ D(); }, libFile); - testOrganizeImports("JsxFactoryUsed", + testOrganizeImports("JsxFactoryUsedJsx", + { + path: "/test.jsx", + content: ` +import { React, Other } from "react"; + +
; +`, + }, + reactLibFile); + + testOrganizeImports("JsxFactoryUsedJs", + { + path: "/test.js", + content: ` +import { React, Other } from "react"; + +
; +`, + }, + reactLibFile); + + testOrganizeImports("JsxFactoryUsedTsx", { path: "/test.tsx", content: ` import { React, Other } from "react"; +
; +`, + }, + reactLibFile); + + // TS files are not JSX contexts, so the parser does not treat + // `
` as a JSX element. + testOrganizeImports("JsxFactoryUsedTs", + { + path: "/test.ts", + content: ` +import { React, Other } from "react"; +
; `, }, @@ -537,7 +572,6 @@ import { React, Other } from "react"; }, reactLibFile); - // This is descriptive, rather than normative testOrganizeImports("JsxFactoryUnusedTsx", { path: "/test.tsx", diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 30f7f1584a4..225e9fae57d 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -92,7 +92,7 @@ namespace ts.OrganizeImports { function removeUnusedImports(oldImports: ReadonlyArray, sourceFile: SourceFile, program: Program) { const typeChecker = program.getTypeChecker(); const jsxNamespace = typeChecker.getJsxNamespace(); - const jsxContext = sourceFile.languageVariant === LanguageVariant.JSX; + const jsxElementsPresent = !!(sourceFile.transformFlags & TransformFlags.ContainsJsx); const usedImports: ImportDeclaration[] = []; @@ -138,8 +138,8 @@ namespace ts.OrganizeImports { return usedImports; function isDeclarationUsed(identifier: Identifier) { - // The JSX factory symbol is always used. - return jsxContext && (identifier.text === jsxNamespace) || FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile); + // The JSX factory symbol is always used if JSX elements are present - even if they are not allowed. + return jsxElementsPresent && (identifier.text === jsxNamespace) || FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile); } } diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUnusedJs.ts b/tests/baselines/reference/organizeImports/JsxFactoryUnusedJs.ts index 6a97e7f660a..60afb95a192 100644 --- a/tests/baselines/reference/organizeImports/JsxFactoryUnusedJs.ts +++ b/tests/baselines/reference/organizeImports/JsxFactoryUnusedJs.ts @@ -4,4 +4,3 @@ import { React, Other } from "react"; // ==ORGANIZED== -import { React } from "react"; diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUnusedJsx.ts b/tests/baselines/reference/organizeImports/JsxFactoryUnusedJsx.ts index 6a97e7f660a..60afb95a192 100644 --- a/tests/baselines/reference/organizeImports/JsxFactoryUnusedJsx.ts +++ b/tests/baselines/reference/organizeImports/JsxFactoryUnusedJsx.ts @@ -4,4 +4,3 @@ import { React, Other } from "react"; // ==ORGANIZED== -import { React } from "react"; diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUnusedTsx.ts b/tests/baselines/reference/organizeImports/JsxFactoryUnusedTsx.ts index 6a97e7f660a..60afb95a192 100644 --- a/tests/baselines/reference/organizeImports/JsxFactoryUnusedTsx.ts +++ b/tests/baselines/reference/organizeImports/JsxFactoryUnusedTsx.ts @@ -4,4 +4,3 @@ import { React, Other } from "react"; // ==ORGANIZED== -import { React } from "react"; diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUsed.ts b/tests/baselines/reference/organizeImports/JsxFactoryUsedJs.ts similarity index 100% rename from tests/baselines/reference/organizeImports/JsxFactoryUsed.ts rename to tests/baselines/reference/organizeImports/JsxFactoryUsedJs.ts diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUsedJsx.ts b/tests/baselines/reference/organizeImports/JsxFactoryUsedJsx.ts new file mode 100644 index 00000000000..430a5b12cd4 --- /dev/null +++ b/tests/baselines/reference/organizeImports/JsxFactoryUsedJsx.ts @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +import { React, Other } from "react"; + +
; + +// ==ORGANIZED== + +import { React } from "react"; + +
; diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUsedTs.ts b/tests/baselines/reference/organizeImports/JsxFactoryUsedTs.ts new file mode 100644 index 00000000000..74da2f99139 --- /dev/null +++ b/tests/baselines/reference/organizeImports/JsxFactoryUsedTs.ts @@ -0,0 +1,10 @@ +// ==ORIGINAL== + +import { React, Other } from "react"; + +
; + +// ==ORGANIZED== + + +
; diff --git a/tests/baselines/reference/organizeImports/JsxFactoryUsedTsx.ts b/tests/baselines/reference/organizeImports/JsxFactoryUsedTsx.ts new file mode 100644 index 00000000000..430a5b12cd4 --- /dev/null +++ b/tests/baselines/reference/organizeImports/JsxFactoryUsedTsx.ts @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +import { React, Other } from "react"; + +
; + +// ==ORGANIZED== + +import { React } from "react"; + +
; From 7106a587cc206f6f7dd3c8306f3e42eee218508b Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 22 May 2018 11:01:18 -0700 Subject: [PATCH 19/21] Add type for diagnostics where location is defined (#23686) * Add type for diagnostics where location is defined * getSemanticDiagnostics may return global diagnostics * Reduce array creation --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 10 +-- src/compiler/core.ts | 8 +-- src/compiler/parser.ts | 2 +- src/compiler/program.ts | 64 +++++++++++-------- src/compiler/transformer.ts | 2 +- src/compiler/transformers/declarations.ts | 2 +- src/compiler/types.ts | 29 +++++---- src/compiler/utilities.ts | 18 +++--- src/harness/harness.ts | 2 +- src/harness/harnessLanguageService.ts | 6 +- src/harness/projectsRunner.ts | 2 +- src/server/client.ts | 10 +-- src/server/editorServices.ts | 2 +- src/services/codeFixProvider.ts | 6 +- .../addMissingInvocationForDecorator.ts | 2 +- .../codefixes/annotateWithTypeFromJSDoc.ts | 4 +- .../codefixes/disableJsDiagnostics.ts | 4 +- src/services/codefixes/fixAddMissingMember.ts | 2 +- ...sDoesntImplementInheritedAbstractMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 4 +- .../fixClassSuperMustPrecedeThisAccess.ts | 2 +- .../fixConstructorForDerivedNeedSuperCall.ts | 2 +- .../fixExtendsInterfaceBecomesImplements.ts | 2 +- .../fixForgottenThisPropertyAccess.ts | 2 +- src/services/codefixes/fixSpelling.ts | 2 +- src/services/codefixes/fixUnusedIdentifier.ts | 4 +- src/services/codefixes/useDefaultImport.ts | 4 +- src/services/formatting/formatting.ts | 2 +- src/services/services.ts | 12 ++-- src/services/shims.ts | 2 +- src/services/suggestionDiagnostics.ts | 4 +- src/services/transform.ts | 2 +- src/services/types.ts | 5 +- .../reference/api/tsserverlibrary.d.ts | 19 ++++-- tests/baselines/reference/api/typescript.d.ts | 19 ++++-- 36 files changed, 149 insertions(+), 117 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 73ef6339552..36fbbeb2ec7 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -158,7 +158,7 @@ namespace ts { * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node) * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations. */ - function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic { + function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { return createDiagnosticForNodeInSourceFile(getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 653e6088499..53d7ce23a99 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -313,11 +313,11 @@ namespace ts { getSuggestionDiagnostics: file => { return (suggestionDiagnostics.get(file.fileName) || emptyArray).concat(getUnusedDiagnostics()); - function getUnusedDiagnostics(): ReadonlyArray { + function getUnusedDiagnostics(): ReadonlyArray { if (file.isDeclarationFile) return emptyArray; checkSourceFile(file); - const diagnostics: Diagnostic[] = []; + const diagnostics: DiagnosticWithLocation[] = []; Debug.assert(!!(getNodeLinks(file).flags & NodeCheckFlags.TypeChecked)); checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (kind, diag) => { if (!unusedIsError(kind)) { @@ -481,7 +481,7 @@ namespace ts { const diagnostics = createDiagnosticCollection(); // Suggestion diagnostics must have a file. Keyed by source file name. - const suggestionDiagnostics = createMultiMap(); + const suggestionDiagnostics = createMultiMap(); const enum TypeFacts { None = 0, @@ -628,7 +628,7 @@ namespace ts { Local, Parameter, } - type AddUnusedDiagnostic = (type: UnusedKind, diagnostic: Diagnostic) => void; + type AddUnusedDiagnostic = (type: UnusedKind, diagnostic: DiagnosticWithLocation) => void; const builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); @@ -824,7 +824,7 @@ namespace ts { diagnostics.add(diagnostic); } - function addErrorOrSuggestion(isError: boolean, diagnostic: Diagnostic) { + function addErrorOrSuggestion(isError: boolean, diagnostic: DiagnosticWithLocation) { if (isError) { diagnostics.add(diagnostic); } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 7f03ba06b11..5307c1de7b4 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -14,8 +14,8 @@ namespace ts { return pathIsRelative(moduleName) || isRootedDiskPath(moduleName); } - export function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray): Diagnostic[] { - return sortAndDeduplicate(diagnostics, compareDiagnostics); + export function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray): T[] { + return sortAndDeduplicate(diagnostics, compareDiagnostics); } } @@ -1619,8 +1619,8 @@ namespace ts { return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message; } - export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic; - export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic { + export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): DiagnosticWithLocation; + export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): DiagnosticWithLocation { Debug.assertGreaterThanOrEqual(start, 0); Debug.assertGreaterThanOrEqual(length, 0); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e9c0ca66f1d..975331e7153 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -595,7 +595,7 @@ namespace ts { // tslint:enable variable-name let sourceFile: SourceFile; - let parseDiagnostics: Diagnostic[]; + let parseDiagnostics: DiagnosticWithLocation[]; let syntaxCursor: IncrementalParser.SyntaxCursor; let currentToken: SyntaxKind; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 365e948f749..c453080f3bf 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -394,8 +394,8 @@ namespace ts { return resolutions; } - interface DiagnosticCache { - perFile?: Map; + interface DiagnosticCache { + perFile?: Map; allDiagnostics?: Diagnostic[]; } @@ -454,7 +454,7 @@ namespace ts { export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): ReadonlyArray { return configFileParseResult.options.configFile ? - configFileParseResult.options.configFile.parseDiagnostics.concat(configFileParseResult.errors) : + [...configFileParseResult.options.configFile.parseDiagnostics, ...configFileParseResult.errors] : configFileParseResult.errors; } @@ -517,8 +517,8 @@ namespace ts { let classifiableNames: UnderscoreEscapedMap; let modifiedFilePaths: Path[] | undefined; - const cachedSemanticDiagnosticsForFile: DiagnosticCache = {}; - const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {}; + const cachedSemanticDiagnosticsForFile: DiagnosticCache = {}; + const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {}; let resolvedTypeReferenceDirectives = createMap(); let fileProcessingDiagnostics = createDiagnosticCollection(); @@ -1313,10 +1313,10 @@ namespace ts { return filesByName.get(path); } - function getDiagnosticsHelper( + function getDiagnosticsHelper( sourceFile: SourceFile, - getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => ReadonlyArray, - cancellationToken: CancellationToken): ReadonlyArray { + getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => ReadonlyArray, + cancellationToken: CancellationToken): ReadonlyArray { if (sourceFile) { return getDiagnostics(sourceFile, cancellationToken); } @@ -1328,7 +1328,7 @@ namespace ts { })); } - function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray { + function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray { return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken); } @@ -1336,7 +1336,7 @@ namespace ts { return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken); } - function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray { + function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray { const options = program.getCompilerOptions(); // collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit) if (!sourceFile || options.out || options.outFile) { @@ -1347,7 +1347,7 @@ namespace ts { } } - function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): ReadonlyArray { + function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): ReadonlyArray { // For JavaScript files, we report semantic errors for using TypeScript-only // constructs from within a JavaScript file as syntactic errors. if (isSourceFileJavaScript(sourceFile)) { @@ -1382,7 +1382,7 @@ namespace ts { } } - function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { + function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray { return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache); } @@ -1403,15 +1403,22 @@ namespace ts { // By default, only type-check .ts, .tsx, 'Deferred' and 'External' files (external files are added by plugins) const includeBindAndCheckDiagnostics = sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX || sourceFile.scriptKind === ScriptKind.External || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred; - const bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; + const bindDiagnostics: ReadonlyArray = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray; const checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray; const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); - let diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); - if (isCheckJs) { - diagnostics = concatenate(diagnostics, sourceFile.jsDocDiagnostics); + + let diagnostics: Diagnostic[] | undefined; + for (const diags of [bindDiagnostics, checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile, isCheckJs ? sourceFile.jsDocDiagnostics : undefined]) { + if (diags) { + for (const diag of diags) { + if (shouldReportDiagnostic(diag)) { + diagnostics = append(diagnostics, diag); + } + } + } } - return filter(diagnostics, shouldReportDiagnostic); + return diagnostics; }); } @@ -1440,9 +1447,9 @@ namespace ts { return true; } - function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] { + function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): DiagnosticWithLocation[] { return runWithCancellationToken(() => { - const diagnostics: Diagnostic[] = []; + const diagnostics: DiagnosticWithLocation[] = []; let parent: Node = sourceFile; walk(sourceFile); @@ -1610,20 +1617,20 @@ namespace ts { } } - function createDiagnosticForNodeArray(nodes: NodeArray, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic { + function createDiagnosticForNodeArray(nodes: NodeArray, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { const start = nodes.pos; return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2); } // Since these are syntactic diagnostics, parent might not have been set // this means the sourceFile cannot be infered from the node - function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic { + function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2); } }); } - function getDeclarationDiagnosticsWorker(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken): Diagnostic[] { + function getDeclarationDiagnosticsWorker(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray { return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache); } @@ -1635,15 +1642,16 @@ namespace ts { }); } - function getAndCacheDiagnostics( + function getAndCacheDiagnostics( sourceFile: SourceFile | undefined, cancellationToken: CancellationToken, - cache: DiagnosticCache, - getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[]) { + cache: DiagnosticCache, + getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => T[], + ): ReadonlyArray { const cachedResult = sourceFile ? cache.perFile && cache.perFile.get(sourceFile.path) - : cache.allDiagnostics; + : cache.allDiagnostics as T[]; if (cachedResult) { return cachedResult; @@ -1651,7 +1659,7 @@ namespace ts { const result = getDiagnostics(sourceFile, cancellationToken) || emptyArray; if (sourceFile) { if (!cache.perFile) { - cache.perFile = createMap(); + cache.perFile = createMap(); } cache.perFile.set(sourceFile.path, result); } @@ -1661,7 +1669,7 @@ namespace ts { return result; } - function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { + function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray { return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken); } diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 16a6912757f..b661120b961 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -90,7 +90,7 @@ namespace ts { let onSubstituteNode: TransformationContext["onSubstituteNode"] = (_, node) => node; let onEmitNode: TransformationContext["onEmitNode"] = (hint, node, callback) => callback(hint, node); let state = TransformationState.Uninitialized; - const diagnostics: Diagnostic[] = []; + const diagnostics: DiagnosticWithLocation[] = []; // The transformation context is provided to each transformer as part of transformer // initialization. diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 346f1343fab..953f8279def 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1,6 +1,6 @@ /*@internal*/ namespace ts { - export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): Diagnostic[] { + export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] { if (file && isSourceFileJavaScript(file)) { return []; // No declaration diagnostics for js for now } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 23e990d913e..44c5ddb5d50 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2599,17 +2599,17 @@ namespace ts { // File-level diagnostics reported by the parser (includes diagnostics about /// references // as well as code diagnostics). - /* @internal */ parseDiagnostics: Diagnostic[]; + /* @internal */ parseDiagnostics: DiagnosticWithLocation[]; // File-level diagnostics reported by the binder. - /* @internal */ bindDiagnostics: Diagnostic[]; - /* @internal */ bindSuggestionDiagnostics?: Diagnostic[]; + /* @internal */ bindDiagnostics: DiagnosticWithLocation[]; + /* @internal */ bindSuggestionDiagnostics?: DiagnosticWithLocation[]; // File-level JSDoc diagnostics reported by the JSDoc parser - /* @internal */ jsDocDiagnostics?: Diagnostic[]; + /* @internal */ jsDocDiagnostics?: DiagnosticWithLocation[]; // Stores additional file-level diagnostics reported by the program - /* @internal */ additionalSyntacticDiagnostics?: ReadonlyArray; + /* @internal */ additionalSyntacticDiagnostics?: ReadonlyArray; // Stores a line map for the file. // This field should never be used directly to obtain line map, use getLineMap function instead. @@ -2747,9 +2747,10 @@ namespace ts { getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; - getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + /** The first time this is called, it will return global diagnostics (no location). */ getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; - getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; getConfigFileParsingDiagnostics(): ReadonlyArray; /** @@ -3070,7 +3071,7 @@ namespace ts { * Does *not* get *all* suggestion diagnostics, just the ones that were convenient to report in the checker. * Others are added in computeSuggestionDiagnostics. */ - /* @internal */ getSuggestionDiagnostics(file: SourceFile): ReadonlyArray; + /* @internal */ getSuggestionDiagnostics(file: SourceFile): ReadonlyArray; /** * Depending on the operation performed, it may be appropriate to throw away the checker @@ -4228,6 +4229,11 @@ namespace ts { code: number; source?: string; } + export interface DiagnosticWithLocation extends Diagnostic { + file: SourceFile; + start: number; + length: number; + } export enum DiagnosticCategory { Warning, @@ -5084,7 +5090,7 @@ namespace ts { */ onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void; - /* @internal */ addDiagnostic(diag: Diagnostic): void; + /* @internal */ addDiagnostic(diag: DiagnosticWithLocation): void; } export interface TransformationResult { @@ -5092,7 +5098,7 @@ namespace ts { transformed: T[]; /** Gets diagnostics for the transformation. */ - diagnostics?: Diagnostic[]; + diagnostics?: DiagnosticWithLocation[]; /** * Gets a substitute for a node, if one is available; otherwise, returns the original node. @@ -5310,7 +5316,8 @@ namespace ts { // If fileName is provided, gets all the diagnostics associated with that file name. // Otherwise, returns all the diagnostics (global and file associated) in this collection. - getDiagnostics(fileName?: string): Diagnostic[]; + getDiagnostics(fileName: string): DiagnosticWithLocation[]; + getDiagnostics(): Diagnostic[]; reattachFileDiagnostics(newFile: SourceFile): void; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index df19a8948c7..64996153d23 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -603,7 +603,7 @@ namespace ts { } } - export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { const sourceFile = getSourceFileOfNode(node); return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3); } @@ -613,17 +613,17 @@ namespace ts { return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3); } - export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { const span = getErrorSpanForNode(sourceFile, node); return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3); } - export function createDiagnosticForNodeSpan(sourceFile: SourceFile, startNode: Node, endNode: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + export function createDiagnosticForNodeSpan(sourceFile: SourceFile, startNode: Node, endNode: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { const start = skipTrivia(sourceFile.text, startNode.pos); return createFileDiagnostic(sourceFile, start, endNode.end - start, message, arg0, arg1, arg2, arg3); } - export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): Diagnostic { + export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): DiagnosticWithLocation { const sourceFile = getSourceFileOfNode(node); const span = getErrorSpanForNode(sourceFile, node); return { @@ -2645,7 +2645,7 @@ namespace ts { export function createDiagnosticCollection(): DiagnosticCollection { let nonFileDiagnostics = [] as SortedArray; const filesWithDiagnostics = [] as SortedArray; - const fileDiagnostics = createMap>(); + const fileDiagnostics = createMap>(); let hasReadNonFileDiagnostics = false; return { @@ -2664,8 +2664,8 @@ namespace ts { if (diagnostic.file) { diagnostics = fileDiagnostics.get(diagnostic.file.fileName); if (!diagnostics) { - diagnostics = [] as SortedArray; - fileDiagnostics.set(diagnostic.file.fileName, diagnostics); + diagnostics = [] as SortedArray; + fileDiagnostics.set(diagnostic.file.fileName, diagnostics as SortedArray); insertSorted(filesWithDiagnostics, diagnostic.file.fileName, compareStringsCaseSensitive); } } @@ -2687,12 +2687,14 @@ namespace ts { return nonFileDiagnostics; } + function getDiagnostics(fileName: string): DiagnosticWithLocation[]; + function getDiagnostics(): Diagnostic[]; function getDiagnostics(fileName?: string): Diagnostic[] { if (fileName) { return fileDiagnostics.get(fileName) || []; } - const fileDiags = flatMap(filesWithDiagnostics, f => fileDiagnostics.get(f)); + const fileDiags: Diagnostic[] = flatMap(filesWithDiagnostics, f => fileDiagnostics.get(f)); if (!nonFileDiagnostics.length) { return fileDiags; } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 28233b797da..96d7a01eaae 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1406,7 +1406,7 @@ namespace Harness { const dupeCase = ts.createMap(); for (const inputFile of inputFiles.filter(f => f.content !== undefined)) { // Filter down to the errors in the file - const fileErrors = diagnostics.filter(e => { + const fileErrors = diagnostics.filter((e): e is ts.DiagnosticWithLocation => { const errFn = e.file; return errFn && utils.removeTestPathPrefixes(errFn.fileName) === utils.removeTestPathPrefixes(inputFile.unitName); }); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 34d6f775a74..8c30f9411e6 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -398,13 +398,13 @@ namespace Harness.LanguageService { cleanupSemanticCache(): void { this.shim.cleanupSemanticCache(); } - getSyntacticDiagnostics(fileName: string): ts.Diagnostic[] { + getSyntacticDiagnostics(fileName: string): ts.DiagnosticWithLocation[] { return unwrapJSONCallResult(this.shim.getSyntacticDiagnostics(fileName)); } - getSemanticDiagnostics(fileName: string): ts.Diagnostic[] { + getSemanticDiagnostics(fileName: string): ts.DiagnosticWithLocation[] { return unwrapJSONCallResult(this.shim.getSemanticDiagnostics(fileName)); } - getSuggestionDiagnostics(fileName: string): ts.Diagnostic[] { + getSuggestionDiagnostics(fileName: string): ts.DiagnosticWithLocation[] { return unwrapJSONCallResult(this.shim.getSuggestionDiagnostics(fileName)); } getCompilerOptionsDiagnostics(): ts.Diagnostic[] { diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 08e92a73be2..9ef536ad0c8 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -154,7 +154,7 @@ namespace project { const configParseResult = ts.parseJsonSourceFileConfigFileContent(result, configParseHost, ts.getDirectoryPath(configFileName), this.compilerOptions); inputFiles = configParseResult.fileNames; this.compilerOptions = configParseResult.options; - errors = result.parseDiagnostics.concat(configParseResult.errors); + errors = [...result.parseDiagnostics, ...configParseResult.errors]; } const compilerHost = new ProjectCompilerHost(this.sys, this.compilerOptions, this.testCaseJustName, this.testCase, moduleKind); diff --git a/src/server/client.ts b/src/server/client.ts index a07e793dcba..2a97a54a18d 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -346,21 +346,21 @@ namespace ts.server { return notImplemented(); } - getSyntacticDiagnostics(file: string): Diagnostic[] { + getSyntacticDiagnostics(file: string): DiagnosticWithLocation[] { return this.getDiagnostics(file, CommandNames.SyntacticDiagnosticsSync); } - getSemanticDiagnostics(file: string): Diagnostic[] { + getSemanticDiagnostics(file: string): DiagnosticWithLocation[] { return this.getDiagnostics(file, CommandNames.SemanticDiagnosticsSync); } - getSuggestionDiagnostics(file: string): Diagnostic[] { + getSuggestionDiagnostics(file: string): DiagnosticWithLocation[] { return this.getDiagnostics(file, CommandNames.SuggestionDiagnosticsSync); } - private getDiagnostics(file: string, command: CommandNames): Diagnostic[] { + private getDiagnostics(file: string, command: CommandNames): DiagnosticWithLocation[] { const request = this.processRequest(command, { file, includeLinePosition: true }); const response = this.processResponse(request); - return (response.body).map((entry): Diagnostic => { + return (response.body).map((entry): DiagnosticWithLocation => { const category = firstDefined(Object.keys(DiagnosticCategory), id => isString(id) && entry.category === id.toLowerCase() ? (DiagnosticCategory)[id] : undefined); return { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index aed37b19127..094e9ad1861 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1329,7 +1329,7 @@ namespace ts.server { if (!result.endOfFileToken) { result.endOfFileToken = { kind: SyntaxKind.EndOfFileToken }; } - const errors = result.parseDiagnostics; + const errors = result.parseDiagnostics as Diagnostic[]; const parsedCommandLine = parseJsonSourceFileConfigFileContent( result, cachedDirectoryStructureHost, diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index 39f760ba04c..31b766d3bf5 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -79,17 +79,17 @@ namespace ts { return { fileName, textChanges }; } - export function codeFixAll(context: CodeFixAllContext, errorCodes: number[], use: (changes: textChanges.ChangeTracker, error: Diagnostic, commands: Push) => void): CombinedCodeActions { + export function codeFixAll(context: CodeFixAllContext, errorCodes: number[], use: (changes: textChanges.ChangeTracker, error: DiagnosticWithLocation, commands: Push) => void): CombinedCodeActions { const commands: CodeActionCommand[] = []; const changes = textChanges.ChangeTracker.with(context, t => eachDiagnostic(context, errorCodes, diag => use(t, diag, commands))); return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands); } - function eachDiagnostic({ program, sourceFile }: CodeFixAllContext, errorCodes: number[], cb: (diag: Diagnostic) => void): void { + function eachDiagnostic({ program, sourceFile }: CodeFixAllContext, errorCodes: number[], cb: (diag: DiagnosticWithLocation) => void): void { for (const diag of program.getSemanticDiagnostics(sourceFile).concat(computeSuggestionDiagnostics(sourceFile, program))) { if (contains(errorCodes, diag.code)) { - cb(diag); + cb(diag as DiagnosticWithLocation); } } } diff --git a/src/services/codefixes/addMissingInvocationForDecorator.ts b/src/services/codefixes/addMissingInvocationForDecorator.ts index ead64f9a2ca..02b97eec37e 100644 --- a/src/services/codefixes/addMissingInvocationForDecorator.ts +++ b/src/services/codefixes/addMissingInvocationForDecorator.ts @@ -9,7 +9,7 @@ namespace ts.codefix { return [createCodeFixAction(fixId, changes, Diagnostics.Call_decorator_expression, fixId, Diagnostics.Add_to_all_uncalled_decorators)]; }, fixIds: [fixId], - getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file!, diag.start!)), + getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start)), }); function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) { diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index 7b664678436..b3fc09b7bc4 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -12,8 +12,8 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { - const decl = getDeclaration(diag.file!, diag.start!); - if (decl) doChange(changes, diag.file!, decl); + const decl = getDeclaration(diag.file, diag.start); + if (decl) doChange(changes, diag.file, decl); }), }); diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts index b5d3059dd42..c81446152dd 100644 --- a/src/services/codefixes/disableJsDiagnostics.ts +++ b/src/services/codefixes/disableJsDiagnostics.ts @@ -38,8 +38,8 @@ namespace ts.codefix { getAllCodeActions: context => { const seenLines = createMap(); return codeFixAll(context, errorCodes, (changes, diag) => { - if (textChanges.isValidLocationToAddComment(diag.file!, diag.start!)) { - makeChange(changes, diag.file!, diag.start!, seenLines); + if (textChanges.isValidLocationToAddComment(diag.file, diag.start)) { + makeChange(changes, diag.file, diag.start, seenLines); } }); }, diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index e53ce41ad8a..c2a8316db37 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -23,7 +23,7 @@ namespace ts.codefix { const seenNames = createMap(); return codeFixAll(context, errorCodes, (changes, diag) => { const { program, preferences } = context; - const info = getInfo(diag.file!, diag.start!, program.getTypeChecker()); + const info = getInfo(diag.file, diag.start, program.getTypeChecker()); if (!info) return; const { classDeclaration, classDeclarationSourceFile, inJs, makeStatic, token, call } = info; if (!addToSeen(seenNames, token.text)) { diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index a931f849cb2..d59df7a02b3 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -17,7 +17,7 @@ namespace ts.codefix { getAllCodeActions: context => { const seenClassDeclarations = createMap(); return codeFixAll(context, errorCodes, (changes, diag) => { - const classDeclaration = getClass(diag.file!, diag.start!); + const classDeclaration = getClass(diag.file, diag.start); if (addToSeen(seenClassDeclarations, getNodeId(classDeclaration))) { addMissingMembers(classDeclaration, context.sourceFile, context.program.getTypeChecker(), changes, context.preferences); } diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 4e0b5745149..0da45c46873 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -18,10 +18,10 @@ namespace ts.codefix { getAllCodeActions(context) { const seenClassDeclarations = createMap(); return codeFixAll(context, errorCodes, (changes, diag) => { - const classDeclaration = getClass(diag.file!, diag.start!); + const classDeclaration = getClass(diag.file, diag.start); if (addToSeen(seenClassDeclarations, getNodeId(classDeclaration))) { for (const implementedTypeNode of getClassImplementsHeritageClauseElements(classDeclaration)) { - addMissingDeclarations(context.program.getTypeChecker(), implementedTypeNode, diag.file!, classDeclaration, changes, context.preferences); + addMissingDeclarations(context.program.getTypeChecker(), implementedTypeNode, diag.file, classDeclaration, changes, context.preferences); } } }); diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts index af38b8e9025..2f7daf93dc7 100644 --- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts +++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts @@ -17,7 +17,7 @@ namespace ts.codefix { const { sourceFile } = context; const seenClasses = createMap(); // Ensure we only do this once per class. return codeFixAll(context, errorCodes, (changes, diag) => { - const nodes = getNodes(diag.file!, diag.start!); + const nodes = getNodes(diag.file, diag.start); if (!nodes) return; const { constructor, superCall } = nodes; if (addToSeen(seenClasses, getNodeId(constructor.parent))) { diff --git a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts index 2aed263ee83..605bb660f06 100644 --- a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts +++ b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts @@ -12,7 +12,7 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => - doChange(changes, context.sourceFile, getNode(diag.file, diag.start!))), + doChange(changes, context.sourceFile, getNode(diag.file, diag.start))), }); function getNode(sourceFile: SourceFile, pos: number): ConstructorDeclaration { diff --git a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts index c3f406b8475..4320513fb61 100644 --- a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts +++ b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts @@ -14,7 +14,7 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { - const nodes = getNodes(diag.file, diag.start!); + const nodes = getNodes(diag.file, diag.start); if (nodes) doChanges(changes, diag.file, nodes.extendsToken, nodes.heritageClauses); }), }); diff --git a/src/services/codefixes/fixForgottenThisPropertyAccess.ts b/src/services/codefixes/fixForgottenThisPropertyAccess.ts index 31c6128d003..ce066277a27 100644 --- a/src/services/codefixes/fixForgottenThisPropertyAccess.ts +++ b/src/services/codefixes/fixForgottenThisPropertyAccess.ts @@ -19,7 +19,7 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { - doChange(changes, context.sourceFile, getInfo(diag.file, diag.start!, diag.code)); + doChange(changes, context.sourceFile, getInfo(diag.file, diag.start, diag.code)); }), }); diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index 252b08b356a..dbb23c3ac09 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -19,7 +19,7 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { - const info = getInfo(diag.file!, diag.start!, context); + const info = getInfo(diag.file, diag.start, context); const { target } = context.host.getCompilationSettings(); if (info) doChange(changes, context.sourceFile, info.node, info.suggestion, target); }), diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index 148b42b1c7e..6ba592ca2b8 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -53,7 +53,7 @@ namespace ts.codefix { return codeFixAll(context, errorCodes, (changes, diag) => { const { sourceFile } = context; const startToken = getTokenAtPosition(sourceFile, diag.start, /*includeJsDocComment*/ false); - const token = findPrecedingToken(textSpanEnd(diag), diag.file!); + const token = findPrecedingToken(textSpanEnd(diag), diag.file); switch (context.fixId) { case fixIdPrefix: if (isIdentifier(token) && canPrefix(token)) { @@ -62,7 +62,7 @@ namespace ts.codefix { break; case fixIdDelete: // Ignore if this range was already deleted. - if (deleted.some(d => rangeContainsPosition(d, diag.start!))) break; + if (deleted.some(d => rangeContainsPosition(d, diag.start))) break; const importDecl = tryGetFullImport(startToken); if (importDecl) { diff --git a/src/services/codefixes/useDefaultImport.ts b/src/services/codefixes/useDefaultImport.ts index 99fc145b563..3fe451c41fb 100644 --- a/src/services/codefixes/useDefaultImport.ts +++ b/src/services/codefixes/useDefaultImport.ts @@ -13,8 +13,8 @@ namespace ts.codefix { }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { - const info = getInfo(diag.file!, diag.start!); - if (info) doChange(changes, diag.file!, info); + const info = getInfo(diag.file, diag.start); + if (info) doChange(changes, diag.file, info); }), }); diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 494a811c238..b0273cc18e7 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -228,7 +228,7 @@ namespace ts.formatting { * This function will return a predicate that for a given text range will tell * if there are any parse errors that overlap with the range. */ - function prepareRangeContainsErrorFunction(errors: Diagnostic[], originalRange: TextRange): (r: TextRange) => boolean { + function prepareRangeContainsErrorFunction(errors: ReadonlyArray, originalRange: TextRange): (r: TextRange) => boolean { if (!errors.length) { return rangeHasNoErrors; } diff --git a/src/services/services.ts b/src/services/services.ts index 9b8d0e04648..0375f6fcf38 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -545,10 +545,10 @@ namespace ts { public referencedFiles: FileReference[]; public typeReferenceDirectives: FileReference[]; - public syntacticDiagnostics: Diagnostic[]; - public parseDiagnostics: Diagnostic[]; - public bindDiagnostics: Diagnostic[]; - public bindSuggestionDiagnostics?: Diagnostic[]; + public syntacticDiagnostics: DiagnosticWithLocation[]; + public parseDiagnostics: DiagnosticWithLocation[]; + public bindDiagnostics: DiagnosticWithLocation[]; + public bindSuggestionDiagnostics?: DiagnosticWithLocation[]; public isDeclarationFile: boolean; public isDefaultLib: boolean; @@ -1377,7 +1377,7 @@ namespace ts { } /// Diagnostics - function getSyntacticDiagnostics(fileName: string): Diagnostic[] { + function getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[] { synchronizeHostData(); return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice(); @@ -1405,7 +1405,7 @@ namespace ts { return [...semanticDiagnostics, ...declarationDiagnostics]; } - function getSuggestionDiagnostics(fileName: string): Diagnostic[] { + function getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[] { synchronizeHostData(); return computeSuggestionDiagnostics(getValidSourceFile(fileName), program); } diff --git a/src/services/shims.ts b/src/services/shims.ts index c371533da0c..808da2eb1ec 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -1147,7 +1147,7 @@ namespace ts { typeAcquisition: configFile.typeAcquisition, files: configFile.fileNames, raw: configFile.raw, - errors: realizeDiagnostics(result.parseDiagnostics.concat(configFile.errors), "\r\n") + errors: realizeDiagnostics([...result.parseDiagnostics, ...configFile.errors], "\r\n") }; }); } diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 40ed7719c9f..c59c267d164 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -1,9 +1,9 @@ /* @internal */ namespace ts { - export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program): Diagnostic[] { + export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program): DiagnosticWithLocation[] { program.getSemanticDiagnostics(sourceFile); const checker = program.getDiagnosticsProducingTypeChecker(); - const diags: Diagnostic[] = []; + const diags: DiagnosticWithLocation[] = []; if (sourceFile.commonJsModuleIndicator && (programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) && diff --git a/src/services/transform.ts b/src/services/transform.ts index 200fb9aacb2..b6b2a357081 100644 --- a/src/services/transform.ts +++ b/src/services/transform.ts @@ -6,7 +6,7 @@ namespace ts { * @param compilerOptions Optional compiler options. */ export function transform(source: T | T[], transformers: TransformerFactory[], compilerOptions?: CompilerOptions) { - const diagnostics: Diagnostic[] = []; + const diagnostics: DiagnosticWithLocation[] = []; compilerOptions = fixupCompilerOptions(compilerOptions, diagnostics); const nodes = isArray(source) ? source : [source]; const result = transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true); diff --git a/src/services/types.ts b/src/services/types.ts index b8e2c488b17..b1b0ccd6de8 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -249,9 +249,10 @@ namespace ts { export interface LanguageService { cleanupSemanticCache(): void; - getSyntacticDiagnostics(fileName: string): Diagnostic[]; + getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[]; + /** The first time this is called, it will return global diagnostics (no location). */ getSemanticDiagnostics(fileName: string): Diagnostic[]; - getSuggestionDiagnostics(fileName: string): Diagnostic[]; + getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[]; // TODO: Rename this to getProgramDiagnostics to better indicate that these are any // diagnostics present for the program level, and not just 'options' diagnostics. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e43a1e69e7b..8516bd7c312 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1734,9 +1734,10 @@ declare namespace ts { emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult; getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; - getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + /** The first time this is called, it will return global diagnostics (no location). */ getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; - getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; getConfigFileParsingDiagnostics(): ReadonlyArray; /** * Gets a type checker that can be used to semantically analyze source files in the program. @@ -2359,6 +2360,11 @@ declare namespace ts { code: number; source?: string; } + interface DiagnosticWithLocation extends Diagnostic { + file: SourceFile; + start: number; + length: number; + } enum DiagnosticCategory { Warning = 0, Error = 1, @@ -2754,7 +2760,7 @@ declare namespace ts { /** Gets the transformed source files. */ transformed: T[]; /** Gets diagnostics for the transformation. */ - diagnostics?: Diagnostic[]; + diagnostics?: DiagnosticWithLocation[]; /** * Gets a substitute for a node, if one is available; otherwise, returns the original node. * @@ -2960,7 +2966,7 @@ declare namespace ts { } declare namespace ts { function isExternalModuleNameRelative(moduleName: string): boolean; - function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray): Diagnostic[]; + function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray): T[]; } declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any; declare function clearTimeout(handle: any): void; @@ -4497,9 +4503,10 @@ declare namespace ts { } interface LanguageService { cleanupSemanticCache(): void; - getSyntacticDiagnostics(fileName: string): Diagnostic[]; + getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[]; + /** The first time this is called, it will return global diagnostics (no location). */ getSemanticDiagnostics(fileName: string): Diagnostic[]; - getSuggestionDiagnostics(fileName: string): Diagnostic[]; + getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[]; getCompilerOptionsDiagnostics(): Diagnostic[]; /** * @deprecated Use getEncodedSyntacticClassifications instead. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2324d24908b..71d598ca102 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1734,9 +1734,10 @@ declare namespace ts { emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult; getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; - getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + /** The first time this is called, it will return global diagnostics (no location). */ getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; - getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; getConfigFileParsingDiagnostics(): ReadonlyArray; /** * Gets a type checker that can be used to semantically analyze source files in the program. @@ -2359,6 +2360,11 @@ declare namespace ts { code: number; source?: string; } + interface DiagnosticWithLocation extends Diagnostic { + file: SourceFile; + start: number; + length: number; + } enum DiagnosticCategory { Warning = 0, Error = 1, @@ -2754,7 +2760,7 @@ declare namespace ts { /** Gets the transformed source files. */ transformed: T[]; /** Gets diagnostics for the transformation. */ - diagnostics?: Diagnostic[]; + diagnostics?: DiagnosticWithLocation[]; /** * Gets a substitute for a node, if one is available; otherwise, returns the original node. * @@ -2960,7 +2966,7 @@ declare namespace ts { } declare namespace ts { function isExternalModuleNameRelative(moduleName: string): boolean; - function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray): Diagnostic[]; + function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray): T[]; } declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any; declare function clearTimeout(handle: any): void; @@ -4497,9 +4503,10 @@ declare namespace ts { } interface LanguageService { cleanupSemanticCache(): void; - getSyntacticDiagnostics(fileName: string): Diagnostic[]; + getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[]; + /** The first time this is called, it will return global diagnostics (no location). */ getSemanticDiagnostics(fileName: string): Diagnostic[]; - getSuggestionDiagnostics(fileName: string): Diagnostic[]; + getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[]; getCompilerOptionsDiagnostics(): Diagnostic[]; /** * @deprecated Use getEncodedSyntacticClassifications instead. From 66590a9391ee6b572648f00629990adb674abe35 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 22 May 2018 11:18:40 -0700 Subject: [PATCH 20/21] Verify ref counts are set correctly when reusing the source file from script info cache --- src/harness/unittests/tsserverProjectSystem.ts | 3 ++- src/services/documentRegistry.ts | 15 ++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 0c73ed15639..561375e30df 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -8459,7 +8459,8 @@ new C();` const moduleInfo = service.getScriptInfo(moduleFile.path); assert.isDefined(moduleInfo); assert.equal(moduleInfo.isOrphan(), moduleIsOrphan); - assert.equal(service.documentRegistry.hasDocument(moduleInfo.path), !moduleIsOrphan); + const key = service.documentRegistry.getKeyForCompilationSettings(project.getCompilationSettings()); + assert.deepEqual(service.documentRegistry.getLanguageServiceRefCounts(moduleInfo.path), [[key, moduleIsOrphan ? undefined : 1]]); } }); }); diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index a51cf82daad..05f6548c62b 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -88,7 +88,7 @@ namespace ts { releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey): void; /*@internal*/ - hasDocument(path: Path): boolean; + getLanguageServiceRefCounts(path: Path): [string, number | undefined][]; reportStats(): string; } @@ -188,9 +188,10 @@ namespace ts { if (!entry && externalCache) { const sourceFile = externalCache.getDocument(key, path); if (sourceFile) { + Debug.assert(acquiring); entry = { sourceFile, - languageServiceRefCount: 1 + languageServiceRefCount: 0 }; bucket.set(path, entry); } @@ -229,6 +230,7 @@ namespace ts { entry.languageServiceRefCount++; } } + Debug.assert(entry.languageServiceRefCount !== 0); return entry.sourceFile; } @@ -252,8 +254,11 @@ namespace ts { } } - function hasDocument(path: Path) { - return !!forEachEntry(buckets, bucket => bucket.has(path)); + function getLanguageServiceRefCounts(path: Path) { + return arrayFrom(buckets.entries(), ([key, bucket]): [string, number | undefined] => { + const entry = bucket.get(path); + return [key, entry && entry.languageServiceRefCount]; + }); } return { @@ -263,7 +268,7 @@ namespace ts { updateDocumentWithKey, releaseDocument, releaseDocumentWithKey, - hasDocument, + getLanguageServiceRefCounts, reportStats, getKeyForCompilationSettings }; From e8a0e56e3e523ac4e237c94280692e1145b212f2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 22 May 2018 11:45:52 -0700 Subject: [PATCH 21/21] Add a test when orphan file changes before it gets added back to project --- .../unittests/tsserverProjectSystem.ts | 107 ++++++++++++------ 1 file changed, 75 insertions(+), 32 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 561375e30df..592cf4a9e4c 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -8416,52 +8416,95 @@ new C();` }); describe("document registry in project service", () => { - it("Caches the source file if script info is orphan", () => { - const projectRootPath = "/user/username/projects/project"; - const importModuleContent = `import {a} from "./module1"`; - const file: File = { - path: `${projectRootPath}/index.ts`, - content: importModuleContent - }; - const moduleFile: File = { - path: `${projectRootPath}/module1.d.ts`, - content: "export const a: number;" - }; - const configFile: File = { - path: `${projectRootPath}/tsconfig.json`, - content: JSON.stringify({ files: ["index.ts"] }) - }; + const projectRootPath = "/user/username/projects/project"; + const importModuleContent = `import {a} from "./module1"`; + const file: File = { + path: `${projectRootPath}/index.ts`, + content: importModuleContent + }; + const moduleFile: File = { + path: `${projectRootPath}/module1.d.ts`, + content: "export const a: number;" + }; + const configFile: File = { + path: `${projectRootPath}/tsconfig.json`, + content: JSON.stringify({ files: ["index.ts"] }) + }; + + function getProject(service: TestProjectService) { + return service.configuredProjects.get(configFile.path); + } + + function checkProject(service: TestProjectService, moduleIsOrphan: boolean) { + // Update the project + const project = getProject(service); + project.getLanguageService(); + checkProjectActualFiles(project, [file.path, libFile.path, configFile.path, ...(moduleIsOrphan ? [] : [moduleFile.path])]); + const moduleInfo = service.getScriptInfo(moduleFile.path); + assert.isDefined(moduleInfo); + assert.equal(moduleInfo.isOrphan(), moduleIsOrphan); + const key = service.documentRegistry.getKeyForCompilationSettings(project.getCompilationSettings()); + assert.deepEqual(service.documentRegistry.getLanguageServiceRefCounts(moduleInfo.path), [[key, moduleIsOrphan ? undefined : 1]]); + } + + function createServiceAndHost() { const host = createServerHost([file, moduleFile, libFile, configFile]); const service = createProjectService(host); service.openClientFile(file.path); - const project = service.configuredProjects.get(configFile.path); - checkProject(/*moduleIsOrphan*/ false); + checkProject(service, /*moduleIsOrphan*/ false); + return { host, service }; + } + + function changeFileToNotImportModule(service: TestProjectService) { + const info = service.getScriptInfo(file.path); + service.applyChangesToFile(info, [{ span: { start: 0, length: importModuleContent.length }, newText: "" }]); + checkProject(service, /*moduleIsOrphan*/ true); + } + + function changeFileToImportModule(service: TestProjectService) { + const info = service.getScriptInfo(file.path); + service.applyChangesToFile(info, [{ span: { start: 0, length: 0 }, newText: importModuleContent }]); + checkProject(service, /*moduleIsOrphan*/ false); + } + + it("Caches the source file if script info is orphan", () => { + const { service } = createServiceAndHost(); + const project = getProject(service); + const moduleInfo = service.getScriptInfo(moduleFile.path); const sourceFile = moduleInfo.cacheSourceFile.sourceFile; assert.equal(project.getSourceFile(moduleInfo.path), sourceFile); // edit file - const info = service.getScriptInfo(file.path); - service.applyChangesToFile(info, [{ span: { start: 0, length: importModuleContent.length }, newText: "" }]); - checkProject(/*moduleIsOrphan*/ true); + changeFileToNotImportModule(service); assert.equal(moduleInfo.cacheSourceFile.sourceFile, sourceFile); // write content back - service.applyChangesToFile(info, [{ span: { start: 0, length: 0 }, newText: importModuleContent }]); - checkProject(/*moduleIsOrphan*/ false); + changeFileToImportModule(service); assert.equal(moduleInfo.cacheSourceFile.sourceFile, sourceFile); assert.equal(project.getSourceFile(moduleInfo.path), sourceFile); + }); - function checkProject(moduleIsOrphan: boolean) { - // Update the project - project.getLanguageService(); - checkProjectActualFiles(project, [file.path, libFile.path, configFile.path, ...(moduleIsOrphan ? [] : [moduleFile.path])]); - const moduleInfo = service.getScriptInfo(moduleFile.path); - assert.isDefined(moduleInfo); - assert.equal(moduleInfo.isOrphan(), moduleIsOrphan); - const key = service.documentRegistry.getKeyForCompilationSettings(project.getCompilationSettings()); - assert.deepEqual(service.documentRegistry.getLanguageServiceRefCounts(moduleInfo.path), [[key, moduleIsOrphan ? undefined : 1]]); - } + it("Caches the source file if script info is orphan, and orphan script info changes", () => { + const { host, service } = createServiceAndHost(); + const project = getProject(service); + + const moduleInfo = service.getScriptInfo(moduleFile.path); + const sourceFile = moduleInfo.cacheSourceFile.sourceFile; + assert.equal(project.getSourceFile(moduleInfo.path), sourceFile); + + // edit file + changeFileToNotImportModule(service); + assert.equal(moduleInfo.cacheSourceFile.sourceFile, sourceFile); + + const updatedModuleContent = moduleFile.content + "\nexport const b: number;"; + host.writeFile(moduleFile.path, updatedModuleContent); + + // write content back + changeFileToImportModule(service); + assert.notEqual(moduleInfo.cacheSourceFile.sourceFile, sourceFile); + assert.equal(project.getSourceFile(moduleInfo.path), moduleInfo.cacheSourceFile.sourceFile); + assert.equal(moduleInfo.cacheSourceFile.sourceFile.text, updatedModuleContent); }); }); }