From 64f17c5a9870fc452be98256402177a68105c30e Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 18 Nov 2016 07:48:12 -0800 Subject: [PATCH 01/38] Use a symbol for untyped modules to distinguish from unknownSymbol --- src/compiler/checker.ts | 16 ++++++----- src/compiler/utilities.ts | 4 +-- .../reference/extendsUntypedModule.errors.txt | 14 ++++++++++ .../reference/extendsUntypedModule.js | 27 +++++++++++++++++++ tests/cases/compiler/extendsUntypedModule.ts | 9 +++++++ tests/cases/fourslash/untypedModuleImport.ts | 2 +- 6 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/extendsUntypedModule.errors.txt create mode 100644 tests/baselines/reference/extendsUntypedModule.js create mode 100644 tests/cases/compiler/extendsUntypedModule.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d25fc8bbbb..cf87755034e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1099,7 +1099,7 @@ namespace ts { const moduleSymbol = resolveExternalModuleName(node, (node.parent).moduleSpecifier); if (moduleSymbol) { - const exportDefaultSymbol = isShorthandAmbientModuleSymbol(moduleSymbol) ? + const exportDefaultSymbol = isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol) ? moduleSymbol : moduleSymbol.exports["export="] ? getPropertyOfType(getTypeOfSymbol(moduleSymbol.exports["export="]), "default") : @@ -1175,7 +1175,7 @@ namespace ts { if (targetSymbol) { const name = specifier.propertyName || specifier.name; if (name.text) { - if (isShorthandAmbientModuleSymbol(moduleSymbol)) { + if (isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol)) { return moduleSymbol; } @@ -1427,15 +1427,19 @@ namespace ts { Debug.assert(!!moduleNotFoundError); const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented; error(errorNode, diag, moduleName, resolvedModule.resolvedFileName); + return undefined; } else if (compilerOptions.noImplicitAny && moduleNotFoundError) { error(errorNode, Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedModule.resolvedFileName); + return undefined; } - // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first. - return undefined; + // Unlike a failed import, an untyped module produces a dummy symbol. This is checked for by `isUntypedOrShorthandAmbientModuleSymbol`. + const untypedSymbol = createSymbol(SymbolFlags.ValueModule, `"${moduleName}"`); + untypedSymbol.exports = createMap(); + return untypedSymbol; } if (moduleNotFoundError) { @@ -3575,7 +3579,7 @@ namespace ts { function getTypeOfFuncClassEnumModule(symbol: Symbol): Type { const links = getSymbolLinks(symbol); if (!links.type) { - if (symbol.flags & SymbolFlags.Module && isShorthandAmbientModuleSymbol(symbol)) { + if (symbol.flags & SymbolFlags.Module && isUntypedOrShorthandAmbientModuleSymbol(symbol)) { links.type = anyType; } else { @@ -19610,7 +19614,7 @@ namespace ts { function moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean { let moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression); - if (!moduleSymbol || isShorthandAmbientModuleSymbol(moduleSymbol)) { + if (!moduleSymbol || isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol)) { // If the module is not found or is shorthand, assume that it may export a value. return true; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 546416884f1..c6dfcebdc54 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -388,8 +388,8 @@ namespace ts { } /** Given a symbol for a module, checks that it is either an untyped import or a shorthand ambient module. */ - export function isShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean { - return isShorthandAmbientModule(moduleSymbol.valueDeclaration); + export function isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean { + return !moduleSymbol.valueDeclaration || isShorthandAmbientModule(moduleSymbol.valueDeclaration); } function isShorthandAmbientModule(node: Node): boolean { diff --git a/tests/baselines/reference/extendsUntypedModule.errors.txt b/tests/baselines/reference/extendsUntypedModule.errors.txt new file mode 100644 index 00000000000..9a1c4235352 --- /dev/null +++ b/tests/baselines/reference/extendsUntypedModule.errors.txt @@ -0,0 +1,14 @@ +/a.ts(2,17): error TS2507: Type 'any' is not a constructor function type. + + +==== /a.ts (1 errors) ==== + import Foo from "foo"; + class A extends Foo { } + ~~~ +!!! error TS2507: Type 'any' is not a constructor function type. + +==== /node_modules/foo/index.js (0 errors) ==== + // Test that extending an untyped module is an error, unlike extending unknownSymbol. + + This file is not read. + \ No newline at end of file diff --git a/tests/baselines/reference/extendsUntypedModule.js b/tests/baselines/reference/extendsUntypedModule.js new file mode 100644 index 00000000000..0804595c08e --- /dev/null +++ b/tests/baselines/reference/extendsUntypedModule.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/extendsUntypedModule.ts] //// + +//// [index.js] +// Test that extending an untyped module is an error, unlike extending unknownSymbol. + +This file is not read. + +//// [a.ts] +import Foo from "foo"; +class A extends Foo { } + + +//// [a.js] +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var foo_1 = require("foo"); +var A = (function (_super) { + __extends(A, _super); + function A() { + return _super.apply(this, arguments) || this; + } + return A; +}(foo_1["default"])); diff --git a/tests/cases/compiler/extendsUntypedModule.ts b/tests/cases/compiler/extendsUntypedModule.ts new file mode 100644 index 00000000000..8eaf6b3833a --- /dev/null +++ b/tests/cases/compiler/extendsUntypedModule.ts @@ -0,0 +1,9 @@ +// Test that extending an untyped module is an error, unlike extending unknownSymbol. +// @noImplicitReferences: true + +// @Filename: /node_modules/foo/index.js +This file is not read. + +// @Filename: /a.ts +import Foo from "foo"; +class A extends Foo { } diff --git a/tests/cases/fourslash/untypedModuleImport.ts b/tests/cases/fourslash/untypedModuleImport.ts index d128ad24ea3..3fd209d480d 100644 --- a/tests/cases/fourslash/untypedModuleImport.ts +++ b/tests/cases/fourslash/untypedModuleImport.ts @@ -13,7 +13,7 @@ verify.numberOfErrorsInCurrentFile(0); goTo.marker("fooModule"); verify.goToDefinitionIs([]); -verify.quickInfoIs(""); +verify.quickInfoIs('module "foo"'); verify.referencesAre([]) goTo.marker("foo"); From 4df4a2bbc7a1a71a440636f3bb18e5d9495569c8 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 25 Jan 2017 06:53:07 -0800 Subject: [PATCH 02/38] Use a single 'untypedModuleSymbol' for all untyped modules instead of creating a new one for each module. --- src/compiler/checker.ts | 10 ++++++---- .../baselines/reference/extendsUntypedModule.js | 17 +++++++++++------ tests/cases/fourslash/untypedModuleImport.ts | 2 +- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 332031903db..224da5e69c2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -132,6 +132,8 @@ namespace ts { const evolvingArrayTypes: EvolvingArrayType[] = []; const unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown"); + const untypedModuleSymbol = createSymbol(SymbolFlags.ValueModule, ""); + untypedModuleSymbol.exports = createMap(); const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__"); const anyType = createIntrinsicType(TypeFlags.Any, "any"); @@ -1490,10 +1492,10 @@ namespace ts { resolvedModule.resolvedFileName); return undefined; } - // Unlike a failed import, an untyped module produces a dummy symbol. This is checked for by `isUntypedOrShorthandAmbientModuleSymbol`. - const untypedSymbol = createSymbol(SymbolFlags.ValueModule, `"${moduleName}"`); - untypedSymbol.exports = createMap(); - return untypedSymbol; + // Unlike a failed import, an untyped module produces a dummy symbol. + // This is checked for by `isUntypedOrShorthandAmbientModuleSymbol`. + // This must be different than `unknownSymbol` because `getBaseConstructorTypeOfClass` won't fail for `unknownSymbol`. + return untypedModuleSymbol; } if (moduleNotFoundError) { diff --git a/tests/baselines/reference/extendsUntypedModule.js b/tests/baselines/reference/extendsUntypedModule.js index 0804595c08e..ad35e4abaac 100644 --- a/tests/baselines/reference/extendsUntypedModule.js +++ b/tests/baselines/reference/extendsUntypedModule.js @@ -12,16 +12,21 @@ class A extends Foo { } //// [a.js] "use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); var foo_1 = require("foo"); var A = (function (_super) { __extends(A, _super); function A() { - return _super.apply(this, arguments) || this; + return _super !== null && _super.apply(this, arguments) || this; } return A; }(foo_1["default"])); diff --git a/tests/cases/fourslash/untypedModuleImport.ts b/tests/cases/fourslash/untypedModuleImport.ts index c09f710177b..276277102b0 100644 --- a/tests/cases/fourslash/untypedModuleImport.ts +++ b/tests/cases/fourslash/untypedModuleImport.ts @@ -12,7 +12,7 @@ verify.numberOfErrorsInCurrentFile(0); goTo.marker("fooModule"); verify.goToDefinitionIs([]); -verify.quickInfoIs('module "foo"'); +verify.quickInfoIs('module '); verify.referencesAre([]) goTo.marker("foo"); From 91421c8dbc0dfa5c50e7219dab22abbd82c77d4f Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 10 Feb 2017 12:24:10 -0800 Subject: [PATCH 03/38] Fix "semicolon" lint rule options (was not enabled) --- src/compiler/checker.ts | 2 +- src/compiler/core.ts | 4 ++-- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/transformers/es2015.ts | 2 +- src/harness/fourslash.ts | 4 ++-- src/harness/harness.ts | 2 +- src/harness/unittests/compileOnSave.ts | 2 +- src/harness/unittests/printer.ts | 2 +- src/harness/unittests/textStorage.ts | 2 +- src/harness/unittests/tsserverProjectSystem.ts | 10 +++++----- src/harness/unittests/typingsInstaller.ts | 4 ++-- src/server/editorServices.ts | 4 ++-- src/server/project.ts | 4 ++-- src/server/scriptInfo.ts | 2 +- src/server/server.ts | 4 ++-- src/server/typingsInstaller/nodeTypingsInstaller.ts | 4 +--- src/services/codefixes/importFixes.ts | 6 +++--- src/services/findAllReferences.ts | 4 ++-- tslint.json | 2 +- 19 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ac1135788cd..cd06c3b577e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19760,7 +19760,7 @@ namespace ts { } if (potentialNewTargetCollisions.length) { - forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope) + forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope); potentialNewTargetCollisions.length = 0; } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 94e32dfdbb3..e75cd09170e 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -84,7 +84,7 @@ namespace ts { this.index++; return { value: this.selector(this.data, this.keys[index]), done: false }; } - return { value: undefined as never, done: true } + return { value: undefined as never, done: true }; } } @@ -140,7 +140,7 @@ namespace ts { action(this.data[key], key); } } - } + }; } export function createFileMap(keyMapper?: (key: string) => string): FileMap { diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 0300ff71ec5..651c8b3897c 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -958,7 +958,7 @@ namespace ts { const result = cache && cache.get(containingDirectory); if (result) { if (traceEnabled) { - trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName) + trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } }; } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index e0fd435a90d..9c11364ed3c 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2581,7 +2581,7 @@ namespace ts { if (loopOutParameters.length) { copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements); } - addRange(statements, lexicalEnvironment) + addRange(statements, lexicalEnvironment); loopBody = createBlock(statements, /*multiline*/ true); } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index fc85fb7276c..5d63298b946 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -571,7 +571,7 @@ namespace FourSlash { } private getGoToDefinition(): ts.DefinitionInfo[] { - return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition) + return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); } public verifyGoToType(arg0: any, endMarkerNames?: string | string[]) { @@ -912,7 +912,7 @@ namespace FourSlash { function rangeToReferenceEntry(r: Range) { let { isWriteAccess, isDefinition } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false }; isWriteAccess = !!isWriteAccess; isDefinition = !!isDefinition; - return { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess, isDefinition } + return { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess, isDefinition }; } } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 1dd41f9d81c..f999c6a0081 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -44,7 +44,7 @@ declare namespace NodeJS { declare var window: {}; declare var XMLHttpRequest: { new(): XMLHttpRequest; -} +}; interface XMLHttpRequest { readonly readyState: number; readonly responseText: string; diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index c8deb9e7554..0c9390924ac 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -495,7 +495,7 @@ namespace ts.projectSystem { const emitOutput = host.readFile(path + ".js"); assert.equal(emitOutput, f.content + newLine, "content of emit output should be identical with the input + newline"); } - }) + }); it("should emit specified file", () => { const file1 = { diff --git a/src/harness/unittests/printer.ts b/src/harness/unittests/printer.ts index 2496a880bc5..1a5a5a12f9e 100644 --- a/src/harness/unittests/printer.ts +++ b/src/harness/unittests/printer.ts @@ -9,7 +9,7 @@ namespace ts { Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, () => printCallback(createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed, ...options }))); }); - } + }; } describe("printFile", () => { diff --git a/src/harness/unittests/textStorage.ts b/src/harness/unittests/textStorage.ts index b4287f2610c..545d090df9b 100644 --- a/src/harness/unittests/textStorage.ts +++ b/src/harness/unittests/textStorage.ts @@ -65,6 +65,6 @@ namespace ts.textStorage { ts1.getLineInfo(0); assert.isTrue(ts1.hasScriptVersionCache(), "have script version cache - 2"); - }) + }); }); } \ No newline at end of file diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index e6f4abde382..228d6aa8f6e 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -600,7 +600,7 @@ namespace ts.projectSystem { checkProjectActualFiles(service.configuredProjects[0], []); checkProjectActualFiles(service.inferredProjects[0], [f1.path]); - }) + }); it("create configured project without file list", () => { const configFile: FileOrFolder = { @@ -1153,7 +1153,7 @@ namespace ts.projectSystem { const host = createServerHost([f1, f2, libFile]); const service = createProjectService(host); - service.openExternalProject({ projectFileName: "/a/b/project", rootFiles: toExternalFiles([f1.path, f2.path]), options: {} }) + service.openExternalProject({ projectFileName: "/a/b/project", rootFiles: toExternalFiles([f1.path, f2.path]), options: {} }); service.openClientFile(f1.path); service.openClientFile(f2.path, "let x: string"); @@ -1185,7 +1185,7 @@ namespace ts.projectSystem { const host = createServerHost([f1, f2, libFile]); const service = createProjectService(host); - service.openExternalProject({ projectFileName: "/a/b/project", rootFiles: [{ fileName: f1.path }, { fileName: f2.path, hasMixedContent: true }], options: {} }) + service.openExternalProject({ projectFileName: "/a/b/project", rootFiles: [{ fileName: f1.path }, { fileName: f2.path, hasMixedContent: true }], options: {} }); service.openClientFile(f1.path); service.openClientFile(f2.path, "let somelongname: string"); @@ -1868,7 +1868,7 @@ namespace ts.projectSystem { for (const f of [f2, f3]) { const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path)); - assert.equal(scriptInfo.containingProjects.length, 0, `expect 0 containing projects for '${f.path}'`) + assert.equal(scriptInfo.containingProjects.length, 0, `expect 0 containing projects for '${f.path}'`); } }); @@ -1984,7 +1984,7 @@ namespace ts.projectSystem { projectFileName, rootFiles: [toExternalFile(f1.path)], options: {} - }) + }); projectService.openClientFile(f1.path, "let x = 1;\nlet y = 2;"); projectService.checkNumberOfProjects({ externalProjects: 1 }); diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 29076df80f2..2eae01c3520 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -56,7 +56,7 @@ namespace ts.projectSystem { path: "/a/config.js", content: "export let x = 1" }; - const typesCache = "/cache" + const typesCache = "/cache"; const typesConfig = { path: typesCache + "/node_modules/@types/config/index.d.ts", content: "export let y: number;" @@ -74,7 +74,7 @@ namespace ts.projectSystem { super(host, { typesRegistry: createTypesRegistry("config"), globalTypingsCacheLocation: typesCache }); } installWorker(_requestId: number, _args: string[], _cwd: string, _cb: server.typingsInstaller.RequestCompletedAction) { - assert(false, "should not be called") + assert(false, "should not be called"); } })(); const service = createProjectService(host, { typingsInstaller: installer }); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index edc4fab9a19..f0aaba3d5bc 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -140,7 +140,7 @@ namespace ts.server { getScriptKind: _ => undefined, hasMixedContent: (fileName, extraFileExtensions) => { const mixedContentExtensions = ts.map(ts.filter(extraFileExtensions, item => item.isMixedContent), item => item.extension); - return forEach(mixedContentExtensions, extension => fileExtensionIs(fileName, extension)) + return forEach(mixedContentExtensions, extension => fileExtensionIs(fileName, extension)); } }; @@ -1377,7 +1377,7 @@ namespace ts.server { // close projects that were missing in the input list forEachKey(projectsToClose, externalProjectName => { - this.closeExternalProject(externalProjectName, /*suppressRefresh*/ true) + this.closeExternalProject(externalProjectName, /*suppressRefresh*/ true); }); this.refreshInferredProjects(); diff --git a/src/server/project.ts b/src/server/project.ts index 6042fd9a62b..4f218d39007 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -689,7 +689,7 @@ namespace ts.server { const fileName = resolvedTypeReferenceDirective.resolvedFileName; const typeFilePath = toPath(fileName, currentDirectory, getCanonicalFileName); referencedFiles.set(typeFilePath, true); - }) + }); } const allFileNames = arrayFrom(referencedFiles.keys()) as Path[]; @@ -711,7 +711,7 @@ namespace ts.server { const id = nextId; nextId++; return makeInferredProjectName(id); - } + }; })(); private _isJsInferredProject = false; diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index be3ef34ce3a..e5df91fd930 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -48,7 +48,7 @@ namespace ts.server { public reloadFromFile(tempFileName?: string) { if (this.svc || (tempFileName !== this.fileName)) { - this.reload(this.getFileText(tempFileName)) + this.reload(this.getFileText(tempFileName)); } else { this.setText(undefined); diff --git a/src/server/server.ts b/src/server/server.ts index e689a2fc782..989c3558848 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -46,14 +46,14 @@ namespace ts.server { if (process.env.XDG_CACHE_HOME) { return process.env.XDG_CACHE_HOME; } - const usersDir = platformIsDarwin ? "Users" : "home" + const usersDir = platformIsDarwin ? "Users" : "home"; const homePath = (os.homedir && os.homedir()) || process.env.HOME || ((process.env.LOGNAME || process.env.USER) && `/${usersDir}/${process.env.LOGNAME || process.env.USER}`) || os.tmpdir(); const cacheFolder = platformIsDarwin ? "Library/Caches" - : ".cache" + : ".cache"; return combinePaths(normalizeSlashes(homePath), cacheFolder); } diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index ff20e89e2d7..447a2c05429 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -61,9 +61,7 @@ namespace ts.server.typingsInstaller { return combinePaths(normalizeSlashes(globalTypingsCacheLocation), `node_modules/${TypesRegistryPackageName}/index.json`); } - type ExecSync = { - (command: string, options: { cwd: string, stdio?: "ignore" }): any - } + type ExecSync = (command: string, options: { cwd: string, stdio?: "ignore" }) => any; export class NodeTypingsInstaller extends TypingsInstaller { private readonly execSync: ExecSync; diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 1f1b499d03b..1c157257051 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -3,8 +3,8 @@ namespace ts.codefix { type ImportCodeActionKind = "CodeChange" | "InsertingIntoExistingImport" | "NewImport"; interface ImportCodeAction extends CodeAction { - kind: ImportCodeActionKind, - moduleSpecifier?: string + kind: ImportCodeActionKind; + moduleSpecifier?: string; } enum ModuleSpecifierComparison { @@ -75,7 +75,7 @@ namespace ts.codefix { getAllActions() { let result: ImportCodeAction[] = []; for (const key in this.symbolIdToActionMap) { - result = concatenate(result, this.symbolIdToActionMap[key]) + result = concatenate(result, this.symbolIdToActionMap[key]); } return result; } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index cd1477c4448..610fa25d7be 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -414,7 +414,7 @@ namespace ts.FindAllReferences { name, textSpan: createTextSpan(0, 1), displayParts: [{ text: name, kind: ScriptElementKind.keyword }] - } + }; const references: ReferenceEntry[] = []; for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); @@ -610,7 +610,7 @@ namespace ts.FindAllReferences { const result: Node[] = []; for (const decl of classSymbol.members.get("__constructor").declarations) { - const ctrKeyword = ts.findChildOfKind(decl, ts.SyntaxKind.ConstructorKeyword, sourceFile)! + const ctrKeyword = ts.findChildOfKind(decl, ts.SyntaxKind.ConstructorKeyword, sourceFile)!; Debug.assert(decl.kind === SyntaxKind.Constructor && !!ctrKeyword); result.push(ctrKeyword); } diff --git a/tslint.json b/tslint.json index 13de7acec63..3952d4fac29 100644 --- a/tslint.json +++ b/tslint.json @@ -17,7 +17,7 @@ "double", "avoid-escape" ], - "semicolon": [true, "ignore-bound-class-methods"], + "semicolon": [true, "always", "ignore-bound-class-methods"], "whitespace": [true, "check-branch", "check-decl", From 1c080d11e6445398ff34b50995f5f9aa6acf2d1d Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 20 Jan 2017 07:20:23 -0800 Subject: [PATCH 04/38] Set ScriptElementKind for enum members to "enum member" instead of "const" --- src/services/types.ts | 3 +-- tests/cases/fourslash/deleteClassWithEnumPresent.ts | 12 ++++++------ ...navigationBarItemsInsideMethodsAndConstructors.ts | 8 ++++---- tests/cases/fourslash/navigationBarItemsItems.ts | 12 ++++++------ tests/cases/fourslash/server/navbar01.ts | 12 ++++++------ 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/services/types.ts b/src/services/types.ts index b4210538518..e7e80cb1cc6 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -701,8 +701,7 @@ namespace ts { /** enum E */ export const enumElement = "enum"; - // TODO: GH#9983 - export const enumMemberElement = "const"; + export const enumMemberElement = "enum member"; /** * Inside module and script only diff --git a/tests/cases/fourslash/deleteClassWithEnumPresent.ts b/tests/cases/fourslash/deleteClassWithEnumPresent.ts index 8914e0020a0..aaa35272fa9 100644 --- a/tests/cases/fourslash/deleteClassWithEnumPresent.ts +++ b/tests/cases/fourslash/deleteClassWithEnumPresent.ts @@ -16,15 +16,15 @@ verify.navigationTree({ "childItems": [ { "text": "a", - "kind": "const" + "kind": "enum member" }, { "text": "b", - "kind": "const" + "kind": "enum member" }, { "text": "c", - "kind": "const" + "kind": "enum member" } ] } @@ -48,15 +48,15 @@ verify.navigationBar([ "childItems": [ { "text": "a", - "kind": "const" + "kind": "enum member" }, { "text": "b", - "kind": "const" + "kind": "enum member" }, { "text": "c", - "kind": "const" + "kind": "enum member" } ], "indent": 1 diff --git a/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts b/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts index 35dff3af14c..1613b1cb868 100644 --- a/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts +++ b/tests/cases/fourslash/navigationBarItemsInsideMethodsAndConstructors.ts @@ -36,7 +36,7 @@ verify.navigationTree({ "childItems": [ { "text": "LocalEnumMemberInConstructor", - "kind": "const" + "kind": "enum member" } ] }, @@ -64,7 +64,7 @@ verify.navigationTree({ "childItems": [ { "text": "LocalEnumMemberInMethod", - "kind": "const" + "kind": "enum member" } ] }, @@ -144,7 +144,7 @@ verify.navigationBar([ "childItems": [ { "text": "LocalEnumMemberInConstructor", - "kind": "const" + "kind": "enum member" } ], "indent": 3 @@ -184,7 +184,7 @@ verify.navigationBar([ "childItems": [ { "text": "LocalEnumMemberInMethod", - "kind": "const" + "kind": "enum member" } ], "indent": 3 diff --git a/tests/cases/fourslash/navigationBarItemsItems.ts b/tests/cases/fourslash/navigationBarItemsItems.ts index 69422dd0cc2..4597ac6474b 100644 --- a/tests/cases/fourslash/navigationBarItemsItems.ts +++ b/tests/cases/fourslash/navigationBarItemsItems.ts @@ -130,15 +130,15 @@ verify.navigationTree({ "childItems": [ { "text": "value1", - "kind": "const" + "kind": "enum member" }, { "text": "value2", - "kind": "const" + "kind": "enum member" }, { "text": "value3", - "kind": "const" + "kind": "enum member" } ] } @@ -263,15 +263,15 @@ verify.navigationBar([ "childItems": [ { "text": "value1", - "kind": "const" + "kind": "enum member" }, { "text": "value2", - "kind": "const" + "kind": "enum member" }, { "text": "value3", - "kind": "const" + "kind": "enum member" } ], "indent": 2 diff --git a/tests/cases/fourslash/server/navbar01.ts b/tests/cases/fourslash/server/navbar01.ts index 4a4f59bcf78..edbfca53afb 100644 --- a/tests/cases/fourslash/server/navbar01.ts +++ b/tests/cases/fourslash/server/navbar01.ts @@ -129,15 +129,15 @@ verify.navigationTree({ "childItems": [ { "text": "value1", - "kind": "const" + "kind": "enum member" }, { "text": "value2", - "kind": "const" + "kind": "enum member" }, { "text": "value3", - "kind": "const" + "kind": "enum member" } ] } @@ -262,15 +262,15 @@ verify.navigationBar([ "childItems": [ { "text": "value1", - "kind": "const" + "kind": "enum member" }, { "text": "value2", - "kind": "const" + "kind": "enum member" }, { "text": "value3", - "kind": "const" + "kind": "enum member" } ], "indent": 2 From de5091081a4768ff7684170d2ad8137cc02efaa0 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 14 Feb 2017 06:53:44 -0800 Subject: [PATCH 05/38] Fix failing tests --- src/compiler/utilities.ts | 2 +- tests/baselines/reference/extendsUntypedModule.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6a338a0f9d2..f4c505b9450 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -426,7 +426,7 @@ namespace ts { /** Given a symbol for a module, checks that it is either an untyped import or a shorthand ambient module. */ export function isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean { - return !moduleSymbol.valueDeclaration || isShorthandAmbientModule(moduleSymbol.valueDeclaration); + return !moduleSymbol.declarations || isShorthandAmbientModule(moduleSymbol.valueDeclaration); } function isShorthandAmbientModule(node: Node): boolean { diff --git a/tests/baselines/reference/extendsUntypedModule.js b/tests/baselines/reference/extendsUntypedModule.js index ad35e4abaac..f86ded7e6cb 100644 --- a/tests/baselines/reference/extendsUntypedModule.js +++ b/tests/baselines/reference/extendsUntypedModule.js @@ -22,6 +22,7 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); +exports.__esModule = true; var foo_1 = require("foo"); var A = (function (_super) { __extends(A, _super); From a742f6271c524790c7cebb8938e7034966bbfa53 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 14 Feb 2017 08:46:58 -0800 Subject: [PATCH 06/38] Handle additional cases --- src/services/symbolDisplay.ts | 12 ++++++---- .../quickInfoDisplayPartsEnum1.baseline | 24 +++++++++---------- .../quickInfoDisplayPartsEnum2.baseline | 24 +++++++++---------- .../quickInfoDisplayPartsEnum3.baseline | 24 +++++++++---------- .../fourslash/quickInfoDisplayPartsEnum1.ts | 4 +++- 5 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 58c83de8509..6a6cd5cd8b3 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -2,7 +2,7 @@ namespace ts.SymbolDisplay { // TODO(drosen): use contextual SemanticMeaning. export function getSymbolKind(typeChecker: TypeChecker, symbol: Symbol, location: Node): string { - const flags = symbol.getFlags(); + const { flags } = symbol; if (flags & SymbolFlags.Class) return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ? ScriptElementKind.localClassElement : ScriptElementKind.classElement; @@ -11,10 +11,10 @@ namespace ts.SymbolDisplay { if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement; if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; - const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, flags, location); + const result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location); if (result === ScriptElementKind.unknown) { if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement; - if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement; + if (flags & SymbolFlags.EnumMember) return ScriptElementKind.enumMemberElement; if (flags & SymbolFlags.Alias) return ScriptElementKind.alias; if (flags & SymbolFlags.Module) return ScriptElementKind.moduleElement; } @@ -22,7 +22,7 @@ namespace ts.SymbolDisplay { return result; } - function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: TypeChecker, symbol: Symbol, flags: SymbolFlags, location: Node) { + function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: TypeChecker, symbol: Symbol, location: Node) { if (typeChecker.isUndefinedSymbol(symbol)) { return ScriptElementKind.variableElement; } @@ -32,6 +32,7 @@ namespace ts.SymbolDisplay { if (location.kind === SyntaxKind.ThisKeyword && isExpression(location)) { return ScriptElementKind.parameterElement; } + const { flags } = symbol; if (flags & SymbolFlags.Variable) { if (isFirstDeclarationOfSymbolParameter(symbol)) { return ScriptElementKind.parameterElement; @@ -90,7 +91,7 @@ namespace ts.SymbolDisplay { const displayParts: SymbolDisplayPart[] = []; let documentation: SymbolDisplayPart[]; const symbolFlags = symbol.flags; - let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, symbolFlags, location); + let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location); let hasAddedSymbolInfo: boolean; const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isExpression(location); let type: Type; @@ -311,6 +312,7 @@ namespace ts.SymbolDisplay { } } if (symbolFlags & SymbolFlags.EnumMember) { + symbolKind = ScriptElementKind.enumMemberElement; addPrefixForAnyFunctionOrVar(symbol, "enum member"); const declaration = symbol.declarations[0]; if (declaration.kind === SyntaxKind.EnumMember) { diff --git a/tests/baselines/reference/quickInfoDisplayPartsEnum1.baseline b/tests/baselines/reference/quickInfoDisplayPartsEnum1.baseline index 142840b9f01..6dc27a4a5b3 100644 --- a/tests/baselines/reference/quickInfoDisplayPartsEnum1.baseline +++ b/tests/baselines/reference/quickInfoDisplayPartsEnum1.baseline @@ -34,7 +34,7 @@ "position": 13 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 13, @@ -95,7 +95,7 @@ "position": 21 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 21, @@ -156,7 +156,7 @@ "position": 34 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 34, @@ -357,7 +357,7 @@ "position": 71 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 71, @@ -488,7 +488,7 @@ "position": 89 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 89, @@ -619,7 +619,7 @@ "position": 107 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 107, @@ -717,7 +717,7 @@ "position": 135 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 135, @@ -778,7 +778,7 @@ "position": 143 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 143, @@ -839,7 +839,7 @@ "position": 156 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 156, @@ -1056,7 +1056,7 @@ "position": 205 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 205, @@ -1195,7 +1195,7 @@ "position": 229 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 229, @@ -1334,7 +1334,7 @@ "position": 253 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 253, diff --git a/tests/baselines/reference/quickInfoDisplayPartsEnum2.baseline b/tests/baselines/reference/quickInfoDisplayPartsEnum2.baseline index efdff818b0f..43d0683faef 100644 --- a/tests/baselines/reference/quickInfoDisplayPartsEnum2.baseline +++ b/tests/baselines/reference/quickInfoDisplayPartsEnum2.baseline @@ -34,7 +34,7 @@ "position": 13 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 13, @@ -99,7 +99,7 @@ "position": 23 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 23, @@ -164,7 +164,7 @@ "position": 38 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 38, @@ -369,7 +369,7 @@ "position": 77 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 77, @@ -504,7 +504,7 @@ "position": 95 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 95, @@ -639,7 +639,7 @@ "position": 113 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 113, @@ -741,7 +741,7 @@ "position": 141 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 141, @@ -806,7 +806,7 @@ "position": 151 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 151, @@ -871,7 +871,7 @@ "position": 166 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 166, @@ -1092,7 +1092,7 @@ "position": 217 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 217, @@ -1235,7 +1235,7 @@ "position": 241 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 241, @@ -1378,7 +1378,7 @@ "position": 265 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 265, diff --git a/tests/baselines/reference/quickInfoDisplayPartsEnum3.baseline b/tests/baselines/reference/quickInfoDisplayPartsEnum3.baseline index 919816394e2..b9f6483f63a 100644 --- a/tests/baselines/reference/quickInfoDisplayPartsEnum3.baseline +++ b/tests/baselines/reference/quickInfoDisplayPartsEnum3.baseline @@ -34,7 +34,7 @@ "position": 13 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 13, @@ -99,7 +99,7 @@ "position": 23 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 23, @@ -164,7 +164,7 @@ "position": 38 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 38, @@ -369,7 +369,7 @@ "position": 77 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 77, @@ -504,7 +504,7 @@ "position": 98 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 98, @@ -639,7 +639,7 @@ "position": 119 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 119, @@ -741,7 +741,7 @@ "position": 150 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 150, @@ -806,7 +806,7 @@ "position": 160 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 160, @@ -871,7 +871,7 @@ "position": 175 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 175, @@ -1092,7 +1092,7 @@ "position": 226 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 226, @@ -1235,7 +1235,7 @@ "position": 253 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 253, @@ -1378,7 +1378,7 @@ "position": 280 }, "quickInfo": { - "kind": "var", + "kind": "enum member", "kindModifiers": "", "textSpan": { "start": 280, diff --git a/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts b/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts index 628fe9c757e..0bc3c1ab89b 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts @@ -19,4 +19,6 @@ /////*25*/eInstance1 = /*26*/constE./*27*/e2; /////*28*/eInstance1 = /*29*/constE./*30*/e3; -verify.baselineQuickInfo(); \ No newline at end of file +//goTo.marker("2"); +//verify.verifyQuickInfoDisplayParts("enum member", "", { start: 0, length: 2 }, /*displayParts*/[], /*documentation*/[]); +verify.baselineQuickInfo(); From 7d82e15ee50c3a8235875d9e2ffa99c9e9bc7ba5 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Feb 2017 17:10:33 -0800 Subject: [PATCH 07/38] Add tests --- .../codeFixClassExtendAbstractGetter.ts | 11 ---------- .../codeFixClassExtendAbstractGetterSetter.ts | 22 +++++++++++++++---- .../codeFixClassExtendAbstractProperty.ts | 4 ++++ .../codeFixClassExtendAbstractSetter.ts | 11 ---------- 4 files changed, 22 insertions(+), 26 deletions(-) delete mode 100644 tests/cases/fourslash/codeFixClassExtendAbstractGetter.ts delete mode 100644 tests/cases/fourslash/codeFixClassExtendAbstractSetter.ts diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractGetter.ts b/tests/cases/fourslash/codeFixClassExtendAbstractGetter.ts deleted file mode 100644 index 8d79cce710e..00000000000 --- a/tests/cases/fourslash/codeFixClassExtendAbstractGetter.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -//// abstract class A { -//// abstract get b(): number; -//// } -//// -//// class C extends A {[| |]} - -verify.rangeAfterCodeFix(` - b: number; -`); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts b/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts index fc0ac400623..4bddfb799f2 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts @@ -2,9 +2,17 @@ //// abstract class A { //// private _a: string; -//// -//// abstract get a(): string; -//// abstract set a(newName: string); +//// +//// abstract get a(): number | string; +//// abstract get b(): this; +//// abstract get c(): A; +//// +//// abstract set d(arg: number | string); +//// abstract set e(arg: this); +//// abstract set f(arg: A); +//// +//// abstract get g(): string; +//// abstract set g(newName: string); //// } //// //// // Don't need to add anything in this case. @@ -13,5 +21,11 @@ //// class C extends A {[| |]} verify.rangeAfterCodeFix(` - a: string; + a: string | number; + b: this; + c: A; + d: string | number; + e: this; + f: A; + g: string; `); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts index 3160a3b9a08..b7300acf5ae 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts @@ -2,6 +2,8 @@ //// abstract class A { //// abstract x: number; +//// abstract y: this; +//// abstract z: A; //// abstract foo(): number; //// } //// @@ -10,6 +12,8 @@ verify.rangeAfterCodeFix(` x: number; + y: this; + z: A; foo(): number { throw new Error('Method not implemented.'); } diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractSetter.ts b/tests/cases/fourslash/codeFixClassExtendAbstractSetter.ts deleted file mode 100644 index e8cb55fa660..00000000000 --- a/tests/cases/fourslash/codeFixClassExtendAbstractSetter.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -//// abstract class A { -//// abstract set c(arg: number | string); -//// } -//// -//// class C extends A {[| |]} - -verify.rangeAfterCodeFix(` - c: string | number; -`); \ No newline at end of file From 33fc26cb9c4ea8e0ace668283abc81ac9a43c28b Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 16 Feb 2017 17:11:01 -0800 Subject: [PATCH 08/38] Detect this type for codefix --- src/services/codefixes/helpers.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 3eab994f84c..45479e49474 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -23,8 +23,6 @@ namespace ts.codefix { * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`. */ function getInsertionForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker, newlineChar: string): string { - // const name = symbol.getName(); - const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); const declarations = symbol.getDeclarations(); if (!(declarations && declarations.length)) { return ""; @@ -34,12 +32,22 @@ namespace ts.codefix { const name = declaration.name ? declaration.name.getText() : undefined; const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration)); + const typeAtNewDeclaration = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); + switch (declaration.kind) { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.PropertySignature: case SyntaxKind.PropertyDeclaration: - const typeString = checker.typeToString(type, enclosingDeclaration, TypeFormatFlags.None); + let typeString: string | undefined = undefined; + const typeAtOldDeclaration = checker.getTypeAtLocation(declaration); + if ((typeAtOldDeclaration as TypeParameter).isThisType) { + typeString = "this"; + } + else { + typeString = checker.typeToString(typeAtNewDeclaration, enclosingDeclaration, TypeFormatFlags.None); + } + return `${visibility}${name}: ${typeString};${newlineChar}`; case SyntaxKind.MethodSignature: @@ -51,7 +59,7 @@ namespace ts.codefix { // If there is more than one overload but no implementation signature // (eg: an abstract method or interface declaration), there is a 1-1 // correspondence of declarations and signatures. - const signatures = checker.getSignaturesOfType(type, SignatureKind.Call); + const signatures = checker.getSignaturesOfType(typeAtNewDeclaration, SignatureKind.Call); if (!(signatures && signatures.length > 0)) { return ""; } From 5ed5e5fd9432a5104de7a1e3459d0a6ea5951661 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Sun, 19 Feb 2017 18:38:09 +0100 Subject: [PATCH 09/38] Add CatchClause to VariableDeclaration.parent --- src/compiler/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index de42d5d9745..234e5570029 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -651,7 +651,7 @@ export interface VariableDeclaration extends Declaration { kind: SyntaxKind.VariableDeclaration; - parent?: VariableDeclarationList; + parent?: VariableDeclarationList | CatchClause; name: BindingName; // Declared variable name type?: TypeNode; // Optional type annotation initializer?: Expression; // Optional initializer From 077862736d00f9184ae89ae08f46f7b52333ebbd Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Sun, 19 Feb 2017 21:26:04 +0100 Subject: [PATCH 10/38] Add parent type for nodes where possible --- src/compiler/types.ts | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 234e5570029..3d93907ae98 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -624,6 +624,7 @@ export interface TypeParameterDeclaration extends Declaration { kind: SyntaxKind.TypeParameter; + parent?: DeclarationWithTypeParameters; name: Identifier; constraint?: TypeNode; default?: TypeNode; @@ -659,11 +660,13 @@ export interface VariableDeclarationList extends Node { kind: SyntaxKind.VariableDeclarationList; + parent?: VariableStatement | ForStatement | ForOfStatement | ForInStatement; declarations: NodeArray; } export interface ParameterDeclaration extends Declaration { kind: SyntaxKind.Parameter; + parent?: SignatureDeclaration; dotDotDotToken?: DotDotDotToken; // Present on rest parameter name: BindingName; // Declared parameter name questionToken?: QuestionToken; // Present on optional parameter @@ -673,6 +676,7 @@ export interface BindingElement extends Declaration { kind: SyntaxKind.BindingElement; + parent?: BindingPattern; propertyName?: PropertyName; // Binding property name (in object binding pattern) dotDotDotToken?: DotDotDotToken; // Present on rest element (in object binding pattern) name: BindingName; // Declared binding element name @@ -754,11 +758,13 @@ export interface ObjectBindingPattern extends Node { kind: SyntaxKind.ObjectBindingPattern; + parent?: VariableDeclaration | ParameterDeclaration | BindingElement; elements: NodeArray; } export interface ArrayBindingPattern extends Node { kind: SyntaxKind.ArrayBindingPattern; + parent?: VariableDeclaration | ParameterDeclaration | BindingElement; elements: NodeArray; } @@ -1327,14 +1333,17 @@ export interface TemplateHead extends LiteralLikeNode { kind: SyntaxKind.TemplateHead; + parent?: TemplateExpression; } export interface TemplateMiddle extends LiteralLikeNode { kind: SyntaxKind.TemplateMiddle; + parent?: TemplateSpan; } export interface TemplateTail extends LiteralLikeNode { kind: SyntaxKind.TemplateTail; + parent?: TemplateSpan; } export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral; @@ -1349,6 +1358,7 @@ // The template literal must have kind TemplateMiddleLiteral or TemplateTailLiteral. export interface TemplateSpan extends Node { kind: SyntaxKind.TemplateSpan; + parent?: TemplateExpression; expression: Expression; literal: TemplateMiddle | TemplateTail; } @@ -1503,6 +1513,7 @@ /// The opening element of a ... JsxElement export interface JsxOpeningElement extends Expression { kind: SyntaxKind.JsxOpeningElement; + parent?: JsxElement; tagName: JsxTagNameExpression; attributes: JsxAttributes; } @@ -1516,6 +1527,7 @@ export interface JsxAttribute extends ObjectLiteralElement { kind: SyntaxKind.JsxAttribute; + parent?: JsxOpeningLikeElement; name: Identifier; /// JSX attribute initializers are optional; is sugar for initializer?: StringLiteral | JsxExpression; @@ -1523,22 +1535,26 @@ export interface JsxSpreadAttribute extends ObjectLiteralElement { kind: SyntaxKind.JsxSpreadAttribute; + parent?: JsxOpeningLikeElement; expression: Expression; } export interface JsxClosingElement extends Node { kind: SyntaxKind.JsxClosingElement; + parent?: JsxElement; tagName: JsxTagNameExpression; } export interface JsxExpression extends Expression { kind: SyntaxKind.JsxExpression; + parent?: JsxElement | JsxAttributeLike; dotDotDotToken?: Token; expression?: Expression; } export interface JsxText extends Node { kind: SyntaxKind.JsxText; + parent?: JsxElement; } export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement; @@ -1680,17 +1696,20 @@ export interface CaseBlock extends Node { kind: SyntaxKind.CaseBlock; + parent?: SwitchStatement; clauses: NodeArray; } export interface CaseClause extends Node { kind: SyntaxKind.CaseClause; + parent?: CaseBlock; expression: Expression; statements: NodeArray; } export interface DefaultClause extends Node { kind: SyntaxKind.DefaultClause; + parent?: CaseBlock; statements: NodeArray; } @@ -1716,6 +1735,7 @@ export interface CatchClause extends Node { kind: SyntaxKind.CatchClause; + parent?: TryStatement; variableDeclaration: VariableDeclaration; block: Block; } @@ -1759,6 +1779,7 @@ export interface HeritageClause extends Node { kind: SyntaxKind.HeritageClause; + parent?: InterfaceDeclaration | ClassDeclaration | ClassExpression; token: SyntaxKind; types?: NodeArray; } @@ -1772,6 +1793,7 @@ export interface EnumMember extends Declaration { kind: SyntaxKind.EnumMember; + parent?: EnumDeclaration; // This does include ComputedPropertyName, but the parser will give an error // if it parses a ComputedPropertyName in an EnumMember name: PropertyName; @@ -1790,7 +1812,8 @@ export interface ModuleDeclaration extends DeclarationStatement { kind: SyntaxKind.ModuleDeclaration; - name: Identifier | StringLiteral; + parent?: ModuleBody | SourceFile; + name: ModuleName; body?: ModuleBody | JSDocNamespaceDeclaration | Identifier; } @@ -1810,6 +1833,7 @@ export interface ModuleBlock extends Node, Statement { kind: SyntaxKind.ModuleBlock; + parent?: ModuleDeclaration; statements: NodeArray; } @@ -1817,6 +1841,7 @@ export interface ImportEqualsDeclaration extends DeclarationStatement { kind: SyntaxKind.ImportEqualsDeclaration; + parent?: SourceFile | ModuleBlock; name: Identifier; // 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external @@ -1826,6 +1851,7 @@ export interface ExternalModuleReference extends Node { kind: SyntaxKind.ExternalModuleReference; + parent?: ImportEqualsDeclaration; expression?: Expression; } @@ -1835,6 +1861,7 @@ // ImportClause information is shown at its declaration below. export interface ImportDeclaration extends Statement { kind: SyntaxKind.ImportDeclaration; + parent?: SourceFile | ModuleBlock; importClause?: ImportClause; moduleSpecifier: Expression; } @@ -1849,12 +1876,14 @@ // import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} export interface ImportClause extends Declaration { kind: SyntaxKind.ImportClause; + parent?: ImportDeclaration; name?: Identifier; // Default binding namedBindings?: NamedImportBindings; } export interface NamespaceImport extends Declaration { kind: SyntaxKind.NamespaceImport; + parent?: ImportClause; name: Identifier; } @@ -1866,17 +1895,20 @@ export interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; + parent?: SourceFile | ModuleBlock; exportClause?: NamedExports; moduleSpecifier?: Expression; } export interface NamedImports extends Node { kind: SyntaxKind.NamedImports; + parent?: ImportClause; elements: NodeArray; } export interface NamedExports extends Node { kind: SyntaxKind.NamedExports; + parent?: ExportDeclaration; elements: NodeArray; } @@ -1884,12 +1916,14 @@ export interface ImportSpecifier extends Declaration { kind: SyntaxKind.ImportSpecifier; + parent?: NamedImports; propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) name: Identifier; // Declared name } export interface ExportSpecifier extends Declaration { kind: SyntaxKind.ExportSpecifier; + parent?: NamedExports; propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent) name: Identifier; // Declared name } @@ -1898,6 +1932,7 @@ export interface ExportAssignment extends DeclarationStatement { kind: SyntaxKind.ExportAssignment; + parent?: SourceFile; isExportEquals?: boolean; expression: Expression; } From 6c9ba46e8b9253e95d899a9d6fbef2aba16ba4b9 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Sun, 19 Feb 2017 22:03:32 +0100 Subject: [PATCH 11/38] Fix compile errors --- src/compiler/checker.ts | 2 +- src/services/breakpoints.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 12b55aa818b..541b49acb9a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11546,7 +11546,7 @@ namespace ts { if (isBindingPattern(declaration.parent)) { const parentDeclaration = declaration.parent.parent; const name = declaration.propertyName || declaration.name; - if (isVariableLike(parentDeclaration) && + if (parentDeclaration.kind !== SyntaxKind.BindingElement && parentDeclaration.type && !isBindingPattern(name)) { const text = getTextOfPropertyName(name); diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index c751cf3871b..1f6bec41109 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -370,8 +370,8 @@ namespace ts.BreakpointResolver { } function textSpanFromVariableDeclaration(variableDeclaration: VariableDeclaration): TextSpan { - const declarations = variableDeclaration.parent.declarations; - if (declarations && declarations[0] === variableDeclaration) { + if (variableDeclaration.parent.kind === SyntaxKind.VariableDeclarationList && + variableDeclaration.parent.declarations[0] === variableDeclaration) { // First declaration - include let keyword return textSpan(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration); } @@ -400,8 +400,8 @@ namespace ts.BreakpointResolver { return textSpanFromVariableDeclaration(variableDeclaration); } - const declarations = variableDeclaration.parent.declarations; - if (declarations && declarations[0] !== variableDeclaration) { + if (variableDeclaration.parent.kind === SyntaxKind.VariableDeclarationList && + variableDeclaration.parent.declarations[0] !== variableDeclaration) { // If we cannot set breakpoint on this declaration, set it on previous one // Because the variable declaration may be binding pattern and // we would like to set breakpoint in last binding element if that's the case, From 1c25034a18d736e07a3f6ad9fb05c3450929e8d3 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 22 Feb 2017 16:15:16 -0800 Subject: [PATCH 12/38] instantiate generic this param correctly --- src/compiler/checker.ts | 1 + src/compiler/types.ts | 1 + ...sDoesntImplementInheritedAbstractMember.ts | 2 +- .../fixClassIncorrectlyImplementsInterface.ts | 4 +-- src/services/codefixes/helpers.ts | 14 ++------ .../codeFixClassExtendAbstractMethod.ts | 2 ++ .../codeFixClassExtendAbstractMethodThis.ts | 13 +++++++ ...entInterfaceMethodThisAndSelfReference.ts} | 4 +-- tests/cases/fourslash/quickInfoOnThis5.ts | 35 +++++++++++++++++++ 9 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts rename tests/cases/fourslash/{codeFixClassImplementInterfaceMethodWithParams.ts => codeFixClassImplementInterfaceMethodThisAndSelfReference.ts} (71%) create mode 100644 tests/cases/fourslash/quickInfoOnThis5.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 12b55aa818b..8b926832200 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -97,6 +97,7 @@ namespace ts { getBaseTypes, getBaseTypeOfLiteralType, getWidenedType, + getTypeWithThisArgument, getTypeFromTypeNode: node => { node = getParseTreeNode(node, isTypeNode); return node ? getTypeFromTypeNode(node) : unknownType; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index de42d5d9745..f4e432bc536 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2411,6 +2411,7 @@ getIndexTypeOfType(type: Type, kind: IndexKind): Type; getBaseTypes(type: InterfaceType): BaseType[]; getBaseTypeOfLiteralType(type: Type): Type; + getTypeWithThisArgument(type: Type, thisArgument?: Type): Type; getWidenedType(type: Type): Type; getReturnTypeOfSignature(signature: Signature): Type; /** diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 22546e55ecc..f7e0fde8d43 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -23,7 +23,7 @@ namespace ts.codefix { const startPos = classDecl.members.pos; const classType = checker.getTypeAtLocation(classDecl) as InterfaceType; - const instantiatedExtendsType = checker.getBaseTypes(classType)[0]; + const instantiatedExtendsType = checker.getTypeWithThisArgument(checker.getBaseTypes(classType)[0], classType.thisType); // Note that this is ultimately derived from a map indexed by symbol names, // so duplicates cannot occur. diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 42488dc2aed..aa7b320b13c 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -17,7 +17,7 @@ namespace ts.codefix { } const startPos: number = classDecl.members.pos; - const classType = checker.getTypeAtLocation(classDecl); + const classType = checker.getTypeAtLocation(classDecl) as InterfaceType; const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl); const hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, IndexKind.Number); @@ -25,7 +25,7 @@ namespace ts.codefix { const result: CodeAction[] = []; for (const implementedTypeNode of implementedTypeNodes) { - const implementedType = checker.getTypeFromTypeNode(implementedTypeNode) as InterfaceType; + const implementedType = checker.getTypeWithThisArgument(checker.getTypeFromTypeNode(implementedTypeNode), classType.thisType) as InterfaceType; // Note that this is ultimately derived from a map indexed by symbol names, // so duplicates cannot occur. const implementedTypeSymbols = checker.getPropertiesOfType(implementedType); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 45479e49474..d20fc0129cd 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -32,22 +32,14 @@ namespace ts.codefix { const name = declaration.name ? declaration.name.getText() : undefined; const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration)); - const typeAtNewDeclaration = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); + const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); switch (declaration.kind) { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.PropertySignature: case SyntaxKind.PropertyDeclaration: - let typeString: string | undefined = undefined; - const typeAtOldDeclaration = checker.getTypeAtLocation(declaration); - if ((typeAtOldDeclaration as TypeParameter).isThisType) { - typeString = "this"; - } - else { - typeString = checker.typeToString(typeAtNewDeclaration, enclosingDeclaration, TypeFormatFlags.None); - } - + const typeString = checker.typeToString(type, enclosingDeclaration, TypeFormatFlags.None); return `${visibility}${name}: ${typeString};${newlineChar}`; case SyntaxKind.MethodSignature: @@ -59,7 +51,7 @@ namespace ts.codefix { // If there is more than one overload but no implementation signature // (eg: an abstract method or interface declaration), there is a 1-1 // correspondence of declarations and signatures. - const signatures = checker.getSignaturesOfType(typeAtNewDeclaration, SignatureKind.Call); + const signatures = checker.getSignaturesOfType(type, SignatureKind.Call); if (!(signatures && signatures.length > 0)) { return ""; } diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts index a657dfeb718..344a7ee3f2b 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts @@ -2,6 +2,7 @@ //// abstract class A { //// abstract f(a: number, b: string): boolean; +//// abstract f(a: number, b: string): this; //// abstract f(a: string, b: number): Function; //// abstract f(a: string): Function; //// } @@ -10,6 +11,7 @@ verify.rangeAfterCodeFix(` f(a: number, b: string): boolean; + f(a: number, b: string): this; f(a: string, b: number): Function; f(a: string): Function; f(a: any, b?: any) { diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts new file mode 100644 index 00000000000..55b3ad4b77e --- /dev/null +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts @@ -0,0 +1,13 @@ +/// + +//// abstract class A { +//// abstract f(): this; +//// } +//// +//// class C extends A {[| |]} + +verify.rangeAfterCodeFix(` + f(): this { + throw new Error('Method not implemented.'); + } +`); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodWithParams.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts similarity index 71% rename from tests/cases/fourslash/codeFixClassImplementInterfaceMethodWithParams.ts rename to tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts index 0ee842975e0..95cc3476bf1 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodWithParams.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts @@ -1,14 +1,14 @@ /// //// interface I { -//// f(x: number, y: string): I +//// f(x: number, y: this): I //// } //// //// class C implements I {[| //// |]} verify.rangeAfterCodeFix(` -f(x: number,y: string): I { +f(x: number,y: this): I { throw new Error('Method not implemented.'); } `); diff --git a/tests/cases/fourslash/quickInfoOnThis5.ts b/tests/cases/fourslash/quickInfoOnThis5.ts new file mode 100644 index 00000000000..fd09aeb4a07 --- /dev/null +++ b/tests/cases/fourslash/quickInfoOnThis5.ts @@ -0,0 +1,35 @@ +/// + +verify.quickInfos({ + 1: "this: ContextualInterface", + 2: "(parameter) this: void" +}); + + + +////interface ContextualInterface { +//// m: number; +//// method(this: this, n: number); +////} +////let o: ContextualInterface = { +//// m: 12, +//// method(n) { +//// let x = this/*1*/.m; +//// } +////} +////interface ContextualInterface2 { +//// (this: void, n: number): void; +////} +////let contextualInterface2: ContextualInterface2 = function (th/*2*/is, n) { } + +class A { + x: number + myMethod(): this { return this; } +} + +class B extends A { + constructor(){ + super(); + this.myMethod(); + } +} From fbccb62d4b7a25994b3adfc87e80029f9d4b5ef9 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 22 Feb 2017 16:20:14 -0800 Subject: [PATCH 13/38] cleanup tests --- tests/cases/fourslash/quickInfoOnThis5.ts | 35 ----------------------- 1 file changed, 35 deletions(-) delete mode 100644 tests/cases/fourslash/quickInfoOnThis5.ts diff --git a/tests/cases/fourslash/quickInfoOnThis5.ts b/tests/cases/fourslash/quickInfoOnThis5.ts deleted file mode 100644 index fd09aeb4a07..00000000000 --- a/tests/cases/fourslash/quickInfoOnThis5.ts +++ /dev/null @@ -1,35 +0,0 @@ -/// - -verify.quickInfos({ - 1: "this: ContextualInterface", - 2: "(parameter) this: void" -}); - - - -////interface ContextualInterface { -//// m: number; -//// method(this: this, n: number); -////} -////let o: ContextualInterface = { -//// m: 12, -//// method(n) { -//// let x = this/*1*/.m; -//// } -////} -////interface ContextualInterface2 { -//// (this: void, n: number): void; -////} -////let contextualInterface2: ContextualInterface2 = function (th/*2*/is, n) { } - -class A { - x: number - myMethod(): this { return this; } -} - -class B extends A { - constructor(){ - super(); - this.myMethod(); - } -} From d6085f75c4f47a034c0fb1e6eb91d65655344c0a Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 28 Feb 2017 15:41:35 -0800 Subject: [PATCH 14/38] Return completions for JsDoc tagname even when there are no "@' sign prefix --- src/services/completions.ts | 38 ++++++++++++++++++++++++++++--------- src/services/jsDoc.ts | 33 ++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 1bf57d33fdc..4450be7cad6 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -16,11 +16,11 @@ namespace ts.Completions { return undefined; } - const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName } = completionData; + const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName } = completionData; if (isJsDocTagName) { // If the current position is a jsDoc tag name, only tag names should be provided for completion - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries() }; + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries(shouldAppendAtSignBeforeJsDocTagName) }; } const entries: CompletionEntry[] = []; @@ -815,6 +815,12 @@ namespace ts.Completions { const isJavaScriptFile = isSourceFileJavaScript(sourceFile); let isJsDocTagName = false; + // This is for the case when users request completion in JsDoc without "@" + // i.e. + // /** + // * |completion here| + // **/ + let shouldAppendAtSignBeforeJsDocTagName = false; let start = timestamp(); const currentToken = getTokenAtPosition(sourceFile, position); @@ -826,10 +832,24 @@ namespace ts.Completions { log("getCompletionData: Is inside comment: " + (timestamp() - start)); if (insideComment) { - // The current position is next to the '@' sign, when no tag name being provided yet. - // Provide a full list of tag names - if (hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) { - isJsDocTagName = true; + if (hasDocComment(sourceFile, position)) { + // The current position is next to the '@' sign, when no tag name being provided yet. + // Provide a full list of tag names + if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) { + isJsDocTagName = true; + } + else { + const lineStart = getLineStartPositionForPosition(position, sourceFile); + shouldAppendAtSignBeforeJsDocTagName = sourceFile.text.substr(lineStart, position).indexOf("@") === -1; + + // This is for the case + // /** + // * |completion here| + // **/ + if (shouldAppendAtSignBeforeJsDocTagName) { + isJsDocTagName = true; + } + } } // Completion should work inside certain JsDoc tags. For example: @@ -854,8 +874,8 @@ namespace ts.Completions { } } - if (isJsDocTagName) { - return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName }; + if (isJsDocTagName || shouldAppendAtSignBeforeJsDocTagName) { + return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName }; } if (!insideJsDocTagExpression) { @@ -983,7 +1003,7 @@ namespace ts.Completions { log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); - return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName }; + return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName }; function getTypeScriptMemberSymbols(): void { // Right of dot member completion list diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 08a51a63e63..40ee276b0fa 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -42,7 +42,8 @@ namespace ts.JsDoc { "prop", "version" ]; - let jsDocCompletionEntries: CompletionEntry[]; + let jsDocTagNameCompletionEntries: CompletionEntry[]; + let jsDocTagNameWithAtSignCompletionEntries: CompletionEntry[]; export function getJsDocCommentsFromDeclarations(declarations: Declaration[]) { // Only collect doc comments from duplicate declarations once: @@ -88,15 +89,27 @@ namespace ts.JsDoc { return undefined; } - export function getAllJsDocCompletionEntries(): CompletionEntry[] { - return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, tagName => { - return { - name: tagName, - kind: ScriptElementKind.keyword, - kindModifiers: "", - sortText: "0", - }; - })); + export function getAllJsDocCompletionEntries(shouldAppendAtSign: boolean): CompletionEntry[] { + if (!shouldAppendAtSign) { + return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, tagName => { + return { + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0", + }; + })); + } + else { + return jsDocTagNameWithAtSignCompletionEntries || (jsDocTagNameWithAtSignCompletionEntries = ts.map(jsDocTagNames, tagName => { + return { + name: `@${tagName}`, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0" + } + })); + } } /** From 441c5880d75fe40c9d3d0fba75bd6b541a0d8573 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 28 Feb 2017 15:41:47 -0800 Subject: [PATCH 15/38] Update fourslash tests --- tests/cases/fourslash/completionInJsDoc.ts | 53 +++++++++++++------ .../completionListAtInvalidLocations.ts | 44 +++++++-------- 2 files changed, 57 insertions(+), 40 deletions(-) diff --git a/tests/cases/fourslash/completionInJsDoc.ts b/tests/cases/fourslash/completionInJsDoc.ts index 8ab9dbd0131..5eca52743a4 100644 --- a/tests/cases/fourslash/completionInJsDoc.ts +++ b/tests/cases/fourslash/completionInJsDoc.ts @@ -2,29 +2,39 @@ // @allowJs: true // @Filename: Foo.js -/////** @/*1*/ */ -////var v1; +//// /** @/*1*/ */ +//// var v1; //// -/////** @p/*2*/ */ -////var v2; +//// /** @p/*2*/ */ +//// var v2; //// -/////** @param /*3*/ */ -////var v3; +//// /** @param /*3*/ */ +//// var v3; //// -/////** @param { n/*4*/ } bar */ -////var v4; +//// /** @param { n/*4*/ } bar */ +//// var v4; //// -/////** @type { n/*5*/ } */ -////var v5; +//// /** @type { n/*5*/ } */ +//// var v5; //// -////// @/*6*/ -////var v6; +//// // @/*6*/ +//// var v6; //// -////// @pa/*7*/ -////var v7; +//// // @pa/*7*/ +//// var v7; //// -/////** @return { n/*8*/ } */ -////var v8; +//// /** @return { n/*8*/ } */ +//// var v8; +//// +//// /** /*9*/ */ +//// +//// /** +//// /*10*/ +//// */ +//// +//// /** +//// * /*11*/ +//// */ goTo.marker('1'); verify.completionListContains("constructor"); @@ -55,3 +65,14 @@ verify.completionListIsEmpty(); goTo.marker('8'); verify.completionListContains('number'); +goTo.marker('9'); +verify.completionListCount(40); +verify.completionListContains("@argument"); + +goTo.marker('10'); +verify.completionListCount(40); +verify.completionListContains("@return"); + +goTo.marker('11'); +verify.completionListCount(40); +verify.completionListContains("@argument"); diff --git a/tests/cases/fourslash/completionListAtInvalidLocations.ts b/tests/cases/fourslash/completionListAtInvalidLocations.ts index 0660f0e183b..171f63825f2 100644 --- a/tests/cases/fourslash/completionListAtInvalidLocations.ts +++ b/tests/cases/fourslash/completionListAtInvalidLocations.ts @@ -1,28 +1,24 @@ /// -////var v1 = ''; -////" /*openString1*/ -////var v2 = ''; -////"/*openString2*/ -////var v3 = ''; -////" bar./*openString3*/ -////var v4 = ''; -////// bar./*inComment1*/ -////var v6 = ''; -////// /*inComment2*/ -////var v7 = ''; -/////** /*inComment3*/ -////var v8 = ''; -/////** /*inComment4*/ **/ -////var v9 = ''; -/////* /*inComment5*/ -////var v11 = ''; -//// // /*inComment6*/ -////var v12 = ''; -////type htm/*inTypeAlias*/ -/// -////// /*inComment7*/ -////foo; -////var v10 = /reg/*inRegExp1*/ex/; +//// var v1 = ''; +//// " /*openString1*/ +//// var v2 = ''; +//// "/*openString2*/ +//// var v3 = ''; +//// " bar./*openString3*/ +//// var v4 = ''; +//// // bar./*inComment1*/ +//// var v6 = ''; +//// // /*inComment2*/ +//// var v7 = ''; +//// /* /*inComment3*/ +//// var v11 = ''; +//// // /*inComment4*/ +//// var v12 = ''; +//// type htm/*inTypeAlias*/ +//// +//// // /*inComment5*/ +//// foo; +//// var v10 = /reg/*inRegExp1*/ex/; goTo.eachMarker(() => verify.completionListIsEmpty()); From e74df1e38bbb911998defecb8899acf1a6806a12 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Tue, 28 Feb 2017 15:51:41 -0800 Subject: [PATCH 16/38] Remove unnecessary comment --- src/services/completions.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 4450be7cad6..1d446f0aa59 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -842,10 +842,6 @@ namespace ts.Completions { const lineStart = getLineStartPositionForPosition(position, sourceFile); shouldAppendAtSignBeforeJsDocTagName = sourceFile.text.substr(lineStart, position).indexOf("@") === -1; - // This is for the case - // /** - // * |completion here| - // **/ if (shouldAppendAtSignBeforeJsDocTagName) { isJsDocTagName = true; } From a5d104c841fcf546e06df04edc021dbe7b93f032 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 17 Feb 2017 16:47:51 -0800 Subject: [PATCH 17/38] Fix #14136: Make `Object.create` return `any` all the time --- src/lib/es5.d.ts | 2 +- ...signingFromObjectToAnythingElse.errors.txt | 18 ++---- tests/baselines/reference/objectCreate.types | 60 +++++++++---------- tests/baselines/reference/objectCreate2.types | 56 ++++++++--------- 4 files changed, 65 insertions(+), 71 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 8f29deb67db..262c2ba21fe 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -140,7 +140,7 @@ interface ObjectConstructor { * Creates an object that has the specified prototype or that has null prototype. * @param o Object to use as a prototype. May be null. */ - create(o: T | null): T | object; + create(o: object | null): any; /** * Creates an object that has the specified prototype, and that optionally contains specified properties. diff --git a/tests/baselines/reference/assigningFromObjectToAnythingElse.errors.txt b/tests/baselines/reference/assigningFromObjectToAnythingElse.errors.txt index 070339e4726..d3395c7ebc9 100644 --- a/tests/baselines/reference/assigningFromObjectToAnythingElse.errors.txt +++ b/tests/baselines/reference/assigningFromObjectToAnythingElse.errors.txt @@ -1,11 +1,8 @@ tests/cases/compiler/assigningFromObjectToAnythingElse.ts(3,1): error TS2322: Type 'Object' is not assignable to type 'RegExp'. The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? Property 'exec' is missing in type 'Object'. -tests/cases/compiler/assigningFromObjectToAnythingElse.ts(5,5): error TS2322: Type 'object | Object' is not assignable to type 'String'. - Type 'object' is not assignable to type 'String'. - Property 'charAt' is missing in type '{}'. -tests/cases/compiler/assigningFromObjectToAnythingElse.ts(6,5): error TS2322: Type 'object | Number' is not assignable to type 'String'. - Type 'object' is not assignable to type 'String'. +tests/cases/compiler/assigningFromObjectToAnythingElse.ts(5,17): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/compiler/assigningFromObjectToAnythingElse.ts(6,17): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/compiler/assigningFromObjectToAnythingElse.ts(8,5): error TS2322: Type 'Object' is not assignable to type 'Error'. The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? Property 'name' is missing in type 'Object'. @@ -21,14 +18,11 @@ tests/cases/compiler/assigningFromObjectToAnythingElse.ts(8,5): error TS2322: Ty !!! error TS2322: Property 'exec' is missing in type 'Object'. var a: String = Object.create(""); - ~ -!!! error TS2322: Type 'object | Object' is not assignable to type 'String'. -!!! error TS2322: Type 'object' is not assignable to type 'String'. -!!! error TS2322: Property 'charAt' is missing in type '{}'. + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. var c: String = Object.create(1); - ~ -!!! error TS2322: Type 'object | Number' is not assignable to type 'String'. -!!! error TS2322: Type 'object' is not assignable to type 'String'. + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. var w: Error = new Object(); ~ diff --git a/tests/baselines/reference/objectCreate.types b/tests/baselines/reference/objectCreate.types index 028c98af817..b4e0e72061e 100644 --- a/tests/baselines/reference/objectCreate.types +++ b/tests/baselines/reference/objectCreate.types @@ -7,19 +7,19 @@ declare var union: null | { a: number, b: string }; >b : string var n = Object.create(null); // object ->n : object ->Object.create(null) : object ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>n : any +>Object.create(null) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >null : null var t = Object.create({ a: 1, b: "" }); // {a: number, b: string } ->t : object | { a: number; b: string; } ->Object.create({ a: 1, b: "" }) : object | { a: number; b: string; } ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>t : any +>Object.create({ a: 1, b: "" }) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >{ a: 1, b: "" } : { a: number; b: string; } >a : number >1 : 1 @@ -27,45 +27,45 @@ var t = Object.create({ a: 1, b: "" }); // {a: number, b: string } >"" : "" var u = Object.create(union); // object | {a: number, b: string } ->u : object | { a: number; b: string; } ->Object.create(union) : object | { a: number; b: string; } ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>u : any +>Object.create(union) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >union : { a: number; b: string; } | null var e = Object.create({}); // {} ->e : object | {} ->Object.create({}) : object | {} ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>e : any +>Object.create({}) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >{} : {} var o = Object.create({}); // object ->o : object ->Object.create({}) : object ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>o : any +>Object.create({}) : any +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >{} : object >{} : {} var a = Object.create(null, {}); // any >a : any >Object.create(null, {}) : any ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >null : null >{} : {} var a = Object.create({ a: 1, b: "" }, {}); >a : any >Object.create({ a: 1, b: "" }, {}) : any ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >{ a: 1, b: "" } : { a: number; b: string; } >a : number >1 : 1 @@ -76,27 +76,27 @@ var a = Object.create({ a: 1, b: "" }, {}); var a = Object.create(union, {}); >a : any >Object.create(union, {}) : any ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >union : { a: number; b: string; } | null >{} : {} var a = Object.create({}, {}); >a : any >Object.create({}, {}) : any ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >{} : {} >{} : {} var a = Object.create({}, {}); >a : any >Object.create({}, {}) : any ->Object.create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T | null): object | T; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } >{} : object >{} : {} >{} : {} diff --git a/tests/baselines/reference/objectCreate2.types b/tests/baselines/reference/objectCreate2.types index 1b33723b0c9..3e19c08bfc0 100644 --- a/tests/baselines/reference/objectCreate2.types +++ b/tests/baselines/reference/objectCreate2.types @@ -9,17 +9,17 @@ declare var union: null | { a: number, b: string }; var n = Object.create(null); // any >n : any >Object.create(null) : any ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >null : null var t = Object.create({ a: 1, b: "" }); // {a: number, b: string } ->t : object | { a: number; b: string; } ->Object.create({ a: 1, b: "" }) : object | { a: number; b: string; } ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>t : any +>Object.create({ a: 1, b: "" }) : any +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >{ a: 1, b: "" } : { a: number; b: string; } >a : number >1 : 1 @@ -27,45 +27,45 @@ var t = Object.create({ a: 1, b: "" }); // {a: number, b: string } >"" : "" var u = Object.create(union); // {a: number, b: string } ->u : object | { a: number; b: string; } ->Object.create(union) : object | { a: number; b: string; } ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>u : any +>Object.create(union) : any +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >union : { a: number; b: string; } var e = Object.create({}); // {} ->e : object | {} ->Object.create({}) : object | {} ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>e : any +>Object.create({}) : any +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >{} : {} var o = Object.create({}); // object ->o : object ->Object.create({}) : object ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>o : any +>Object.create({}) : any +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >{} : object >{} : {} var a = Object.create(null, {}); // any >a : any >Object.create(null, {}) : any ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >null : null >{} : {} var a = Object.create({ a: 1, b: "" }, {}); >a : any >Object.create({ a: 1, b: "" }, {}) : any ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >{ a: 1, b: "" } : { a: number; b: string; } >a : number >1 : 1 @@ -76,27 +76,27 @@ var a = Object.create({ a: 1, b: "" }, {}); var a = Object.create(union, {}); >a : any >Object.create(union, {}) : any ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >union : { a: number; b: string; } >{} : {} var a = Object.create({}, {}); >a : any >Object.create({}, {}) : any ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >{} : {} >{} : {} var a = Object.create({}, {}); >a : any >Object.create({}, {}) : any ->Object.create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >Object : ObjectConstructor ->create : { (o: T): object | T; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } >{} : object >{} : {} >{} : {} From a4904935e0b2be0f7f49bc0de89921884b223614 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 17 Feb 2017 18:01:13 -0800 Subject: [PATCH 18/38] Fix for-await-of emit in async function --- src/compiler/transformers/esnext.ts | 22 ++++++++++++------- ...ter.asyncGenerators.classMethods.es2015.js | 9 ++++++++ ...mitter.asyncGenerators.classMethods.es5.js | 9 ++++++++ ...cGenerators.functionDeclarations.es2015.js | 7 ++++++ ...syncGenerators.functionDeclarations.es5.js | 7 ++++++ ...ncGenerators.functionExpressions.es2015.js | 7 ++++++ ...asyncGenerators.functionExpressions.es5.js | 7 ++++++ ...cGenerators.objectLiteralMethods.es2015.js | 7 ++++++ ...syncGenerators.objectLiteralMethods.es5.js | 7 ++++++ .../reference/emitter.forAwait.es2015.js | 14 ++++++++---- .../reference/emitter.forAwait.es5.js | 18 ++++++++++----- 11 files changed, 96 insertions(+), 18 deletions(-) diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 482f37d45f9..971dddd20ea 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -357,10 +357,12 @@ namespace ts { const values = createAsyncValuesHelper(context, expression, /*location*/ node.expression); const next = createYield( /*asteriskToken*/ undefined, - createArrayLiteral([ - createLiteral("await"), - createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, []) - ]) + enclosingFunctionFlags & FunctionFlags.Generator + ? createArrayLiteral([ + createLiteral("await"), + createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, []) + ]) + : createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, []) ); hoistVariableDeclaration(errorRecord); @@ -431,10 +433,12 @@ namespace ts { createStatement( createYield( /*asteriskToken*/ undefined, - createArrayLiteral([ - createLiteral("await"), - createFunctionCall(returnMethod, iterator, []) - ]) + enclosingFunctionFlags & FunctionFlags.Generator + ? createArrayLiteral([ + createLiteral("await"), + createFunctionCall(returnMethod, iterator, []) + ]) + : createFunctionCall(returnMethod, iterator, []) ) ) ), @@ -872,6 +876,7 @@ namespace ts { scoped: false, text: ` var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -932,6 +937,7 @@ namespace ts { scoped: false, text: ` var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js index 2edcfd99e4b..ba4902102b1 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js @@ -62,6 +62,7 @@ class C9 extends B9 { //// [C1.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -81,6 +82,7 @@ class C1 { } //// [C2.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -101,6 +103,7 @@ class C2 { } //// [C3.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -126,6 +129,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -146,6 +150,7 @@ class C4 { } //// [C5.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -171,6 +176,7 @@ class C5 { } //// [C6.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -191,6 +197,7 @@ class C6 { } //// [C7.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -211,6 +218,7 @@ class C7 { } //// [C8.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -233,6 +241,7 @@ class C8 { } //// [C9.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js index 2b296936368..74a65673e5a 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js @@ -89,6 +89,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -141,6 +142,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -199,6 +201,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -262,6 +265,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -330,6 +334,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -410,6 +415,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -468,6 +474,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -520,6 +527,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -585,6 +593,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js index 97df064bbe8..2b0d6db5353 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js @@ -31,6 +31,7 @@ async function * f7() { //// [F1.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -48,6 +49,7 @@ function f1() { } //// [F2.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -66,6 +68,7 @@ function f2() { } //// [F3.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -89,6 +92,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -107,6 +111,7 @@ function f4() { } //// [F5.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -130,6 +135,7 @@ function f5() { } //// [F6.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -148,6 +154,7 @@ function f6() { } //// [F7.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js index 2a1b4393a9b..42098455ed1 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js @@ -58,6 +58,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -105,6 +106,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -158,6 +160,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -216,6 +219,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -279,6 +283,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -354,6 +359,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -407,6 +413,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js index bc64f029289..90f4b70e9bd 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js @@ -31,6 +31,7 @@ const f7 = async function * () { //// [F1.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -48,6 +49,7 @@ const f1 = function () { }; //// [F2.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -66,6 +68,7 @@ const f2 = function () { }; //// [F3.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -89,6 +92,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -107,6 +111,7 @@ const f4 = function () { }; //// [F5.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -130,6 +135,7 @@ const f5 = function () { }; //// [F6.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -148,6 +154,7 @@ const f6 = function () { }; //// [F7.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js index 9593562987b..a6265063fde 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js @@ -58,6 +58,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -105,6 +106,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -158,6 +160,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -216,6 +219,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -279,6 +283,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -354,6 +359,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -407,6 +413,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js index 3d3af24d030..817b3904f02 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js @@ -45,6 +45,7 @@ const o7 = { //// [O1.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -64,6 +65,7 @@ const o1 = { }; //// [O2.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -84,6 +86,7 @@ const o2 = { }; //// [O3.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -109,6 +112,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -129,6 +133,7 @@ const o4 = { }; //// [O5.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -154,6 +159,7 @@ const o5 = { }; //// [O6.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -174,6 +180,7 @@ const o6 = { }; //// [O7.js] var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js index f819945f288..a0839d8258d 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js @@ -72,6 +72,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -121,6 +122,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -176,6 +178,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -236,6 +239,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -301,6 +305,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -378,6 +383,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -433,6 +439,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.forAwait.es2015.js b/tests/baselines/reference/emitter.forAwait.es2015.js index bfd44581b82..a76c3e0b545 100644 --- a/tests/baselines/reference/emitter.forAwait.es2015.js +++ b/tests/baselines/reference/emitter.forAwait.es2015.js @@ -35,6 +35,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; @@ -42,14 +43,14 @@ function f1() { return __awaiter(this, void 0, void 0, function* () { let y; try { - for (var y_1 = __asyncValues(y), y_1_1 = yield ["await", y_1.next()]; !y_1_1.done; y_1_1 = yield ["await", y_1.next()]) { + for (var y_1 = __asyncValues(y), y_1_1 = yield y_1.next(); !y_1_1.done; y_1_1 = yield y_1.next()) { const x = y_1_1.value; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { - if (y_1_1 && !y_1_1.done && (_a = y_1.return)) yield ["await", _a.call(y_1)]; + if (y_1_1 && !y_1_1.done && (_a = y_1.return)) yield _a.call(y_1); } finally { if (e_1) throw e_1.error; } } @@ -66,6 +67,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; @@ -73,14 +75,14 @@ function f2() { return __awaiter(this, void 0, void 0, function* () { let x, y; try { - for (var y_1 = __asyncValues(y), y_1_1 = yield ["await", y_1.next()]; !y_1_1.done; y_1_1 = yield ["await", y_1.next()]) { + for (var y_1 = __asyncValues(y), y_1_1 = yield y_1.next(); !y_1_1.done; y_1_1 = yield y_1.next()) { x = y_1_1.value; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { - if (y_1_1 && !y_1_1.done && (_a = y_1.return)) yield ["await", _a.call(y_1)]; + if (y_1_1 && !y_1_1.done && (_a = y_1.return)) yield _a.call(y_1); } finally { if (e_1) throw e_1.error; } } @@ -89,10 +91,12 @@ function f2() { } //// [file3.js] var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -124,10 +128,12 @@ function f3() { } //// [file4.js] var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } diff --git a/tests/baselines/reference/emitter.forAwait.es5.js b/tests/baselines/reference/emitter.forAwait.es5.js index 5b904cf10a7..efbbe872b3f 100644 --- a/tests/baselines/reference/emitter.forAwait.es5.js +++ b/tests/baselines/reference/emitter.forAwait.es5.js @@ -62,6 +62,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; @@ -73,7 +74,7 @@ function f1() { case 0: _c.trys.push([0, 6, 7, 12]); y_1 = __asyncValues(y); - return [4 /*yield*/, ["await", y_1.next()]]; + return [4 /*yield*/, y_1.next()]; case 1: y_1_1 = _c.sent(); _c.label = 2; @@ -81,7 +82,7 @@ function f1() { if (!!y_1_1.done) return [3 /*break*/, 5]; x = y_1_1.value; _c.label = 3; - case 3: return [4 /*yield*/, ["await", y_1.next()]]; + case 3: return [4 /*yield*/, y_1.next()]; case 4: y_1_1 = _c.sent(); return [3 /*break*/, 2]; @@ -93,7 +94,7 @@ function f1() { case 7: _c.trys.push([7, , 10, 11]); if (!(y_1_1 && !y_1_1.done && (_b = y_1.return))) return [3 /*break*/, 9]; - return [4 /*yield*/, ["await", _b.call(y_1)]]; + return [4 /*yield*/, _b.call(y_1)]; case 8: _c.sent(); _c.label = 9; @@ -144,6 +145,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; @@ -155,7 +157,7 @@ function f2() { case 0: _c.trys.push([0, 6, 7, 12]); y_1 = __asyncValues(y); - return [4 /*yield*/, ["await", y_1.next()]]; + return [4 /*yield*/, y_1.next()]; case 1: y_1_1 = _c.sent(); _c.label = 2; @@ -163,7 +165,7 @@ function f2() { if (!!y_1_1.done) return [3 /*break*/, 5]; x = y_1_1.value; _c.label = 3; - case 3: return [4 /*yield*/, ["await", y_1.next()]]; + case 3: return [4 /*yield*/, y_1.next()]; case 4: y_1_1 = _c.sent(); return [3 /*break*/, 2]; @@ -175,7 +177,7 @@ function f2() { case 7: _c.trys.push([7, , 10, 11]); if (!(y_1_1 && !y_1_1.done && (_b = y_1.return))) return [3 /*break*/, 9]; - return [4 /*yield*/, ["await", _b.call(y_1)]]; + return [4 /*yield*/, _b.call(y_1)]; case 8: _c.sent(); _c.label = 9; @@ -218,10 +220,12 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } @@ -304,10 +308,12 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; var __asyncValues = (this && this.__asyncIterator) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); }; var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), q = [], c, i; return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; } From bb86e9e291a9a592af2f2ce43ebbe0eb946b4a18 Mon Sep 17 00:00:00 2001 From: Jason Jarrett Date: Sun, 19 Feb 2017 22:14:39 -0800 Subject: [PATCH 19/38] Update protocol.ts --- src/server/protocol.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index d8faad28b10..c7d27d80d25 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -820,7 +820,7 @@ namespace ts.server.protocol { * Represents a file in external project. * External project is project whose set of files, compilation options and open\close state * is maintained by the client (i.e. if all this data come from .csproj file in Visual Studio). - * External project will exist even if all files in it are closed and should be closed explicity. + * External project will exist even if all files in it are closed and should be closed explicitly. * If external project includes one or more tsconfig.json/jsconfig.json files then tsserver will * create configured project for every config file but will maintain a link that these projects were created * as a result of opening external project so they should be removed once external project is closed. From a2f61a8041f0e539f656435aaaf956500236fb60 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 21 Feb 2017 10:27:50 -0800 Subject: [PATCH 20/38] handle the case when conversion of tsconfig.json failed (#14160) --- .../unittests/tsserverProjectSystem.ts | 27 +++++++++++++++++++ src/server/editorServices.ts | 4 +-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 92ec0b4ee0e..7446cc84deb 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -3035,6 +3035,33 @@ namespace ts.projectSystem { const inferredProject = projectService.inferredProjects[0]; assert.isTrue(inferredProject.containsFile(file1.path)); }); + + it("should be able to handle @types if input file list is empty", () => { + const f = { + path: "/a/app.ts", + content: "let x = 1" + }; + const config = { + path: "/a/tsconfig.json", + content: JSON.stringify({ + compiler: {}, + files: [] + }) + }; + const t1 = { + path: "/a/node_modules/@types/typings/index.d.ts", + content: `export * from "./lib"` + }; + const t2 = { + path: "/a/node_modules/@types/typings/lib.d.ts", + content: `export const x: number` + }; + const host = createServerHost([f, config, t1, t2], { currentDirectory: getDirectoryPath(f.path) }); + const projectService = createProjectService(host); + + projectService.openClientFile(f.path); + projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 }); + }); }); describe("reload", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 36aa3939c83..d0535e2f528 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -948,9 +948,9 @@ namespace ts.server { private openConfigFile(configFileName: NormalizedPath, clientFileName?: string): OpenConfigFileResult { const conversionResult = this.convertConfigFileContentToProjectOptions(configFileName); - const projectOptions = conversionResult.success + const projectOptions: ProjectOptions = conversionResult.success ? conversionResult.projectOptions - : { files: [], compilerOptions: {} }; + : { files: [], compilerOptions: {}, typeAcquisition: { enable: false } }; const project = this.createAndAddConfiguredProject(configFileName, projectOptions, conversionResult.configFileErrors, clientFileName); return { success: conversionResult.success, From c77ea9e9ea85373c324d67d42e0dae2276a28159 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 21 Feb 2017 13:59:33 -0800 Subject: [PATCH 21/38] ignore request for codefixes with no error codes (#14215) --- src/server/session.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/server/session.ts b/src/server/session.ts index 262ba8da1da..f1b373c4a90 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1412,6 +1412,9 @@ namespace ts.server { } private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): protocol.CodeAction[] | CodeAction[] { + if (args.errorCodes.length === 0) { + return undefined; + } const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); const scriptInfo = project.getScriptInfoForNormalizedPath(file); From 5bcbd7aabc8f25a8fbcb68aa8c9b44eaa88561fc Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 22 Feb 2017 16:15:16 -0800 Subject: [PATCH 22/38] instantiate generic this param correctly --- src/compiler/checker.ts | 15 +++++++++++++-- src/compiler/utilities.ts | 8 ++++++++ ...ClassDoesntImplementInheritedAbstractMember.ts | 4 ++-- .../fixClassIncorrectlyImplementsInterface.ts | 4 ++-- src/services/codefixes/helpers.ts | 14 +++----------- .../fourslash/codeFixClassExtendAbstractMethod.ts | 2 ++ .../codeFixClassExtendAbstractMethodThis.ts | 13 +++++++++++++ .../codeFixClassExtendAbstractPropertyThis.ts | 11 +++++++++++ ...plementInterfaceMethodThisAndSelfReference.ts} | 4 ++-- 9 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts create mode 100644 tests/cases/fourslash/codeFixClassExtendAbstractPropertyThis.ts rename tests/cases/fourslash/{codeFixClassImplementInterfaceMethodWithParams.ts => codeFixClassImplementInterfaceMethodThisAndSelfReference.ts} (71%) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 12b55aa818b..9698f0cf4f0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21106,7 +21106,15 @@ namespace ts { } if (isPartOfTypeNode(node)) { - return getTypeFromTypeNode(node); + let typeFromTypeNode = getTypeFromTypeNode(node); + + if (typeFromTypeNode && isExpressionWithTypeArgumentsInClassImplementsClause(node)) { + const containingClass = getContainingClass(node); + const classType = getTypeOfNode(containingClass) as InterfaceType; + typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType); + } + + return typeFromTypeNode; } if (isPartOfExpression(node)) { @@ -21116,7 +21124,10 @@ namespace ts { if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) { // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the // extends clause of a class. We handle that case here. - return getBaseTypes(getDeclaredTypeOfSymbol(getSymbolOfNode(node.parent.parent)))[0]; + const classNode = getContainingClass(node); + const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode)) as InterfaceType; classType; + const baseType = getBaseTypes(classType)[0]; baseType; + return baseType && getTypeWithThisArgument(baseType, classType.thisType); } if (isTypeDeclaration(node)) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 66bf693d831..9eb76405031 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3126,6 +3126,14 @@ namespace ts { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } + export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): boolean { + return node.kind === SyntaxKind.ExpressionWithTypeArguments + && node.parent + && (node.parent).token === SyntaxKind.ImplementsKeyword + && node.parent.parent + && isClassLike(node.parent.parent); + } + export function isEntityNameExpression(node: Expression): node is EntityNameExpression { return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression && isEntityNameExpression((node).expression); diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 22546e55ecc..16edce0a516 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -22,8 +22,8 @@ namespace ts.codefix { const classDecl = token.parent as ClassLikeDeclaration; const startPos = classDecl.members.pos; - const classType = checker.getTypeAtLocation(classDecl) as InterfaceType; - const instantiatedExtendsType = checker.getBaseTypes(classType)[0]; + const extendsNode = getClassExtendsHeritageClauseElement(classDecl); + const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode); // Note that this is ultimately derived from a map indexed by symbol names, // so duplicates cannot occur. diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 42488dc2aed..856a57c46b7 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -17,7 +17,7 @@ namespace ts.codefix { } const startPos: number = classDecl.members.pos; - const classType = checker.getTypeAtLocation(classDecl); + const classType = checker.getTypeAtLocation(classDecl) as InterfaceType; const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl); const hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, IndexKind.Number); @@ -25,7 +25,7 @@ namespace ts.codefix { const result: CodeAction[] = []; for (const implementedTypeNode of implementedTypeNodes) { - const implementedType = checker.getTypeFromTypeNode(implementedTypeNode) as InterfaceType; + const implementedType = checker.getTypeAtLocation(implementedTypeNode) as InterfaceType; // Note that this is ultimately derived from a map indexed by symbol names, // so duplicates cannot occur. const implementedTypeSymbols = checker.getPropertiesOfType(implementedType); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 45479e49474..d20fc0129cd 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -32,22 +32,14 @@ namespace ts.codefix { const name = declaration.name ? declaration.name.getText() : undefined; const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration)); - const typeAtNewDeclaration = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); + const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration); switch (declaration.kind) { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.PropertySignature: case SyntaxKind.PropertyDeclaration: - let typeString: string | undefined = undefined; - const typeAtOldDeclaration = checker.getTypeAtLocation(declaration); - if ((typeAtOldDeclaration as TypeParameter).isThisType) { - typeString = "this"; - } - else { - typeString = checker.typeToString(typeAtNewDeclaration, enclosingDeclaration, TypeFormatFlags.None); - } - + const typeString = checker.typeToString(type, enclosingDeclaration, TypeFormatFlags.None); return `${visibility}${name}: ${typeString};${newlineChar}`; case SyntaxKind.MethodSignature: @@ -59,7 +51,7 @@ namespace ts.codefix { // If there is more than one overload but no implementation signature // (eg: an abstract method or interface declaration), there is a 1-1 // correspondence of declarations and signatures. - const signatures = checker.getSignaturesOfType(typeAtNewDeclaration, SignatureKind.Call); + const signatures = checker.getSignaturesOfType(type, SignatureKind.Call); if (!(signatures && signatures.length > 0)) { return ""; } diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts index a657dfeb718..344a7ee3f2b 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts @@ -2,6 +2,7 @@ //// abstract class A { //// abstract f(a: number, b: string): boolean; +//// abstract f(a: number, b: string): this; //// abstract f(a: string, b: number): Function; //// abstract f(a: string): Function; //// } @@ -10,6 +11,7 @@ verify.rangeAfterCodeFix(` f(a: number, b: string): boolean; + f(a: number, b: string): this; f(a: string, b: number): Function; f(a: string): Function; f(a: any, b?: any) { diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts new file mode 100644 index 00000000000..55b3ad4b77e --- /dev/null +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts @@ -0,0 +1,13 @@ +/// + +//// abstract class A { +//// abstract f(): this; +//// } +//// +//// class C extends A {[| |]} + +verify.rangeAfterCodeFix(` + f(): this { + throw new Error('Method not implemented.'); + } +`); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractPropertyThis.ts b/tests/cases/fourslash/codeFixClassExtendAbstractPropertyThis.ts new file mode 100644 index 00000000000..de128ca1b79 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassExtendAbstractPropertyThis.ts @@ -0,0 +1,11 @@ +/// + +//// abstract class A { +//// abstract x: this; +//// } +//// +//// class C extends A {[| |]} + +verify.rangeAfterCodeFix(` + x: this; +`); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodWithParams.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts similarity index 71% rename from tests/cases/fourslash/codeFixClassImplementInterfaceMethodWithParams.ts rename to tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts index 0ee842975e0..95cc3476bf1 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMethodWithParams.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMethodThisAndSelfReference.ts @@ -1,14 +1,14 @@ /// //// interface I { -//// f(x: number, y: string): I +//// f(x: number, y: this): I //// } //// //// class C implements I {[| //// |]} verify.rangeAfterCodeFix(` -f(x: number,y: string): I { +f(x: number,y: this): I { throw new Error('Method not implemented.'); } `); From c8aa257a3009079c8d9b8147db1efbf3a49f8d6d Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 1 Mar 2017 07:57:34 -0800 Subject: [PATCH 23/38] Fix gulp-typescript usage now that it is set to latest --- Gulpfile.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 633a1387ab6..3d4bae39a32 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -390,7 +390,7 @@ gulp.task(builtLocalCompiler, false, [servicesFile], () => { .pipe(localCompilerProject()) .pipe(prependCopyright()) .pipe(sourcemaps.write(".")) - .pipe(gulp.dest(".")); + .pipe(gulp.dest("src/compiler")); }); gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => { @@ -422,7 +422,7 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => { file.path = nodeStandaloneDefinitionsFile; return content.replace(/declare (namespace|module) ts/g, 'declare module "typescript"'); })) - ]).pipe(gulp.dest(".")); + ]).pipe(gulp.dest("src/services")); }); // cancellationToken.js @@ -448,7 +448,7 @@ gulp.task(typingsInstallerJs, false, [servicesFile], () => { .pipe(cancellationTokenProject()) .pipe(prependCopyright()) .pipe(sourcemaps.write(".")) - .pipe(gulp.dest(".")); + .pipe(gulp.dest("src/server/typingsInstaller")); }); const serverFile = path.join(builtLocalDirectory, "tsserver.js"); @@ -461,7 +461,7 @@ gulp.task(serverFile, false, [servicesFile, typingsInstallerJs, cancellationToke .pipe(serverProject()) .pipe(prependCopyright()) .pipe(sourcemaps.write(".")) - .pipe(gulp.dest(".")); + .pipe(gulp.dest("src/server")); }); const tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js"); @@ -556,7 +556,7 @@ gulp.task(run, false, [servicesFile], () => { .pipe(sourcemaps.init()) .pipe(testProject()) .pipe(sourcemaps.write(".", { includeContent: false, sourceRoot: "../../" })) - .pipe(gulp.dest(".")); + .pipe(gulp.dest("src/harness")); }); const internalTests = "internal/"; @@ -778,7 +778,7 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo }); })) .pipe(sourcemaps.write(".", { includeContent: false })) - .pipe(gulp.dest(".")); + .pipe(gulp.dest("src/harness")); }); From 9ac2ea722db7db8d17bd200e1563ca20b5d88960 Mon Sep 17 00:00:00 2001 From: Magnus Hiie Date: Wed, 1 Mar 2017 18:48:08 +0200 Subject: [PATCH 24/38] Add insert...Braces Option to Server Protocol Closes #13275 --- lib/protocol.d.ts | 1 + src/server/protocol.ts | 1 + tests/cases/fourslash/fourslash.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/lib/protocol.d.ts b/lib/protocol.d.ts index 2fc15c3a256..e675ba87417 100644 --- a/lib/protocol.d.ts +++ b/lib/protocol.d.ts @@ -1742,6 +1742,7 @@ declare namespace ts.server.protocol { insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean; + insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean; insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean; insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; insertSpaceBeforeFunctionParenthesis?: boolean; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index c7d27d80d25..d054867cd1c 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2218,6 +2218,7 @@ namespace ts.server.protocol { insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean; + insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean; insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean; insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; insertSpaceBeforeFunctionParenthesis?: boolean; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 34afb71ec85..ab83752d93b 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -92,6 +92,7 @@ declare namespace FourSlashInterface { InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; + InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: boolean; InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean; InsertSpaceAfterTypeAssertion: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; From 6ad9fe146a9f80028ecc7b8abc9df7faf7d56824 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Wed, 1 Mar 2017 18:08:53 +0100 Subject: [PATCH 25/38] Add parent type to ExpressionWithTypeArguments --- src/compiler/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3d93907ae98..bce435a7e6f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1446,6 +1446,7 @@ export interface ExpressionWithTypeArguments extends TypeNode { kind: SyntaxKind.ExpressionWithTypeArguments; + parent?: HeritageClause; expression: LeftHandSideExpression; typeArguments?: NodeArray; } From 9bef19c54c629e8b4a109706ef8bfa118afd66f9 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 1 Mar 2017 09:19:47 -0800 Subject: [PATCH 26/38] Fix JsDoc tagname in tests --- tests/cases/fourslash/completionInJsDoc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/completionInJsDoc.ts b/tests/cases/fourslash/completionInJsDoc.ts index 5eca52743a4..cf8a448bf19 100644 --- a/tests/cases/fourslash/completionInJsDoc.ts +++ b/tests/cases/fourslash/completionInJsDoc.ts @@ -71,7 +71,7 @@ verify.completionListContains("@argument"); goTo.marker('10'); verify.completionListCount(40); -verify.completionListContains("@return"); +verify.completionListContains("@returns"); goTo.marker('11'); verify.completionListCount(40); From d878f80f90cc5376ec1f1198055d0e8634cf7f56 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 1 Mar 2017 11:23:49 -0800 Subject: [PATCH 27/38] more rigorous implements-clause check --- src/compiler/utilities.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9eb76405031..37fb48bef05 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3126,8 +3126,9 @@ namespace ts { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } - export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): boolean { + export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): node is ExpressionWithTypeArguments { return node.kind === SyntaxKind.ExpressionWithTypeArguments + && isEntityNameExpression((node as ExpressionWithTypeArguments).expression) && node.parent && (node.parent).token === SyntaxKind.ImplementsKeyword && node.parent.parent From 0261586d6e4384fbae32ccec76089c6bb1c79f2f Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 1 Mar 2017 11:27:59 -0800 Subject: [PATCH 28/38] cleanup --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9698f0cf4f0..d1990d03ac3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21125,8 +21125,8 @@ namespace ts { // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the // extends clause of a class. We handle that case here. const classNode = getContainingClass(node); - const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode)) as InterfaceType; classType; - const baseType = getBaseTypes(classType)[0]; baseType; + const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode)) as InterfaceType; + const baseType = getBaseTypes(classType)[0]; return baseType && getTypeWithThisArgument(baseType, classType.thisType); } From b5c6221e36c1e4d20300b07ebefcdcab9121b57c Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 1 Mar 2017 17:46:35 -0800 Subject: [PATCH 29/38] Address PR --- src/services/completions.ts | 56 +++++++++++++++++++++++-------------- src/services/jsDoc.ts | 43 ++++++++++++++-------------- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 1d446f0aa59..042312c1240 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -16,11 +16,16 @@ namespace ts.Completions { return undefined; } - const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName } = completionData; + const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag } = completionData; - if (isJsDocTagName) { + if (requestJsDocTagName) { // If the current position is a jsDoc tag name, only tag names should be provided for completion - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries(shouldAppendAtSignBeforeJsDocTagName) }; + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagNameCompletions() }; + } + + if (requestJsDocTag) { + // If the current position is a jsDoc tag, only tags should be provided for completion + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagCompletions() }; } const entries: CompletionEntry[] = []; @@ -54,7 +59,7 @@ namespace ts.Completions { } // Add keywords if this is not a member completion list - if (!isMemberCompletion && !isJsDocTagName) { + if (!isMemberCompletion && !(requestJsDocTag && requestJsDocTagName)) { addRange(entries, keywordCompletions); } @@ -814,13 +819,10 @@ namespace ts.Completions { function getCompletionData(typeChecker: TypeChecker, log: (message: string) => void, sourceFile: SourceFile, position: number) { const isJavaScriptFile = isSourceFileJavaScript(sourceFile); - let isJsDocTagName = false; - // This is for the case when users request completion in JsDoc without "@" - // i.e. - // /** - // * |completion here| - // **/ - let shouldAppendAtSignBeforeJsDocTagName = false; + // JsDoc tag-name is just the name of the JSDoc tagname (exclude "@") + let requestJsDocTagName = false; + // JsDoc tag includes both "@" and tag-name + let requestJsDocTag = false; let start = timestamp(); const currentToken = getTokenAtPosition(sourceFile, position); @@ -836,15 +838,27 @@ namespace ts.Completions { // The current position is next to the '@' sign, when no tag name being provided yet. // Provide a full list of tag names if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) { - isJsDocTagName = true; + requestJsDocTagName = true; } else { + // When completion is requested without "@", we will have check to make sure that + // there are no comments prefix the request position. We will only allow "*" and space. + // e.g + // /** |c| /* + // + // /** + // |c| + // */ + // + // /** + // * |c| + // */ + // + // /** + // * |c| + // */ const lineStart = getLineStartPositionForPosition(position, sourceFile); - shouldAppendAtSignBeforeJsDocTagName = sourceFile.text.substr(lineStart, position).indexOf("@") === -1; - - if (shouldAppendAtSignBeforeJsDocTagName) { - isJsDocTagName = true; - } + requestJsDocTag = !(sourceFile.text.substr(lineStart, position).match(/[^\*|\s|(/\*\*)]/)); } } @@ -855,7 +869,7 @@ namespace ts.Completions { const tag = getJsDocTagAtPosition(sourceFile, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { - isJsDocTagName = true; + requestJsDocTagName = true; } switch (tag.kind) { @@ -870,8 +884,8 @@ namespace ts.Completions { } } - if (isJsDocTagName || shouldAppendAtSignBeforeJsDocTagName) { - return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName }; + if (requestJsDocTagName || requestJsDocTag) { + return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag }; } if (!insideJsDocTagExpression) { @@ -999,7 +1013,7 @@ namespace ts.Completions { log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); - return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName, shouldAppendAtSignBeforeJsDocTagName }; + return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag }; function getTypeScriptMemberSymbols(): void { // Right of dot member completion list diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 40ee276b0fa..59c6ad4b03b 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -43,7 +43,7 @@ namespace ts.JsDoc { "version" ]; let jsDocTagNameCompletionEntries: CompletionEntry[]; - let jsDocTagNameWithAtSignCompletionEntries: CompletionEntry[]; + let jsDocTagCompletionEntries: CompletionEntry[]; export function getJsDocCommentsFromDeclarations(declarations: Declaration[]) { // Only collect doc comments from duplicate declarations once: @@ -89,27 +89,26 @@ namespace ts.JsDoc { return undefined; } - export function getAllJsDocCompletionEntries(shouldAppendAtSign: boolean): CompletionEntry[] { - if (!shouldAppendAtSign) { - return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, tagName => { - return { - name: tagName, - kind: ScriptElementKind.keyword, - kindModifiers: "", - sortText: "0", - }; - })); - } - else { - return jsDocTagNameWithAtSignCompletionEntries || (jsDocTagNameWithAtSignCompletionEntries = ts.map(jsDocTagNames, tagName => { - return { - name: `@${tagName}`, - kind: ScriptElementKind.keyword, - kindModifiers: "", - sortText: "0" - } - })); - } + export function getJSDocTagNameCompletions(): CompletionEntry[] { + return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, tagName => { + return { + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0", + }; + })); + } + + export function getJSDocTagCompletions(): CompletionEntry[] { + return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, tagName => { + return { + name: `@${tagName}`, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0" + } + })); } /** From 34b68095d213ed14a718afbb3074f73576d70189 Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 1 Mar 2017 17:46:46 -0800 Subject: [PATCH 30/38] Add more tests --- tests/cases/fourslash/completionInJsDoc.ts | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/cases/fourslash/completionInJsDoc.ts b/tests/cases/fourslash/completionInJsDoc.ts index cf8a448bf19..3fd92f42d52 100644 --- a/tests/cases/fourslash/completionInJsDoc.ts +++ b/tests/cases/fourslash/completionInJsDoc.ts @@ -36,6 +36,22 @@ //// * /*11*/ //// */ +//// /** +//// /*12*/ +//// */ + +//// /** +//// * /*13*/ +//// */ + +//// /** +//// * some comment /*14*/ +//// */ + +//// /** +//// * @param /*15*/ +//// */ + goTo.marker('1'); verify.completionListContains("constructor"); verify.completionListContains("param"); @@ -76,3 +92,17 @@ verify.completionListContains("@returns"); goTo.marker('11'); verify.completionListCount(40); verify.completionListContains("@argument"); + +goTo.marker('12'); +verify.completionListCount(40); +verify.completionListContains("@constructor"); + +goTo.marker('13'); +verify.completionListCount(40); +verify.completionListContains("@param"); + +goTo.marker('14'); +verify.completionListIsEmpty(); + +goTo.marker('15'); +verify.completionListIsEmpty(); \ No newline at end of file From da51f396955ffa416e37e985fc33f4cf35aebfe6 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 1 Mar 2017 21:11:34 -0800 Subject: [PATCH 31/38] FIx minor stuffs --- src/services/completions.ts | 4 ++-- tests/cases/fourslash/completionInJsDoc.ts | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 042312c1240..6a4ee3485de 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -59,7 +59,7 @@ namespace ts.Completions { } // Add keywords if this is not a member completion list - if (!isMemberCompletion && !(requestJsDocTag && requestJsDocTagName)) { + if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) { addRange(entries, keywordCompletions); } @@ -858,7 +858,7 @@ namespace ts.Completions { // * |c| // */ const lineStart = getLineStartPositionForPosition(position, sourceFile); - requestJsDocTag = !(sourceFile.text.substr(lineStart, position).match(/[^\*|\s|(/\*\*)]/)); + requestJsDocTag = !(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/)); } } diff --git a/tests/cases/fourslash/completionInJsDoc.ts b/tests/cases/fourslash/completionInJsDoc.ts index 3fd92f42d52..60707905956 100644 --- a/tests/cases/fourslash/completionInJsDoc.ts +++ b/tests/cases/fourslash/completionInJsDoc.ts @@ -35,22 +35,24 @@ //// /** //// * /*11*/ //// */ - +//// //// /** //// /*12*/ //// */ - +//// //// /** //// * /*13*/ //// */ - +//// //// /** //// * some comment /*14*/ //// */ - +//// //// /** //// * @param /*15*/ //// */ +//// +//// /** @param /*16*/ */ goTo.marker('1'); verify.completionListContains("constructor"); @@ -105,4 +107,7 @@ goTo.marker('14'); verify.completionListIsEmpty(); goTo.marker('15'); +verify.completionListIsEmpty(); + +goTo.marker('16'); verify.completionListIsEmpty(); \ No newline at end of file From 3bc125463b96314702a9b4b20ae58e63a0030e62 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 3 Mar 2017 07:00:52 -0800 Subject: [PATCH 32/38] Add more missing semicolons --- src/compiler/checker.ts | 2 +- src/compiler/declarationEmitter.ts | 2 +- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/transformer.ts | 4 ++-- src/compiler/transformers/module/module.ts | 2 +- src/compiler/types.ts | 2 +- src/harness/fourslash.ts | 4 ++-- src/harness/harness.ts | 2 +- src/harness/harnessLanguageService.ts | 2 +- src/harness/unittests/tsserverProjectSystem.ts | 8 ++++---- src/server/server.ts | 2 +- src/server/session.ts | 10 +++++----- src/server/watchGuard/watchGuard.ts | 2 +- src/services/jsDoc.ts | 2 +- 14 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 45ccdae1b41..c189475fd4d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -141,7 +141,7 @@ namespace ts { getAugmentedPropertiesOfType, getRootSymbols, getContextualType: node => { - node = getParseTreeNode(node, isExpression) + node = getParseTreeNode(node, isExpression); return node ? getContextualType(node) : undefined; }, getFullyQualifiedName, diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 12411cabd56..4a542ab30c7 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1164,7 +1164,7 @@ namespace ts { emitTypeParameters(node.typeParameters); const baseTypeNode = getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { - node.name + node.name; emitHeritageClause(node.name, [baseTypeNode], /*isImplementsList*/ false); } emitHeritageClause(node.name, getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true); diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 5bdc4621a34..1911605a0a6 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -675,7 +675,7 @@ namespace ts { } export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations { - return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /* jsOnly*/ false); + return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /*jsOnly*/ false); } /* @internal */ diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index b9a75015f41..d51fdb12ac3 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -121,13 +121,13 @@ namespace ts { enableEmitNotification, isSubstitutionEnabled, isEmitNotificationEnabled, - get onSubstituteNode() { return onSubstituteNode }, + get onSubstituteNode() { return onSubstituteNode; }, set onSubstituteNode(value) { Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed."); Debug.assert(value !== undefined, "Value must not be 'undefined'"); onSubstituteNode = value; }, - get onEmitNode() { return onEmitNode }, + get onEmitNode() { return onEmitNode; }, set onEmitNode(value) { Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed."); Debug.assert(value !== undefined, "Value must not be 'undefined'"); diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 72a3558b1a3..52c6db707c1 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1152,7 +1152,7 @@ namespace ts { createIdentifier("__esModule"), createLiteral(true) ) - ) + ); } else { statement = createStatement( diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4ffd44e6aa1..53d84118609 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3297,7 +3297,7 @@ } export interface PluginImport { - name: string + name: string; } export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike | PluginImport[]; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 77c58b8d8b7..2532a1875d9 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2136,7 +2136,7 @@ namespace FourSlash { const result = includeWhiteSpace ? actualText === expectedText - : this.removeWhitespace(actualText) === this.removeWhitespace(expectedText) + : this.removeWhitespace(actualText) === this.removeWhitespace(expectedText); if (!result) { this.raiseError(`Actual text doesn't match expected text. Actual:\n'${actualText}'\nExpected:\n'${expectedText}'`); @@ -2173,7 +2173,7 @@ namespace FourSlash { start: diagnostic.start, length: diagnostic.length, code: diagnostic.code - } + }; }); const dedupedDiagnositcs = ts.deduplicate(diagnosticsForCodeFix, ts.equalOwnProperties); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 3d9b64bd30c..23e8106864a 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1017,7 +1017,7 @@ namespace Harness { } else { if (!es6TestLibFileNameSourceFileMap.get(libFileName)) { - es6TestLibFileNameSourceFileMap.set(libFileName, createSourceFileAndAssertInvariants(libFileName, IO.readFile(libFileName), scriptTarget)) + es6TestLibFileNameSourceFileMap.set(libFileName, createSourceFileAndAssertInvariants(libFileName, IO.readFile(libFileName), scriptTarget)); } } } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 202b429fcbc..e7f32748570 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -779,7 +779,7 @@ namespace Harness.LanguageService { start: 0 }); return prev; - } + }; return proxy; } }), diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index d7e39652ed8..1531b18bb9d 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -3307,12 +3307,12 @@ namespace ts.projectSystem { isCancellationRequested: () => false, setRequest: requestId => { if (expectedRequestId === undefined) { - assert.isTrue(false, "unexpected call") + assert.isTrue(false, "unexpected call"); } assert.equal(requestId, expectedRequestId); }, resetRequest: noop - } + }; const session = createSession(host, /*typingsInstaller*/ undefined, /*projectServiceEventHandler*/ undefined, cancellationToken); expectedRequestId = session.getNextSeq(); @@ -3359,13 +3359,13 @@ namespace ts.projectSystem { currentId = requestId; }, resetRequest(requestId) { - assert.equal(requestId, currentId, "unexpected request id in cancellation") + assert.equal(requestId, currentId, "unexpected request id in cancellation"); currentId = undefined; }, isCancellationRequested() { return requestToCancel === currentId; } - } + }; })(); const host = createServerHost([f1, config]); const session = createSession(host, /*typingsInstaller*/ undefined, () => {}, cancellationToken); diff --git a/src/server/server.ts b/src/server/server.ts index 3badc2c2b50..2c68963ec5c 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -653,7 +653,7 @@ namespace ts.server { // this drive is unsafe - return no-op watcher return { close() { } }; } - } + }; } // Override sys.write because fs.writeSync is not reliable on Node 4 diff --git a/src/server/session.ts b/src/server/session.ts index f1b373c4a90..b5e7e44970d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -226,7 +226,7 @@ namespace ts.server { /** * Represents operation that can schedule its next step to be executed later. - * Scheduling is done via instance of NextStep. If on current step subsequent step was not scheduled - operation is assumed to be completed. + * Scheduling is done via instance of NextStep. If on current step subsequent step was not scheduled - operation is assumed to be completed. */ class MultistepOperation { private requestId: number; @@ -239,7 +239,7 @@ namespace ts.server { this.next = { immediate: action => this.immediate(action), delay: (ms, action) => this.delay(ms, action) - } + }; } public startNew(action: (next: NextStep) => void) { @@ -262,7 +262,7 @@ namespace ts.server { private immediate(action: () => void) { const requestId = this.requestId; - Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id") + Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id"); this.setImmediateId(this.operationHost.getServerHost().setImmediate(() => { this.immediateId = undefined; this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action)); @@ -271,7 +271,7 @@ namespace ts.server { private delay(ms: number, action: () => void) { const requestId = this.requestId; - Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id") + Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id"); this.setTimerHandle(this.operationHost.getServerHost().setTimeout(() => { this.timerHandle = undefined; this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action)); @@ -351,7 +351,7 @@ namespace ts.server { logError: (err, cmd) => this.logError(err, cmd), sendRequestCompletedEvent: requestId => this.sendRequestCompletedEvent(requestId), isCancellationRequested: () => cancellationToken.isCancellationRequested() - } + }; this.errorCheck = new MultistepOperation(multistepOperationHost); this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander); this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger); diff --git a/src/server/watchGuard/watchGuard.ts b/src/server/watchGuard/watchGuard.ts index 7a0307a9120..f57369aecb9 100644 --- a/src/server/watchGuard/watchGuard.ts +++ b/src/server/watchGuard/watchGuard.ts @@ -11,7 +11,7 @@ const fs: { watch(directoryName: string, options: any, callback: () => {}): any // This means that here we treat any result (success or exception) from fs.watch as success since it does not tear down the process. // The only case that should be considered as failure - when watchGuard process crashes. try { - const watcher = fs.watch(directoryName, { recursive: true }, () => ({})) + const watcher = fs.watch(directoryName, { recursive: true }, () => ({})); watcher.close(); } catch (_e) { diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 59c6ad4b03b..a2a32f95fa4 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -107,7 +107,7 @@ namespace ts.JsDoc { kind: ScriptElementKind.keyword, kindModifiers: "", sortText: "0" - } + }; })); } From b2f7d4797762412e57e58798ad5ccadeac748e8e Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 3 Mar 2017 08:54:41 -0800 Subject: [PATCH 33/38] Remove old commented-out code --- tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts b/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts index 0bc3c1ab89b..14c7b3caf1c 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsEnum1.ts @@ -19,6 +19,4 @@ /////*25*/eInstance1 = /*26*/constE./*27*/e2; /////*28*/eInstance1 = /*29*/constE./*30*/e3; -//goTo.marker("2"); -//verify.verifyQuickInfoDisplayParts("enum member", "", { start: 0, length: 2 }, /*displayParts*/[], /*documentation*/[]); verify.baselineQuickInfo(); From 65cea207dad1eb593fcc47454e29cc0735949687 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 3 Mar 2017 14:32:18 -0800 Subject: [PATCH 34/38] Use getTypeOfExpression when inferring variable type from initializer --- src/compiler/checker.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c189475fd4d..a4c0acc405d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16131,7 +16131,7 @@ namespace ts { } function checkDeclarationInitializer(declaration: VariableLikeDeclaration) { - const type = checkExpressionCached(declaration.initializer); + const type = getTypeOfExpression(declaration.initializer, /*cache*/ true); return getCombinedNodeFlags(declaration) & NodeFlags.Const || getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration) || isTypeAssertion(declaration.initializer) ? type : getWidenedLiteralType(type); @@ -16204,10 +16204,12 @@ namespace ts { // Returns the type of an expression. Unlike checkExpression, this function is simply concerned // with computing the type and may not fully check all contained sub-expressions for errors. - function getTypeOfExpression(node: Expression) { + // A cache argument of true indicates that if the function performs a full type check, it is ok + // to cache the result. + function getTypeOfExpression(node: Expression, cache?: boolean) { // Optimize for the common case of a call to a function with a single non-generic call // signature where we can just fetch the return type without checking the arguments. - if (node.kind === SyntaxKind.CallExpression && (node).expression.kind !== SyntaxKind.SuperKeyword) { + if (node.kind === SyntaxKind.CallExpression && (node).expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) { const funcType = checkNonNullExpression((node).expression); const signature = getSingleCallSignature(funcType); if (signature && !signature.typeParameters) { @@ -16217,7 +16219,7 @@ namespace ts { // Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions // should have a parameter that indicates whether full error checking is required such that // we can perform the optimizations locally. - return checkExpression(node); + return cache ? checkExpressionCached(node) : checkExpression(node); } // Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When From 6995055c861c2983acc9901da8c9b07779e27b92 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 3 Mar 2017 14:32:59 -0800 Subject: [PATCH 35/38] Accept new baselines --- .../reference/ambientRequireFunction.types | 2 +- .../controlFlowIterationErrors.errors.txt | 18 +----------------- ...implicitAnyFromCircularInference.errors.txt | 5 +---- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/tests/baselines/reference/ambientRequireFunction.types b/tests/baselines/reference/ambientRequireFunction.types index e0341d97ec3..7b01a59268f 100644 --- a/tests/baselines/reference/ambientRequireFunction.types +++ b/tests/baselines/reference/ambientRequireFunction.types @@ -3,7 +3,7 @@ const fs = require("fs"); >fs : typeof "fs" ->require("fs") : any +>require("fs") : typeof "fs" >require : (moduleName: string) => any >"fs" : "fs" diff --git a/tests/baselines/reference/controlFlowIterationErrors.errors.txt b/tests/baselines/reference/controlFlowIterationErrors.errors.txt index 1f090ccd35f..bc4b19b0602 100644 --- a/tests/baselines/reference/controlFlowIterationErrors.errors.txt +++ b/tests/baselines/reference/controlFlowIterationErrors.errors.txt @@ -6,15 +6,9 @@ tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(35,17): error Type 'string' is not assignable to type 'number'. tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(46,17): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(77,13): error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(77,26): error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'. - Type 'true' is not assignable to type 'string | number'. -tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,13): error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,26): error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'. - Type 'true' is not assignable to type 'string | number'. -==== tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts (8 errors) ==== +==== tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts (4 errors) ==== let cond: boolean; @@ -104,11 +98,6 @@ tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,26): error x = "0"; while (cond) { let y = asNumber(x); - ~ -!!! error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. - ~ -!!! error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'. -!!! error TS2345: Type 'true' is not assignable to type 'string | number'. x = y + 1; x; } @@ -120,11 +109,6 @@ tests/cases/conformance/controlFlow/controlFlowIterationErrors.ts(88,26): error while (cond) { x; let y = asNumber(x); - ~ -!!! error TS7022: 'y' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. - ~ -!!! error TS2345: Argument of type 'string | number | boolean' is not assignable to parameter of type 'string | number'. -!!! error TS2345: Type 'true' is not assignable to type 'string | number'. x = y + 1; x; } diff --git a/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt b/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt index bb43d96b003..7d4dfa2cf5e 100644 --- a/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt +++ b/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt @@ -7,11 +7,10 @@ tests/cases/compiler/implicitAnyFromCircularInference.ts(18,10): error TS7024: F tests/cases/compiler/implicitAnyFromCircularInference.ts(23,10): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. tests/cases/compiler/implicitAnyFromCircularInference.ts(26,10): error TS7023: 'h' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. tests/cases/compiler/implicitAnyFromCircularInference.ts(28,14): error TS7023: 'foo' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -tests/cases/compiler/implicitAnyFromCircularInference.ts(41,5): error TS7022: 's' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/compiler/implicitAnyFromCircularInference.ts(46,9): error TS7023: 'x' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -==== tests/cases/compiler/implicitAnyFromCircularInference.ts (11 errors) ==== +==== tests/cases/compiler/implicitAnyFromCircularInference.ts (10 errors) ==== // Error expected var a: typeof a; @@ -71,8 +70,6 @@ tests/cases/compiler/implicitAnyFromCircularInference.ts(46,9): error TS7023: 'x class C { // Error expected s = foo(this); - ~~~~~~~~~~~~~~ -!!! error TS7022: 's' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. } class D { From c2431ade0cf271d2cbec7b651f06030493ec23a8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 3 Mar 2017 14:33:07 -0800 Subject: [PATCH 36/38] Add regression test --- .../circularInferredTypeOfVariable.js | 44 +++++++++++++++++ .../circularInferredTypeOfVariable.symbols | 34 ++++++++++++++ .../circularInferredTypeOfVariable.types | 47 +++++++++++++++++++ .../circularInferredTypeOfVariable.ts | 20 ++++++++ 4 files changed, 145 insertions(+) create mode 100644 tests/baselines/reference/circularInferredTypeOfVariable.js create mode 100644 tests/baselines/reference/circularInferredTypeOfVariable.symbols create mode 100644 tests/baselines/reference/circularInferredTypeOfVariable.types create mode 100644 tests/cases/compiler/circularInferredTypeOfVariable.ts diff --git a/tests/baselines/reference/circularInferredTypeOfVariable.js b/tests/baselines/reference/circularInferredTypeOfVariable.js new file mode 100644 index 00000000000..38c5334761a --- /dev/null +++ b/tests/baselines/reference/circularInferredTypeOfVariable.js @@ -0,0 +1,44 @@ +//// [circularInferredTypeOfVariable.ts] + +// Repro from #14428 + +(async () => { + function foo(p: string[]): string[] { + return []; + } + + function bar(p: string[]): string[] { + return []; + } + + let a1: string[] | undefined = []; + + while (true) { + let a2 = foo(a1!); + a1 = await bar(a2); + } +}); + +//// [circularInferredTypeOfVariable.js] +// Repro from #14428 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +(() => __awaiter(this, void 0, void 0, function* () { + function foo(p) { + return []; + } + function bar(p) { + return []; + } + let a1 = []; + while (true) { + let a2 = foo(a1); + a1 = yield bar(a2); + } +})); diff --git a/tests/baselines/reference/circularInferredTypeOfVariable.symbols b/tests/baselines/reference/circularInferredTypeOfVariable.symbols new file mode 100644 index 00000000000..653978f0e83 --- /dev/null +++ b/tests/baselines/reference/circularInferredTypeOfVariable.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/circularInferredTypeOfVariable.ts === + +// Repro from #14428 + +(async () => { + function foo(p: string[]): string[] { +>foo : Symbol(foo, Decl(circularInferredTypeOfVariable.ts, 3, 14)) +>p : Symbol(p, Decl(circularInferredTypeOfVariable.ts, 4, 17)) + + return []; + } + + function bar(p: string[]): string[] { +>bar : Symbol(bar, Decl(circularInferredTypeOfVariable.ts, 6, 5)) +>p : Symbol(p, Decl(circularInferredTypeOfVariable.ts, 8, 17)) + + return []; + } + + let a1: string[] | undefined = []; +>a1 : Symbol(a1, Decl(circularInferredTypeOfVariable.ts, 12, 7)) + + while (true) { + let a2 = foo(a1!); +>a2 : Symbol(a2, Decl(circularInferredTypeOfVariable.ts, 15, 11)) +>foo : Symbol(foo, Decl(circularInferredTypeOfVariable.ts, 3, 14)) +>a1 : Symbol(a1, Decl(circularInferredTypeOfVariable.ts, 12, 7)) + + a1 = await bar(a2); +>a1 : Symbol(a1, Decl(circularInferredTypeOfVariable.ts, 12, 7)) +>bar : Symbol(bar, Decl(circularInferredTypeOfVariable.ts, 6, 5)) +>a2 : Symbol(a2, Decl(circularInferredTypeOfVariable.ts, 15, 11)) + } +}); diff --git a/tests/baselines/reference/circularInferredTypeOfVariable.types b/tests/baselines/reference/circularInferredTypeOfVariable.types new file mode 100644 index 00000000000..df227bd9ae0 --- /dev/null +++ b/tests/baselines/reference/circularInferredTypeOfVariable.types @@ -0,0 +1,47 @@ +=== tests/cases/compiler/circularInferredTypeOfVariable.ts === + +// Repro from #14428 + +(async () => { +>(async () => { function foo(p: string[]): string[] { return []; } function bar(p: string[]): string[] { return []; } let a1: string[] | undefined = []; while (true) { let a2 = foo(a1!); a1 = await bar(a2); }}) : () => Promise +>async () => { function foo(p: string[]): string[] { return []; } function bar(p: string[]): string[] { return []; } let a1: string[] | undefined = []; while (true) { let a2 = foo(a1!); a1 = await bar(a2); }} : () => Promise + + function foo(p: string[]): string[] { +>foo : (p: string[]) => string[] +>p : string[] + + return []; +>[] : undefined[] + } + + function bar(p: string[]): string[] { +>bar : (p: string[]) => string[] +>p : string[] + + return []; +>[] : undefined[] + } + + let a1: string[] | undefined = []; +>a1 : string[] +>[] : undefined[] + + while (true) { +>true : true + + let a2 = foo(a1!); +>a2 : string[] +>foo(a1!) : string[] +>foo : (p: string[]) => string[] +>a1! : string[] +>a1 : string[] + + a1 = await bar(a2); +>a1 = await bar(a2) : string[] +>a1 : string[] +>await bar(a2) : string[] +>bar(a2) : string[] +>bar : (p: string[]) => string[] +>a2 : string[] + } +}); diff --git a/tests/cases/compiler/circularInferredTypeOfVariable.ts b/tests/cases/compiler/circularInferredTypeOfVariable.ts new file mode 100644 index 00000000000..662b6bfc8d8 --- /dev/null +++ b/tests/cases/compiler/circularInferredTypeOfVariable.ts @@ -0,0 +1,20 @@ +// @target: es6 + +// Repro from #14428 + +(async () => { + function foo(p: string[]): string[] { + return []; + } + + function bar(p: string[]): string[] { + return []; + } + + let a1: string[] | undefined = []; + + while (true) { + let a2 = foo(a1!); + a1 = await bar(a2); + } +}); \ No newline at end of file From 56e2735f5677811d5b519e18b0a48d352c79f647 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 3 Mar 2017 14:57:14 -0800 Subject: [PATCH 37/38] Fix fourslash test --- tests/cases/fourslash/extendArrayInterfaceMember.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/extendArrayInterfaceMember.ts b/tests/cases/fourslash/extendArrayInterfaceMember.ts index ef3c06b2053..22aeed01f1d 100644 --- a/tests/cases/fourslash/extendArrayInterfaceMember.ts +++ b/tests/cases/fourslash/extendArrayInterfaceMember.ts @@ -10,7 +10,7 @@ verify.numberOfErrorsInCurrentFile(1); // - Supplied parameters do not match any signature of call target. // - Could not select overload for 'call' expression. -verify.quickInfoAt("y", "var y: any"); +verify.quickInfoAt("y", "var y: number"); goTo.eof(); edit.insert("interface Array { pop(def: T): T; }"); From b1520345bec020280c3cd8a38fca5f0d43f4761e Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Sun, 5 Mar 2017 15:41:47 -0800 Subject: [PATCH 38/38] use ES6 library when building tslint rules (#14474) --- Jakefile.js | 12 +++++++++--- scripts/parallel-lint.js | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index f8be7c2b671..4512aa23794 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -328,8 +328,14 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts if (opts.stripInternal) { options += " --stripInternal"; } - - options += " --target es5 --lib es5,scripthost --noUnusedLocals --noUnusedParameters"; + options += " --target es5"; + if (opts.lib) { + options += " --lib " + opts.lib + } + else { + options += " --lib es5,scripthost" + } + options += " --noUnusedLocals --noUnusedParameters"; var cmd = host + " " + compilerPath + " " + options + " "; cmd = cmd + sources.join(" "); @@ -1110,7 +1116,7 @@ desc("Compiles tslint rules to js"); task("build-rules", ["build-rules-start"].concat(tslintRulesOutFiles).concat(["build-rules-end"])); tslintRulesFiles.forEach(function (ruleFile, i) { compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, - { noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint") }); + { noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint"), lib: "es6" }); }); desc("Emit the start of the build-rules fold"); diff --git a/scripts/parallel-lint.js b/scripts/parallel-lint.js index aec9960ce47..2ac84667d6f 100644 --- a/scripts/parallel-lint.js +++ b/scripts/parallel-lint.js @@ -1,5 +1,6 @@ var tslint = require("tslint"); var fs = require("fs"); +var path = require("path"); function getLinterOptions() { return { @@ -9,7 +10,7 @@ function getLinterOptions() { }; } function getLinterConfiguration() { - return require("../tslint.json"); + return tslint.Configuration.loadConfigurationFromPath(path.join(__dirname, "../tslint.json")); } function lintFileContents(options, configuration, path, contents) {