From 8a8a412a7f24542a6b9ed1255ec7e67eadaa2c48 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 14 Jul 2015 16:51:22 -0700 Subject: [PATCH 01/85] Fix file endings. --- src/compiler/program.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 5ce4846b43b..ca12f6de03d 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -341,7 +341,7 @@ namespace ts { }); } - function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { + function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return runWithCancellationToken(() => { if (!isDeclarationFile(sourceFile)) { let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken); @@ -350,7 +350,7 @@ namespace ts { return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile); } }); - } + } function getOptionsDiagnostics(): Diagnostic[] { let allDiagnostics: Diagnostic[] = []; From b8b4c0f5d4a5b72f3418e502f97ef1ede6769ed9 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 14 Jul 2015 17:25:34 -0700 Subject: [PATCH 02/85] Bump version number. --- package.json | 2 +- src/compiler/program.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 82ab734d6f1..54162c53a57 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "1.5.3", + "version": "1.6.0", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/program.ts b/src/compiler/program.ts index ca12f6de03d..d79f617e1cf 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -8,7 +8,7 @@ namespace ts { /* @internal */ export let ioWriteTime = 0; /** The version of the TypeScript compiler release */ - export const version = "1.5.3"; + export const version = "1.6.0"; export function findConfigFile(searchPath: string): string { let fileName = "tsconfig.json"; From 86b84054506ce6669175141de9655482ed510241 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 14 Jul 2015 18:09:42 -0700 Subject: [PATCH 03/85] Add configureNightly script. --- .gitignore | 1 + scripts/configureNightly.ts | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 scripts/configureNightly.ts diff --git a/.gitignore b/.gitignore index 3147b8e8724..58a45545939 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ tests/baselines/reference/projectOutput/* tests/baselines/local/projectOutput/* tests/services/baselines/prototyping/local/* tests/services/browser/typescriptServices.js +scripts/configureNightly.js scripts/processDiagnosticMessages.d.ts scripts/processDiagnosticMessages.js scripts/importDefinitelyTypedTests.js diff --git a/scripts/configureNightly.ts b/scripts/configureNightly.ts new file mode 100644 index 00000000000..a0e30b007cf --- /dev/null +++ b/scripts/configureNightly.ts @@ -0,0 +1,69 @@ +/// + +/** + * A minimal description for a parsed package.json object. + */ +interface PackageJson { + name: string; + version: string; + keywords: string[]; +} + +function main(): void { + const sys = ts.sys; + if (sys.args.length < 2) { + sys.write("Usage:" + sys.newLine) + sys.write("\tnode configureNightly.js " + sys.newLine); + return; + } + + // Acquire the version from the package.json file and modify it appropriately. + const packageJsonFilePath = ts.normalizePath(sys.args[0]); + const packageJsonContents = sys.readFile(packageJsonFilePath); + const packageJsonValue: PackageJson = JSON.parse(packageJsonContents); + + const nightlyVersion = getNightlyVersionString(packageJsonValue.version); + + // Modify the package.json structure + packageJsonValue.version = nightlyVersion; + + if (packageJsonValue.name !== "typescript-nightly") { + packageJsonValue.name = "typescript-nightly"; + packageJsonValue.keywords.push("nightly", "alpha", "beta", "prerelease"); + } + + // Acquire and modify the source file that exposes the version string. + const tsFilePath = ts.normalizePath(sys.args[1]); + const tsFileContents = sys.readFile(tsFilePath); + const versionAssignmentRegExp = /export\s+const\s+version\s+=\s+".*";/; + const modifiedTsFileContents = tsFileContents.replace(versionAssignmentRegExp, `export const version = "${nightlyVersion}";`); + + // Ensure we are actually changing something - the user probably wants to know that the update failed. + if (tsFileContents === modifiedTsFileContents) { + throw `File '${tsFilePath}' did not contain pattern ${versionAssignmentRegExp}`; + } + + // Finally write the changes to disk. + sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4)) + sys.writeFile(tsFilePath, modifiedTsFileContents); +} + +function getNightlyVersionString(versionString: string): string { + // If the version string already contains "-nightly", + // then get the base string and update based on that. + const dashNightlyPos = versionString.indexOf("-nightly"); + if (dashNightlyPos >= 0) { + versionString = versionString.slice(0, dashNightlyPos); + } + + // We're going to append a representation of the current time at the end of the current version. + // String.prototype.toISOString() returns a 24-character string formatted as 'YYYY-MM-DDTHH:mm:ss.sssZ', + // but we'd prefer to just use hyphens as separators instead of 'T', ':', and '.'. + // The trailing 'Z' in this string can be removed; UTC time will always be implicit here. + const now = new Date(); + const timeStr = now.toISOString().slice(0, -1).replace(/:|T|\./g, "-"); + + return `${versionString}-nightly-${timeStr}`; +} + +main(); \ No newline at end of file From 230ccd6262115605b295802861da175b9f254580 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 15 Jul 2015 12:56:00 -0700 Subject: [PATCH 04/85] Added a 'publish-nightly' task to to the Jakefile. --- Jakefile.js | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index 33ad46c8b58..b1ec9f3024c 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -311,7 +311,7 @@ var processDiagnosticMessagesTs = path.join(scriptsDirectory, "processDiagnostic var diagnosticMessagesJson = path.join(compilerDirectory, "diagnosticMessages.json"); var diagnosticInfoMapTs = path.join(compilerDirectory, "diagnosticInformationMap.generated.ts"); -file(processDiagnosticMessagesTs) +file(processDiagnosticMessagesTs); // processDiagnosticMessages script compileFile(processDiagnosticMessagesJs, @@ -342,6 +342,65 @@ desc("Generates a diagnostic file in TypeScript based on an input JSON file"); task("generate-diagnostics", [diagnosticInfoMapTs]) +// Publish nightly +var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js"); +var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts"); +var packageJson = "package.json"; +var programTs = path.join(compilerDirectory, "program.ts") + +file(configureNightlyTs); + +compileFile(/*outfile*/configureNightlyJs, + /*sources*/ [configureNightlyTs], + /*prereqs*/ [configureNightlyTs], + /*prefixes*/ [], + /*useBuiltCompiler*/ false, + /*noOutFile*/ false, + /*generateDeclarations*/ false, + /*outDir*/ undefined, + /*preserveConstEnums*/ undefined, + /*keepComments*/ false, + /*noResolve*/ false, + /*stripInternal*/ false, + /*callback*/ function () { + var cmd = "node " + configureNightlyJs + " " + packageJson + " " + programTs; + console.log(cmd); + var ex = jake.createExec([cmd]); + // Add listeners for output and error + ex.addListener("stdout", function(output) { + process.stdout.write(output); + }); + ex.addListener("stderr", function(error) { + process.stderr.write(error); + }); + ex.addListener("cmdEnd", function() { + complete(); + }); + ex.run(); + }); + +task("setDebugModeTrue", function() { + useDebugMode = true; +}); + +desc("Configure, build, test, and publish the nightly release."); +task("publish-nightly", [configureNightlyJs, "LKG", "clean", "setDebugModeTrue", "runtests"], function () { + var cmd = "npm publish"; + console.log(cmd); + var ex = jake.createExec([cmd]); + // Add listeners for output and error + ex.addListener("stdout", function(output) { + process.stdout.write(output); + }); + ex.addListener("stderr", function(error) { + process.stderr.write(error); + }); + ex.addListener("cmdEnd", function() { + complete(); + }); + ex.run(); +}, {async: true}); + // Local target to build the compiler and services var tscFile = path.join(builtLocalDirectory, compilerFilename); compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false); From 50198247bbd8093923aead123617d9c0c1eae4db Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 15 Jul 2015 14:02:47 -0700 Subject: [PATCH 05/85] Use 'exec'. --- Jakefile.js | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index b1ec9f3024c..edfd14fc1af 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -365,18 +365,7 @@ compileFile(/*outfile*/configureNightlyJs, /*callback*/ function () { var cmd = "node " + configureNightlyJs + " " + packageJson + " " + programTs; console.log(cmd); - var ex = jake.createExec([cmd]); - // Add listeners for output and error - ex.addListener("stdout", function(output) { - process.stdout.write(output); - }); - ex.addListener("stderr", function(error) { - process.stderr.write(error); - }); - ex.addListener("cmdEnd", function() { - complete(); - }); - ex.run(); + exec(cmd, completeHandler, errorHandler) }); task("setDebugModeTrue", function() { @@ -387,18 +376,7 @@ desc("Configure, build, test, and publish the nightly release."); task("publish-nightly", [configureNightlyJs, "LKG", "clean", "setDebugModeTrue", "runtests"], function () { var cmd = "npm publish"; console.log(cmd); - var ex = jake.createExec([cmd]); - // Add listeners for output and error - ex.addListener("stdout", function(output) { - process.stdout.write(output); - }); - ex.addListener("stderr", function(error) { - process.stderr.write(error); - }); - ex.addListener("cmdEnd", function() { - complete(); - }); - ex.run(); + exec(cmd, completeHandler, errorHandler) }, {async: true}); // Local target to build the compiler and services From e2c16962f3308c852918edcb125b118aa0f37160 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 15 Jul 2015 17:38:51 -0700 Subject: [PATCH 06/85] Added tests. --- .../modules/defaultExportsCannotMerge01.ts | 31 +++++++++++++++++++ .../modules/defaultExportsCannotMerge02.ts | 19 ++++++++++++ .../modules/defaultExportsCannotMerge03.ts | 16 ++++++++++ 3 files changed, 66 insertions(+) create mode 100644 tests/cases/conformance/es6/modules/defaultExportsCannotMerge01.ts create mode 100644 tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts create mode 100644 tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts diff --git a/tests/cases/conformance/es6/modules/defaultExportsCannotMerge01.ts b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge01.ts new file mode 100644 index 00000000000..7caa9caf574 --- /dev/null +++ b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge01.ts @@ -0,0 +1,31 @@ +// @module: commonjs +// @target: ES5 + +// @filename: m1.ts +export default function Decl() { + return 0; +} + +export interface Decl { + p1: number; + p2: number; +} + +export namespace Decl { + export var x = 10; + export var y = 20; + + interface I { + } +} + +// @filename: m2.ts +import Entity from "m1" + +Entity(); + +var x: Entity; +var y: Entity.I; + +Entity.x; +Entity.y; \ No newline at end of file diff --git a/tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts new file mode 100644 index 00000000000..84172248e93 --- /dev/null +++ b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts @@ -0,0 +1,19 @@ +// @module: commonjs +// @target: ES5 + +// @filename: m1.ts +export default class foo { + +} + +export default function bar() { + +} + +var x = 10; +export default x; + +// @filename: m2.ts +import Entity from "m1" + +Entity(); \ No newline at end of file diff --git a/tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts new file mode 100644 index 00000000000..1e9c8dabc13 --- /dev/null +++ b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts @@ -0,0 +1,16 @@ +// @module: commonjs +// @target: ES5 + +// @filename: m1.ts +export default function foo() { + +} + +export default function bar() { + +} + +// @filename: m2.ts +import Entity from "m1" + +Entity(); \ No newline at end of file From 17593bf444f7a5b7843e71b02798008dd578c7b5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 15 Jul 2015 17:51:11 -0700 Subject: [PATCH 07/85] Accepted baselines. --- .../defaultExportsCannotMerge01.errors.txt | 43 ++++++++++++++++ .../reference/defaultExportsCannotMerge01.js | 49 +++++++++++++++++++ .../defaultExportsCannotMerge02.errors.txt | 31 ++++++++++++ .../reference/defaultExportsCannotMerge02.js | 35 +++++++++++++ .../defaultExportsCannotMerge03.errors.txt | 22 +++++++++ .../reference/defaultExportsCannotMerge03.js | 27 ++++++++++ 6 files changed, 207 insertions(+) create mode 100644 tests/baselines/reference/defaultExportsCannotMerge01.errors.txt create mode 100644 tests/baselines/reference/defaultExportsCannotMerge01.js create mode 100644 tests/baselines/reference/defaultExportsCannotMerge02.errors.txt create mode 100644 tests/baselines/reference/defaultExportsCannotMerge02.js create mode 100644 tests/baselines/reference/defaultExportsCannotMerge03.errors.txt create mode 100644 tests/baselines/reference/defaultExportsCannotMerge03.js diff --git a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt new file mode 100644 index 00000000000..6eece36e077 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt @@ -0,0 +1,43 @@ +tests/cases/conformance/es6/modules/m2.ts(5,8): error TS2304: Cannot find name 'Entity'. +tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. +tests/cases/conformance/es6/modules/m2.ts(8,8): error TS2339: Property 'x' does not exist on type '() => number'. +tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does not exist on type '() => number'. + + +==== tests/cases/conformance/es6/modules/m1.ts (0 errors) ==== + + export default function Decl() { + return 0; + } + + export interface Decl { + p1: number; + p2: number; + } + + export namespace Decl { + export var x = 10; + export var y = 20; + + interface I { + } + } + +==== tests/cases/conformance/es6/modules/m2.ts (4 errors) ==== + import Entity from "m1" + + Entity(); + + var x: Entity; + ~~~~~~ +!!! error TS2304: Cannot find name 'Entity'. + var y: Entity.I; + ~~~~~~ +!!! error TS2503: Cannot find namespace 'Entity'. + + Entity.x; + ~ +!!! error TS2339: Property 'x' does not exist on type '() => number'. + Entity.y; + ~ +!!! error TS2339: Property 'y' does not exist on type '() => number'. \ No newline at end of file diff --git a/tests/baselines/reference/defaultExportsCannotMerge01.js b/tests/baselines/reference/defaultExportsCannotMerge01.js new file mode 100644 index 00000000000..3e0a61d54d4 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge01.js @@ -0,0 +1,49 @@ +//// [tests/cases/conformance/es6/modules/defaultExportsCannotMerge01.ts] //// + +//// [m1.ts] + +export default function Decl() { + return 0; +} + +export interface Decl { + p1: number; + p2: number; +} + +export namespace Decl { + export var x = 10; + export var y = 20; + + interface I { + } +} + +//// [m2.ts] +import Entity from "m1" + +Entity(); + +var x: Entity; +var y: Entity.I; + +Entity.x; +Entity.y; + +//// [m1.js] +function Decl() { + return 0; +} +exports.default = Decl; +var Decl; +(function (Decl) { + Decl.x = 10; + Decl.y = 20; +})(Decl = exports.Decl || (exports.Decl = {})); +//// [m2.js] +var m1_1 = require("m1"); +m1_1.default(); +var x; +var y; +m1_1.default.x; +m1_1.default.y; diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt new file mode 100644 index 00000000000..7b49afe1a4e --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt @@ -0,0 +1,31 @@ +tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2300: Duplicate identifier 'foo'. +tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2300: Duplicate identifier 'bar'. +tests/cases/conformance/es6/modules/m1.ts(11,1): error TS2300: Duplicate identifier 'default'. +tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof foo' is not callable. Did you mean to include 'new'? + + +==== tests/cases/conformance/es6/modules/m1.ts (3 errors) ==== + + export default class foo { + ~~~ +!!! error TS2300: Duplicate identifier 'foo'. + + } + + export default function bar() { + ~~~ +!!! error TS2300: Duplicate identifier 'bar'. + + } + + var x = 10; + export default x; + ~~~~~~~~~~~~~~~~~ +!!! error TS2300: Duplicate identifier 'default'. + +==== tests/cases/conformance/es6/modules/m2.ts (1 errors) ==== + import Entity from "m1" + + Entity(); + ~~~~~~~~ +!!! error TS2348: Value of type 'typeof foo' is not callable. Did you mean to include 'new'? \ No newline at end of file diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.js b/tests/baselines/reference/defaultExportsCannotMerge02.js new file mode 100644 index 00000000000..54d4e284c71 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge02.js @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts] //// + +//// [m1.ts] + +export default class foo { + +} + +export default function bar() { + +} + +var x = 10; +export default x; + +//// [m2.ts] +import Entity from "m1" + +Entity(); + +//// [m1.js] +var foo = (function () { + function foo() { + } + return foo; +})(); +exports.default = foo; +function bar() { +} +exports.default = bar; +var x = 10; +exports.default = x; +//// [m2.js] +var m1_1 = require("m1"); +m1_1.default(); diff --git a/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt new file mode 100644 index 00000000000..51220ecfae2 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt @@ -0,0 +1,22 @@ +tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2393: Duplicate function implementation. +tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2393: Duplicate function implementation. + + +==== tests/cases/conformance/es6/modules/m1.ts (2 errors) ==== + + export default function foo() { + ~~~ +!!! error TS2393: Duplicate function implementation. + + } + + export default function bar() { + ~~~ +!!! error TS2393: Duplicate function implementation. + + } + +==== tests/cases/conformance/es6/modules/m2.ts (0 errors) ==== + import Entity from "m1" + + Entity(); \ No newline at end of file diff --git a/tests/baselines/reference/defaultExportsCannotMerge03.js b/tests/baselines/reference/defaultExportsCannotMerge03.js new file mode 100644 index 00000000000..cf9003a97c8 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge03.js @@ -0,0 +1,27 @@ +//// [tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts] //// + +//// [m1.ts] + +export default function foo() { + +} + +export default function bar() { + +} + +//// [m2.ts] +import Entity from "m1" + +Entity(); + +//// [m1.js] +function foo() { +} +exports.default = foo; +function bar() { +} +exports.default = bar; +//// [m2.js] +var m1_1 = require("m1"); +m1_1.default(); From b403da3ea22aecd722d4225b5618e24710e0ce98 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 15 Jul 2015 17:51:50 -0700 Subject: [PATCH 08/85] Removed baselines Ryan forgot to remove. --- .../reference/tsxAttributeResolution9.symbols | 47 ------------------ .../reference/tsxAttributeResolution9.types | 49 ------------------- 2 files changed, 96 deletions(-) delete mode 100644 tests/baselines/reference/tsxAttributeResolution9.symbols delete mode 100644 tests/baselines/reference/tsxAttributeResolution9.types diff --git a/tests/baselines/reference/tsxAttributeResolution9.symbols b/tests/baselines/reference/tsxAttributeResolution9.symbols deleted file mode 100644 index 081482d5d47..00000000000 --- a/tests/baselines/reference/tsxAttributeResolution9.symbols +++ /dev/null @@ -1,47 +0,0 @@ -=== tests/cases/conformance/jsx/react.d.ts === - -declare module JSX { ->JSX : Symbol(JSX, Decl(react.d.ts, 0, 0)) - - interface Element { } ->Element : Symbol(Element, Decl(react.d.ts, 1, 20)) - - interface IntrinsicElements { ->IntrinsicElements : Symbol(IntrinsicElements, Decl(react.d.ts, 2, 22)) - } - interface ElementAttributesProperty { ->ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(react.d.ts, 4, 2)) - - props; ->props : Symbol(props, Decl(react.d.ts, 5, 38)) - } -} - -interface Props { ->Props : Symbol(Props, Decl(react.d.ts, 8, 1)) - - foo: string; ->foo : Symbol(foo, Decl(react.d.ts, 10, 17)) -} - -=== tests/cases/conformance/jsx/file.tsx === -export class MyComponent { ->MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0)) - - render() { ->render : Symbol(render, Decl(file.tsx, 0, 26)) - } - - props: { foo: string; } ->props : Symbol(props, Decl(file.tsx, 2, 3)) ->foo : Symbol(foo, Decl(file.tsx, 4, 10)) -} - -; // ok ->MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0)) ->foo : Symbol(unknown) - -; // should be an error ->MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0)) ->foo : Symbol(unknown) - diff --git a/tests/baselines/reference/tsxAttributeResolution9.types b/tests/baselines/reference/tsxAttributeResolution9.types deleted file mode 100644 index 1b2c6d42389..00000000000 --- a/tests/baselines/reference/tsxAttributeResolution9.types +++ /dev/null @@ -1,49 +0,0 @@ -=== tests/cases/conformance/jsx/react.d.ts === - -declare module JSX { ->JSX : any - - interface Element { } ->Element : Element - - interface IntrinsicElements { ->IntrinsicElements : IntrinsicElements - } - interface ElementAttributesProperty { ->ElementAttributesProperty : ElementAttributesProperty - - props; ->props : any - } -} - -interface Props { ->Props : Props - - foo: string; ->foo : string -} - -=== tests/cases/conformance/jsx/file.tsx === -export class MyComponent { ->MyComponent : MyComponent - - render() { ->render : () => void - } - - props: { foo: string; } ->props : { foo: string; } ->foo : string -} - -; // ok -> : JSX.Element ->MyComponent : typeof MyComponent ->foo : any - -; // should be an error -> : JSX.Element ->MyComponent : typeof MyComponent ->foo : any - From 3e2928926ecfa92e9b0f9d256b1e045a0bae2f38 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 15 Jul 2015 18:04:05 -0700 Subject: [PATCH 09/85] Minor cleanup. --- src/compiler/checker.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8bafa7a38f..3536152ee35 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10661,9 +10661,6 @@ namespace ts { return; } - // Exports should be checked only if enclosing module contains both exported and non exported declarations. - // In case if all declarations are non-exported check is unnecessary. - // if localSymbol is defined on node then node itself is exported - check is required let symbol = node.localSymbol; if (!symbol) { @@ -10683,9 +10680,9 @@ namespace ts { // we use SymbolFlags.ExportValue, SymbolFlags.ExportType and SymbolFlags.ExportNamespace // to denote disjoint declarationSpaces (without making new enum type). - let exportedDeclarationSpaces: SymbolFlags = 0; - let nonExportedDeclarationSpaces: SymbolFlags = 0; - forEach(symbol.declarations, d => { + let exportedDeclarationSpaces = SymbolFlags.None; + let nonExportedDeclarationSpaces = SymbolFlags.None; + for (let d of symbol.declarations) { let declarationSpaces = getDeclarationSpaces(d); if (getEffectiveDeclarationFlags(d, NodeFlags.Export)) { exportedDeclarationSpaces |= declarationSpaces; @@ -10693,17 +10690,17 @@ namespace ts { else { nonExportedDeclarationSpaces |= declarationSpaces; } - }); + } let commonDeclarationSpace = exportedDeclarationSpaces & nonExportedDeclarationSpaces; if (commonDeclarationSpace) { // declaration spaces for exported and non-exported declarations intersect - forEach(symbol.declarations, d => { + for (let d of symbol.declarations) { if (getDeclarationSpaces(d) & commonDeclarationSpace) { error(d.name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(d.name)); } - }); + } } function getDeclarationSpaces(d: Declaration): SymbolFlags { From 89398e640dda9eeebe79a2e78751b10eb49c1dfd Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 16 Jul 2015 12:09:10 -0700 Subject: [PATCH 10/85] Added single quotes around the declaration name in an error. --- src/compiler/diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index a0a95d47c8c..c17a49484b8 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -293,7 +293,7 @@ namespace ts { Multiple_constructor_implementations_are_not_allowed: { code: 2392, category: DiagnosticCategory.Error, key: "Multiple constructor implementations are not allowed." }, Duplicate_function_implementation: { code: 2393, category: DiagnosticCategory.Error, key: "Duplicate function implementation." }, Overload_signature_is_not_compatible_with_function_implementation: { code: 2394, category: DiagnosticCategory.Error, key: "Overload signature is not compatible with function implementation." }, - Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: DiagnosticCategory.Error, key: "Individual declarations in merged declaration {0} must be all exported or all local." }, + Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: DiagnosticCategory.Error, key: "Individual declarations in merged declaration '{0}' must be all exported or all local." }, Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: { code: 2396, category: DiagnosticCategory.Error, key: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters." }, Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: { code: 2399, category: DiagnosticCategory.Error, key: "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference." }, Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: { code: 2400, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index acf4e74ae9f..d01084c1bc8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1161,7 +1161,7 @@ "category": "Error", "code": 2394 }, - "Individual declarations in merged declaration {0} must be all exported or all local.": { + "Individual declarations in merged declaration '{0}' must be all exported or all local.": { "category": "Error", "code": 2395 }, From d0fb339666c2f2c615987f40da8f55c8265dc38a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 16 Jul 2015 12:09:49 -0700 Subject: [PATCH 11/85] Accepted baselines. --- .../duplicateSymbolsExportMatching.errors.txt | 68 +++++++++---------- .../reference/innerModExport2.errors.txt | 8 +-- tests/baselines/reference/multivar.errors.txt | 8 +-- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/baselines/reference/duplicateSymbolsExportMatching.errors.txt b/tests/baselines/reference/duplicateSymbolsExportMatching.errors.txt index df4f8f13c31..85dd29b78a3 100644 --- a/tests/baselines/reference/duplicateSymbolsExportMatching.errors.txt +++ b/tests/baselines/reference/duplicateSymbolsExportMatching.errors.txt @@ -1,21 +1,21 @@ -tests/cases/compiler/duplicateSymbolsExportMatching.ts(24,15): error TS2395: Individual declarations in merged declaration I must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(25,22): error TS2395: Individual declarations in merged declaration I must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(26,22): error TS2395: Individual declarations in merged declaration E must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(27,15): error TS2395: Individual declarations in merged declaration E must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(32,12): error TS2395: Individual declarations in merged declaration inst must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(35,19): error TS2395: Individual declarations in merged declaration inst must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(42,9): error TS2395: Individual declarations in merged declaration v must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(43,16): error TS2395: Individual declarations in merged declaration v must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(44,9): error TS2395: Individual declarations in merged declaration w must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(45,16): error TS2395: Individual declarations in merged declaration w must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(49,12): error TS2395: Individual declarations in merged declaration F must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(24,15): error TS2395: Individual declarations in merged declaration 'I' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(25,22): error TS2395: Individual declarations in merged declaration 'I' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(26,22): error TS2395: Individual declarations in merged declaration 'E' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(27,15): error TS2395: Individual declarations in merged declaration 'E' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(32,12): error TS2395: Individual declarations in merged declaration 'inst' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(35,19): error TS2395: Individual declarations in merged declaration 'inst' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(42,9): error TS2395: Individual declarations in merged declaration 'v' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(43,16): error TS2395: Individual declarations in merged declaration 'v' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(44,9): error TS2395: Individual declarations in merged declaration 'w' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(45,16): error TS2395: Individual declarations in merged declaration 'w' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(49,12): error TS2395: Individual declarations in merged declaration 'F' must be all exported or all local. tests/cases/compiler/duplicateSymbolsExportMatching.ts(49,12): error TS2434: A namespace declaration cannot be located prior to a class or function with which it is merged -tests/cases/compiler/duplicateSymbolsExportMatching.ts(52,21): error TS2395: Individual declarations in merged declaration F must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(56,11): error TS2395: Individual declarations in merged declaration C must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(57,12): error TS2395: Individual declarations in merged declaration C must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(58,19): error TS2395: Individual declarations in merged declaration C must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(64,11): error TS2395: Individual declarations in merged declaration D must be all exported or all local. -tests/cases/compiler/duplicateSymbolsExportMatching.ts(65,18): error TS2395: Individual declarations in merged declaration D must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(52,21): error TS2395: Individual declarations in merged declaration 'F' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(56,11): error TS2395: Individual declarations in merged declaration 'C' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(57,12): error TS2395: Individual declarations in merged declaration 'C' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(58,19): error TS2395: Individual declarations in merged declaration 'C' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(64,11): error TS2395: Individual declarations in merged declaration 'D' must be all exported or all local. +tests/cases/compiler/duplicateSymbolsExportMatching.ts(65,18): error TS2395: Individual declarations in merged declaration 'D' must be all exported or all local. ==== tests/cases/compiler/duplicateSymbolsExportMatching.ts (18 errors) ==== @@ -44,28 +44,28 @@ tests/cases/compiler/duplicateSymbolsExportMatching.ts(65,18): error TS2395: Ind module N2 { interface I { } ~ -!!! error TS2395: Individual declarations in merged declaration I must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'I' must be all exported or all local. export interface I { } // error ~ -!!! error TS2395: Individual declarations in merged declaration I must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'I' must be all exported or all local. export interface E { } ~ -!!! error TS2395: Individual declarations in merged declaration E must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'E' must be all exported or all local. interface E { } // error ~ -!!! error TS2395: Individual declarations in merged declaration E must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'E' must be all exported or all local. } // Should report error only once for instantiated module module M { module inst { ~~~~ -!!! error TS2395: Individual declarations in merged declaration inst must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'inst' must be all exported or all local. var t; } export module inst { // one error ~~~~ -!!! error TS2395: Individual declarations in merged declaration inst must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'inst' must be all exported or all local. var t; } } @@ -74,41 +74,41 @@ tests/cases/compiler/duplicateSymbolsExportMatching.ts(65,18): error TS2395: Ind module M2 { var v: string; ~ -!!! error TS2395: Individual declarations in merged declaration v must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'v' must be all exported or all local. export var v: string; // one error (visibility) ~ -!!! error TS2395: Individual declarations in merged declaration v must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'v' must be all exported or all local. var w: number; ~ -!!! error TS2395: Individual declarations in merged declaration w must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'w' must be all exported or all local. export var w: string; // two errors (visibility and type mismatch) ~ -!!! error TS2395: Individual declarations in merged declaration w must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'w' must be all exported or all local. } module M { module F { ~ -!!! error TS2395: Individual declarations in merged declaration F must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'F' must be all exported or all local. ~ !!! error TS2434: A namespace declaration cannot be located prior to a class or function with which it is merged var t; } export function F() { } // Only one error for duplicate identifier (don't consider visibility) ~ -!!! error TS2395: Individual declarations in merged declaration F must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'F' must be all exported or all local. } module M { class C { } ~ -!!! error TS2395: Individual declarations in merged declaration C must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'C' must be all exported or all local. module C { } ~ -!!! error TS2395: Individual declarations in merged declaration C must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'C' must be all exported or all local. export module C { // Two visibility errors (one for the clodule symbol, and one for the merged container symbol) ~ -!!! error TS2395: Individual declarations in merged declaration C must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'C' must be all exported or all local. var t; } } @@ -116,7 +116,7 @@ tests/cases/compiler/duplicateSymbolsExportMatching.ts(65,18): error TS2395: Ind // Top level interface D { } ~ -!!! error TS2395: Individual declarations in merged declaration D must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'D' must be all exported or all local. export interface D { } ~ -!!! error TS2395: Individual declarations in merged declaration D must be all exported or all local. \ No newline at end of file +!!! error TS2395: Individual declarations in merged declaration 'D' must be all exported or all local. \ No newline at end of file diff --git a/tests/baselines/reference/innerModExport2.errors.txt b/tests/baselines/reference/innerModExport2.errors.txt index 52a9d01c997..f9568bb45a4 100644 --- a/tests/baselines/reference/innerModExport2.errors.txt +++ b/tests/baselines/reference/innerModExport2.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/innerModExport2.ts(5,5): error TS2304: Cannot find name 'module'. tests/cases/compiler/innerModExport2.ts(5,12): error TS1005: ';' expected. -tests/cases/compiler/innerModExport2.ts(7,20): error TS2395: Individual declarations in merged declaration export_var must be all exported or all local. -tests/cases/compiler/innerModExport2.ts(13,9): error TS2395: Individual declarations in merged declaration export_var must be all exported or all local. +tests/cases/compiler/innerModExport2.ts(7,20): error TS2395: Individual declarations in merged declaration 'export_var' must be all exported or all local. +tests/cases/compiler/innerModExport2.ts(13,9): error TS2395: Individual declarations in merged declaration 'export_var' must be all exported or all local. tests/cases/compiler/innerModExport2.ts(20,7): error TS2339: Property 'NonExportFunc' does not exist on type 'typeof Outer'. @@ -18,7 +18,7 @@ tests/cases/compiler/innerModExport2.ts(20,7): error TS2339: Property 'NonExport var non_export_var = 0; export var export_var = 1; ~~~~~~~~~~ -!!! error TS2395: Individual declarations in merged declaration export_var must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'export_var' must be all exported or all local. function NonExportFunc() { return 0; } @@ -26,7 +26,7 @@ tests/cases/compiler/innerModExport2.ts(20,7): error TS2339: Property 'NonExport } var export_var: number; ~~~~~~~~~~ -!!! error TS2395: Individual declarations in merged declaration export_var must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'export_var' must be all exported or all local. export var outer_var_export = 0; export function outerFuncExport() { return 0; } diff --git a/tests/baselines/reference/multivar.errors.txt b/tests/baselines/reference/multivar.errors.txt index 931e61de5ae..44061b9d74c 100644 --- a/tests/baselines/reference/multivar.errors.txt +++ b/tests/baselines/reference/multivar.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/multivar.ts(6,19): error TS2395: Individual declarations in merged declaration b2 must be all exported or all local. -tests/cases/compiler/multivar.ts(22,9): error TS2395: Individual declarations in merged declaration b2 must be all exported or all local. +tests/cases/compiler/multivar.ts(6,19): error TS2395: Individual declarations in merged declaration 'b2' must be all exported or all local. +tests/cases/compiler/multivar.ts(22,9): error TS2395: Individual declarations in merged declaration 'b2' must be all exported or all local. ==== tests/cases/compiler/multivar.ts (2 errors) ==== @@ -10,7 +10,7 @@ tests/cases/compiler/multivar.ts(22,9): error TS2395: Individual declarations in export var a, b2: number = 10, b; ~~ -!!! error TS2395: Individual declarations in merged declaration b2 must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'b2' must be all exported or all local. var m1; var a2, b22: number = 10, b222; var m3; @@ -28,7 +28,7 @@ tests/cases/compiler/multivar.ts(22,9): error TS2395: Individual declarations in declare var d1, d2; var b2; ~~ -!!! error TS2395: Individual declarations in merged declaration b2 must be all exported or all local. +!!! error TS2395: Individual declarations in merged declaration 'b2' must be all exported or all local. declare var v1; } From 824293f5e4c8b3c9f26c601cfc45c4bc7ccaf63d Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 16 Jul 2015 13:40:36 -0700 Subject: [PATCH 12/85] Fix CRLF --- src/compiler/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e0f16a00c2b..9570617a106 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1774,10 +1774,10 @@ namespace ts { StringLike = String | StringLiteral, NumberLike = Number | Enum, ObjectType = Class | Interface | Reference | Tuple | Anonymous, - UnionOrIntersection = Union | Intersection, + UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, /* @internal */ - RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral + RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral } // Properties common to all types From 58cbf9171191ad2b0e4ac1ac6eb23e86fa7185ec Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 16 Jul 2015 13:41:19 -0700 Subject: [PATCH 13/85] Add check for super when extending null --- src/compiler/checker.ts | 12 +++++++++--- src/compiler/diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8bafa7a38f..634d64516a4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10248,19 +10248,25 @@ namespace ts { // TS 1.0 spec (April 2014): 8.3.2 // Constructors of classes with no extends clause may not contain super calls, whereas // constructors of derived classes must contain at least one super call somewhere in their function body. - if (getClassExtendsHeritageClauseElement(node.parent)) { + let containingClassDecl = node.parent; + if (getClassExtendsHeritageClauseElement(containingClassDecl)) { + let baseConstructorType = getBaseConstructorTypeOfClass(containingClassDecl); if (containsSuperCall(node.body)) { + if (baseConstructorType === nullType) { + error(node, Diagnostics.A_constructor_can_not_contain_super_call_when_a_class_extends_null); + } + // The first statement in the body of a constructor must be a super call if both of the following are true: // - The containing class is a derived class. // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. + let statements = (node.body).statements; let superCallShouldBeFirst = forEach((node.parent).members, isInstancePropertyWithInitializer) || forEach(node.parameters, p => p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)); if (superCallShouldBeFirst) { - let statements = (node.body).statements; if (!statements.length || statements[0].kind !== SyntaxKind.ExpressionStatement || !isSuperCallExpression((statements[0]).expression)) { error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties); } @@ -10270,7 +10276,7 @@ namespace ts { } } } - else { + else if (baseConstructorType !== nullType) { error(node, Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call); } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index a0a95d47c8c..80698217a4b 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -613,5 +613,6 @@ namespace ts { Expected_corresponding_JSX_closing_tag_for_0: { code: 17002, category: DiagnosticCategory.Error, key: "Expected corresponding JSX closing tag for '{0}'." }, JSX_attribute_expected: { code: 17003, category: DiagnosticCategory.Error, key: "JSX attribute expected." }, Cannot_use_JSX_unless_the_jsx_flag_is_provided: { code: 17004, category: DiagnosticCategory.Error, key: "Cannot use JSX unless the '--jsx' flag is provided." }, + A_constructor_can_not_contain_super_call_when_a_class_extends_null: { code: 17005, category: DiagnosticCategory.Error, key: "A constructor can not contain super call when a class extends null" }, }; } \ No newline at end of file diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index acf4e74ae9f..6f1185eb250 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2445,5 +2445,9 @@ "Cannot use JSX unless the '--jsx' flag is provided.": { "category": "Error", "code": 17004 + }, + "A constructor can not contain super call when a class extends null": { + "category": "Error", + "code": 17005 } } From 13aba26ced01b09a30cff6f012e70230c150684a Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 16 Jul 2015 13:41:39 -0700 Subject: [PATCH 14/85] Add tests and baseline --- .../reference/classExtendsNull.errors.txt | 21 +++++++++++ tests/baselines/reference/classExtendsNull.js | 35 +++++++++++++++++++ tests/cases/compiler/classExtendsNull.ts | 12 +++++++ 3 files changed, 68 insertions(+) create mode 100644 tests/baselines/reference/classExtendsNull.errors.txt create mode 100644 tests/baselines/reference/classExtendsNull.js create mode 100644 tests/cases/compiler/classExtendsNull.ts diff --git a/tests/baselines/reference/classExtendsNull.errors.txt b/tests/baselines/reference/classExtendsNull.errors.txt new file mode 100644 index 00000000000..93ef3b7765e --- /dev/null +++ b/tests/baselines/reference/classExtendsNull.errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor can not contain super call when a class extends null + + +==== tests/cases/compiler/classExtendsNull.ts (1 errors) ==== + class C extends null { + constructor() { + ~~~~~~~~~~~~~~~ + super(); + ~~~~~~~~~~~~~~~~ + return Object.create(null); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } + ~~~~~ +!!! error TS17005: A constructor can not contain super call when a class extends null + } + + class D extends null { + constructor() { + return Object.create(null); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/classExtendsNull.js b/tests/baselines/reference/classExtendsNull.js new file mode 100644 index 00000000000..5627f10dca6 --- /dev/null +++ b/tests/baselines/reference/classExtendsNull.js @@ -0,0 +1,35 @@ +//// [classExtendsNull.ts] +class C extends null { + constructor() { + super(); + return Object.create(null); + } +} + +class D extends null { + constructor() { + return Object.create(null); + } +} + +//// [classExtendsNull.js] +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 C = (function (_super) { + __extends(C, _super); + function C() { + _super.call(this); + return Object.create(null); + } + return C; +})(null); +var D = (function (_super) { + __extends(D, _super); + function D() { + return Object.create(null); + } + return D; +})(null); diff --git a/tests/cases/compiler/classExtendsNull.ts b/tests/cases/compiler/classExtendsNull.ts new file mode 100644 index 00000000000..5532fa72702 --- /dev/null +++ b/tests/cases/compiler/classExtendsNull.ts @@ -0,0 +1,12 @@ +class C extends null { + constructor() { + super(); + return Object.create(null); + } +} + +class D extends null { + constructor() { + return Object.create(null); + } +} \ No newline at end of file From 90f3153eac46609f6fe5711f9201eca273548711 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 16 Jul 2015 17:43:15 -0700 Subject: [PATCH 15/85] Renamed tests. --- ...defaultExportsCannotMerge02.ts => multipleDefaultExports01.ts} | 0 ...defaultExportsCannotMerge03.ts => multipleDefaultExports02.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/cases/conformance/es6/modules/{defaultExportsCannotMerge02.ts => multipleDefaultExports01.ts} (100%) rename tests/cases/conformance/es6/modules/{defaultExportsCannotMerge03.ts => multipleDefaultExports02.ts} (100%) diff --git a/tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts b/tests/cases/conformance/es6/modules/multipleDefaultExports01.ts similarity index 100% rename from tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts rename to tests/cases/conformance/es6/modules/multipleDefaultExports01.ts diff --git a/tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts b/tests/cases/conformance/es6/modules/multipleDefaultExports02.ts similarity index 100% rename from tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts rename to tests/cases/conformance/es6/modules/multipleDefaultExports02.ts From a38dec0cdf7d90638e97ef0b0de3b5fa40805c9e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 16 Jul 2015 17:44:07 -0700 Subject: [PATCH 16/85] Renamed/accepted baselines. --- ...otMerge02.errors.txt => multipleDefaultExports01.errors.txt} | 0 ...faultExportsCannotMerge02.js => multipleDefaultExports01.js} | 2 +- ...otMerge03.errors.txt => multipleDefaultExports02.errors.txt} | 0 ...faultExportsCannotMerge03.js => multipleDefaultExports02.js} | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename tests/baselines/reference/{defaultExportsCannotMerge02.errors.txt => multipleDefaultExports01.errors.txt} (100%) rename tests/baselines/reference/{defaultExportsCannotMerge02.js => multipleDefaultExports01.js} (79%) rename tests/baselines/reference/{defaultExportsCannotMerge03.errors.txt => multipleDefaultExports02.errors.txt} (100%) rename tests/baselines/reference/{defaultExportsCannotMerge03.js => multipleDefaultExports02.js} (75%) diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt b/tests/baselines/reference/multipleDefaultExports01.errors.txt similarity index 100% rename from tests/baselines/reference/defaultExportsCannotMerge02.errors.txt rename to tests/baselines/reference/multipleDefaultExports01.errors.txt diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.js b/tests/baselines/reference/multipleDefaultExports01.js similarity index 79% rename from tests/baselines/reference/defaultExportsCannotMerge02.js rename to tests/baselines/reference/multipleDefaultExports01.js index 54d4e284c71..8faf33388c6 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge02.js +++ b/tests/baselines/reference/multipleDefaultExports01.js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts] //// +//// [tests/cases/conformance/es6/modules/multipleDefaultExports01.ts] //// //// [m1.ts] diff --git a/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt b/tests/baselines/reference/multipleDefaultExports02.errors.txt similarity index 100% rename from tests/baselines/reference/defaultExportsCannotMerge03.errors.txt rename to tests/baselines/reference/multipleDefaultExports02.errors.txt diff --git a/tests/baselines/reference/defaultExportsCannotMerge03.js b/tests/baselines/reference/multipleDefaultExports02.js similarity index 75% rename from tests/baselines/reference/defaultExportsCannotMerge03.js rename to tests/baselines/reference/multipleDefaultExports02.js index cf9003a97c8..faec7c9d2b4 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge03.js +++ b/tests/baselines/reference/multipleDefaultExports02.js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts] //// +//// [tests/cases/conformance/es6/modules/multipleDefaultExports02.ts] //// //// [m1.ts] From 005b8583f5c744d7e8797d1072245e608196df2f Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 17 Jul 2015 10:33:07 -0700 Subject: [PATCH 17/85] remove for-loops --- src/compiler/emitter.ts | 10 ++++++++++ src/services/services.ts | 28 ++++++++++++++++------------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9c8438565e7..6073c0c9421 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6764,6 +6764,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi return leadingComments; } + /** + * Removes all but the pinned or triple slash comments. + * @param ranges The array to be filtered + * @param onlyPinnedOrTripleSlashComments whether the filtering should be performed. + * + * This probably shouldn't be a parameter at all. It appears that in every call, the argument is + * precisely 'compilerOptions.removeComments'. + * + * How to fix this? + */ function filterComments(ranges: CommentRange[], onlyPinnedOrTripleSlashComments: boolean): CommentRange[] { // If we're removing comments, then we want to strip out all but the pinned or // triple slash comments. diff --git a/src/services/services.ts b/src/services/services.ts index c2432816f24..71dc03f35ce 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -260,26 +260,30 @@ namespace ts { } public getFirstToken(sourceFile?: SourceFile): Node { - let children = this.getChildren(); - for (let child of children) { - if (child.kind < SyntaxKind.FirstNode) { - return child; - } + let children = this.getChildren(); // why isn't sourceFile passed as an argument?? + if (!(children && children.length > 0)) { return undefined; } - return child.getFirstToken(sourceFile); + let child = children[0]; + + if (child.kind < SyntaxKind.FirstNode) { + return child; } + + return child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFile): Node { let children = this.getChildren(sourceFile); - for (let i = children.length - 1; i >= 0; i--) { - let child = children[i]; - if (child.kind < SyntaxKind.FirstNode) { - return child; - } + if (!children) { return undefined; } - return child.getLastToken(sourceFile); + let child = lastOrUndefined(children); + if (!child) { return undefined; } + + if (child.kind < SyntaxKind.FirstNode) { + return child; } + + return child.getLastToken(sourceFile); } } From 4e8203d2953b6ffe44adecb480aeff4e0d9ef9a4 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 17 Jul 2015 10:48:54 -0700 Subject: [PATCH 18/85] fixed a comment --- src/compiler/emitter.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6073c0c9421..bb94bea1491 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6768,11 +6768,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi * Removes all but the pinned or triple slash comments. * @param ranges The array to be filtered * @param onlyPinnedOrTripleSlashComments whether the filtering should be performed. - * - * This probably shouldn't be a parameter at all. It appears that in every call, the argument is - * precisely 'compilerOptions.removeComments'. - * - * How to fix this? */ function filterComments(ranges: CommentRange[], onlyPinnedOrTripleSlashComments: boolean): CommentRange[] { // If we're removing comments, then we want to strip out all but the pinned or From a756b561c5eed5166e26a1f5c1f32ab116ca54a5 Mon Sep 17 00:00:00 2001 From: "shyyko.serhiy@gmail.com" Date: Fri, 17 Jul 2015 20:54:14 +0300 Subject: [PATCH 19/85] fixed issue #3859 --- src/compiler/checker.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7d022825ea7..e16eb3655d8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10260,7 +10260,8 @@ namespace ts { if (getClassExtendsHeritageClauseElement(node.parent)) { if (containsSuperCall(node.body)) { - // The first statement in the body of a constructor must be a super call if both of the following are true: + // The first statement in the body of a constructor must be a super call(or prologue directives followed by a super call) + // if both of the following are true: // - The containing class is a derived class. // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. @@ -10270,12 +10271,22 @@ namespace ts { if (superCallShouldBeFirst) { let statements = (node.body).statements; - if (!statements.length || statements[0].kind !== SyntaxKind.ExpressionStatement || !isSuperCallExpression((statements[0]).expression)) { - error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties); + let superCallStatement: ExpressionStatement; + for (let i = 0; i < statements.length; i++) { + let statement = statements[i]; + if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) { + superCallStatement = statement; + break; + } + if (!isPrologueDirective(statement)) { + break; + } } - else { + if (!superCallStatement) { + error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties); + } else { // In such a required super call, it is a compile-time error for argument expressions to reference this. - markThisReferencesAsErrors((statements[0]).expression); + markThisReferencesAsErrors(superCallStatement.expression); } } } From 62e08fc1ebea105bb85723557a71e8feeaad155a Mon Sep 17 00:00:00 2001 From: "shyyko.serhiy@gmail.com" Date: Fri, 17 Jul 2015 21:00:46 +0300 Subject: [PATCH 20/85] fixed strictModeInConstructor.error.txt baseline --- .../reference/strictModeInConstructor.errors.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/baselines/reference/strictModeInConstructor.errors.txt b/tests/baselines/reference/strictModeInConstructor.errors.txt index 11ba2e26a68..9a80732842a 100644 --- a/tests/baselines/reference/strictModeInConstructor.errors.txt +++ b/tests/baselines/reference/strictModeInConstructor.errors.txt @@ -1,8 +1,7 @@ -tests/cases/compiler/strictModeInConstructor.ts(9,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. -==== tests/cases/compiler/strictModeInConstructor.ts (2 errors) ==== +==== tests/cases/compiler/strictModeInConstructor.ts (1 errors) ==== class A { } @@ -12,14 +11,9 @@ tests/cases/compiler/strictModeInConstructor.ts(27,5): error TS2376: A 'super' c public s: number = 9; constructor () { - ~~~~~~~~~~~~~~~~ "use strict"; // No error - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ super(); - ~~~~~~~~~~~~~~~~ } - ~~~~~ -!!! error TS2376: A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties. } class C extends A { From 1ca17aba260367bb56a0b1bc65ddd1ca5bef9265 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 17 Jul 2015 11:20:51 -0700 Subject: [PATCH 21/85] Addressed Daniel's Comments --- src/services/services.ts | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 71dc03f35ce..0efab7ca149 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -260,30 +260,25 @@ namespace ts { } public getFirstToken(sourceFile?: SourceFile): Node { - let children = this.getChildren(); // why isn't sourceFile passed as an argument?? - if (!(children && children.length > 0)) { return undefined; } + let children = this.getChildren(sourceFile); + if (!(children.length > 0)) { + return undefined; + } let child = children[0]; - if (child.kind < SyntaxKind.FirstNode) { - return child; - } - - return child.getFirstToken(sourceFile); + return child.kind < SyntaxKind.FirstNode ? child : child.getFirstToken(sourceFile); } public getLastToken(sourceFile?: SourceFile): Node { let children = this.getChildren(sourceFile); - if (!children) { return undefined; } let child = lastOrUndefined(children); - if (!child) { return undefined; } - - if (child.kind < SyntaxKind.FirstNode) { - return child; + if (!child) { + return undefined; } - return child.getLastToken(sourceFile); + return child.kind < SyntaxKind.FirstNode ? child : child.getLastToken(sourceFile); } } From b4f82aa3f7f9cdec6c62f42e08a04d4205930c06 Mon Sep 17 00:00:00 2001 From: "shyyko.serhiy@gmail.com" Date: Sat, 18 Jul 2015 01:36:59 +0300 Subject: [PATCH 22/85] fixed indent issue, changed "for" loop to "for of" loop --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e16eb3655d8..dd5bbacaa3b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10272,8 +10272,7 @@ namespace ts { if (superCallShouldBeFirst) { let statements = (node.body).statements; let superCallStatement: ExpressionStatement; - for (let i = 0; i < statements.length; i++) { - let statement = statements[i]; + for (let statement of statements) { if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) { superCallStatement = statement; break; @@ -10284,7 +10283,8 @@ namespace ts { } if (!superCallStatement) { error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties); - } else { + } + else { // In such a required super call, it is a compile-time error for argument expressions to reference this. markThisReferencesAsErrors(superCallStatement.expression); } From 58cf926b2677a1c2f994beb5c42555210d1927e2 Mon Sep 17 00:00:00 2001 From: "shyyko.serhiy@gmail.com" Date: Sat, 18 Jul 2015 02:45:26 +0300 Subject: [PATCH 23/85] added comments --- src/compiler/checker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dd5bbacaa3b..81f6deaa09b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10260,7 +10260,7 @@ namespace ts { if (getClassExtendsHeritageClauseElement(node.parent)) { if (containsSuperCall(node.body)) { - // The first statement in the body of a constructor must be a super call(or prologue directives followed by a super call) + // The first statement in the body of a constructor (excluding prologue directives) must be a super call // if both of the following are true: // - The containing class is a derived class. // - The constructor declares parameter properties @@ -10269,6 +10269,8 @@ namespace ts { forEach((node.parent).members, isInstancePropertyWithInitializer) || forEach(node.parameters, p => p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)); + // Skip past any prologue directives to find the first statement + // to ensure that it was a super call. if (superCallShouldBeFirst) { let statements = (node.body).statements; let superCallStatement: ExpressionStatement; From ddd78fb609a9fa9062fc3d6315ef420478602aa6 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 20 Jul 2015 18:16:03 -0700 Subject: [PATCH 24/85] Fix crash when the element instance type was undefined --- src/compiler/checker.ts | 2 +- .../reference/jsxViaImport.errors.txt | 27 ++++++++++++ tests/baselines/reference/jsxViaImport.js | 43 +++++++++++++++++++ tests/cases/compiler/jsxViaImport.tsx | 23 ++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/jsxViaImport.errors.txt create mode 100644 tests/baselines/reference/jsxViaImport.js create mode 100644 tests/cases/compiler/jsxViaImport.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da45c08ab44..5fee3dd3a54 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7261,7 +7261,7 @@ namespace ts { if (links.jsxFlags & JsxFlags.ClassElement) { let elemInstanceType = getJsxElementInstanceType(node); - if (isTypeAny(elemInstanceType)) { + if (!elemInstanceType || isTypeAny(elemInstanceType)) { return links.resolvedJsxType = anyType; } diff --git a/tests/baselines/reference/jsxViaImport.errors.txt b/tests/baselines/reference/jsxViaImport.errors.txt new file mode 100644 index 00000000000..8fa22809a44 --- /dev/null +++ b/tests/baselines/reference/jsxViaImport.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/consumer.tsx(5,17): error TS2604: JSX element type 'BaseComponent' does not have any construct or call signatures. + + +==== tests/cases/compiler/consumer.tsx (1 errors) ==== + /// + import BaseComponent = require('BaseComponent'); + class TestComponent extends React.Component { + render() { + return ; + ~~~~~~~~~~~~~ +!!! error TS2604: JSX element type 'BaseComponent' does not have any construct or call signatures. + } + } + +==== tests/cases/compiler/component.d.ts (0 errors) ==== + + declare module JSX { + interface ElementAttributesProperty { props; } + } + declare module React { + class Component { } + } + declare module "BaseComponent" { + var base: React.Component; + export = base; + } + \ No newline at end of file diff --git a/tests/baselines/reference/jsxViaImport.js b/tests/baselines/reference/jsxViaImport.js new file mode 100644 index 00000000000..6bf61af67f5 --- /dev/null +++ b/tests/baselines/reference/jsxViaImport.js @@ -0,0 +1,43 @@ +//// [tests/cases/compiler/jsxViaImport.tsx] //// + +//// [component.d.ts] + +declare module JSX { + interface ElementAttributesProperty { props; } +} +declare module React { + class Component { } +} +declare module "BaseComponent" { + var base: React.Component; + export = base; +} + +//// [consumer.tsx] +/// +import BaseComponent = require('BaseComponent'); +class TestComponent extends React.Component { + render() { + return ; + } +} + + +//// [consumer.jsx] +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 BaseComponent = require('BaseComponent'); +var TestComponent = (function (_super) { + __extends(TestComponent, _super); + function TestComponent() { + _super.apply(this, arguments); + } + TestComponent.prototype.render = function () { + return ; + }; + return TestComponent; +})(React.Component); diff --git a/tests/cases/compiler/jsxViaImport.tsx b/tests/cases/compiler/jsxViaImport.tsx new file mode 100644 index 00000000000..5b3b7e11d83 --- /dev/null +++ b/tests/cases/compiler/jsxViaImport.tsx @@ -0,0 +1,23 @@ +//@jsx: preserve +//@module: commonjs + +//@filename: component.d.ts +declare module JSX { + interface ElementAttributesProperty { props; } +} +declare module React { + class Component { } +} +declare module "BaseComponent" { + var base: React.Component; + export = base; +} + +//@filename: consumer.tsx +/// +import BaseComponent = require('BaseComponent'); +class TestComponent extends React.Component { + render() { + return ; + } +} From d86fd85bd5423910afa8880aed7b136a4f1f0680 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 21 Jul 2015 11:35:05 -0700 Subject: [PATCH 25/85] Correctly identify identifiers inside JSX exprs as expression identifiers --- src/compiler/emitter.ts | 2 ++ .../reference/jsxImportInAttribute.js | 21 ++++++++++++++++++ .../reference/jsxImportInAttribute.symbols | 19 ++++++++++++++++ .../reference/jsxImportInAttribute.types | 22 +++++++++++++++++++ tests/cases/compiler/jsxImportInAttribute.tsx | 14 ++++++++++++ 5 files changed, 78 insertions(+) create mode 100644 tests/baselines/reference/jsxImportInAttribute.js create mode 100644 tests/baselines/reference/jsxImportInAttribute.symbols create mode 100644 tests/baselines/reference/jsxImportInAttribute.types create mode 100644 tests/cases/compiler/jsxImportInAttribute.tsx diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index fd0d4ad796e..3dd06ea4515 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1425,6 +1425,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi case SyntaxKind.IfStatement: case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxExpression: case SyntaxKind.NewExpression: case SyntaxKind.ParenthesizedExpression: case SyntaxKind.PostfixUnaryExpression: @@ -1484,6 +1485,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } else if (languageVersion < ScriptTarget.ES6) { + debugger; let declaration = resolver.getReferencedImportDeclaration(node); if (declaration) { if (declaration.kind === SyntaxKind.ImportClause) { diff --git a/tests/baselines/reference/jsxImportInAttribute.js b/tests/baselines/reference/jsxImportInAttribute.js new file mode 100644 index 00000000000..40b21e87c3f --- /dev/null +++ b/tests/baselines/reference/jsxImportInAttribute.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/jsxImportInAttribute.tsx] //// + +//// [component.d.ts] + +declare module "Test" { + export default class Text { } +} + +//// [consumer.tsx] +/// +import Test from 'Test'; + +let x = Test; // emit test_1.default +; // ? + + +//// [consumer.jsx] +/// +var Test_1 = require('Test'); +var x = Test_1["default"]; // emit test_1.default +; // ? diff --git a/tests/baselines/reference/jsxImportInAttribute.symbols b/tests/baselines/reference/jsxImportInAttribute.symbols new file mode 100644 index 00000000000..8481771f085 --- /dev/null +++ b/tests/baselines/reference/jsxImportInAttribute.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/consumer.tsx === +/// +import Test from 'Test'; +>Test : Symbol(Test, Decl(consumer.tsx, 1, 6)) + +let x = Test; // emit test_1.default +>x : Symbol(x, Decl(consumer.tsx, 3, 3)) +>Test : Symbol(Test, Decl(consumer.tsx, 1, 6)) + +; // ? +>attr : Symbol(unknown) + +=== tests/cases/compiler/component.d.ts === + +declare module "Test" { + export default class Text { } +>Text : Symbol(Text, Decl(component.d.ts, 1, 23)) +} + diff --git a/tests/baselines/reference/jsxImportInAttribute.types b/tests/baselines/reference/jsxImportInAttribute.types new file mode 100644 index 00000000000..8dfbe292fe0 --- /dev/null +++ b/tests/baselines/reference/jsxImportInAttribute.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/consumer.tsx === +/// +import Test from 'Test'; +>Test : typeof Test + +let x = Test; // emit test_1.default +>x : typeof Test +>Test : typeof Test + +; // ? +> : any +>anything : any +>attr : any +>Test : any + +=== tests/cases/compiler/component.d.ts === + +declare module "Test" { + export default class Text { } +>Text : Text +} + diff --git a/tests/cases/compiler/jsxImportInAttribute.tsx b/tests/cases/compiler/jsxImportInAttribute.tsx new file mode 100644 index 00000000000..c4f16f55ddb --- /dev/null +++ b/tests/cases/compiler/jsxImportInAttribute.tsx @@ -0,0 +1,14 @@ +//@jsx: preserve +//@module: commonjs + +//@filename: component.d.ts +declare module "Test" { + export default class Text { } +} + +//@filename: consumer.tsx +/// +import Test from 'Test'; + +let x = Test; // emit test_1.default +; // ? From 4ac078be0e086a43c225b0baacb738f1bc89f6ea Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 21 Jul 2015 12:32:24 -0700 Subject: [PATCH 26/85] Remove debugger statement --- src/compiler/emitter.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 3dd06ea4515..afafc983845 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1485,7 +1485,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } else if (languageVersion < ScriptTarget.ES6) { - debugger; let declaration = resolver.getReferencedImportDeclaration(node); if (declaration) { if (declaration.kind === SyntaxKind.ImportClause) { From 09caacd4cfceef2fb382689a58729f7ac9cd696d Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 21 Jul 2015 15:29:12 -0700 Subject: [PATCH 27/85] Move declarations to top of tests\cases\fourslash.ts --- tests/cases/fourslash/fourslash.ts | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index a0463073d8c..b963e9a573c 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -1,3 +1,21 @@ +/// + +// declare var FourSlash; +// module ts { +// export interface SymbolDisplayPart { +// text: string; +// kind: string; +// } +// } + +// DO NOT EDIT ABOVE THIS LINE! +// We want type-completion while we edit this file, but at compile time we don't want to include the above reference +// because we are compiling this file in "--out" mode and don't want to rope in the entire codebase +// for each fourslash test. +// So, the compile script manually modifies the aboce code so that we compile correctly. + +//--------------------------------------------- + // Welcome to the FourSlash syntax guide! // A line in the source text is indicated by four slashes (////) @@ -29,7 +47,7 @@ // type 'fs.' as an alternate way of accessing the top-level objects // (e.g. 'fs.goTo.eof();') -declare var FourSlash; +//--------------------------------------- // Return code used by getEmitOutput function to indicate status of the function // It is a duplicate of the one in types.ts to expose it to testcases in fourslash @@ -698,12 +716,7 @@ module fs { export var format = new FourSlashInterface.format(); export var cancellation = new FourSlashInterface.cancellation(); } -module ts { - export interface SymbolDisplayPart { - text: string; - kind: string; - } -} + function verifyOperationIsCancelled(f) { FourSlash.verifyOperationIsCancelled(f); } From b244d0d26307d3241453f6359c4dd3cb1cd339c6 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 21 Jul 2015 15:31:30 -0700 Subject: [PATCH 28/85] fixed a reference in a test --- tests/cases/fourslash/addDeclareToFunction.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/cases/fourslash/addDeclareToFunction.ts b/tests/cases/fourslash/addDeclareToFunction.ts index 46e5d123632..a31713fc56f 100644 --- a/tests/cases/fourslash/addDeclareToFunction.ts +++ b/tests/cases/fourslash/addDeclareToFunction.ts @@ -1,7 +1,8 @@ +/// + //// /*1*/function parseInt(s/*2*/:string):number; goTo.marker('2'); edit.deleteAtCaret(':string'.length); goTo.marker('1'); -edit.insert('declare '); - +edit.insert('declare '); \ No newline at end of file From 8e93a49c7b6e2e8b964b45a4d0ed651e1aecc182 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 21 Jul 2015 16:05:03 -0700 Subject: [PATCH 29/85] Narrow exported session API, Unit tests for session API --- Jakefile.js | 1 + src/harness/harness.ts | 1 + src/server/session.ts | 90 +++--- tests/cases/unittests/session.ts | 458 +++++++++++++++++++++++++++++++ 4 files changed, 505 insertions(+), 45 deletions(-) create mode 100644 tests/cases/unittests/session.ts diff --git a/Jakefile.js b/Jakefile.js index 33ad46c8b58..9ff73d5af14 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -136,6 +136,7 @@ var harnessSources = [ "services/documentRegistry.ts", "services/preProcessFile.ts", "services/patternMatcher.ts", + "session.ts", "versionCache.ts", "convertToBase64.ts", "transpile.ts" diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 9f26887ff90..cf81e172527 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -29,6 +29,7 @@ var Buffer: BufferConstructor = require('buffer').Buffer; // this will work in the browser via browserify var _chai: typeof chai = require('chai'); var assert: typeof _chai.assert = _chai.assert; +var expect: typeof _chai.expect = _chai.expect; declare var __dirname: string; // Node-specific var global = Function("return this").call(null); diff --git a/src/server/session.ts b/src/server/session.ts index e0c540db18b..47c605f5b47 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -109,13 +109,13 @@ namespace ts.server { } export class Session { - projectService: ProjectService; - pendingOperation = false; - fileHash: ts.Map = {}; - nextFileId = 1; - errorTimer: any; /*NodeJS.Timer | number*/ - immediateId: any; - changeSeq = 0; + protected projectService: ProjectService; + private pendingOperation = false; + private fileHash: ts.Map = {}; + private nextFileId = 1; + private errorTimer: any; /*NodeJS.Timer | number*/ + private immediateId: any; + private changeSeq = 0; constructor( private host: ServerHost, @@ -129,7 +129,7 @@ namespace ts.server { }); } - handleEvent(eventName: string, project: Project, fileName: string) { + private handleEvent(eventName: string, project: Project, fileName: string) { if (eventName == "context") { this.projectService.log("got context event, updating diagnostics for" + fileName, "Info"); this.updateErrorCheck([{ fileName, project }], this.changeSeq, @@ -137,7 +137,7 @@ namespace ts.server { } } - logError(err: Error, cmd: string) { + public logError(err: Error, cmd: string) { var typedErr = err; var msg = "Exception on executing command " + cmd; if (typedErr.message) { @@ -149,11 +149,11 @@ namespace ts.server { this.projectService.log(msg); } - sendLineToClient(line: string) { + private sendLineToClient(line: string) { this.host.write(line + this.host.newLine); } - send(msg: protocol.Message) { + public send(msg: protocol.Message) { var json = JSON.stringify(msg); if (this.logger.isVerbose()) { this.logger.info(msg.type + ": " + json); @@ -162,7 +162,7 @@ namespace ts.server { '\r\n\r\n' + json); } - event(info: any, eventName: string) { + public event(info: any, eventName: string) { var ev: protocol.Event = { seq: 0, type: "event", @@ -172,7 +172,7 @@ namespace ts.server { this.send(ev); } - response(info: any, cmdName: string, reqSeq = 0, errorMsg?: string) { + private response(info: any, cmdName: string, reqSeq = 0, errorMsg?: string) { var res: protocol.Response = { seq: 0, type: "response", @@ -189,11 +189,11 @@ namespace ts.server { this.send(res); } - output(body: any, commandName: string, requestSequence = 0, errorMessage?: string) { + public output(body: any, commandName: string, requestSequence = 0, errorMessage?: string) { this.response(body, commandName, requestSequence, errorMessage); } - semanticCheck(file: string, project: Project) { + private semanticCheck(file: string, project: Project) { try { var diags = project.compilerService.languageService.getSemanticDiagnostics(file); @@ -207,7 +207,7 @@ namespace ts.server { } } - syntacticCheck(file: string, project: Project) { + private syntacticCheck(file: string, project: Project) { try { var diags = project.compilerService.languageService.getSyntacticDiagnostics(file); if (diags) { @@ -220,12 +220,12 @@ namespace ts.server { } } - errorCheck(file: string, project: Project) { + private errorCheck(file: string, project: Project) { this.syntacticCheck(file, project); this.semanticCheck(file, project); } - updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) { + private updateProjectStructure(seq: number, matchSeq: (seq: number) => boolean, ms = 1500) { setTimeout(() => { if (matchSeq(seq)) { this.projectService.updateProjectStructure(); @@ -233,7 +233,7 @@ namespace ts.server { }, ms); } - updateErrorCheck(checkList: PendingErrorCheck[], seq: number, + private updateErrorCheck(checkList: PendingErrorCheck[], seq: number, matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) { if (followMs > ms) { followMs = ms; @@ -269,7 +269,7 @@ namespace ts.server { } } - getDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] { + private getDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -291,7 +291,7 @@ namespace ts.server { })); } - getTypeDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] { + private getTypeDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -313,7 +313,7 @@ namespace ts.server { })); } - getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{ + private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{ fileName = ts.normalizePath(fileName); let project = this.projectService.getProjectForFile(fileName); @@ -343,7 +343,7 @@ namespace ts.server { }); } - getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { + private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { fileName = ts.normalizePath(fileName) let project = this.projectService.getProjectForFile(fileName) @@ -358,7 +358,7 @@ namespace ts.server { return projectInfo; } - getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody { + private getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -426,7 +426,7 @@ namespace ts.server { return { info: renameInfo, locs: bakedRenameLocs }; } - getReferences(line: number, offset: number, fileName: string): protocol.ReferencesResponseBody { + private getReferences(line: number, offset: number, fileName: string): protocol.ReferencesResponseBody { // TODO: get all projects for this file; report refs for all projects deleting duplicates // can avoid duplicates by eliminating same ref file from subsequent projects var file = ts.normalizePath(fileName); @@ -473,12 +473,12 @@ namespace ts.server { }; } - openClientFile(fileName: string) { + private openClientFile(fileName: string) { var file = ts.normalizePath(fileName); this.projectService.openClientFile(file); } - getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody { + private getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -504,7 +504,7 @@ namespace ts.server { }; } - getFormattingEditsForRange(line: number, offset: number, endLine: number, endOffset: number, fileName: string): protocol.CodeEdit[] { + private getFormattingEditsForRange(line: number, offset: number, endLine: number, endOffset: number, fileName: string): protocol.CodeEdit[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -531,7 +531,7 @@ namespace ts.server { }); } - getFormattingEditsAfterKeystroke(line: number, offset: number, key: string, fileName: string): protocol.CodeEdit[] { + private getFormattingEditsAfterKeystroke(line: number, offset: number, key: string, fileName: string): protocol.CodeEdit[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); @@ -607,7 +607,7 @@ namespace ts.server { }); } - getCompletions(line: number, offset: number, prefix: string, fileName: string): protocol.CompletionEntry[] { + private getCompletions(line: number, offset: number, prefix: string, fileName: string): protocol.CompletionEntry[] { if (!prefix) { prefix = ""; } @@ -633,7 +633,7 @@ namespace ts.server { }, []).sort((a, b) => a.name.localeCompare(b.name)); } - getCompletionEntryDetails(line: number, offset: number, + private getCompletionEntryDetails(line: number, offset: number, entryNames: string[], fileName: string): protocol.CompletionEntryDetails[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); @@ -653,7 +653,7 @@ namespace ts.server { }, []); } - getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems { + private getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -682,7 +682,7 @@ namespace ts.server { return result; } - getDiagnostics(delay: number, fileNames: string[]) { + private getDiagnostics(delay: number, fileNames: string[]) { var checkList = fileNames.reduce((accum: PendingErrorCheck[], fileName: string) => { fileName = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(fileName); @@ -697,7 +697,7 @@ namespace ts.server { } } - change(line: number, offset: number, endLine: number, endOffset: number, insertString: string, fileName: string) { + private change(line: number, offset: number, endLine: number, endOffset: number, insertString: string, fileName: string) { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (project) { @@ -712,7 +712,7 @@ namespace ts.server { } } - reload(fileName: string, tempFileName: string, reqSeq = 0) { + private reload(fileName: string, tempFileName: string, reqSeq = 0) { var file = ts.normalizePath(fileName); var tmpfile = ts.normalizePath(tempFileName); var project = this.projectService.getProjectForFile(file); @@ -725,7 +725,7 @@ namespace ts.server { } } - saveToTmp(fileName: string, tempFileName: string) { + private saveToTmp(fileName: string, tempFileName: string) { var file = ts.normalizePath(fileName); var tmpfile = ts.normalizePath(tempFileName); @@ -735,12 +735,12 @@ namespace ts.server { } } - closeClientFile(fileName: string) { + private closeClientFile(fileName: string) { var file = ts.normalizePath(fileName); this.projectService.closeClientFile(file); } - decorateNavigationBarItem(project: Project, fileName: string, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] { + private decorateNavigationBarItem(project: Project, fileName: string, items: ts.NavigationBarItem[]): protocol.NavigationBarItem[] { if (!items) { return undefined; } @@ -759,7 +759,7 @@ namespace ts.server { })); } - getNavigationBarItems(fileName: string): protocol.NavigationBarItem[] { + private getNavigationBarItems(fileName: string): protocol.NavigationBarItem[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -775,7 +775,7 @@ namespace ts.server { return this.decorateNavigationBarItem(project, fileName, items); } - getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] { + private getNavigateToItems(searchValue: string, fileName: string, maxResultCount?: number): protocol.NavtoItem[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); if (!project) { @@ -814,7 +814,7 @@ namespace ts.server { }); } - getBraceMatching(line: number, offset: number, fileName: string): protocol.TextSpan[] { + private getBraceMatching(line: number, offset: number, fileName: string): protocol.TextSpan[] { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); @@ -836,7 +836,7 @@ namespace ts.server { })); } - exit() { + public exit() { } private handlers : Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = { @@ -942,14 +942,14 @@ namespace ts.server { return {response: this.getProjectInfo(file, needFileNameList)}; }, }; - addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) { + public addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) { if (this.handlers[command]) { throw new Error(`Protocol handler already exists for command "${command}"`); } this.handlers[command] = handler; } - executeCommand(request: protocol.Request) : {response?: any, responseRequired?: boolean} { + public executeCommand(request: protocol.Request) : {response?: any, responseRequired?: boolean} { var handler = this.handlers[request.command]; if (handler) { return handler(request); @@ -960,7 +960,7 @@ namespace ts.server { } } - onMessage(message: string) { + public onMessage(message: string) { if (this.logger.isVerbose()) { this.logger.info("request: " + message); var start = this.hrtime(); diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts new file mode 100644 index 00000000000..53353c12dda --- /dev/null +++ b/tests/cases/unittests/session.ts @@ -0,0 +1,458 @@ +/// + +module ts.server { + let lastWrittenToHost: string, + mockHost: ServerHost = { + args: [], + newLine: '\n', + useCaseSensitiveFileNames: true, + write: (s) => lastWrittenToHost = s, + readFile: () => void 0, + writeFile: () => void 0, + resolvePath: () => void 0, + fileExists: () => false, + directoryExists: () => false, + createDirectory: () => void 0, + getExecutingFilePath: () => void 0, + getCurrentDirectory: () => void 0, + readDirectory: () => void 0, + exit: () => void 0 + }, + mockLogger: Logger = { + close(): void {}, + isVerbose(): boolean { return false; }, + loggingEnabled(): boolean { return false; }, + perftrc(s: string): void {}, + info(s: string): void {}, + startGroup(): void {}, + endGroup(): void {}, + msg(s: string, type?: string): void {}, + }; + + describe('the Session class', () => { + let session:Session, + lastSent:protocol.Message; + + beforeEach(() => { + session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + session.send = (msg: protocol.Message) => { + lastSent = msg; + }; + }); + + describe('executeCommand', () => { + it('should throw when commands are executed with invalid arguments', () => { + let req : protocol.FileRequest = { + command: CommandNames.Open, + seq: 0, + type: 'command', + arguments: { + file: undefined + } + }; + + expect(() => session.executeCommand(req)).to.throw(); + }); + it('should output an error response when a command does not exist', () => { + let req : protocol.Request = { + command: 'foobar', + seq: 0, + type: 'command' + }; + + session.executeCommand(req); + + expect(lastSent).to.deep.equal({ + command: CommandNames.Unknown, + type: 'response', + seq: 0, + message: 'Unrecognized JSON command: foobar', + request_seq: 0, + success: false + }); + }); + it('should return a tuple containing the response and if a response is required on success', () => { + let req : protocol.ConfigureRequest = { + command: CommandNames.Configure, + seq: 0, + type: 'command', + arguments: { + hostInfo: 'unit test', + formatOptions: { + newLineCharacter: '`n' + } + } + }; + + expect(session.executeCommand(req)).to.deep.equal({ + responseRequired: false + }); + expect(lastSent).to.deep.equal({ + command: CommandNames.Configure, + type: 'response', + success: true, + request_seq: 0, + seq: 0, + body: undefined + }); + }); + }); + + describe('onMessage', () => { + it('should not throw when commands are executed with invalid arguments', () => { + let i = 0; + for (name in CommandNames) { + if (!Object.prototype.hasOwnProperty.call(CommandNames, name)) { + continue; + } + let req : protocol.Request = { + command: name, + seq: i++, + type: 'command' + }; + session.onMessage(JSON.stringify(req)); + req.seq+=2; + req.arguments = {}; + session.onMessage(JSON.stringify(req)); + req.seq+=2; + req.arguments = null; + session.onMessage(JSON.stringify(req)); + } + }); + it('should output the response for a correctly handled message', () => { + let req : protocol.ConfigureRequest = { + command: CommandNames.Configure, + seq: 0, + type: 'command', + arguments: { + hostInfo: 'unit test', + formatOptions: { + newLineCharacter: '`n' + } + } + }; + + session.onMessage(JSON.stringify(req)); + + expect(lastSent).to.deep.equal({ + command: CommandNames.Configure, + type: 'response', + success: true, + request_seq: 0, + seq: 0, + body: undefined + }); + }); + }); + + describe('exit', () => { + it('is a noop which can be handled by subclasses', () => { + session.exit(); //does nothing, should keep running tests + expect(session).to.exist; + }); + }); + + describe('send', () => { + it('is an overrideable handle which sends protocol messages over the wire', () => { + let msg = {seq: 0, type: 'none'}, + strmsg = JSON.stringify(msg), + len = 1+Buffer.byteLength(strmsg, 'utf8'), + resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; + + session.send = Session.prototype.send; + assert(session.send); + expect(session.send(msg)).to.not.exist; + expect(lastWrittenToHost).to.equal(resultMsg); + }); + }); + + describe('addProtocolHandler', () => { + it('can add protocol handlers', () => { + let respBody = { + item: false + }, + command = 'newhandle', + result = { + response: respBody, + responseRequired: true + }; + + session.addProtocolHandler(command, (req) => result); + + expect(session.executeCommand({ + command, + seq: 0, + type: 'command' + })).to.deep.equal(result); + }); + it('throws when a duplicate handler is passed', () => { + let respBody = { + item: false + }, + resp = { + response: respBody, + responseRequired: true + }, + command = 'newhandle'; + + session.addProtocolHandler(command, (req) => resp); + + expect(() => session.addProtocolHandler(command, (req) => resp)) + .to.throw(`Protocol handler already exists for command "${command}"`); + }); + }); + + describe('event', () => { + it('can format event responses and send them', () => { + let evt = 'notify-test', + info = { + test: true + }; + + session.event(info, evt); + + expect(lastSent).to.deep.equal({ + type: 'event', + seq: 0, + event: evt, + body: info + }); + }); + }); + + describe('output', () => { + it('can format command responses and send them', () => { + let body = { + block: { + key: 'value' + } + }, + command = 'test'; + + session.output(body, command); + + expect(lastSent).to.deep.equal({ + seq: 0, + request_seq: 0, + type: 'response', + command, + body: body, + success: true + }); + }); + }); + }); + + describe('how Session is extendable via subclassing', () => { + let TestSession = class extends Session { + lastSent: protocol.Message; + customHandler:string = 'testhandler'; + constructor(){ + super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + this.addProtocolHandler(this.customHandler, () => { + return {response: undefined, responseRequired: true}; + }); + } + send(msg: protocol.Message) { + this.lastSent = msg; + } + }; + + it('can override methods such as send', () => { + let session = new TestSession(), + body = { + block: { + key: 'value' + } + }, + command = 'test'; + + session.output(body, command); + + expect(session.lastSent).to.deep.equal({ + seq: 0, + request_seq: 0, + type: 'response', + command, + body: body, + success: true + }); + }); + it('can add and respond to new protocol handlers', () => { + let session = new TestSession(); + + expect(session.executeCommand({ + seq: 0, + type: 'command', + command: session.customHandler + })).to.deep.equal({ + response: undefined, + responseRequired: true + }); + }); + it('has access to the project service', () => { + let ServiceSession = class extends TestSession { + constructor() { + super(); + assert(this.projectService); + expect(this.projectService).to.be.instanceOf(ProjectService); + } + }; + new ServiceSession(); + }); + }); + + describe('an example of using the Session API to create an in-process server', () => { + let inProcHost: ServerHost = { + args: [], + newLine: '\n', + useCaseSensitiveFileNames: true, + write: (s) => lastWrittenToHost = s, + readFile: () => void 0, + writeFile: () => void 0, + resolvePath: () => void 0, + fileExists: () => false, + directoryExists: () => false, + createDirectory: () => void 0, + getExecutingFilePath: () => void 0, + getCurrentDirectory: () => void 0, + readDirectory: () => void 0, + exit: () => void 0 + }, + InProcSession = class extends Session { + private queue: protocol.Request[] = []; + constructor(private client: {handle: (msg: protocol.Message) => void}) { + super(inProcHost, Buffer.byteLength, process.hrtime, mockLogger); + this.addProtocolHandler('echo', (req: protocol.Request) => ({ + response: req.arguments, + responseRequired: true + })); + } + + send(msg: protocol.Message) { + this.client.handle(msg); + } + + enqueue(msg: protocol.Request) { + this.queue = [msg].concat(this.queue); + } + + handleRequest(msg: protocol.Request) { + try { + var {response} = this.executeCommand(msg); + } catch (e) { + this.output(undefined, msg.command, msg.seq, e.toString()); + return; + } + if (response) { + this.output(response, msg.command, msg.seq); + } + } + + consumeQueue() { + while (this.queue.length > 0) { + let elem = this.queue[this.queue.length-1]; + this.queue = this.queue.slice(0,this.queue.length-1); + this.handleRequest(elem); + } + } + }, + InProcClient = class { + private server: Session&{enqueue: (msg: protocol.Request) => void}; + private seq: number = 0; + private callbacks: ts.Map<(resp: protocol.Response) => void> = {}; + private eventHandlers: ts.Map<(args: any) => void> = {}; + + handle(msg: protocol.Message): void { + if (msg.type === 'response') { + var response = msg; + if (this.callbacks[response.request_seq]) { + this.callbacks[response.request_seq](response); + delete this.callbacks[response.request_seq]; + } + } else if (msg.type === 'event') { + var event = msg; + this.emit(event.event, event.body); + } + } + + emit(name: string, args: any): void { + if (!this.eventHandlers[name]) { + return; + } + this.eventHandlers[name](args); + } + + on(name: string, handler: (args: any) => void): void { + this.eventHandlers[name] = handler; + } + + connect(session: Session&{enqueue: (msg: protocol.Request) => void}): void { + this.server = session; + } + + execute(command: string, args: any, callback: (resp: protocol.Response) => void): void { + if (!this.server) { + return; + } + this.seq++; + this.server.enqueue({ + seq: this.seq, + type: 'command', + command, + arguments: args + }); + this.callbacks[this.seq] = callback; + } + }; + + it('can be constructed and respond to commands', (done) => { + let cli = new InProcClient(), + session = new InProcSession(cli), + toEcho = { + data: true + }, + toEvent = { + data: false + }, + responses = 0; + + //Connect the client + cli.connect(session); + + //add an event handler + cli.on('testevent', (eventinfo) => { + expect(eventinfo).to.equal(toEvent); + responses++; + expect(responses).to.equal(1); + }); + + //trigger said event from the server + session.event(toEvent,'testevent'); + + //Queue an echo command + cli.execute('echo', toEcho, (resp) => { + assert(resp.success, resp.message); + responses++; + expect(responses).to.equal(2); + expect(resp.body).to.deep.equal(toEcho); + }); + + //Queue a configure command + cli.execute('configure', { + hostInfo: 'unit test', + formatOptions: { + newLineCharacter: '`n' + } + }, (resp) => { + assert(resp.success, resp.message); + responses++; + expect(responses).to.equal(3); + done(); + }); + + //Consume the queue and trigger the callbacks + session.consumeQueue(); + }); + }); +} \ No newline at end of file From d7e6fba4d3a24c641b47a694c4bc8b1a217cb717 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 21 Jul 2015 16:20:17 -0700 Subject: [PATCH 30/85] fixed some warts --- src/harness/fourslash.ts | 13 +++++-------- tests/cases/fourslash/fourslash.ts | 25 +++---------------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 02ca17cefd7..272f4c1c1dd 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1875,7 +1875,7 @@ module FourSlash { } } - private verifyProjectInfo(expected: string[]) { + public verifyProjectInfo(expected: string[]) { if (this.testType === FourSlashTestType.Server) { let actual = (this.languageService).getProjectInfo( this.activeFile.fileName, @@ -2057,11 +2057,8 @@ module FourSlash { return result; } - public verifGetScriptLexicalStructureListContains( - name: string, - kind: string, - markerPosition?: number) { - this.taoInvalidReason = 'verifGetScriptLexicalStructureListContains impossible'; + public verifyGetScriptLexicalStructureListContains(name: string, kind: string) { + this.taoInvalidReason = 'verifyGetScriptLexicalStructureListContains impossible'; let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); @@ -2263,7 +2260,7 @@ module FourSlash { return 'line ' + (pos.line + 1) + ', col ' + pos.character; } - private getMarkerByName(markerName: string) { + public getMarkerByName(markerName: string) { let markerPos = this.testData.markerPositions[markerName]; if (markerPos === undefined) { let markerNames: string[] = []; @@ -2738,4 +2735,4 @@ module FourSlash { fileName: fileName }; } -} +} \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b963e9a573c..3abb7f1cee4 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -1,4 +1,4 @@ -/// +/// // declare var FourSlash; // module ts { @@ -60,7 +60,6 @@ enum EmitReturnStatus { } module FourSlashInterface { - declare var FourSlash; export interface Marker { fileName: string; @@ -219,15 +218,6 @@ module FourSlashInterface { FourSlash.currentTestState.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess); } - public implementorsCountIs(count: number) { - FourSlash.currentTestState.verifyImplementorsCountIs(count); - } - - // Add tests for this. - public currentParameterIsVariable() { - FourSlash.currentTestState.verifyCurrentParameterIsVariable(!this.negative); - } - public signatureHelpPresent() { FourSlash.currentTestState.verifySignatureHelpPresent(!this.negative); } @@ -379,14 +369,11 @@ module FourSlashInterface { FourSlash.currentTestState.verifyNoMatchingBracePosition(bracePosition); } - public setVerifyDocComments(val: boolean) { - FourSlash.currentTestState.setVerifyDocComments(val); - } - public getScriptLexicalStructureListCount(count: number) { FourSlash.currentTestState.verifyGetScriptLexicalStructureListCount(count); } + // TODO: figure out what to do with the unused arguments. public getScriptLexicalStructureListContains( name: string, kind: string, @@ -394,13 +381,7 @@ module FourSlashInterface { parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number) { - FourSlash.currentTestState.verifGetScriptLexicalStructureListContains( - name, - kind, - fileName, - parentName, - isAdditionalSpan, - markerPosition); + FourSlash.currentTestState.verifyGetScriptLexicalStructureListContains(name, kind); } public navigationItemsListCount(count: number, searchValue: string, matchKind?: string) { From 8884f3b4f60881f00c510ab71ecf2776900151aa Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 21 Jul 2015 16:26:03 -0700 Subject: [PATCH 31/85] Fix tslint issues --- tests/cases/unittests/session.ts | 43 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts index 53353c12dda..1d7b9572bbb 100644 --- a/tests/cases/unittests/session.ts +++ b/tests/cases/unittests/session.ts @@ -30,8 +30,8 @@ module ts.server { }; describe('the Session class', () => { - let session:Session, - lastSent:protocol.Message; + let session: Session, + lastSent: protocol.Message; beforeEach(() => { session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger); @@ -111,10 +111,10 @@ module ts.server { type: 'command' }; session.onMessage(JSON.stringify(req)); - req.seq+=2; + req.seq += 2; req.arguments = {}; session.onMessage(JSON.stringify(req)); - req.seq+=2; + req.seq += 2; req.arguments = null; session.onMessage(JSON.stringify(req)); } @@ -147,7 +147,7 @@ module ts.server { describe('exit', () => { it('is a noop which can be handled by subclasses', () => { - session.exit(); //does nothing, should keep running tests + session.exit(); // Does nothing, should keep running tests expect(session).to.exist; }); }); @@ -156,7 +156,7 @@ module ts.server { it('is an overrideable handle which sends protocol messages over the wire', () => { let msg = {seq: 0, type: 'none'}, strmsg = JSON.stringify(msg), - len = 1+Buffer.byteLength(strmsg, 'utf8'), + len = 1 + Buffer.byteLength(strmsg, 'utf8'), resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; session.send = Session.prototype.send; @@ -246,7 +246,7 @@ module ts.server { describe('how Session is extendable via subclassing', () => { let TestSession = class extends Session { lastSent: protocol.Message; - customHandler:string = 'testhandler'; + customHandler: string = 'testhandler'; constructor(){ super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); this.addProtocolHandler(this.customHandler, () => { @@ -338,8 +338,9 @@ module ts.server { } handleRequest(msg: protocol.Request) { + let response: protocol.Response; try { - var {response} = this.executeCommand(msg); + response = this.executeCommand(msg).response; } catch (e) { this.output(undefined, msg.command, msg.seq, e.toString()); return; @@ -351,27 +352,27 @@ module ts.server { consumeQueue() { while (this.queue.length > 0) { - let elem = this.queue[this.queue.length-1]; - this.queue = this.queue.slice(0,this.queue.length-1); + let elem = this.queue[this.queue.length - 1]; + this.queue = this.queue.slice(0, this.queue.length - 1); this.handleRequest(elem); } } }, InProcClient = class { - private server: Session&{enqueue: (msg: protocol.Request) => void}; + private server: Session & {enqueue: (msg: protocol.Request) => void}; private seq: number = 0; private callbacks: ts.Map<(resp: protocol.Response) => void> = {}; private eventHandlers: ts.Map<(args: any) => void> = {}; handle(msg: protocol.Message): void { if (msg.type === 'response') { - var response = msg; + let response = msg; if (this.callbacks[response.request_seq]) { this.callbacks[response.request_seq](response); delete this.callbacks[response.request_seq]; } } else if (msg.type === 'event') { - var event = msg; + let event = msg; this.emit(event.event, event.body); } } @@ -387,7 +388,7 @@ module ts.server { this.eventHandlers[name] = handler; } - connect(session: Session&{enqueue: (msg: protocol.Request) => void}): void { + connect(session: Session & {enqueue: (msg: protocol.Request) => void}): void { this.server = session; } @@ -417,20 +418,20 @@ module ts.server { }, responses = 0; - //Connect the client + // Connect the client cli.connect(session); - //add an event handler + // Add an event handler cli.on('testevent', (eventinfo) => { expect(eventinfo).to.equal(toEvent); responses++; expect(responses).to.equal(1); }); - //trigger said event from the server - session.event(toEvent,'testevent'); + // Trigger said event from the server + session.event(toEvent, 'testevent'); - //Queue an echo command + // Queue an echo command cli.execute('echo', toEcho, (resp) => { assert(resp.success, resp.message); responses++; @@ -438,7 +439,7 @@ module ts.server { expect(resp.body).to.deep.equal(toEcho); }); - //Queue a configure command + // Queue a configure command cli.execute('configure', { hostInfo: 'unit test', formatOptions: { @@ -451,7 +452,7 @@ module ts.server { done(); }); - //Consume the queue and trigger the callbacks + // Consume the queue and trigger the callbacks session.consumeQueue(); }); }); From 9255d551540e2ec216da68224a6ac6ce04408c26 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 21 Jul 2015 16:51:08 -0700 Subject: [PATCH 32/85] better error message when using forward references in initializers of const enums --- src/compiler/checker.ts | 61 +++++++++++-------- .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++ .../reference/constEnumErrors.errors.txt | 4 +- 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c09b069bee6..9478fed1f6c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4363,11 +4363,11 @@ namespace ts { return getInferredType(context, i); } } - return t; + return t; }; mapper.context = context; - return mapper; + return mapper; } function identityMapper(type: Type): Type { @@ -12736,28 +12736,7 @@ namespace ts { } let initializer = member.initializer; if (initializer) { - autoValue = getConstantValueForEnumMemberInitializer(initializer); - if (autoValue === undefined) { - if (enumIsConst) { - error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression); - } - else if (!ambient) { - // Only here do we need to check that the initializer is assignable to the enum type. - // If it is a constant value (not undefined), it is syntactically constrained to be a number. - // Also, we do not need to check this for ambients because there is already - // a syntax error if it is not a constant. - checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined); - } - } - else if (enumIsConst) { - if (isNaN(autoValue)) { - error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN); - } - else if (!isFinite(autoValue)) { - error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value); - } - } - + autoValue = computeConstantValueForEnumMemberInitializer(initializer, enumType, enumIsConst, ambient); } else if (ambient && !enumIsConst) { autoValue = undefined; @@ -12771,8 +12750,36 @@ namespace ts { nodeLinks.flags |= NodeCheckFlags.EnumValuesComputed; } - function getConstantValueForEnumMemberInitializer(initializer: Expression): number { - return evalConstant(initializer); + function computeConstantValueForEnumMemberInitializer(initializer: Expression, enumType: Type, enumIsConst: boolean, ambient: boolean): number { + // Controls if error should be reported after evaluation of constant value is completed + // Can be false if another more precise error was already reported during evaluation. + let reportError = true; + let value = evalConstant(initializer); + + if (reportError) { + if (value === undefined) { + if (enumIsConst) { + error(initializer, Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression); + } + else if (!ambient) { + // Only here do we need to check that the initializer is assignable to the enum type. + // If it is a constant value (not undefined), it is syntactically constrained to be a number. + // Also, we do not need to check this for ambients because there is already + // a syntax error if it is not a constant. + checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, /*headMessage*/ undefined); + } + } + else if (enumIsConst) { + if (isNaN(value)) { + error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN); + } + else if (!isFinite(value)) { + error(initializer, Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value); + } + } + } + + return value; function evalConstant(e: Node): number { switch (e.kind) { @@ -12881,6 +12888,8 @@ namespace ts { // illegal case: forward reference if (!isDefinedBefore(propertyDecl, member)) { + reportError = false; + error(e, Diagnostics.A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums); return undefined; } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index b91399e8ee1..9007ee44db6 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -425,6 +425,7 @@ namespace ts { JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, + A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2474, category: DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9fda73740ba..fa4f30a3557 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1689,6 +1689,10 @@ "category": "Error", "code": 2650 }, + "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums.": { + "category": "Error", + "code": 2474 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index be7dad54eeb..e7d5f347be2 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/constEnumErrors.ts(1,12): error TS2300: Duplicate identifier 'E'. tests/cases/compiler/constEnumErrors.ts(5,8): error TS2300: Duplicate identifier 'E'. -tests/cases/compiler/constEnumErrors.ts(12,9): error TS2474: In 'const' enum declarations member initializer must be constant expression. +tests/cases/compiler/constEnumErrors.ts(12,9): error TS2474: A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums. tests/cases/compiler/constEnumErrors.ts(14,9): error TS2474: In 'const' enum declarations member initializer must be constant expression. tests/cases/compiler/constEnumErrors.ts(15,10): error TS2474: In 'const' enum declarations member initializer must be constant expression. tests/cases/compiler/constEnumErrors.ts(22,13): error TS2476: A const enum member can only be accessed using a string literal. @@ -31,7 +31,7 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member // forward reference to the element of the same enum X = Y, ~ -!!! error TS2474: In 'const' enum declarations member initializer must be constant expression. +!!! error TS2474: A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums. // forward reference to the element of the same enum Y = E1.Z, ~~~~ From 6398671a2688c45a2a34f3bb0387cd8134e874c0 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 21 Jul 2015 16:57:37 -0700 Subject: [PATCH 33/85] fix error code --- src/compiler/diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/constEnumErrors.errors.txt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 9007ee44db6..abff354ff74 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -425,7 +425,7 @@ namespace ts { JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, - A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2474, category: DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." }, + A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2651, category: DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fa4f30a3557..85ac097abe0 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1691,7 +1691,7 @@ }, "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums.": { "category": "Error", - "code": 2474 + "code": 2651 }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index e7d5f347be2..4236544defa 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/constEnumErrors.ts(1,12): error TS2300: Duplicate identifier 'E'. tests/cases/compiler/constEnumErrors.ts(5,8): error TS2300: Duplicate identifier 'E'. -tests/cases/compiler/constEnumErrors.ts(12,9): error TS2474: A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums. +tests/cases/compiler/constEnumErrors.ts(12,9): error TS2651: A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums. tests/cases/compiler/constEnumErrors.ts(14,9): error TS2474: In 'const' enum declarations member initializer must be constant expression. tests/cases/compiler/constEnumErrors.ts(15,10): error TS2474: In 'const' enum declarations member initializer must be constant expression. tests/cases/compiler/constEnumErrors.ts(22,13): error TS2476: A const enum member can only be accessed using a string literal. @@ -31,7 +31,7 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member // forward reference to the element of the same enum X = Y, ~ -!!! error TS2474: A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums. +!!! error TS2651: A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums. // forward reference to the element of the same enum Y = E1.Z, ~~~~ From f631a201403e3a6928fac4d0072f8651d5dc8601 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 21 Jul 2015 17:12:50 -0700 Subject: [PATCH 34/85] Added another test. --- .../modules/defaultExportsCannotMerge02.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts diff --git a/tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts new file mode 100644 index 00000000000..f7312ec2e66 --- /dev/null +++ b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts @@ -0,0 +1,26 @@ +// @module: commonjs +// @target: ES5 + +// @filename: m1.ts +export default class Decl { +} + +export interface Decl { + p1: number; + p2: number; +} + +export namespace Decl { + interface I { + } +} + +// @filename: m2.ts +import Entity from "m1" + +Entity(); + +var x: Entity; +var y: Entity.I; +var z = new Entity(); +var sum = z.p1 + z.p2 \ No newline at end of file From 7e464458f8035aba05666f639df6fb5adc6572a2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 21 Jul 2015 17:13:16 -0700 Subject: [PATCH 35/85] Accepted baselines. --- .../defaultExportsCannotMerge02.errors.txt | 38 +++++++++++++++++ .../reference/defaultExportsCannotMerge02.js | 41 +++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 tests/baselines/reference/defaultExportsCannotMerge02.errors.txt create mode 100644 tests/baselines/reference/defaultExportsCannotMerge02.js diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt new file mode 100644 index 00000000000..52e00547a89 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt @@ -0,0 +1,38 @@ +tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? +tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. +tests/cases/conformance/es6/modules/m2.ts(8,13): error TS2339: Property 'p1' does not exist on type 'Decl'. +tests/cases/conformance/es6/modules/m2.ts(8,20): error TS2339: Property 'p2' does not exist on type 'Decl'. + + +==== tests/cases/conformance/es6/modules/m1.ts (0 errors) ==== + + export default class Decl { + } + + export interface Decl { + p1: number; + p2: number; + } + + export namespace Decl { + interface I { + } + } + +==== tests/cases/conformance/es6/modules/m2.ts (4 errors) ==== + import Entity from "m1" + + Entity(); + ~~~~~~~~ +!!! error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? + + var x: Entity; + var y: Entity.I; + ~~~~~~ +!!! error TS2503: Cannot find namespace 'Entity'. + var z = new Entity(); + var sum = z.p1 + z.p2 + ~~ +!!! error TS2339: Property 'p1' does not exist on type 'Decl'. + ~~ +!!! error TS2339: Property 'p2' does not exist on type 'Decl'. \ No newline at end of file diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.js b/tests/baselines/reference/defaultExportsCannotMerge02.js new file mode 100644 index 00000000000..72a8e3c5f1d --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge02.js @@ -0,0 +1,41 @@ +//// [tests/cases/conformance/es6/modules/defaultExportsCannotMerge02.ts] //// + +//// [m1.ts] + +export default class Decl { +} + +export interface Decl { + p1: number; + p2: number; +} + +export namespace Decl { + interface I { + } +} + +//// [m2.ts] +import Entity from "m1" + +Entity(); + +var x: Entity; +var y: Entity.I; +var z = new Entity(); +var sum = z.p1 + z.p2 + +//// [m1.js] +var Decl = (function () { + function Decl() { + } + return Decl; +})(); +exports.default = Decl; +//// [m2.js] +var m1_1 = require("m1"); +m1_1.default(); +var x; +var y; +var z = new m1_1.default(); +var sum = z.p1 + z.p2; From 8d5d73eb9191ffa25875eecabf3d922e63d484eb Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 21 Jul 2015 17:22:14 -0700 Subject: [PATCH 36/85] Take default export spaces into account when checking merged declarations. --- src/compiler/checker.ts | 21 +++++++++++++++---- .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3536152ee35..e09df418b2a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10682,10 +10682,18 @@ namespace ts { // to denote disjoint declarationSpaces (without making new enum type). let exportedDeclarationSpaces = SymbolFlags.None; let nonExportedDeclarationSpaces = SymbolFlags.None; + let defaultExportedDeclarationFlags = SymbolFlags.None; for (let d of symbol.declarations) { let declarationSpaces = getDeclarationSpaces(d); - if (getEffectiveDeclarationFlags(d, NodeFlags.Export)) { - exportedDeclarationSpaces |= declarationSpaces; + let effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, NodeFlags.Export | NodeFlags.Default); + + if (effectiveDeclarationFlags & NodeFlags.Export) { + if (effectiveDeclarationFlags & NodeFlags.Default) { + defaultExportedDeclarationFlags |= declarationSpaces; + } + else { + exportedDeclarationSpaces |= declarationSpaces; + } } else { nonExportedDeclarationSpaces |= declarationSpaces; @@ -10693,11 +10701,16 @@ namespace ts { } let commonDeclarationSpace = exportedDeclarationSpaces & nonExportedDeclarationSpaces; + let commonDeclarationSpaceForDefault = defaultExportedDeclarationFlags & (exportedDeclarationSpaces | nonExportedDeclarationSpaces); - if (commonDeclarationSpace) { + if (commonDeclarationSpace || commonDeclarationSpaceForDefault) { // declaration spaces for exported and non-exported declarations intersect for (let d of symbol.declarations) { - if (getDeclarationSpaces(d) & commonDeclarationSpace) { + let declarationSpaces = getDeclarationSpaces(d); + if (declarationSpaces & commonDeclarationSpaceForDefault) { + error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration, declarationNameToString(d.name)); + } + else if (declarationSpaces & commonDeclarationSpace) { error(d.name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(d.name)); } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index c17a49484b8..c1afb8c9706 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -424,6 +424,7 @@ namespace ts { JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, + Merged_declaration_0_cannot_include_a_default_export_declaration: { code: 2651, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d01084c1bc8..fa792639556 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1685,6 +1685,10 @@ "category": "Error", "code": 2650 }, + "Merged declaration '{0}' cannot include a default export declaration.": { + "category": "Error", + "code": 2651 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 From be44bc651c45d31c080323b14b5f3ed77118b1b1 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 21 Jul 2015 17:22:56 -0700 Subject: [PATCH 37/85] Accepted baselines. --- .../reference/defaultExportsCannotMerge01.errors.txt | 8 +++++++- .../reference/defaultExportsCannotMerge02.errors.txt | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt index 6eece36e077..4b1ad1424bd 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt @@ -1,12 +1,16 @@ +tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. +tests/cases/conformance/es6/modules/m1.ts(11,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. tests/cases/conformance/es6/modules/m2.ts(5,8): error TS2304: Cannot find name 'Entity'. tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,8): error TS2339: Property 'x' does not exist on type '() => number'. tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does not exist on type '() => number'. -==== tests/cases/conformance/es6/modules/m1.ts (0 errors) ==== +==== tests/cases/conformance/es6/modules/m1.ts (2 errors) ==== export default function Decl() { + ~~~~ +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. return 0; } @@ -16,6 +20,8 @@ tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does } export namespace Decl { + ~~~~ +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. export var x = 10; export var y = 20; diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt index 52e00547a89..e1abe6068fe 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt @@ -1,15 +1,21 @@ +tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. +tests/cases/conformance/es6/modules/m1.ts(5,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,13): error TS2339: Property 'p1' does not exist on type 'Decl'. tests/cases/conformance/es6/modules/m2.ts(8,20): error TS2339: Property 'p2' does not exist on type 'Decl'. -==== tests/cases/conformance/es6/modules/m1.ts (0 errors) ==== +==== tests/cases/conformance/es6/modules/m1.ts (2 errors) ==== export default class Decl { + ~~~~ +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. } export interface Decl { + ~~~~ +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. p1: number; p2: number; } From 18e36b898c3904985a117cab8533241fd6bad4c7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 21 Jul 2015 17:47:15 -0700 Subject: [PATCH 38/85] Add suggestion to error message. --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e09df418b2a..a51f0751272 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10708,7 +10708,7 @@ namespace ts { for (let d of symbol.declarations) { let declarationSpaces = getDeclarationSpaces(d); if (declarationSpaces & commonDeclarationSpaceForDefault) { - error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration, declarationNameToString(d.name)); + error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration, declarationNameToString(d.name)); } else if (declarationSpaces & commonDeclarationSpace) { error(d.name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(d.name)); diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index c1afb8c9706..03026ee0547 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -424,7 +424,7 @@ namespace ts { JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, - Merged_declaration_0_cannot_include_a_default_export_declaration: { code: 2651, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration." }, + Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration: { code: 2651, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0};' declaration." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fa792639556..bb6430a1344 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1685,7 +1685,7 @@ "category": "Error", "code": 2650 }, - "Merged declaration '{0}' cannot include a default export declaration.": { + "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0};' declaration.": { "category": "Error", "code": 2651 }, From beff65191f6e3a8538c4d81878a7c2454be59b4f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 21 Jul 2015 17:47:53 -0700 Subject: [PATCH 39/85] Accepted baselines. --- .../reference/defaultExportsCannotMerge01.errors.txt | 8 ++++---- .../reference/defaultExportsCannotMerge02.errors.txt | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt index 4b1ad1424bd..ee0f549aa97 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. -tests/cases/conformance/es6/modules/m1.ts(11,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. +tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +tests/cases/conformance/es6/modules/m1.ts(11,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. tests/cases/conformance/es6/modules/m2.ts(5,8): error TS2304: Cannot find name 'Entity'. tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,8): error TS2339: Property 'x' does not exist on type '() => number'. @@ -10,7 +10,7 @@ tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does export default function Decl() { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. return 0; } @@ -21,7 +21,7 @@ tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does export namespace Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. export var x = 10; export var y = 20; diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt index e1abe6068fe..fbf7076eb51 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. -tests/cases/conformance/es6/modules/m1.ts(5,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. +tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +tests/cases/conformance/es6/modules/m1.ts(5,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,13): error TS2339: Property 'p1' does not exist on type 'Decl'. @@ -10,12 +10,12 @@ tests/cases/conformance/es6/modules/m2.ts(8,20): error TS2339: Property 'p2' doe export default class Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. } export interface Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. p1: number; p2: number; } From 851d361a7dfa4527dd4006de395eb8af68f8bdb9 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 21 Jul 2015 18:08:41 -0700 Subject: [PATCH 40/85] Move message after guide --- tests/cases/fourslash/fourslash.ts | 44 ++++++++++++++++++------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 3abb7f1cee4..31817fb6890 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -1,21 +1,3 @@ -/// - -// declare var FourSlash; -// module ts { -// export interface SymbolDisplayPart { -// text: string; -// kind: string; -// } -// } - -// DO NOT EDIT ABOVE THIS LINE! -// We want type-completion while we edit this file, but at compile time we don't want to include the above reference -// because we are compiling this file in "--out" mode and don't want to rope in the entire codebase -// for each fourslash test. -// So, the compile script manually modifies the aboce code so that we compile correctly. - -//--------------------------------------------- - // Welcome to the FourSlash syntax guide! // A line in the source text is indicated by four slashes (////) @@ -48,6 +30,32 @@ // (e.g. 'fs.goTo.eof();') //--------------------------------------- +// When editting this file, and only while editing this file, enable the reference comments +// and comment out the declarations in this section to get proper type information. +// Undo these changes before compiling/committing/editing any other fourslash tests. +// The test suite will likely crash if you try 'jake runtests' with reference comments enabled. +// +// Explanation: +// We want type-completion while we edit this file, but at compile time/while editting fourslash tests, +// we don't want to include the following reference because we are compiling this file in "--out" mode and don't want to rope +// in the entire codebase into the compilattion each fourslash test. Additionally, we don't want to expose the +// src/harness/fourslash.ts API's (or the rest of the compiler) because they are unstable and complicate the +// fourslash testing DSL. Finally, in this case, runtime reflection is (much) faster. +// +// TODO: figure out a better solution to the API exposure problem. + +// /// +// /// + +declare var FourSlash; +module ts { + export interface SymbolDisplayPart { + text: string; + kind: string; + } +} + +//--------------------------------------------- // Return code used by getEmitOutput function to indicate status of the function // It is a duplicate of the one in types.ts to expose it to testcases in fourslash From 2f7a597dcaaf8e877ad972878b63516b43f966e1 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 21 Jul 2015 18:27:01 -0700 Subject: [PATCH 41/85] Qualification --- tests/cases/fourslash/fourslash.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 31817fb6890..0008b33673f 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -30,6 +30,7 @@ // (e.g. 'fs.goTo.eof();') //--------------------------------------- +// For API editors: // When editting this file, and only while editing this file, enable the reference comments // and comment out the declarations in this section to get proper type information. // Undo these changes before compiling/committing/editing any other fourslash tests. From 06f766ce447ec682fa45f87ae5bd099f07ec6eff Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 22 Jul 2015 09:27:57 -0700 Subject: [PATCH 42/85] Remove check about ctors returning object types -- it isn't useful --- src/compiler/checker.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5fee3dd3a54..0cd41a2a02b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7196,12 +7196,7 @@ namespace ts { } } - // Check that the constructor/factory returns an object type let returnType = getUnionType(signatures.map(s => getReturnTypeOfSignature(s))); - if (!isTypeAny(returnType) && !(returnType.flags & TypeFlags.ObjectType)) { - error(node.tagName, Diagnostics.The_return_type_of_a_JSX_element_constructor_must_return_an_object_type); - return undefined; - } // Issue an error if this return type isn't assignable to JSX.ElementClass let elemClassType = getJsxGlobalElementClassType(); From e05a81cb3d10f90cdbe4f79a31a19c12b14c96ae Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 22 Jul 2015 09:41:53 -0700 Subject: [PATCH 43/85] Baseline update --- .../reference/tsxAttributeResolution9.symbols | 47 ------------- .../reference/tsxAttributeResolution9.types | 49 ------------- .../tsxElementResolution8.errors.txt | 8 +-- .../tsxElementResolution9.errors.txt | 35 ---------- .../reference/tsxElementResolution9.symbols | 67 ++++++++++++++++++ .../reference/tsxElementResolution9.types | 70 +++++++++++++++++++ 6 files changed, 138 insertions(+), 138 deletions(-) delete mode 100644 tests/baselines/reference/tsxAttributeResolution9.symbols delete mode 100644 tests/baselines/reference/tsxAttributeResolution9.types delete mode 100644 tests/baselines/reference/tsxElementResolution9.errors.txt create mode 100644 tests/baselines/reference/tsxElementResolution9.symbols create mode 100644 tests/baselines/reference/tsxElementResolution9.types diff --git a/tests/baselines/reference/tsxAttributeResolution9.symbols b/tests/baselines/reference/tsxAttributeResolution9.symbols deleted file mode 100644 index 081482d5d47..00000000000 --- a/tests/baselines/reference/tsxAttributeResolution9.symbols +++ /dev/null @@ -1,47 +0,0 @@ -=== tests/cases/conformance/jsx/react.d.ts === - -declare module JSX { ->JSX : Symbol(JSX, Decl(react.d.ts, 0, 0)) - - interface Element { } ->Element : Symbol(Element, Decl(react.d.ts, 1, 20)) - - interface IntrinsicElements { ->IntrinsicElements : Symbol(IntrinsicElements, Decl(react.d.ts, 2, 22)) - } - interface ElementAttributesProperty { ->ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(react.d.ts, 4, 2)) - - props; ->props : Symbol(props, Decl(react.d.ts, 5, 38)) - } -} - -interface Props { ->Props : Symbol(Props, Decl(react.d.ts, 8, 1)) - - foo: string; ->foo : Symbol(foo, Decl(react.d.ts, 10, 17)) -} - -=== tests/cases/conformance/jsx/file.tsx === -export class MyComponent { ->MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0)) - - render() { ->render : Symbol(render, Decl(file.tsx, 0, 26)) - } - - props: { foo: string; } ->props : Symbol(props, Decl(file.tsx, 2, 3)) ->foo : Symbol(foo, Decl(file.tsx, 4, 10)) -} - -; // ok ->MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0)) ->foo : Symbol(unknown) - -; // should be an error ->MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0)) ->foo : Symbol(unknown) - diff --git a/tests/baselines/reference/tsxAttributeResolution9.types b/tests/baselines/reference/tsxAttributeResolution9.types deleted file mode 100644 index 1b2c6d42389..00000000000 --- a/tests/baselines/reference/tsxAttributeResolution9.types +++ /dev/null @@ -1,49 +0,0 @@ -=== tests/cases/conformance/jsx/react.d.ts === - -declare module JSX { ->JSX : any - - interface Element { } ->Element : Element - - interface IntrinsicElements { ->IntrinsicElements : IntrinsicElements - } - interface ElementAttributesProperty { ->ElementAttributesProperty : ElementAttributesProperty - - props; ->props : any - } -} - -interface Props { ->Props : Props - - foo: string; ->foo : string -} - -=== tests/cases/conformance/jsx/file.tsx === -export class MyComponent { ->MyComponent : MyComponent - - render() { ->render : () => void - } - - props: { foo: string; } ->props : { foo: string; } ->foo : string -} - -; // ok -> : JSX.Element ->MyComponent : typeof MyComponent ->foo : any - -; // should be an error -> : JSX.Element ->MyComponent : typeof MyComponent ->foo : any - diff --git a/tests/baselines/reference/tsxElementResolution8.errors.txt b/tests/baselines/reference/tsxElementResolution8.errors.txt index 5710c4e177d..92ff05d1aed 100644 --- a/tests/baselines/reference/tsxElementResolution8.errors.txt +++ b/tests/baselines/reference/tsxElementResolution8.errors.txt @@ -1,10 +1,8 @@ tests/cases/conformance/jsx/tsxElementResolution8.tsx(8,2): error TS2604: JSX element type 'Div' does not have any construct or call signatures. -tests/cases/conformance/jsx/tsxElementResolution8.tsx(16,2): error TS2601: The return type of a JSX element constructor must return an object type. -tests/cases/conformance/jsx/tsxElementResolution8.tsx(29,2): error TS2601: The return type of a JSX element constructor must return an object type. tests/cases/conformance/jsx/tsxElementResolution8.tsx(34,2): error TS2604: JSX element type 'Obj3' does not have any construct or call signatures. -==== tests/cases/conformance/jsx/tsxElementResolution8.tsx (4 errors) ==== +==== tests/cases/conformance/jsx/tsxElementResolution8.tsx (2 errors) ==== declare module JSX { interface Element { } interface IntrinsicElements { } @@ -23,8 +21,6 @@ tests/cases/conformance/jsx/tsxElementResolution8.tsx(34,2): error TS2604: JSX e // Error function Fnum(): number{ return 42; } - ~~~~ -!!! error TS2601: The return type of a JSX element constructor must return an object type. interface Obj1 { new(): {}; @@ -38,8 +34,6 @@ tests/cases/conformance/jsx/tsxElementResolution8.tsx(34,2): error TS2604: JSX e } var Obj2: Obj2; ; // Error - ~~~~ -!!! error TS2601: The return type of a JSX element constructor must return an object type. interface Obj3 { } diff --git a/tests/baselines/reference/tsxElementResolution9.errors.txt b/tests/baselines/reference/tsxElementResolution9.errors.txt deleted file mode 100644 index f4412719b33..00000000000 --- a/tests/baselines/reference/tsxElementResolution9.errors.txt +++ /dev/null @@ -1,35 +0,0 @@ -tests/cases/conformance/jsx/tsxElementResolution9.tsx(11,2): error TS2601: The return type of a JSX element constructor must return an object type. -tests/cases/conformance/jsx/tsxElementResolution9.tsx(18,2): error TS2601: The return type of a JSX element constructor must return an object type. - - -==== tests/cases/conformance/jsx/tsxElementResolution9.tsx (2 errors) ==== - declare module JSX { - interface Element { } - interface IntrinsicElements { } - } - - interface Obj1 { - new(n: string): { x: number }; - new(n: number): { y: string }; - } - var Obj1: Obj1; - ; // Error, return type is not an object type - ~~~~ -!!! error TS2601: The return type of a JSX element constructor must return an object type. - - interface Obj2 { - (n: string): { x: number }; - (n: number): { y: string }; - } - var Obj2: Obj2; - ; // Error, return type is not an object type - ~~~~ -!!! error TS2601: The return type of a JSX element constructor must return an object type. - - interface Obj3 { - (n: string): { x: number }; - (n: number): { x: number; y: string }; - } - var Obj3: Obj3; - ; // OK - \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution9.symbols b/tests/baselines/reference/tsxElementResolution9.symbols new file mode 100644 index 00000000000..bfa04219ef9 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution9.symbols @@ -0,0 +1,67 @@ +=== tests/cases/conformance/jsx/tsxElementResolution9.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxElementResolution9.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxElementResolution9.tsx, 0, 20)) + + interface IntrinsicElements { } +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxElementResolution9.tsx, 1, 22)) +} + +interface Obj1 { +>Obj1 : Symbol(Obj1, Decl(tsxElementResolution9.tsx, 3, 1), Decl(tsxElementResolution9.tsx, 9, 3)) + + new(n: string): { x: number }; +>n : Symbol(n, Decl(tsxElementResolution9.tsx, 6, 5)) +>x : Symbol(x, Decl(tsxElementResolution9.tsx, 6, 18)) + + new(n: number): { y: string }; +>n : Symbol(n, Decl(tsxElementResolution9.tsx, 7, 5)) +>y : Symbol(y, Decl(tsxElementResolution9.tsx, 7, 18)) +} +var Obj1: Obj1; +>Obj1 : Symbol(Obj1, Decl(tsxElementResolution9.tsx, 3, 1), Decl(tsxElementResolution9.tsx, 9, 3)) +>Obj1 : Symbol(Obj1, Decl(tsxElementResolution9.tsx, 3, 1), Decl(tsxElementResolution9.tsx, 9, 3)) + +; // Error, return type is not an object type +>Obj1 : Symbol(Obj1, Decl(tsxElementResolution9.tsx, 3, 1), Decl(tsxElementResolution9.tsx, 9, 3)) + +interface Obj2 { +>Obj2 : Symbol(Obj2, Decl(tsxElementResolution9.tsx, 10, 9), Decl(tsxElementResolution9.tsx, 16, 3)) + + (n: string): { x: number }; +>n : Symbol(n, Decl(tsxElementResolution9.tsx, 13, 2)) +>x : Symbol(x, Decl(tsxElementResolution9.tsx, 13, 15)) + + (n: number): { y: string }; +>n : Symbol(n, Decl(tsxElementResolution9.tsx, 14, 2)) +>y : Symbol(y, Decl(tsxElementResolution9.tsx, 14, 15)) +} +var Obj2: Obj2; +>Obj2 : Symbol(Obj2, Decl(tsxElementResolution9.tsx, 10, 9), Decl(tsxElementResolution9.tsx, 16, 3)) +>Obj2 : Symbol(Obj2, Decl(tsxElementResolution9.tsx, 10, 9), Decl(tsxElementResolution9.tsx, 16, 3)) + +; // Error, return type is not an object type +>Obj2 : Symbol(Obj2, Decl(tsxElementResolution9.tsx, 10, 9), Decl(tsxElementResolution9.tsx, 16, 3)) + +interface Obj3 { +>Obj3 : Symbol(Obj3, Decl(tsxElementResolution9.tsx, 17, 9), Decl(tsxElementResolution9.tsx, 23, 3)) + + (n: string): { x: number }; +>n : Symbol(n, Decl(tsxElementResolution9.tsx, 20, 2)) +>x : Symbol(x, Decl(tsxElementResolution9.tsx, 20, 15)) + + (n: number): { x: number; y: string }; +>n : Symbol(n, Decl(tsxElementResolution9.tsx, 21, 2)) +>x : Symbol(x, Decl(tsxElementResolution9.tsx, 21, 15)) +>y : Symbol(y, Decl(tsxElementResolution9.tsx, 21, 26)) +} +var Obj3: Obj3; +>Obj3 : Symbol(Obj3, Decl(tsxElementResolution9.tsx, 17, 9), Decl(tsxElementResolution9.tsx, 23, 3)) +>Obj3 : Symbol(Obj3, Decl(tsxElementResolution9.tsx, 17, 9), Decl(tsxElementResolution9.tsx, 23, 3)) + +; // OK +>Obj3 : Symbol(Obj3, Decl(tsxElementResolution9.tsx, 17, 9), Decl(tsxElementResolution9.tsx, 23, 3)) +>x : Symbol(unknown) + diff --git a/tests/baselines/reference/tsxElementResolution9.types b/tests/baselines/reference/tsxElementResolution9.types new file mode 100644 index 00000000000..525e4600b2e --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution9.types @@ -0,0 +1,70 @@ +=== tests/cases/conformance/jsx/tsxElementResolution9.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { } +>IntrinsicElements : IntrinsicElements +} + +interface Obj1 { +>Obj1 : Obj1 + + new(n: string): { x: number }; +>n : string +>x : number + + new(n: number): { y: string }; +>n : number +>y : string +} +var Obj1: Obj1; +>Obj1 : Obj1 +>Obj1 : Obj1 + +; // Error, return type is not an object type +> : JSX.Element +>Obj1 : Obj1 + +interface Obj2 { +>Obj2 : Obj2 + + (n: string): { x: number }; +>n : string +>x : number + + (n: number): { y: string }; +>n : number +>y : string +} +var Obj2: Obj2; +>Obj2 : Obj2 +>Obj2 : Obj2 + +; // Error, return type is not an object type +> : JSX.Element +>Obj2 : Obj2 + +interface Obj3 { +>Obj3 : Obj3 + + (n: string): { x: number }; +>n : string +>x : number + + (n: number): { x: number; y: string }; +>n : number +>x : number +>y : string +} +var Obj3: Obj3; +>Obj3 : Obj3 +>Obj3 : Obj3 + +; // OK +> : JSX.Element +>Obj3 : Obj3 +>x : any + From 500cadac5cec5f81a89cf4bbf90f10bd5c69738d Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 22 Jul 2015 11:58:27 -0700 Subject: [PATCH 44/85] add transpileModule function that can return emitted source map --- .../diagnosticInformationMap.generated.ts | 1 - src/compiler/diagnosticMessages.json | 4 - src/compiler/program.ts | 8 +- src/services/services.ts | 63 +++++++--- .../isolatedModulesSourceMap.errors.txt | 7 -- .../reference/isolatedModulesSourceMap.js | 4 +- .../reference/isolatedModulesSourceMap.js.map | 2 +- .../isolatedModulesSourceMap.sourcemap.txt | 16 ++- .../isolatedModulesSourceMap.symbols | 5 + .../reference/isolatedModulesSourceMap.types | 6 + .../compiler/isolatedModulesSourceMap.ts | 2 +- tests/cases/unittests/transpile.ts | 117 ++++++++++++++---- 12 files changed, 167 insertions(+), 68 deletions(-) delete mode 100644 tests/baselines/reference/isolatedModulesSourceMap.errors.txt create mode 100644 tests/baselines/reference/isolatedModulesSourceMap.symbols create mode 100644 tests/baselines/reference/isolatedModulesSourceMap.types diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index b91399e8ee1..ecea3a76673 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -509,7 +509,6 @@ namespace ts { Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." }, Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." }, Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." }, - Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." }, Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." }, Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." }, Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9fda73740ba..2765d04f400 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2025,10 +2025,6 @@ "category": "Error", "code": 5042 }, - "Option 'sourceMap' cannot be specified with option 'isolatedModules'.": { - "category": "Error", - "code": 5043 - }, "Option 'declaration' cannot be specified with option 'isolatedModules'.": { "category": "Error", "code": 5044 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 5ce4846b43b..b8f48a0fd63 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -341,7 +341,7 @@ namespace ts { }); } - function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { + function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] { return runWithCancellationToken(() => { if (!isDeclarationFile(sourceFile)) { let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken); @@ -350,7 +350,7 @@ namespace ts { return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile); } }); - } + } function getOptionsDiagnostics(): Diagnostic[] { let allDiagnostics: Diagnostic[] = []; @@ -602,10 +602,6 @@ namespace ts { function verifyCompilerOptions() { if (options.isolatedModules) { - if (options.sourceMap) { - diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules)); - } - if (options.declaration) { diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules)); } diff --git a/src/services/services.ts b/src/services/services.ts index 16f5b0b91fe..de4004000d4 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1754,18 +1754,31 @@ namespace ts { sourceFile.version = version; sourceFile.scriptSnapshot = scriptSnapshot; } - + + export interface TranspileOptions { + compilerOptions?: CompilerOptions; + fileName?: string; + reportDiagnostics?: boolean; + moduleName?: string; + } + + export interface TranspileOutput { + outputText: string; + diagnostics?: Diagnostic[]; + sourceMapText?: string; + } + /* * This function will compile source text from 'input' argument using specified compiler options. * If not options are provided - it will use a set of default compiler options. - * Extra compiler options that will unconditionally be used bu this function are: + * Extra compiler options that will unconditionally be used by this function are: * - isolatedModules = true * - allowNonTsExtensions = true * - noLib = true * - noResolve = true - */ - export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string { - let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions(); + */ + export function transpileModule(input: string, transpileOptions?: TranspileOptions): TranspileOutput { + let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; @@ -1781,23 +1794,30 @@ namespace ts { options.noResolve = true; // Parse - let inputFileName = fileName || "module.ts"; + let inputFileName = transpileOptions.fileName || "module.ts"; let sourceFile = createSourceFile(inputFileName, input, options.target); - if (moduleName) { - sourceFile.moduleName = moduleName; + if (transpileOptions.moduleName) { + sourceFile.moduleName = transpileOptions.moduleName; } let newLine = getNewLineCharacter(options); // Output let outputText: string; + let sourceMapText: string; // Create a compilerHost object to allow the compiler to read and write files let compilerHost: CompilerHost = { getSourceFile: (fileName, target) => fileName === inputFileName ? sourceFile : undefined, writeFile: (name, text, writeByteOrderMark) => { - Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name); - outputText = text; + if (fileExtensionIs(name, ".map")) { + Debug.assert(sourceMapText === undefined, `Unexpected multiple source map outputs for the file '${name}'`); + sourceMapText = text; + } + else { + Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name); + outputText = text; + } }, getDefaultLibFileName: () => "lib.d.ts", useCaseSensitiveFileNames: () => false, @@ -1807,16 +1827,29 @@ namespace ts { }; let program = createProgram([inputFileName], options, compilerHost); - - addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile)); - addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics()); - + + let diagnostics: Diagnostic[]; + if (transpileOptions.reportDiagnostics) { + diagnostics = []; + addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile)); + addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics()); + } // Emit program.emit(); Debug.assert(outputText !== undefined, "Output generation failed"); - return outputText; + return { outputText, diagnostics, sourceMapText }; + } + + /* + * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result. + */ + export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string { + let output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName }); + // addRange correctly handles cases when wither 'from' or 'to' argument is missing + addRange(diagnostics, output.diagnostics); + return output.outputText; } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile { diff --git a/tests/baselines/reference/isolatedModulesSourceMap.errors.txt b/tests/baselines/reference/isolatedModulesSourceMap.errors.txt deleted file mode 100644 index 6383e85ecd5..00000000000 --- a/tests/baselines/reference/isolatedModulesSourceMap.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'. - - -!!! error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'. -==== tests/cases/compiler/isolatedModulesSourceMap.ts (0 errors) ==== - - export var x; \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesSourceMap.js b/tests/baselines/reference/isolatedModulesSourceMap.js index ca6f4b4190e..2722a3ce7ab 100644 --- a/tests/baselines/reference/isolatedModulesSourceMap.js +++ b/tests/baselines/reference/isolatedModulesSourceMap.js @@ -1,7 +1,7 @@ //// [isolatedModulesSourceMap.ts] -export var x; +export var x = 1; //// [isolatedModulesSourceMap.js] -export var x; +export var x = 1; //# sourceMappingURL=isolatedModulesSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesSourceMap.js.map b/tests/baselines/reference/isolatedModulesSourceMap.js.map index 8e505dcda7a..9fa3e0da0d6 100644 --- a/tests/baselines/reference/isolatedModulesSourceMap.js.map +++ b/tests/baselines/reference/isolatedModulesSourceMap.js.map @@ -1,2 +1,2 @@ //// [isolatedModulesSourceMap.js.map] -{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,CAAC"} \ No newline at end of file +{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,GAAG,CAAC,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt b/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt index 5c6b7659bc6..d31445505f7 100644 --- a/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt +++ b/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt @@ -8,20 +8,26 @@ sources: isolatedModulesSourceMap.ts emittedFile:tests/cases/compiler/isolatedModulesSourceMap.js sourceFile:isolatedModulesSourceMap.ts ------------------------------------------------------------------- ->>>export var x; +>>>export var x = 1; 1 > 2 >^^^^^^^^^^^ 3 > ^ -4 > ^ -5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +4 > ^^^ +5 > ^ +6 > ^ +7 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> 1 > > 2 >export var 3 > x -4 > ; +4 > = +5 > 1 +6 > ; 1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0) 2 >Emitted(1, 12) Source(2, 12) + SourceIndex(0) 3 >Emitted(1, 13) Source(2, 13) + SourceIndex(0) -4 >Emitted(1, 14) Source(2, 14) + SourceIndex(0) +4 >Emitted(1, 16) Source(2, 16) + SourceIndex(0) +5 >Emitted(1, 17) Source(2, 17) + SourceIndex(0) +6 >Emitted(1, 18) Source(2, 18) + SourceIndex(0) --- >>>//# sourceMappingURL=isolatedModulesSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesSourceMap.symbols b/tests/baselines/reference/isolatedModulesSourceMap.symbols new file mode 100644 index 00000000000..d4ae3c34cf1 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesSourceMap.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/isolatedModulesSourceMap.ts === + +export var x = 1; +>x : Symbol(x, Decl(isolatedModulesSourceMap.ts, 1, 10)) + diff --git a/tests/baselines/reference/isolatedModulesSourceMap.types b/tests/baselines/reference/isolatedModulesSourceMap.types new file mode 100644 index 00000000000..1955fe5da6e --- /dev/null +++ b/tests/baselines/reference/isolatedModulesSourceMap.types @@ -0,0 +1,6 @@ +=== tests/cases/compiler/isolatedModulesSourceMap.ts === + +export var x = 1; +>x : number +>1 : number + diff --git a/tests/cases/compiler/isolatedModulesSourceMap.ts b/tests/cases/compiler/isolatedModulesSourceMap.ts index 31dd4d9f0cf..465941d9a8b 100644 --- a/tests/cases/compiler/isolatedModulesSourceMap.ts +++ b/tests/cases/compiler/isolatedModulesSourceMap.ts @@ -3,4 +3,4 @@ // @target: es6 // @filename: file1.ts -export var x; \ No newline at end of file +export var x = 1; \ No newline at end of file diff --git a/tests/cases/unittests/transpile.ts b/tests/cases/unittests/transpile.ts index fcce034b227..1fd8c860d01 100644 --- a/tests/cases/unittests/transpile.ts +++ b/tests/cases/unittests/transpile.ts @@ -2,58 +2,120 @@ module ts { describe("Transpile", () => { - - function runTest(input: string, compilerOptions: ts.CompilerOptions = {}, fileName?: string, moduleName?: string, expectedOutput?: string, expectedDiagnosticCodes: number[] = []): void { - let diagnostics: Diagnostic[] = []; - let result = transpile(input, compilerOptions, fileName || "file.ts", diagnostics, moduleName); - + + interface TranspileTestSettings { + options?: TranspileOptions; + expectedOutput?: string; + expectedDiagnosticCodes?: number[]; + } + + function checkDiagnostics(diagnostics: Diagnostic[], expectedDiagnosticCodes?: number[]) { + if(!expectedDiagnosticCodes) { + return; + } + for (let i = 0; i < expectedDiagnosticCodes.length; i++) { assert.equal(expectedDiagnosticCodes[i], diagnostics[i] && diagnostics[i].code, `Could not find expeced diagnostic.`); } - assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected"); - - if (expectedOutput !== undefined) { - assert.equal(result, expectedOutput); - } + assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected"); } + + function test(input: string, testSettings: TranspileTestSettings): void { + let diagnostics: Diagnostic[] = []; + + let transpileOptions: TranspileOptions = testSettings.options || {}; + let transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName); + + transpileOptions.reportDiagnostics = true; + let transpileModuleResult = transpileModule(input, transpileOptions); + + checkDiagnostics(diagnostics, testSettings.expectedDiagnosticCodes); + checkDiagnostics(transpileModuleResult.diagnostics, testSettings.expectedDiagnosticCodes); + + if (testSettings.expectedOutput !== undefined) { + assert.equal(transpileResult, testSettings.expectedOutput); + assert.equal(transpileModuleResult.outputText, testSettings.expectedOutput); + } + + // check source maps + if (!transpileOptions.compilerOptions) { + transpileOptions.compilerOptions = {}; + } + + if (!transpileOptions.fileName) { + transpileOptions.fileName = "file.ts"; + } + + transpileOptions.compilerOptions.sourceMap = true; + let transpileModuleResultWithSourceMap = transpileModule(input, transpileOptions); + assert.isTrue(transpileModuleResultWithSourceMap.sourceMapText !== undefined); + + let expectedSourceMapFileName = removeFileExtension(transpileOptions.fileName) + ".js.map"; + let expectedSourceMappingUrlLine = `//# sourceMappingURL=${expectedSourceMapFileName}`; + + if (testSettings.expectedOutput !== undefined) { + assert.equal(transpileModuleResultWithSourceMap.outputText, testSettings.expectedOutput + expectedSourceMappingUrlLine); + } + else { + // expected output is not set, just verify that output text has sourceMappingURL as a last line + let output = transpileModuleResultWithSourceMap.outputText; + assert.isTrue(output.length >= expectedSourceMappingUrlLine.length); + if (output.length === expectedSourceMappingUrlLine.length) { + assert.equal(output, expectedSourceMappingUrlLine); + } + else { + let suffix = getNewLineCharacter(transpileOptions.compilerOptions) + expectedSourceMappingUrlLine + assert.isTrue(output.indexOf(suffix, output.length - suffix.length) !== -1); + } + } + } + it("Generates correct compilerOptions diagnostics", () => { // Expecting 5047: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." - runTest(`var x = 0;`, {}, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [5047]); + test(`var x = 0;`, { expectedDiagnosticCodes: [5047] }); }); it("Generates no diagnostics with valid inputs", () => { // No errors - runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []); + test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); }); it("Generates no diagnostics for missing file references", () => { - runTest(`/// -var x = 0;`, - { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []); + test(`/// +var x = 0;`, + { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); }); it("Generates no diagnostics for missing module imports", () => { - runTest(`import {a} from "module2";`, - { module: ModuleKind.CommonJS }, /*fileName*/ undefined,/*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []); + test(`import {a} from "module2";`, + { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); }); it("Generates expected syntactic diagnostics", () => { - runTest(`a b`, - { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [1005]); /// 1005: ';' Expected + test(`a b`, + { options: { compilerOptions: { module: ModuleKind.CommonJS } }, expectedDiagnosticCodes: [1005] }); /// 1005: ';' Expected }); it("Does not generate semantic diagnostics", () => { - runTest(`var x: string = 0;`, - { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []); + test(`var x: string = 0;`, + { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); }); it("Generates module output", () => { - runTest(`var x = 0;`, { module: ModuleKind.AMD }, /*fileName*/ undefined, /*moduleName*/undefined, `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n`); + test(`var x = 0;`, + { + options: { compilerOptions: { module: ModuleKind.AMD } }, + expectedOutput: `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n` + }); }); it("Uses correct newLine character", () => { - runTest(`var x = 0;`, { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed }, /*fileName*/ undefined, /*moduleName*/undefined, `var x = 0;\n`, /*expectedDiagnosticCodes*/ []); + test(`var x = 0;`, + { + options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } }, + expectedOutput: `var x = 0;\n` + }); }); it("Sets module name", () => { @@ -66,12 +128,15 @@ var x = 0;`, ` }\n` + ` }\n` + `});\n`; - runTest("var x = 1;", { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, /*fileName*/ undefined, "NamedModule", output) + test("var x = 1;", + { + options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" }, + expectedOutput: output + }) }); it("No extra errors for file without extension", () => { - runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, "file", /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/[]); + test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "file" } }); }); - }); } From 0f828ca91b75b79c391aeda9c5f494d70db5937f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 22 Jul 2015 12:05:30 -0700 Subject: [PATCH 45/85] Accepted baselines. --- tests/baselines/reference/defaultExportsCannotMerge01.js | 1 + tests/baselines/reference/defaultExportsCannotMerge02.js | 1 + tests/baselines/reference/multipleDefaultExports01.js | 3 +++ tests/baselines/reference/multipleDefaultExports02.js | 2 ++ 4 files changed, 7 insertions(+) diff --git a/tests/baselines/reference/defaultExportsCannotMerge01.js b/tests/baselines/reference/defaultExportsCannotMerge01.js index 3e0a61d54d4..99b8ecab1d3 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge01.js +++ b/tests/baselines/reference/defaultExportsCannotMerge01.js @@ -34,6 +34,7 @@ Entity.y; function Decl() { return 0; } +Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Decl; var Decl; (function (Decl) { diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.js b/tests/baselines/reference/defaultExportsCannotMerge02.js index 72a8e3c5f1d..e3897395c74 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge02.js +++ b/tests/baselines/reference/defaultExportsCannotMerge02.js @@ -31,6 +31,7 @@ var Decl = (function () { } return Decl; })(); +Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Decl; //// [m2.js] var m1_1 = require("m1"); diff --git a/tests/baselines/reference/multipleDefaultExports01.js b/tests/baselines/reference/multipleDefaultExports01.js index 8faf33388c6..e633cf69f55 100644 --- a/tests/baselines/reference/multipleDefaultExports01.js +++ b/tests/baselines/reference/multipleDefaultExports01.js @@ -24,11 +24,14 @@ var foo = (function () { } return foo; })(); +Object.defineProperty(exports, "__esModule", { value: true }); exports.default = foo; function bar() { } +Object.defineProperty(exports, "__esModule", { value: true }); exports.default = bar; var x = 10; +Object.defineProperty(exports, "__esModule", { value: true }); exports.default = x; //// [m2.js] var m1_1 = require("m1"); diff --git a/tests/baselines/reference/multipleDefaultExports02.js b/tests/baselines/reference/multipleDefaultExports02.js index faec7c9d2b4..3d1b84ff6a6 100644 --- a/tests/baselines/reference/multipleDefaultExports02.js +++ b/tests/baselines/reference/multipleDefaultExports02.js @@ -18,9 +18,11 @@ Entity(); //// [m1.js] function foo() { } +Object.defineProperty(exports, "__esModule", { value: true }); exports.default = foo; function bar() { } +Object.defineProperty(exports, "__esModule", { value: true }); exports.default = bar; //// [m2.js] var m1_1 = require("m1"); From 753f0f8d1c7c514f415a8277cb9ed9f56a5fe2f6 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 22 Jul 2015 13:58:25 -0700 Subject: [PATCH 46/85] Don't add an inference candidate if it contains the anyFunctionType --- src/compiler/checker.ts | 22 ++++++++++++---------- src/compiler/types.ts | 8 ++++++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c09b069bee6..e0777dc67b7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -112,6 +112,8 @@ namespace ts { emptyGenericType.instantiations = {}; let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + anyFunctionType.flags |= TypeFlags.ContainsAnyFunctionType; + let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); let anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false); @@ -3759,19 +3761,19 @@ namespace ts { // This function is used to propagate widening flags when creating new object types references and union types. // It is only necessary to do so if a constituent type might be the undefined type, the null type, or the type // of an object literal (since those types have widening related information we need to track). - function getWideningFlagsOfTypes(types: Type[]): TypeFlags { + function getContainsLiteralFlagsOfTypes(types: Type[]): TypeFlags { let result: TypeFlags = 0; for (let type of types) { result |= type.flags; } - return result & TypeFlags.RequiresWidening; + return result & TypeFlags.ContainsLiteralFlags; } function createTypeReference(target: GenericType, typeArguments: Type[]): TypeReference { let id = getTypeListId(typeArguments); let type = target.instantiations[id]; if (!type) { - let flags = TypeFlags.Reference | getWideningFlagsOfTypes(typeArguments); + let flags = TypeFlags.Reference | getContainsLiteralFlagsOfTypes(typeArguments); type = target.instantiations[id] = createObjectType(flags, target.symbol); type.target = target; type.typeArguments = typeArguments; @@ -4025,7 +4027,7 @@ namespace ts { let id = getTypeListId(elementTypes); let type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(TypeFlags.Tuple | getWideningFlagsOfTypes(elementTypes)); + type = tupleTypes[id] = createObjectType(TypeFlags.Tuple | getContainsLiteralFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -4174,7 +4176,7 @@ namespace ts { let id = getTypeListId(typeSet); let type = unionTypes[id]; if (!type) { - type = unionTypes[id] = createObjectType(TypeFlags.Union | getWideningFlagsOfTypes(typeSet)); + type = unionTypes[id] = createObjectType(TypeFlags.Union | getContainsLiteralFlagsOfTypes(typeSet)); type.types = typeSet; } return type; @@ -4208,7 +4210,7 @@ namespace ts { let id = getTypeListId(typeSet); let type = intersectionTypes[id]; if (!type) { - type = intersectionTypes[id] = createObjectType(TypeFlags.Intersection | getWideningFlagsOfTypes(typeSet)); + type = intersectionTypes[id] = createObjectType(TypeFlags.Intersection | getContainsLiteralFlagsOfTypes(typeSet)); type.types = typeSet; } return type; @@ -5655,11 +5657,11 @@ namespace ts { } function inferFromTypes(source: Type, target: Type) { - if (source === anyFunctionType) { - return; - } if (target.flags & TypeFlags.TypeParameter) { // If target is a type parameter, make an inference + if (source.flags & TypeFlags.ContainsAnyFunctionType) { + return; + } let typeParameters = context.typeParameters; for (let i = 0; i < typeParameters.length; i++) { if (target === typeParameters[i]) { @@ -7092,7 +7094,7 @@ namespace ts { let stringIndexType = getIndexType(IndexKind.String); let numberIndexType = getIndexType(IndexKind.Number); let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull); + result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsLiteralFlags); return result; function getIndexType(kind: IndexKind) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8d5596c6f64..02c45968e21 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1767,7 +1767,9 @@ namespace ts { ContainsUndefinedOrNull = 0x00200000, // Type is or contains Undefined or Null type /* @internal */ ContainsObjectLiteral = 0x00400000, // Type is or contains object literal type - ESSymbol = 0x00800000, // Type of symbol primitive introduced in ES6 + /* @internal */ + ContainsAnyFunctionType = 0x00800000, // Type is or contains object literal type + ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6 /* @internal */ Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null, @@ -1779,7 +1781,9 @@ namespace ts { UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, /* @internal */ - RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral + RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral, + /* @internal */ + ContainsLiteralFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType } // Properties common to all types From ab51ccc7f3bb9633d00aa5f03ed6ca6ae2d3033a Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 22 Jul 2015 13:58:36 -0700 Subject: [PATCH 47/85] Accept baseline --- .../reference/inferentialTypingUsingApparentType2.types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/inferentialTypingUsingApparentType2.types b/tests/baselines/reference/inferentialTypingUsingApparentType2.types index 597f5885f5a..5841e021c3a 100644 --- a/tests/baselines/reference/inferentialTypingUsingApparentType2.types +++ b/tests/baselines/reference/inferentialTypingUsingApparentType2.types @@ -13,7 +13,7 @@ function foo(x: T): T { } foo({ m(x) { return x.length } }); ->foo({ m(x) { return x.length } }) : { } +>foo({ m(x) { return x.length } }) : { m(x: string): number; } >foo : (x: T) => T >{ m(x) { return x.length } } : { m(x: string): number; } >m : (x: string) => number From 8529de64d77aadf367ac54a223a329f0ae8f9aac Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 22 Jul 2015 13:58:43 -0700 Subject: [PATCH 48/85] Add tests --- .../reference/inferringAnyFunctionType1.js | 12 ++++++++++ .../inferringAnyFunctionType1.symbols | 19 +++++++++++++++ .../reference/inferringAnyFunctionType1.types | 22 +++++++++++++++++ .../reference/inferringAnyFunctionType2.js | 12 ++++++++++ .../inferringAnyFunctionType2.symbols | 19 +++++++++++++++ .../reference/inferringAnyFunctionType2.types | 22 +++++++++++++++++ .../reference/inferringAnyFunctionType3.js | 12 ++++++++++ .../inferringAnyFunctionType3.symbols | 19 +++++++++++++++ .../reference/inferringAnyFunctionType3.types | 22 +++++++++++++++++ .../reference/inferringAnyFunctionType4.js | 12 ++++++++++ .../inferringAnyFunctionType4.symbols | 19 +++++++++++++++ .../reference/inferringAnyFunctionType4.types | 21 ++++++++++++++++ .../reference/inferringAnyFunctionType5.js | 12 ++++++++++ .../inferringAnyFunctionType5.symbols | 21 ++++++++++++++++ .../reference/inferringAnyFunctionType5.types | 24 +++++++++++++++++++ .../compiler/inferringAnyFunctionType1.ts | 5 ++++ .../compiler/inferringAnyFunctionType2.ts | 5 ++++ .../compiler/inferringAnyFunctionType3.ts | 5 ++++ .../compiler/inferringAnyFunctionType4.ts | 5 ++++ .../compiler/inferringAnyFunctionType5.ts | 5 ++++ 20 files changed, 293 insertions(+) create mode 100644 tests/baselines/reference/inferringAnyFunctionType1.js create mode 100644 tests/baselines/reference/inferringAnyFunctionType1.symbols create mode 100644 tests/baselines/reference/inferringAnyFunctionType1.types create mode 100644 tests/baselines/reference/inferringAnyFunctionType2.js create mode 100644 tests/baselines/reference/inferringAnyFunctionType2.symbols create mode 100644 tests/baselines/reference/inferringAnyFunctionType2.types create mode 100644 tests/baselines/reference/inferringAnyFunctionType3.js create mode 100644 tests/baselines/reference/inferringAnyFunctionType3.symbols create mode 100644 tests/baselines/reference/inferringAnyFunctionType3.types create mode 100644 tests/baselines/reference/inferringAnyFunctionType4.js create mode 100644 tests/baselines/reference/inferringAnyFunctionType4.symbols create mode 100644 tests/baselines/reference/inferringAnyFunctionType4.types create mode 100644 tests/baselines/reference/inferringAnyFunctionType5.js create mode 100644 tests/baselines/reference/inferringAnyFunctionType5.symbols create mode 100644 tests/baselines/reference/inferringAnyFunctionType5.types create mode 100644 tests/cases/compiler/inferringAnyFunctionType1.ts create mode 100644 tests/cases/compiler/inferringAnyFunctionType2.ts create mode 100644 tests/cases/compiler/inferringAnyFunctionType3.ts create mode 100644 tests/cases/compiler/inferringAnyFunctionType4.ts create mode 100644 tests/cases/compiler/inferringAnyFunctionType5.ts diff --git a/tests/baselines/reference/inferringAnyFunctionType1.js b/tests/baselines/reference/inferringAnyFunctionType1.js new file mode 100644 index 00000000000..6b48cf2db58 --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType1.js @@ -0,0 +1,12 @@ +//// [inferringAnyFunctionType1.ts] +function f number }>(p: T): T { + return p; +} + +var v = f([x => x]); + +//// [inferringAnyFunctionType1.js] +function f(p) { + return p; +} +var v = f([function (x) { return x; }]); diff --git a/tests/baselines/reference/inferringAnyFunctionType1.symbols b/tests/baselines/reference/inferringAnyFunctionType1.symbols new file mode 100644 index 00000000000..6a43952d770 --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType1.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/inferringAnyFunctionType1.ts === +function f number }>(p: T): T { +>f : Symbol(f, Decl(inferringAnyFunctionType1.ts, 0, 0)) +>T : Symbol(T, Decl(inferringAnyFunctionType1.ts, 0, 11)) +>p1 : Symbol(p1, Decl(inferringAnyFunctionType1.ts, 0, 29)) +>p : Symbol(p, Decl(inferringAnyFunctionType1.ts, 0, 54)) +>T : Symbol(T, Decl(inferringAnyFunctionType1.ts, 0, 11)) +>T : Symbol(T, Decl(inferringAnyFunctionType1.ts, 0, 11)) + + return p; +>p : Symbol(p, Decl(inferringAnyFunctionType1.ts, 0, 54)) +} + +var v = f([x => x]); +>v : Symbol(v, Decl(inferringAnyFunctionType1.ts, 4, 3)) +>f : Symbol(f, Decl(inferringAnyFunctionType1.ts, 0, 0)) +>x : Symbol(x, Decl(inferringAnyFunctionType1.ts, 4, 11)) +>x : Symbol(x, Decl(inferringAnyFunctionType1.ts, 4, 11)) + diff --git a/tests/baselines/reference/inferringAnyFunctionType1.types b/tests/baselines/reference/inferringAnyFunctionType1.types new file mode 100644 index 00000000000..16402cc3ced --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType1.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/inferringAnyFunctionType1.ts === +function f number }>(p: T): T { +>f : number; }>(p: T) => T +>T : T +>p1 : number +>p : T +>T : T +>T : T + + return p; +>p : T +} + +var v = f([x => x]); +>v : [(x: number) => number] +>f([x => x]) : [(x: number) => number] +>f : number; }>(p: T) => T +>[x => x] : [(x: number) => number] +>x => x : (x: number) => number +>x : number +>x : number + diff --git a/tests/baselines/reference/inferringAnyFunctionType2.js b/tests/baselines/reference/inferringAnyFunctionType2.js new file mode 100644 index 00000000000..3841793233e --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType2.js @@ -0,0 +1,12 @@ +//// [inferringAnyFunctionType2.ts] +function f number]>(p: T): T { + return p; +} + +var v = f([x => x]); + +//// [inferringAnyFunctionType2.js] +function f(p) { + return p; +} +var v = f([function (x) { return x; }]); diff --git a/tests/baselines/reference/inferringAnyFunctionType2.symbols b/tests/baselines/reference/inferringAnyFunctionType2.symbols new file mode 100644 index 00000000000..9bdb627d46d --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType2.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/inferringAnyFunctionType2.ts === +function f number]>(p: T): T { +>f : Symbol(f, Decl(inferringAnyFunctionType2.ts, 0, 0)) +>T : Symbol(T, Decl(inferringAnyFunctionType2.ts, 0, 11)) +>p1 : Symbol(p1, Decl(inferringAnyFunctionType2.ts, 0, 23)) +>p : Symbol(p, Decl(inferringAnyFunctionType2.ts, 0, 47)) +>T : Symbol(T, Decl(inferringAnyFunctionType2.ts, 0, 11)) +>T : Symbol(T, Decl(inferringAnyFunctionType2.ts, 0, 11)) + + return p; +>p : Symbol(p, Decl(inferringAnyFunctionType2.ts, 0, 47)) +} + +var v = f([x => x]); +>v : Symbol(v, Decl(inferringAnyFunctionType2.ts, 4, 3)) +>f : Symbol(f, Decl(inferringAnyFunctionType2.ts, 0, 0)) +>x : Symbol(x, Decl(inferringAnyFunctionType2.ts, 4, 11)) +>x : Symbol(x, Decl(inferringAnyFunctionType2.ts, 4, 11)) + diff --git a/tests/baselines/reference/inferringAnyFunctionType2.types b/tests/baselines/reference/inferringAnyFunctionType2.types new file mode 100644 index 00000000000..7884bdfc6ba --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType2.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/inferringAnyFunctionType2.ts === +function f number]>(p: T): T { +>f : number]>(p: T) => T +>T : T +>p1 : number +>p : T +>T : T +>T : T + + return p; +>p : T +} + +var v = f([x => x]); +>v : [(x: number) => number] +>f([x => x]) : [(x: number) => number] +>f : number]>(p: T) => T +>[x => x] : [(x: number) => number] +>x => x : (x: number) => number +>x : number +>x : number + diff --git a/tests/baselines/reference/inferringAnyFunctionType3.js b/tests/baselines/reference/inferringAnyFunctionType3.js new file mode 100644 index 00000000000..ed1c4348dfc --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType3.js @@ -0,0 +1,12 @@ +//// [inferringAnyFunctionType3.ts] +function f number)[]>(p: T): T { + return p; +} + +var v = f([x => x]); + +//// [inferringAnyFunctionType3.js] +function f(p) { + return p; +} +var v = f([function (x) { return x; }]); diff --git a/tests/baselines/reference/inferringAnyFunctionType3.symbols b/tests/baselines/reference/inferringAnyFunctionType3.symbols new file mode 100644 index 00000000000..472d170b81d --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType3.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/inferringAnyFunctionType3.ts === +function f number)[]>(p: T): T { +>f : Symbol(f, Decl(inferringAnyFunctionType3.ts, 0, 0)) +>T : Symbol(T, Decl(inferringAnyFunctionType3.ts, 0, 11)) +>p1 : Symbol(p1, Decl(inferringAnyFunctionType3.ts, 0, 23)) +>p : Symbol(p, Decl(inferringAnyFunctionType3.ts, 0, 49)) +>T : Symbol(T, Decl(inferringAnyFunctionType3.ts, 0, 11)) +>T : Symbol(T, Decl(inferringAnyFunctionType3.ts, 0, 11)) + + return p; +>p : Symbol(p, Decl(inferringAnyFunctionType3.ts, 0, 49)) +} + +var v = f([x => x]); +>v : Symbol(v, Decl(inferringAnyFunctionType3.ts, 4, 3)) +>f : Symbol(f, Decl(inferringAnyFunctionType3.ts, 0, 0)) +>x : Symbol(x, Decl(inferringAnyFunctionType3.ts, 4, 11)) +>x : Symbol(x, Decl(inferringAnyFunctionType3.ts, 4, 11)) + diff --git a/tests/baselines/reference/inferringAnyFunctionType3.types b/tests/baselines/reference/inferringAnyFunctionType3.types new file mode 100644 index 00000000000..1edcfc34643 --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType3.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/inferringAnyFunctionType3.ts === +function f number)[]>(p: T): T { +>f : number)[]>(p: T) => T +>T : T +>p1 : number +>p : T +>T : T +>T : T + + return p; +>p : T +} + +var v = f([x => x]); +>v : ((x: number) => number)[] +>f([x => x]) : ((x: number) => number)[] +>f : number)[]>(p: T) => T +>[x => x] : ((x: number) => number)[] +>x => x : (x: number) => number +>x : number +>x : number + diff --git a/tests/baselines/reference/inferringAnyFunctionType4.js b/tests/baselines/reference/inferringAnyFunctionType4.js new file mode 100644 index 00000000000..dccc51920b0 --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType4.js @@ -0,0 +1,12 @@ +//// [inferringAnyFunctionType4.ts] +function f number>(p: T): T { + return p; +} + +var v = f(x => x); + +//// [inferringAnyFunctionType4.js] +function f(p) { + return p; +} +var v = f(function (x) { return x; }); diff --git a/tests/baselines/reference/inferringAnyFunctionType4.symbols b/tests/baselines/reference/inferringAnyFunctionType4.symbols new file mode 100644 index 00000000000..bfbacfc277c --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType4.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/inferringAnyFunctionType4.ts === +function f number>(p: T): T { +>f : Symbol(f, Decl(inferringAnyFunctionType4.ts, 0, 0)) +>T : Symbol(T, Decl(inferringAnyFunctionType4.ts, 0, 11)) +>p1 : Symbol(p1, Decl(inferringAnyFunctionType4.ts, 0, 22)) +>p : Symbol(p, Decl(inferringAnyFunctionType4.ts, 0, 45)) +>T : Symbol(T, Decl(inferringAnyFunctionType4.ts, 0, 11)) +>T : Symbol(T, Decl(inferringAnyFunctionType4.ts, 0, 11)) + + return p; +>p : Symbol(p, Decl(inferringAnyFunctionType4.ts, 0, 45)) +} + +var v = f(x => x); +>v : Symbol(v, Decl(inferringAnyFunctionType4.ts, 4, 3)) +>f : Symbol(f, Decl(inferringAnyFunctionType4.ts, 0, 0)) +>x : Symbol(x, Decl(inferringAnyFunctionType4.ts, 4, 10)) +>x : Symbol(x, Decl(inferringAnyFunctionType4.ts, 4, 10)) + diff --git a/tests/baselines/reference/inferringAnyFunctionType4.types b/tests/baselines/reference/inferringAnyFunctionType4.types new file mode 100644 index 00000000000..49d46d0433e --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType4.types @@ -0,0 +1,21 @@ +=== tests/cases/compiler/inferringAnyFunctionType4.ts === +function f number>(p: T): T { +>f : number>(p: T) => T +>T : T +>p1 : number +>p : T +>T : T +>T : T + + return p; +>p : T +} + +var v = f(x => x); +>v : (x: number) => number +>f(x => x) : (x: number) => number +>f : number>(p: T) => T +>x => x : (x: number) => number +>x : number +>x : number + diff --git a/tests/baselines/reference/inferringAnyFunctionType5.js b/tests/baselines/reference/inferringAnyFunctionType5.js new file mode 100644 index 00000000000..babbab1be9e --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType5.js @@ -0,0 +1,12 @@ +//// [inferringAnyFunctionType5.ts] +function f number }>(p: T): T { + return p; +} + +var v = f({ q: x => x }); + +//// [inferringAnyFunctionType5.js] +function f(p) { + return p; +} +var v = f({ q: function (x) { return x; } }); diff --git a/tests/baselines/reference/inferringAnyFunctionType5.symbols b/tests/baselines/reference/inferringAnyFunctionType5.symbols new file mode 100644 index 00000000000..abf0fe68f46 --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType5.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/inferringAnyFunctionType5.ts === +function f number }>(p: T): T { +>f : Symbol(f, Decl(inferringAnyFunctionType5.ts, 0, 0)) +>T : Symbol(T, Decl(inferringAnyFunctionType5.ts, 0, 11)) +>q : Symbol(q, Decl(inferringAnyFunctionType5.ts, 0, 22)) +>p1 : Symbol(p1, Decl(inferringAnyFunctionType5.ts, 0, 27)) +>p : Symbol(p, Decl(inferringAnyFunctionType5.ts, 0, 52)) +>T : Symbol(T, Decl(inferringAnyFunctionType5.ts, 0, 11)) +>T : Symbol(T, Decl(inferringAnyFunctionType5.ts, 0, 11)) + + return p; +>p : Symbol(p, Decl(inferringAnyFunctionType5.ts, 0, 52)) +} + +var v = f({ q: x => x }); +>v : Symbol(v, Decl(inferringAnyFunctionType5.ts, 4, 3)) +>f : Symbol(f, Decl(inferringAnyFunctionType5.ts, 0, 0)) +>q : Symbol(q, Decl(inferringAnyFunctionType5.ts, 4, 11)) +>x : Symbol(x, Decl(inferringAnyFunctionType5.ts, 4, 14)) +>x : Symbol(x, Decl(inferringAnyFunctionType5.ts, 4, 14)) + diff --git a/tests/baselines/reference/inferringAnyFunctionType5.types b/tests/baselines/reference/inferringAnyFunctionType5.types new file mode 100644 index 00000000000..8f7ae123eac --- /dev/null +++ b/tests/baselines/reference/inferringAnyFunctionType5.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/inferringAnyFunctionType5.ts === +function f number }>(p: T): T { +>f : number; }>(p: T) => T +>T : T +>q : (p1: number) => number +>p1 : number +>p : T +>T : T +>T : T + + return p; +>p : T +} + +var v = f({ q: x => x }); +>v : { q: (x: number) => number; } +>f({ q: x => x }) : { q: (x: number) => number; } +>f : number; }>(p: T) => T +>{ q: x => x } : { q: (x: number) => number; } +>q : (x: number) => number +>x => x : (x: number) => number +>x : number +>x : number + diff --git a/tests/cases/compiler/inferringAnyFunctionType1.ts b/tests/cases/compiler/inferringAnyFunctionType1.ts new file mode 100644 index 00000000000..bc1e6f68973 --- /dev/null +++ b/tests/cases/compiler/inferringAnyFunctionType1.ts @@ -0,0 +1,5 @@ +function f number }>(p: T): T { + return p; +} + +var v = f([x => x]); \ No newline at end of file diff --git a/tests/cases/compiler/inferringAnyFunctionType2.ts b/tests/cases/compiler/inferringAnyFunctionType2.ts new file mode 100644 index 00000000000..0984e578f67 --- /dev/null +++ b/tests/cases/compiler/inferringAnyFunctionType2.ts @@ -0,0 +1,5 @@ +function f number]>(p: T): T { + return p; +} + +var v = f([x => x]); \ No newline at end of file diff --git a/tests/cases/compiler/inferringAnyFunctionType3.ts b/tests/cases/compiler/inferringAnyFunctionType3.ts new file mode 100644 index 00000000000..4576a30898a --- /dev/null +++ b/tests/cases/compiler/inferringAnyFunctionType3.ts @@ -0,0 +1,5 @@ +function f number)[]>(p: T): T { + return p; +} + +var v = f([x => x]); \ No newline at end of file diff --git a/tests/cases/compiler/inferringAnyFunctionType4.ts b/tests/cases/compiler/inferringAnyFunctionType4.ts new file mode 100644 index 00000000000..592908bdfec --- /dev/null +++ b/tests/cases/compiler/inferringAnyFunctionType4.ts @@ -0,0 +1,5 @@ +function f number>(p: T): T { + return p; +} + +var v = f(x => x); \ No newline at end of file diff --git a/tests/cases/compiler/inferringAnyFunctionType5.ts b/tests/cases/compiler/inferringAnyFunctionType5.ts new file mode 100644 index 00000000000..2ff4a325c5a --- /dev/null +++ b/tests/cases/compiler/inferringAnyFunctionType5.ts @@ -0,0 +1,5 @@ +function f number }>(p: T): T { + return p; +} + +var v = f({ q: x => x }); \ No newline at end of file From f42fd6296842c7b14820f3287b5bed2197680612 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 22 Jul 2015 14:03:53 -0700 Subject: [PATCH 49/85] Add comments --- src/compiler/checker.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e0777dc67b7..b6d3a3347c5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -112,6 +112,8 @@ namespace ts { emptyGenericType.instantiations = {}; let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated + // in getContainsLiteralFlagsOfTypes, and it is checked in inferFromTypes. anyFunctionType.flags |= TypeFlags.ContainsAnyFunctionType; let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -5658,10 +5660,16 @@ namespace ts { function inferFromTypes(source: Type, target: Type) { if (target.flags & TypeFlags.TypeParameter) { - // If target is a type parameter, make an inference + // If target is a type parameter, make an inference, unless the source type contains + // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions). + // Because the anyFunctionType is internal, it should not be exposed to the user by adding + // it as an inference candidate. Hopefully, a better candidate will come along that does + // not contain anyFunctionType when we come back to this argument for its second round + // of inference. if (source.flags & TypeFlags.ContainsAnyFunctionType) { return; } + let typeParameters = context.typeParameters; for (let i = 0; i < typeParameters.length; i++) { if (target === typeParameters[i]) { From 3270e71fcf66bc10a4b4f002a00297c5c0b7c470 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 22 Jul 2015 14:36:06 -0700 Subject: [PATCH 50/85] Address CR --- src/compiler/checker.ts | 6 ++++-- src/compiler/diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/classExtendsNull.errors.txt | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 634d64516a4..0ccf23164cb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10250,11 +10250,13 @@ namespace ts { // constructors of derived classes must contain at least one super call somewhere in their function body. let containingClassDecl = node.parent; if (getClassExtendsHeritageClauseElement(containingClassDecl)) { - let baseConstructorType = getBaseConstructorTypeOfClass(containingClassDecl); + let symbol = getSymbolOfNode(containingClassDecl); + let type = getDeclaredTypeOfSymbol(symbol); + let baseConstructorType = getBaseConstructorTypeOfClass(type); if (containsSuperCall(node.body)) { if (baseConstructorType === nullType) { - error(node, Diagnostics.A_constructor_can_not_contain_super_call_when_a_class_extends_null); + error(node, Diagnostics.A_constructor_cannot_contain_super_call_when_a_class_extends_null); } // The first statement in the body of a constructor must be a super call if both of the following are true: diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 80698217a4b..44f14ac0995 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -613,6 +613,6 @@ namespace ts { Expected_corresponding_JSX_closing_tag_for_0: { code: 17002, category: DiagnosticCategory.Error, key: "Expected corresponding JSX closing tag for '{0}'." }, JSX_attribute_expected: { code: 17003, category: DiagnosticCategory.Error, key: "JSX attribute expected." }, Cannot_use_JSX_unless_the_jsx_flag_is_provided: { code: 17004, category: DiagnosticCategory.Error, key: "Cannot use JSX unless the '--jsx' flag is provided." }, - A_constructor_can_not_contain_super_call_when_a_class_extends_null: { code: 17005, category: DiagnosticCategory.Error, key: "A constructor can not contain super call when a class extends null" }, + A_constructor_cannot_contain_super_call_when_a_class_extends_null: { code: 17005, category: DiagnosticCategory.Error, key: "A constructor cannot contain 'super' call when a class extends 'null'" }, }; } \ No newline at end of file diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6f1185eb250..1203c5ef61e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2446,7 +2446,7 @@ "category": "Error", "code": 17004 }, - "A constructor can not contain super call when a class extends null": { + "A constructor cannot contain 'super' call when a class extends 'null'": { "category": "Error", "code": 17005 } diff --git a/tests/baselines/reference/classExtendsNull.errors.txt b/tests/baselines/reference/classExtendsNull.errors.txt index 93ef3b7765e..cc5de5cda83 100644 --- a/tests/baselines/reference/classExtendsNull.errors.txt +++ b/tests/baselines/reference/classExtendsNull.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor can not contain super call when a class extends null +tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor cannot contain 'super' call when a class extends 'null' ==== tests/cases/compiler/classExtendsNull.ts (1 errors) ==== @@ -11,7 +11,7 @@ tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor can ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~~~~~ -!!! error TS17005: A constructor can not contain super call when a class extends null +!!! error TS17005: A constructor cannot contain 'super' call when a class extends 'null' } class D extends null { From d6998da76129f8574c4c3b947abd9ba9519cd58b Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 22 Jul 2015 15:27:25 -0700 Subject: [PATCH 51/85] Add getBaseTypes on TypeObject in services --- src/compiler/checker.ts | 1 + src/compiler/types.ts | 3 +++ src/services/services.ts | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c09b069bee6..cc3341fb594 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -68,6 +68,7 @@ namespace ts { getPropertyOfType, getSignaturesOfType, getIndexTypeOfType, + getBaseTypes, getReturnTypeOfSignature, getSymbolsInScope, getSymbolAtLocation, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8d5596c6f64..21eed30c244 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1404,6 +1404,7 @@ namespace ts { getPropertyOfType(type: Type, propertyName: string): Symbol; getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type; + getBaseTypes(type: InterfaceType): ObjectType[]; getReturnTypeOfSignature(signature: Signature): Type; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; @@ -1808,7 +1809,9 @@ namespace ts { typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic) outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none) localTypeParameters: TypeParameter[]; // Local type parameters (undefined if none) + /* @internal */ resolvedBaseConstructorType?: Type; // Resolved base constructor type of class + /* @internal */ resolvedBaseTypes: ObjectType[]; // Resolved base types } diff --git a/src/services/services.ts b/src/services/services.ts index 16f5b0b91fe..47ccc5c73aa 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -48,6 +48,7 @@ namespace ts { getConstructSignatures(): Signature[]; getStringIndexType(): Type; getNumberIndexType(): Type; + getBaseTypes(): ObjectType[] } export interface Signature { @@ -682,6 +683,11 @@ namespace ts { getNumberIndexType(): Type { return this.checker.getIndexTypeOfType(this, IndexKind.Number); } + getBaseTypes(): ObjectType[] { + return this.flags & (TypeFlags.Class | TypeFlags.Interface) + ? this.checker.getBaseTypes(this) + : undefined; + } } class SignatureObject implements Signature { From 55b2eca48e272b33191bdcc81f1b6b48021f455e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 22 Jul 2015 16:48:03 -0700 Subject: [PATCH 52/85] Add AUTHORS.md --- AUTHORS.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 AUTHORS.md diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 00000000000..1c45bf17cf5 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1,45 @@ +TypeScript is authored by: + +* Ahmad Farid +* Anders Hejlsberg +* Arnav Singh +* Basarat Ali Syed +* Bill Ticehurst +* Bryan Forbes +* Caitlin Potter +* Chris Bubernak +* Colin Snover +* Cyrus Najmabadi +* Dan Quirk +* Daniel Rosenwasser +* Dick van den Brink +* Dirk Bäumer +* Frank Wallis +* Guillaume Salles +* Ivo Gabe de Wolff +* James Whitney +* Jason Freeman +* Jason Ramsay +* Johannes Rieken +* Jonathan Bond- Caron +* Kagami Sascha Rosylight +* Keith Mashinter +* Lorant Pinter +* Masahiro Wakame +* Mohamed Hegazy +* Oleg Mihailik +* Paul van Brenk +* Pedro Maltez +* Ron Buckton +* Ryan Cavanaugh +* Sheetal Nandi +* Shengping Zhong +* Stan Thomas +* Steve Lucco +* Tingan Ho +* Tomas Grubliauskas +* TruongSinh Tran-Nguyen +* Vladimir Matveev +* Yui Tanglertsampan +* Zev Spitz +* Zhengbo Li \ No newline at end of file From 98d747415183d2f924e9af0e7fd52f3b07ccbcfd Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 22 Jul 2015 17:19:42 -0700 Subject: [PATCH 53/85] Update AUTHORS.md for release 1.6 --- AUTHORS.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/AUTHORS.md b/AUTHORS.md index 1c45bf17cf5..0ade4c31221 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,45 +1,70 @@ TypeScript is authored by: +* Adam Freidin * Ahmad Farid * Anders Hejlsberg * Arnav Singh +* Arthur Ozga * Basarat Ali Syed +* Ben Duffield * Bill Ticehurst * Bryan Forbes * Caitlin Potter * Chris Bubernak +* Colby Russell * Colin Snover * Cyrus Najmabadi * Dan Quirk * Daniel Rosenwasser +* David Li * Dick van den Brink * Dirk Bäumer * Frank Wallis +* Gabriel Isenberg +* Gilad Peleg * Guillaume Salles +* Harald Niesche +* Ingvar Stepanyan * Ivo Gabe de Wolff * James Whitney * Jason Freeman * Jason Ramsay +* Jed Mao * Johannes Rieken -* Jonathan Bond- Caron +* Jonathan Bond-Caron +* Jonathan Park +* Jonathan Turner +* Josh Kalderimis * Kagami Sascha Rosylight * Keith Mashinter +* Kenji Imamula * Lorant Pinter * Masahiro Wakame +* Max Deepfield +* Micah Zoltu * Mohamed Hegazy * Oleg Mihailik +* Oleksandr Chekhovskyi * Paul van Brenk * Pedro Maltez +* Philip Bulley +* piloopin * Ron Buckton * Ryan Cavanaugh * Sheetal Nandi * Shengping Zhong +* Shyyko Serhiy +* Simon Hürlimann +* Solal Pirelli * Stan Thomas * Steve Lucco +* Tien Hoanhtien * Tingan Ho +* togru * Tomas Grubliauskas * TruongSinh Tran-Nguyen * Vladimir Matveev +* Wesley Wigham * Yui Tanglertsampan * Zev Spitz * Zhengbo Li \ No newline at end of file From c42b9f84fe9896567f467bed996825ceb9094049 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 23 Jul 2015 10:53:57 -0700 Subject: [PATCH 54/85] fixed a typo --- tests/cases/fourslash/fourslash.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 0008b33673f..cbba2e916ce 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -39,7 +39,7 @@ // Explanation: // We want type-completion while we edit this file, but at compile time/while editting fourslash tests, // we don't want to include the following reference because we are compiling this file in "--out" mode and don't want to rope -// in the entire codebase into the compilattion each fourslash test. Additionally, we don't want to expose the +// in the entire codebase into the compilation each fourslash test. Additionally, we don't want to expose the // src/harness/fourslash.ts API's (or the rest of the compiler) because they are unstable and complicate the // fourslash testing DSL. Finally, in this case, runtime reflection is (much) faster. // From 5fb5b244fbd9c1360b539798dd36ec9ab868badf Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 11:14:19 -0700 Subject: [PATCH 55/85] Feedback from PR, lint fixes --- tests/cases/unittests/session.ts | 819 +++++++++++++++---------------- 1 file changed, 407 insertions(+), 412 deletions(-) diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts index 1d7b9572bbb..1d2efbb498c 100644 --- a/tests/cases/unittests/session.ts +++ b/tests/cases/unittests/session.ts @@ -1,24 +1,24 @@ /// module ts.server { - let lastWrittenToHost: string, - mockHost: ServerHost = { - args: [], - newLine: '\n', - useCaseSensitiveFileNames: true, - write: (s) => lastWrittenToHost = s, - readFile: () => void 0, - writeFile: () => void 0, - resolvePath: () => void 0, - fileExists: () => false, - directoryExists: () => false, - createDirectory: () => void 0, - getExecutingFilePath: () => void 0, - getCurrentDirectory: () => void 0, - readDirectory: () => void 0, - exit: () => void 0 - }, - mockLogger: Logger = { + let lastWrittenToHost: string; + const mockHost: ServerHost = { + args: [], + newLine: "\n", + useCaseSensitiveFileNames: true, + write(s): void { lastWrittenToHost = s; }, + readFile(): string { return void 0; }, + writeFile(): void {}, + resolvePath(): string { return void 0; }, + fileExists: () => false, + directoryExists: () => false, + createDirectory(): void {}, + getExecutingFilePath(): string { return void 0; }, + getCurrentDirectory(): string { return void 0; }, + readDirectory(): string[] { return []; }, + exit(): void {} + }; + const mockLogger: Logger = { close(): void {}, isVerbose(): boolean { return false; }, loggingEnabled(): boolean { return false; }, @@ -27,433 +27,428 @@ module ts.server { startGroup(): void {}, endGroup(): void {}, msg(s: string, type?: string): void {}, - }; - - describe('the Session class', () => { - let session: Session, - lastSent: protocol.Message; + }; + + describe("the Session class", () => { + let session: Session; + let lastSent: protocol.Message; - beforeEach(() => { - session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger); - session.send = (msg: protocol.Message) => { - lastSent = msg; - }; - }); + beforeEach(() => { + session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + session.send = (msg: protocol.Message) => { + lastSent = msg; + }; + }); - describe('executeCommand', () => { - it('should throw when commands are executed with invalid arguments', () => { - let req : protocol.FileRequest = { - command: CommandNames.Open, - seq: 0, - type: 'command', - arguments: { - file: undefined - } - }; + describe("executeCommand", () => { + it("should throw when commands are executed with invalid arguments", () => { + const req: protocol.FileRequest = { + command: CommandNames.Open, + seq: 0, + type: "command", + arguments: { + file: undefined + } + }; - expect(() => session.executeCommand(req)).to.throw(); - }); - it('should output an error response when a command does not exist', () => { - let req : protocol.Request = { - command: 'foobar', - seq: 0, - type: 'command' - }; + expect(() => session.executeCommand(req)).to.throw(); + }); + it("should output an error response when a command does not exist", () => { + const req: protocol.Request = { + command: "foobar", + seq: 0, + type: "command" + }; - session.executeCommand(req); + session.executeCommand(req); - expect(lastSent).to.deep.equal({ - command: CommandNames.Unknown, - type: 'response', - seq: 0, - message: 'Unrecognized JSON command: foobar', - request_seq: 0, - success: false - }); - }); - it('should return a tuple containing the response and if a response is required on success', () => { - let req : protocol.ConfigureRequest = { - command: CommandNames.Configure, - seq: 0, - type: 'command', - arguments: { - hostInfo: 'unit test', - formatOptions: { - newLineCharacter: '`n' - } - } - }; + expect(lastSent).to.deep.equal({ + command: CommandNames.Unknown, + type: "response", + seq: 0, + message: "Unrecognized JSON command: foobar", + request_seq: 0, + success: false + }); + }); + it("should return a tuple containing the response and if a response is required on success", () => { + const req: protocol.ConfigureRequest = { + command: CommandNames.Configure, + seq: 0, + type: "command", + arguments: { + hostInfo: "unit test", + formatOptions: { + newLineCharacter: "`n" + } + } + }; - expect(session.executeCommand(req)).to.deep.equal({ - responseRequired: false - }); - expect(lastSent).to.deep.equal({ - command: CommandNames.Configure, - type: 'response', - success: true, - request_seq: 0, - seq: 0, - body: undefined - }); - }); - }); + expect(session.executeCommand(req)).to.deep.equal({ + responseRequired: false + }); + expect(lastSent).to.deep.equal({ + command: CommandNames.Configure, + type: "response", + success: true, + request_seq: 0, + seq: 0, + body: undefined + }); + }); + }); - describe('onMessage', () => { - it('should not throw when commands are executed with invalid arguments', () => { - let i = 0; - for (name in CommandNames) { - if (!Object.prototype.hasOwnProperty.call(CommandNames, name)) { - continue; - } - let req : protocol.Request = { - command: name, - seq: i++, - type: 'command' - }; - session.onMessage(JSON.stringify(req)); - req.seq += 2; - req.arguments = {}; - session.onMessage(JSON.stringify(req)); - req.seq += 2; - req.arguments = null; - session.onMessage(JSON.stringify(req)); - } - }); - it('should output the response for a correctly handled message', () => { - let req : protocol.ConfigureRequest = { - command: CommandNames.Configure, - seq: 0, - type: 'command', - arguments: { - hostInfo: 'unit test', - formatOptions: { - newLineCharacter: '`n' - } - } - }; + describe("onMessage", () => { + it("should not throw when commands are executed with invalid arguments", () => { + let i = 0; + for (name in CommandNames) { + if (!Object.prototype.hasOwnProperty.call(CommandNames, name)) { + continue; + } + const req: protocol.Request = { + command: name, + seq: i++, + type: "command" + }; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = {}; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = null; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = ""; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = 0; + session.onMessage(JSON.stringify(req)); + req.seq = i++; + req.arguments = []; + session.onMessage(JSON.stringify(req)); + } + session.onMessage("GARBAGE NON_JSON DATA"); + }); + it("should output the response for a correctly handled message", () => { + const req: protocol.ConfigureRequest = { + command: CommandNames.Configure, + seq: 0, + type: "command", + arguments: { + hostInfo: "unit test", + formatOptions: { + newLineCharacter: "`n" + } + } + }; - session.onMessage(JSON.stringify(req)); + session.onMessage(JSON.stringify(req)); - expect(lastSent).to.deep.equal({ - command: CommandNames.Configure, - type: 'response', - success: true, - request_seq: 0, - seq: 0, - body: undefined - }); - }); - }); + expect(lastSent).to.deep.equal({ + command: CommandNames.Configure, + type: "response", + success: true, + request_seq: 0, + seq: 0, + body: undefined + }); + }); + }); - describe('exit', () => { - it('is a noop which can be handled by subclasses', () => { - session.exit(); // Does nothing, should keep running tests - expect(session).to.exist; - }); - }); + describe("exit", () => { + it("is a noop which can be handled by subclasses", () => { + session.exit(); // Does nothing, should keep running tests + expect(session).to.exist; + }); + }); - describe('send', () => { - it('is an overrideable handle which sends protocol messages over the wire', () => { - let msg = {seq: 0, type: 'none'}, - strmsg = JSON.stringify(msg), - len = 1 + Buffer.byteLength(strmsg, 'utf8'), - resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; + describe("send", () => { + it("is an overrideable handle which sends protocol messages over the wire", () => { + const msg = {seq: 0, type: "none"}; + const strmsg = JSON.stringify(msg); + const len = 1 + Buffer.byteLength(strmsg, "utf8"); + const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; - session.send = Session.prototype.send; - assert(session.send); - expect(session.send(msg)).to.not.exist; - expect(lastWrittenToHost).to.equal(resultMsg); - }); - }); + session.send = Session.prototype.send; + assert(session.send); + expect(session.send(msg)).to.not.exist; + expect(lastWrittenToHost).to.equal(resultMsg); + }); + }); - describe('addProtocolHandler', () => { - it('can add protocol handlers', () => { - let respBody = { - item: false - }, - command = 'newhandle', - result = { - response: respBody, - responseRequired: true - }; + describe("addProtocolHandler", () => { + it("can add protocol handlers", () => { + const respBody = { + item: false + }; + const command = "newhandle"; + const result = { + response: respBody, + responseRequired: true + }; - session.addProtocolHandler(command, (req) => result); + session.addProtocolHandler(command, (req) => result); - expect(session.executeCommand({ - command, - seq: 0, - type: 'command' - })).to.deep.equal(result); - }); - it('throws when a duplicate handler is passed', () => { - let respBody = { - item: false - }, - resp = { - response: respBody, - responseRequired: true - }, - command = 'newhandle'; + expect(session.executeCommand({ + command, + seq: 0, + type: "command" + })).to.deep.equal(result); + }); + it("throws when a duplicate handler is passed", () => { + const respBody = { + item: false + }; + const resp = { + response: respBody, + responseRequired: true + }; + const command = "newhandle"; - session.addProtocolHandler(command, (req) => resp); + session.addProtocolHandler(command, (req) => resp); - expect(() => session.addProtocolHandler(command, (req) => resp)) - .to.throw(`Protocol handler already exists for command "${command}"`); - }); - }); - - describe('event', () => { - it('can format event responses and send them', () => { - let evt = 'notify-test', - info = { - test: true - }; + expect(() => session.addProtocolHandler(command, (req) => resp)) + .to.throw(`Protocol handler already exists for command "${command}"`); + }); + }); + + describe("event", () => { + it("can format event responses and send them", () => { + const evt = "notify-test"; + const info = { + test: true + }; - session.event(info, evt); + session.event(info, evt); - expect(lastSent).to.deep.equal({ - type: 'event', - seq: 0, - event: evt, - body: info - }); - }); - }); + expect(lastSent).to.deep.equal({ + type: "event", + seq: 0, + event: evt, + body: info + }); + }); + }); - describe('output', () => { - it('can format command responses and send them', () => { - let body = { - block: { - key: 'value' - } - }, - command = 'test'; + describe("output", () => { + it("can format command responses and send them", () => { + const body = { + block: { + key: "value" + } + }; + const command = "test"; - session.output(body, command); + session.output(body, command); - expect(lastSent).to.deep.equal({ - seq: 0, - request_seq: 0, - type: 'response', - command, - body: body, - success: true - }); - }); - }); - }); + expect(lastSent).to.deep.equal({ + seq: 0, + request_seq: 0, + type: "response", + command, + body: body, + success: true + }); + }); + }); + }); - describe('how Session is extendable via subclassing', () => { - let TestSession = class extends Session { - lastSent: protocol.Message; - customHandler: string = 'testhandler'; - constructor(){ - super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); - this.addProtocolHandler(this.customHandler, () => { - return {response: undefined, responseRequired: true}; - }); - } - send(msg: protocol.Message) { - this.lastSent = msg; - } - }; + describe("how Session is extendable via subclassing", () => { + class TestSession extends Session { + lastSent: protocol.Message; + customHandler: string = "testhandler"; + constructor(){ + super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + this.addProtocolHandler(this.customHandler, () => { + return {response: undefined, responseRequired: true}; + }); + } + send(msg: protocol.Message) { + this.lastSent = msg; + } + }; - it('can override methods such as send', () => { - let session = new TestSession(), - body = { - block: { - key: 'value' - } - }, - command = 'test'; + it("can override methods such as send", () => { + const session = new TestSession(); + const body = { + block: { + key: "value" + } + }; + const command = "test"; - session.output(body, command); + session.output(body, command); - expect(session.lastSent).to.deep.equal({ - seq: 0, - request_seq: 0, - type: 'response', - command, - body: body, - success: true - }); - }); - it('can add and respond to new protocol handlers', () => { - let session = new TestSession(); + expect(session.lastSent).to.deep.equal({ + seq: 0, + request_seq: 0, + type: "response", + command, + body: body, + success: true + }); + }); + it("can add and respond to new protocol handlers", () => { + const session = new TestSession(); - expect(session.executeCommand({ - seq: 0, - type: 'command', - command: session.customHandler - })).to.deep.equal({ - response: undefined, - responseRequired: true - }); - }); - it('has access to the project service', () => { - let ServiceSession = class extends TestSession { - constructor() { - super(); - assert(this.projectService); - expect(this.projectService).to.be.instanceOf(ProjectService); - } - }; - new ServiceSession(); - }); - }); + expect(session.executeCommand({ + seq: 0, + type: "command", + command: session.customHandler + })).to.deep.equal({ + response: undefined, + responseRequired: true + }); + }); + it("has access to the project service", () => { + class ServiceSession extends TestSession { + constructor() { + super(); + assert(this.projectService); + expect(this.projectService).to.be.instanceOf(ProjectService); + } + }; + new ServiceSession(); + }); + }); - describe('an example of using the Session API to create an in-process server', () => { - let inProcHost: ServerHost = { - args: [], - newLine: '\n', - useCaseSensitiveFileNames: true, - write: (s) => lastWrittenToHost = s, - readFile: () => void 0, - writeFile: () => void 0, - resolvePath: () => void 0, - fileExists: () => false, - directoryExists: () => false, - createDirectory: () => void 0, - getExecutingFilePath: () => void 0, - getCurrentDirectory: () => void 0, - readDirectory: () => void 0, - exit: () => void 0 - }, - InProcSession = class extends Session { - private queue: protocol.Request[] = []; - constructor(private client: {handle: (msg: protocol.Message) => void}) { - super(inProcHost, Buffer.byteLength, process.hrtime, mockLogger); - this.addProtocolHandler('echo', (req: protocol.Request) => ({ - response: req.arguments, - responseRequired: true - })); - } - - send(msg: protocol.Message) { - this.client.handle(msg); - } + describe("an example of using the Session API to create an in-process server", () => { + class InProcSession extends Session { + private queue: protocol.Request[] = []; + constructor(private client: {handle: (msg: protocol.Message) => void}) { + super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + this.addProtocolHandler("echo", (req: protocol.Request) => ({ + response: req.arguments, + responseRequired: true + })); + } + + send(msg: protocol.Message) { + this.client.handle(msg); + } - enqueue(msg: protocol.Request) { - this.queue = [msg].concat(this.queue); - } - - handleRequest(msg: protocol.Request) { - let response: protocol.Response; - try { - response = this.executeCommand(msg).response; - } catch (e) { - this.output(undefined, msg.command, msg.seq, e.toString()); - return; - } - if (response) { - this.output(response, msg.command, msg.seq); - } - } + enqueue(msg: protocol.Request) { + this.queue.unshift(msg); + } + + handleRequest(msg: protocol.Request) { + let response: protocol.Response; + try { + ({response} = this.executeCommand(msg)); + } + catch (e) { + this.output(undefined, msg.command, msg.seq, e.toString()); + return; + } + if (response) { + this.output(response, msg.command, msg.seq); + } + } - consumeQueue() { - while (this.queue.length > 0) { - let elem = this.queue[this.queue.length - 1]; - this.queue = this.queue.slice(0, this.queue.length - 1); - this.handleRequest(elem); - } - } - }, - InProcClient = class { - private server: Session & {enqueue: (msg: protocol.Request) => void}; - private seq: number = 0; - private callbacks: ts.Map<(resp: protocol.Response) => void> = {}; - private eventHandlers: ts.Map<(args: any) => void> = {}; + consumeQueue() { + while (this.queue.length > 0) { + const elem = this.queue.pop(); + this.handleRequest(elem); + } + } + } + + class InProcClient { + private server: InProcSession; + private seq: number = 0; + private callbacks: ts.Map<(resp: protocol.Response) => void> = {}; + private eventHandlers: ts.Map<(args: any) => void> = {}; - handle(msg: protocol.Message): void { - if (msg.type === 'response') { - let response = msg; - if (this.callbacks[response.request_seq]) { - this.callbacks[response.request_seq](response); - delete this.callbacks[response.request_seq]; - } - } else if (msg.type === 'event') { - let event = msg; - this.emit(event.event, event.body); - } - } + handle(msg: protocol.Message): void { + if (msg.type === "response") { + const response = msg; + if (this.callbacks[response.request_seq]) { + this.callbacks[response.request_seq](response); + delete this.callbacks[response.request_seq]; + } + } + else if (msg.type === "event") { + const event = msg; + this.emit(event.event, event.body); + } + } - emit(name: string, args: any): void { - if (!this.eventHandlers[name]) { - return; - } - this.eventHandlers[name](args); - } + emit(name: string, args: any): void { + if (this.eventHandlers[name]) { + this.eventHandlers[name](args); + } + } - on(name: string, handler: (args: any) => void): void { - this.eventHandlers[name] = handler; - } + on(name: string, handler: (args: any) => void): void { + this.eventHandlers[name] = handler; + } - connect(session: Session & {enqueue: (msg: protocol.Request) => void}): void { - this.server = session; - } - - execute(command: string, args: any, callback: (resp: protocol.Response) => void): void { - if (!this.server) { - return; - } - this.seq++; - this.server.enqueue({ - seq: this.seq, - type: 'command', - command, - arguments: args - }); - this.callbacks[this.seq] = callback; - } - }; - - it('can be constructed and respond to commands', (done) => { - let cli = new InProcClient(), - session = new InProcSession(cli), - toEcho = { - data: true - }, - toEvent = { - data: false - }, - responses = 0; + connect(session: InProcSession): void { + this.server = session; + } + + execute(command: string, args: any, callback: (resp: protocol.Response) => void): void { + if (!this.server) { + return; + } + this.seq++; + this.server.enqueue({ + seq: this.seq, + type: "command", + command, + arguments: args + }); + this.callbacks[this.seq] = callback; + } + }; + + it("can be constructed and respond to commands", (done) => { + const cli = new InProcClient(); + const session = new InProcSession(cli); + const toEcho = { + data: true + }; + const toEvent = { + data: false + }; + let responses = 0; - // Connect the client - cli.connect(session); - - // Add an event handler - cli.on('testevent', (eventinfo) => { - expect(eventinfo).to.equal(toEvent); - responses++; - expect(responses).to.equal(1); - }); - - // Trigger said event from the server - session.event(toEvent, 'testevent'); - - // Queue an echo command - cli.execute('echo', toEcho, (resp) => { - assert(resp.success, resp.message); - responses++; - expect(responses).to.equal(2); - expect(resp.body).to.deep.equal(toEcho); - }); - - // Queue a configure command - cli.execute('configure', { - hostInfo: 'unit test', - formatOptions: { - newLineCharacter: '`n' - } - }, (resp) => { - assert(resp.success, resp.message); - responses++; - expect(responses).to.equal(3); - done(); - }); - - // Consume the queue and trigger the callbacks - session.consumeQueue(); - }); - }); + // Connect the client + cli.connect(session); + + // Add an event handler + cli.on("testevent", (eventinfo) => { + expect(eventinfo).to.equal(toEvent); + responses++; + expect(responses).to.equal(1); + }); + + // Trigger said event from the server + session.event(toEvent, "testevent"); + + // Queue an echo command + cli.execute("echo", toEcho, (resp) => { + assert(resp.success, resp.message); + responses++; + expect(responses).to.equal(2); + expect(resp.body).to.deep.equal(toEcho); + }); + + // Queue a configure command + cli.execute("configure", { + hostInfo: "unit test", + formatOptions: { + newLineCharacter: "`n" + } + }, (resp) => { + assert(resp.success, resp.message); + responses++; + expect(responses).to.equal(3); + done(); + }); + + // Consume the queue and trigger the callbacks + session.consumeQueue(); + }); + }); } \ No newline at end of file From d1fe21dda965e917912c30fb9f2fbd1602b6cadc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 23 Jul 2015 12:32:17 -0700 Subject: [PATCH 56/85] Publish to TypeScript itself, create a task to preview changes. --- Jakefile.js | 25 +++++++++++++------------ scripts/configureNightly.ts | 26 +++++++++++++++----------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index edfd14fc1af..5f8fbfbfce6 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -361,23 +361,24 @@ compileFile(/*outfile*/configureNightlyJs, /*preserveConstEnums*/ undefined, /*keepComments*/ false, /*noResolve*/ false, - /*stripInternal*/ false, - /*callback*/ function () { - var cmd = "node " + configureNightlyJs + " " + packageJson + " " + programTs; - console.log(cmd); - exec(cmd, completeHandler, errorHandler) - }); + /*stripInternal*/ false); -task("setDebugModeTrue", function() { +task("setDebugMode", function() { useDebugMode = true; }); -desc("Configure, build, test, and publish the nightly release."); -task("publish-nightly", [configureNightlyJs, "LKG", "clean", "setDebugModeTrue", "runtests"], function () { - var cmd = "npm publish"; +task("configure-nightly", [configureNightlyJs], function() { + var cmd = "node " + configureNightlyJs + " " + packageJson + " " + programTs; console.log(cmd); - exec(cmd, completeHandler, errorHandler) -}, {async: true}); + exec(cmd); +}, { async: true }); + +desc("Configure, build, test, and publish the nightly release."); +task("publish-nightly", ["configure-nightly", "LKG", "clean", "setDebugMode", "runtests"], function () { + var cmd = "npm publish --tag next"; + console.log(cmd); + exec(cmd); +}); // Local target to build the compiler and services var tscFile = path.join(builtLocalDirectory, compilerFilename); diff --git a/scripts/configureNightly.ts b/scripts/configureNightly.ts index a0e30b007cf..640f330b376 100644 --- a/scripts/configureNightly.ts +++ b/scripts/configureNightly.ts @@ -27,11 +27,6 @@ function main(): void { // Modify the package.json structure packageJsonValue.version = nightlyVersion; - if (packageJsonValue.name !== "typescript-nightly") { - packageJsonValue.name = "typescript-nightly"; - packageJsonValue.keywords.push("nightly", "alpha", "beta", "prerelease"); - } - // Acquire and modify the source file that exposes the version string. const tsFilePath = ts.normalizePath(sys.args[1]); const tsFileContents = sys.readFile(tsFilePath); @@ -40,7 +35,16 @@ function main(): void { // Ensure we are actually changing something - the user probably wants to know that the update failed. if (tsFileContents === modifiedTsFileContents) { - throw `File '${tsFilePath}' did not contain pattern ${versionAssignmentRegExp}`; + let err = `\n '${tsFilePath}' was not updated while configuring for a nightly publish.\n `; + + if (tsFileContents.match(versionAssignmentRegExp)) { + err += `Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- "${tsFilePath}"'.`; + } + else { + err += `The file seems to no longer have a string matching '${versionAssignmentRegExp}'.`; + } + + throw err + "\n"; } // Finally write the changes to disk. @@ -51,19 +55,19 @@ function main(): void { function getNightlyVersionString(versionString: string): string { // If the version string already contains "-nightly", // then get the base string and update based on that. - const dashNightlyPos = versionString.indexOf("-nightly"); + const dashNightlyPos = versionString.indexOf("-dev"); if (dashNightlyPos >= 0) { versionString = versionString.slice(0, dashNightlyPos); } // We're going to append a representation of the current time at the end of the current version. // String.prototype.toISOString() returns a 24-character string formatted as 'YYYY-MM-DDTHH:mm:ss.sssZ', - // but we'd prefer to just use hyphens as separators instead of 'T', ':', and '.'. - // The trailing 'Z' in this string can be removed; UTC time will always be implicit here. + // but we'd prefer to just remove separators and limit ourselves to YYYYMMDD. + // UTC time will always be implicit here. const now = new Date(); - const timeStr = now.toISOString().slice(0, -1).replace(/:|T|\./g, "-"); + const timeStr = now.toISOString().replace(/:|T|\.|-/g, "").slice(0, 8); - return `${versionString}-nightly-${timeStr}`; + return `${versionString}-dev.${timeStr}`; } main(); \ No newline at end of file From 90bbb7fb3c94300a406fc9deb6e3dcafdefed83b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 12:33:34 -0700 Subject: [PATCH 57/85] More linting from PR --- tests/cases/unittests/session.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts index 1d2efbb498c..25be08293f2 100644 --- a/tests/cases/unittests/session.ts +++ b/tests/cases/unittests/session.ts @@ -1,6 +1,6 @@ /// -module ts.server { +namespace ts.server { let lastWrittenToHost: string; const mockHost: ServerHost = { args: [], @@ -256,8 +256,8 @@ module ts.server { describe("how Session is extendable via subclassing", () => { class TestSession extends Session { lastSent: protocol.Message; - customHandler: string = "testhandler"; - constructor(){ + customHandler = "testhandler"; + constructor() { super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); this.addProtocolHandler(this.customHandler, () => { return {response: undefined, responseRequired: true}; @@ -315,7 +315,7 @@ module ts.server { describe("an example of using the Session API to create an in-process server", () => { class InProcSession extends Session { private queue: protocol.Request[] = []; - constructor(private client: {handle: (msg: protocol.Message) => void}) { + constructor(private client: InProcClient) { super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); this.addProtocolHandler("echo", (req: protocol.Request) => ({ response: req.arguments, @@ -355,7 +355,7 @@ module ts.server { class InProcClient { private server: InProcSession; - private seq: number = 0; + private seq = 0; private callbacks: ts.Map<(resp: protocol.Response) => void> = {}; private eventHandlers: ts.Map<(args: any) => void> = {}; From ef0a289c771a09cf7c739df47cb6ca3d6489ed51 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 12:50:24 -0700 Subject: [PATCH 58/85] Remove exit test --- tests/cases/unittests/session.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts index 25be08293f2..c1dfd508942 100644 --- a/tests/cases/unittests/session.ts +++ b/tests/cases/unittests/session.ts @@ -155,13 +155,6 @@ namespace ts.server { }); }); - describe("exit", () => { - it("is a noop which can be handled by subclasses", () => { - session.exit(); // Does nothing, should keep running tests - expect(session).to.exist; - }); - }); - describe("send", () => { it("is an overrideable handle which sends protocol messages over the wire", () => { const msg = {seq: 0, type: "none"}; From b443cfecc9bb4f08439085afc031ce4a3d6aaca3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 23 Jul 2015 12:53:41 -0700 Subject: [PATCH 59/85] Semicolons. --- Jakefile.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 5f8fbfbfce6..5bfd4d7d278 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -336,17 +336,17 @@ file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], complete(); }); ex.run(); -}, {async: true}) +}, {async: true}); desc("Generates a diagnostic file in TypeScript based on an input JSON file"); -task("generate-diagnostics", [diagnosticInfoMapTs]) +task("generate-diagnostics", [diagnosticInfoMapTs]); // Publish nightly var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js"); var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts"); var packageJson = "package.json"; -var programTs = path.join(compilerDirectory, "program.ts") +var programTs = path.join(compilerDirectory, "program.ts"); file(configureNightlyTs); @@ -476,11 +476,11 @@ file(specMd, [word2mdJs, specWord], function () { child_process.exec(cmd, function () { complete(); }); -}, {async: true}) +}, {async: true}); desc("Generates a Markdown version of the Language Specification"); -task("generate-spec", [specMd]) +task("generate-spec", [specMd]); // Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory @@ -612,7 +612,7 @@ task("runtests", ["tests", builtLocalDirectory], function() { exec(cmd, deleteTemporaryProjectOutput); }, {async: true}); -desc("Generates code coverage data via instanbul") +desc("Generates code coverage data via instanbul"); task("generate-code-coverage", ["tests", builtLocalDirectory], function () { var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run; console.log(cmd); @@ -655,7 +655,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory], function( function getDiffTool() { var program = process.env['DIFF'] if (!program) { - fail("Add the 'DIFF' environment variable to the path of the program you want to use.") + fail("Add the 'DIFF' environment variable to the path of the program you want to use."); } return program; } @@ -664,14 +664,14 @@ function getDiffTool() { desc("Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable"); task('diff', function () { var cmd = '"' + getDiffTool() + '" ' + refBaseline + ' ' + localBaseline; - console.log(cmd) + console.log(cmd); exec(cmd); }, {async: true}); desc("Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable"); task('diff-rwc', function () { var cmd = '"' + getDiffTool() + '" ' + refRwcBaseline + ' ' + localRwcBaseline; - console.log(cmd) + console.log(cmd); exec(cmd); }, {async: true}); From f040386eff39013ce9902a3cafc19494a0194838 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 13:42:25 -0700 Subject: [PATCH 60/85] Fix jake lint with newest tslint --- Jakefile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index bd5074b43d6..4e400a0b6a8 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -738,7 +738,7 @@ task("lint", [], function() { var lintTargets = compilerSources.concat(harnessCoreSources); for(var i in lintTargets) { var f = lintTargets[i]; - var cmd = 'tslint -f ' + f; + var cmd = 'tslint -c tslint.json ' + f; exec(cmd, success(f), failure(f)); } }, { async: true }); From a759687a12a40408c1a6259a70d8db8366dcb927 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 13:59:41 -0700 Subject: [PATCH 61/85] Adds space --- Jakefile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index 4e400a0b6a8..541537d589c 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -736,7 +736,7 @@ task("lint", [], function() { function failure(f) { return function() { console.log('FAILURE: Please fix linting errors in ' + f + '\n') }}; var lintTargets = compilerSources.concat(harnessCoreSources); - for(var i in lintTargets) { + for (var i in lintTargets) { var f = lintTargets[i]; var cmd = 'tslint -c tslint.json ' + f; exec(cmd, success(f), failure(f)); From ab713827a542662cce294ebd3dd1851306622a57 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 15:57:58 -0700 Subject: [PATCH 62/85] Add `jake lint` to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 57dfe06c67c..f7f1838c8fb 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,8 @@ jake runtests # Run tests using the built compiler and test infrastructu # Use host= or tests=. jake runtests-browser # Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|]'. -jake baseline-accept # This replaces the baseline test results with the results obtained from jake runtests. +jake baseline-accept # This replaces the baseline test results with the results obtained from jake runtests. +jake lint # Runs tslint over the compiler jake -T # List the above commands. ``` From a16920b577edd587763d9b1d2a361effbe5e4548 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 16:06:46 -0700 Subject: [PATCH 63/85] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7f1838c8fb..2912624c679 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ jake runtests # Run tests using the built compiler and test infrastructu jake runtests-browser # Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|]'. jake baseline-accept # This replaces the baseline test results with the results obtained from jake runtests. -jake lint # Runs tslint over the compiler +jake lint # Runs tslint over the TypeScript source code jake -T # List the above commands. ``` From 7cd7ae7c1571716f13d2c13d3193bbd0dfdf69eb Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 23 Jul 2015 16:07:30 -0700 Subject: [PATCH 64/85] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2912624c679..8fdf088f6d9 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ jake runtests # Run tests using the built compiler and test infrastructu jake runtests-browser # Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|]'. jake baseline-accept # This replaces the baseline test results with the results obtained from jake runtests. -jake lint # Runs tslint over the TypeScript source code +jake lint # Runs tslint on the TypeScript source jake -T # List the above commands. ``` From c5c7e25c8f60daed17a925d4ed0a3e1f9ee2b673 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 23 Jul 2015 16:28:37 -0700 Subject: [PATCH 65/85] Added period. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fdf088f6d9..77053fc9166 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ jake runtests # Run tests using the built compiler and test infrastructu jake runtests-browser # Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|]'. jake baseline-accept # This replaces the baseline test results with the results obtained from jake runtests. -jake lint # Runs tslint on the TypeScript source +jake lint # Runs tslint on the TypeScript source. jake -T # List the above commands. ``` From fa522e079628f77b4faddfda53d2dc56153b8fb4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 24 Jul 2015 11:28:08 -0700 Subject: [PATCH 66/85] Add nightly info to README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 77053fc9166..c8bc5936c24 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,19 @@ [TypeScript](http://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](http://www.typescriptlang.org/Playground), and stay up to date via [our blog](http://blogs.msdn.com/typescript) and [twitter account](https://twitter.com/typescriptlang). +## Installing + +For the latest stable version: + +``` +npm install -g typescript +``` + +For our nightly builds: + +``` +npm install -g typescript@next +``` ## Contribute From aac34519d410857c3fb31856c64428e3022b4046 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Thu, 23 Jul 2015 16:27:04 -0700 Subject: [PATCH 67/85] Remove error for parameter with default initializer before a required parameter --- src/compiler/checker.ts | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3363987322a..217a6103198 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1994,15 +1994,15 @@ namespace ts { } return _displayBuilder || (_displayBuilder = { - buildSymbolDisplay: buildSymbolDisplay, - buildTypeDisplay: buildTypeDisplay, - buildTypeParameterDisplay: buildTypeParameterDisplay, - buildParameterDisplay: buildParameterDisplay, - buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters, - buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters, - buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol, - buildSignatureDisplay: buildSignatureDisplay, - buildReturnTypeDisplay: buildReturnTypeDisplay + buildSymbolDisplay, + buildTypeDisplay, + buildTypeParameterDisplay, + buildParameterDisplay, + buildDisplayForParametersAndDelimiters, + buildDisplayForTypeParametersAndDelimiters, + buildTypeParameterDisplayFromSymbol, + buildSignatureDisplay, + buildReturnTypeDisplay }); } @@ -14771,17 +14771,15 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_parameter_cannot_have_an_initializer); } } - else if (parameter.questionToken || parameter.initializer) { + else if (parameter.questionToken) { seenOptionalParameter = true; - if (parameter.questionToken && parameter.initializer) { + if (parameter.initializer) { return grammarErrorOnNode(parameter.name, Diagnostics.Parameter_cannot_have_question_mark_and_initializer); } } - else { - if (seenOptionalParameter) { - return grammarErrorOnNode(parameter.name, Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter); - } + else if (seenOptionalParameter && !parameter.initializer) { + return grammarErrorOnNode(parameter.name, Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter); } } } From a47e02aeac8c952832ec12f320693499b032a9b2 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Fri, 24 Jul 2015 13:59:20 -0700 Subject: [PATCH 68/85] Adjust notion of minArgumentCount to account for required parameters with default initializers --- src/compiler/checker.ts | 23 ++++++++++++++++++++--- src/compiler/utilities.ts | 4 +--- src/services/signatureHelp.ts | 18 +++++++++++++++--- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 217a6103198..ec6c6d2f8e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3517,7 +3517,19 @@ namespace ts { } function isOptionalParameter(node: ParameterDeclaration) { - return hasQuestionToken(node) || !!node.initializer; + if (hasQuestionToken(node)) { + return true; + } + + if (node.initializer) { + let signatureDeclaration = node.parent; + let signature = getSignatureFromDeclaration(signatureDeclaration); + let parameterIndex = signatureDeclaration.parameters.indexOf(node); + Debug.assert(parameterIndex >= 0); + return parameterIndex >= signature.minArgumentCount; + } + + return false; } function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature { @@ -3535,11 +3547,16 @@ namespace ts { if (param.type && param.type.kind === SyntaxKind.StringLiteral) { hasStringLiterals = true; } - if (minArgumentCount < 0) { - if (param.initializer || param.questionToken || param.dotDotDotToken) { + + if (param.initializer || param.questionToken || param.dotDotDotToken) { + if (minArgumentCount < 0) { minArgumentCount = i; } } + else { + // If we see any required parameters, it means the prior ones were not in fact optional. + minArgumentCount = -1; + } } if (minArgumentCount < 0) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 56eb2415cf9..312a3666757 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -988,15 +988,13 @@ namespace ts { if (node) { switch (node.kind) { case SyntaxKind.Parameter: - return (node).questionToken !== undefined; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - return (node).questionToken !== undefined; case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.PropertyAssignment: case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - return (node).questionToken !== undefined; + return (node).questionToken !== undefined; } } diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index f44ebade2a7..6230a66910e 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -569,7 +569,15 @@ namespace ts.SignatureHelp { prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); let parameters = candidateSignature.parameters; - signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray; + if (parameters.length > 0) { + signatureHelpParameters = []; + for (let i = 0; i < parameters.length; i++) { + signatureHelpParameters.push(createSignatureHelpParameterAtIndex(candidateSignature, i)); + } + } + else { + signatureHelpParameters = emptyArray; + } suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } @@ -607,11 +615,15 @@ namespace ts.SignatureHelp { argumentCount }; - function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { + function createSignatureHelpParameterAtIndex(signature: Signature, parameterIndex: number): SignatureHelpParameter { + let parameter = signature.parameters[parameterIndex]; let displayParts = mapToDisplayParts(writer => typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation)); - let isOptional = hasQuestionToken(parameter.valueDeclaration); + let parameterDeclaration = parameter.valueDeclaration; + let isOptional = + hasQuestionToken(parameterDeclaration) || + parameterDeclaration.initializer && parameterIndex >= signature.minArgumentCount; return { name: parameter.name, From f44bcbda3c5c4c5552c93f498fe146ad8c030a9e Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Fri, 24 Jul 2015 14:58:53 -0700 Subject: [PATCH 69/85] Accept baselines and fix test comments --- .../fatarrowfunctionsOptionalArgsErrors1.errors.txt | 9 +++------ .../fatarrowfunctionsOptionalArgsErrors1.js | 4 ++-- .../reference/optionalParamArgsTest.errors.txt | 12 ++++-------- tests/baselines/reference/optionalParamArgsTest.js | 6 ++---- .../compiler/fatarrowfunctionsOptionalArgsErrors1.ts | 2 +- tests/cases/compiler/optionalParamArgsTest.ts | 3 +-- 6 files changed, 13 insertions(+), 23 deletions(-) diff --git a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.errors.txt b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.errors.txt index 5934ab52ccf..b32a7b67b61 100644 --- a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.errors.txt +++ b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.errors.txt @@ -1,10 +1,9 @@ tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(1,9): error TS1016: A required parameter cannot follow an optional parameter. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(2,8): error TS1047: A rest parameter cannot be optional. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(4,5): error TS1048: A rest parameter cannot have an initializer. -tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(7,12): error TS1016: A required parameter cannot follow an optional parameter. -==== tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts (4 errors) ==== +==== tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts (3 errors) ==== (arg1?, arg2) => 101; ~~~~ !!! error TS1016: A required parameter cannot follow an optional parameter. @@ -16,7 +15,5 @@ tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(7,12): error TS1016 ~~~ !!! error TS1048: A rest parameter cannot have an initializer. - // Non optional parameter following an optional one - (arg1 = 1, arg2) => 1; - ~~~~ -!!! error TS1016: A required parameter cannot follow an optional parameter. \ No newline at end of file + // Uninitialized parameter makes the initialized one required + (arg1 = 1, arg2) => 1; \ No newline at end of file diff --git a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.js b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.js index e746b24a066..4d27f8230eb 100644 --- a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.js +++ b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.js @@ -4,7 +4,7 @@ (...arg) => 103; (...arg:number [] = []) => 104; -// Non optional parameter following an optional one +// Uninitialized parameter makes the initialized one required (arg1 = 1, arg2) => 1; //// [fatarrowfunctionsOptionalArgsErrors1.js] @@ -30,7 +30,7 @@ } return 104; }); -// Non optional parameter following an optional one +// Uninitialized parameter makes the initialized one required (function (arg1, arg2) { if (arg1 === void 0) { arg1 = 1; } return 1; diff --git a/tests/baselines/reference/optionalParamArgsTest.errors.txt b/tests/baselines/reference/optionalParamArgsTest.errors.txt index 3c4d2e37be9..05fefa85065 100644 --- a/tests/baselines/reference/optionalParamArgsTest.errors.txt +++ b/tests/baselines/reference/optionalParamArgsTest.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/optionalParamArgsTest.ts(31,12): error TS2393: Duplicate function implementation. -tests/cases/compiler/optionalParamArgsTest.ts(35,12): error TS2393: Duplicate function implementation. -tests/cases/compiler/optionalParamArgsTest.ts(35,47): error TS1016: A required parameter cannot follow an optional parameter. +tests/cases/compiler/optionalParamArgsTest.ts(34,12): error TS2393: Duplicate function implementation. +tests/cases/compiler/optionalParamArgsTest.ts(98,1): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/compiler/optionalParamArgsTest.ts(99,1): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/compiler/optionalParamArgsTest.ts(100,1): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/compiler/optionalParamArgsTest.ts(101,1): error TS2346: Supplied parameters do not match any signature of call target. @@ -20,10 +20,9 @@ tests/cases/compiler/optionalParamArgsTest.ts(114,1): error TS2346: Supplied par tests/cases/compiler/optionalParamArgsTest.ts(115,1): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/compiler/optionalParamArgsTest.ts(116,1): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/compiler/optionalParamArgsTest.ts(117,1): error TS2346: Supplied parameters do not match any signature of call target. -tests/cases/compiler/optionalParamArgsTest.ts(118,1): error TS2346: Supplied parameters do not match any signature of call target. -==== tests/cases/compiler/optionalParamArgsTest.ts (23 errors) ==== +==== tests/cases/compiler/optionalParamArgsTest.ts (22 errors) ==== // Optional parameter and default argument tests // Key: @@ -58,13 +57,10 @@ tests/cases/compiler/optionalParamArgsTest.ts(118,1): error TS2346: Supplied par ~~~~ !!! error TS2393: Duplicate function implementation. - // Negative test - // "Optional parameters may only be followed by other optional parameters" + // Uninitialized parameter makes the initialized one required public C1M5(C1M5A1:number,C1M5A2:number=0,C1M5A3:number) { return C1M5A1 + C1M5A2; } ~~~~ !!! error TS2393: Duplicate function implementation. - ~~~~~~ -!!! error TS1016: A required parameter cannot follow an optional parameter. } class C2 extends C1 { diff --git a/tests/baselines/reference/optionalParamArgsTest.js b/tests/baselines/reference/optionalParamArgsTest.js index 414f474598d..0c5a5d82814 100644 --- a/tests/baselines/reference/optionalParamArgsTest.js +++ b/tests/baselines/reference/optionalParamArgsTest.js @@ -31,8 +31,7 @@ class C1 { public C1M5(C1M5A1:number,C1M5A2:number=0,C1M5A3?:number) { return C1M5A1 + C1M5A2; } - // Negative test - // "Optional parameters may only be followed by other optional parameters" + // Uninitialized parameter makes the initialized one required public C1M5(C1M5A1:number,C1M5A2:number=0,C1M5A3:number) { return C1M5A1 + C1M5A2; } } @@ -152,8 +151,7 @@ var C1 = (function () { if (C1M5A2 === void 0) { C1M5A2 = 0; } return C1M5A1 + C1M5A2; }; - // Negative test - // "Optional parameters may only be followed by other optional parameters" + // Uninitialized parameter makes the initialized one required C1.prototype.C1M5 = function (C1M5A1, C1M5A2, C1M5A3) { if (C1M5A2 === void 0) { C1M5A2 = 0; } return C1M5A1 + C1M5A2; diff --git a/tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts b/tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts index d8ddcf4bb8f..814f1b41619 100644 --- a/tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts +++ b/tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts @@ -3,5 +3,5 @@ (...arg) => 103; (...arg:number [] = []) => 104; -// Non optional parameter following an optional one +// Uninitialized parameter makes the initialized one required (arg1 = 1, arg2) => 1; \ No newline at end of file diff --git a/tests/cases/compiler/optionalParamArgsTest.ts b/tests/cases/compiler/optionalParamArgsTest.ts index ce34acae869..609cbfe4734 100644 --- a/tests/cases/compiler/optionalParamArgsTest.ts +++ b/tests/cases/compiler/optionalParamArgsTest.ts @@ -30,8 +30,7 @@ class C1 { public C1M5(C1M5A1:number,C1M5A2:number=0,C1M5A3?:number) { return C1M5A1 + C1M5A2; } - // Negative test - // "Optional parameters may only be followed by other optional parameters" + // Uninitialized parameter makes the initialized one required public C1M5(C1M5A1:number,C1M5A2:number=0,C1M5A3:number) { return C1M5A1 + C1M5A2; } } From 628d63cf7586171385e528f2770f1f3efa22a50d Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Fri, 24 Jul 2015 14:59:01 -0700 Subject: [PATCH 70/85] Add tests --- .../requiredInitializedParameter1.errors.txt | 28 ++++++++++ .../requiredInitializedParameter1.js | 51 +++++++++++++++++++ .../requiredInitializedParameter2.errors.txt | 17 +++++++ .../requiredInitializedParameter2.js | 18 +++++++ .../requiredInitializedParameter3.js | 27 ++++++++++ .../requiredInitializedParameter3.symbols | 17 +++++++ .../requiredInitializedParameter3.types | 18 +++++++ .../compiler/requiredInitializedParameter1.ts | 19 +++++++ .../compiler/requiredInitializedParameter2.ts | 7 +++ .../compiler/requiredInitializedParameter3.ts | 8 +++ 10 files changed, 210 insertions(+) create mode 100644 tests/baselines/reference/requiredInitializedParameter1.errors.txt create mode 100644 tests/baselines/reference/requiredInitializedParameter1.js create mode 100644 tests/baselines/reference/requiredInitializedParameter2.errors.txt create mode 100644 tests/baselines/reference/requiredInitializedParameter2.js create mode 100644 tests/baselines/reference/requiredInitializedParameter3.js create mode 100644 tests/baselines/reference/requiredInitializedParameter3.symbols create mode 100644 tests/baselines/reference/requiredInitializedParameter3.types create mode 100644 tests/cases/compiler/requiredInitializedParameter1.ts create mode 100644 tests/cases/compiler/requiredInitializedParameter2.ts create mode 100644 tests/cases/compiler/requiredInitializedParameter3.ts diff --git a/tests/baselines/reference/requiredInitializedParameter1.errors.txt b/tests/baselines/reference/requiredInitializedParameter1.errors.txt new file mode 100644 index 00000000000..ef958dbdec9 --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter1.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/requiredInitializedParameter1.ts(11,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/compiler/requiredInitializedParameter1.ts(16,1): error TS2346: Supplied parameters do not match any signature of call target. + + +==== tests/cases/compiler/requiredInitializedParameter1.ts (2 errors) ==== + function f1(a, b = 0, c) { } + function f2(a, b = 0, c = 0) { } + function f3(a, b = 0, c?) { } + function f4(a, b = 0, ...c) { } + + f1(0, 1, 2); + f2(0, 1, 2); + f3(0, 1, 2); + f4(0, 1, 2); + + f1(0, 1); + ~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + f2(0, 1); + f3(0, 1); + f4(0, 1); + + f1(0); + ~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + f2(0); + f3(0); + f4(0); \ No newline at end of file diff --git a/tests/baselines/reference/requiredInitializedParameter1.js b/tests/baselines/reference/requiredInitializedParameter1.js new file mode 100644 index 00000000000..0fe07503056 --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter1.js @@ -0,0 +1,51 @@ +//// [requiredInitializedParameter1.ts] +function f1(a, b = 0, c) { } +function f2(a, b = 0, c = 0) { } +function f3(a, b = 0, c?) { } +function f4(a, b = 0, ...c) { } + +f1(0, 1, 2); +f2(0, 1, 2); +f3(0, 1, 2); +f4(0, 1, 2); + +f1(0, 1); +f2(0, 1); +f3(0, 1); +f4(0, 1); + +f1(0); +f2(0); +f3(0); +f4(0); + +//// [requiredInitializedParameter1.js] +function f1(a, b, c) { + if (b === void 0) { b = 0; } +} +function f2(a, b, c) { + if (b === void 0) { b = 0; } + if (c === void 0) { c = 0; } +} +function f3(a, b, c) { + if (b === void 0) { b = 0; } +} +function f4(a, b) { + if (b === void 0) { b = 0; } + var c = []; + for (var _i = 2; _i < arguments.length; _i++) { + c[_i - 2] = arguments[_i]; + } +} +f1(0, 1, 2); +f2(0, 1, 2); +f3(0, 1, 2); +f4(0, 1, 2); +f1(0, 1); +f2(0, 1); +f3(0, 1); +f4(0, 1); +f1(0); +f2(0); +f3(0); +f4(0); diff --git a/tests/baselines/reference/requiredInitializedParameter2.errors.txt b/tests/baselines/reference/requiredInitializedParameter2.errors.txt new file mode 100644 index 00000000000..5dcec536e1b --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter2.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/requiredInitializedParameter2.ts(5,7): error TS2420: Class 'C1' incorrectly implements interface 'I1'. + Types of property 'method' are incompatible. + Type '(a: number, b: any) => void' is not assignable to type '() => any'. + + +==== tests/cases/compiler/requiredInitializedParameter2.ts (1 errors) ==== + interface I1 { + method(); + } + + class C1 implements I1 { + ~~ +!!! error TS2420: Class 'C1' incorrectly implements interface 'I1'. +!!! error TS2420: Types of property 'method' are incompatible. +!!! error TS2420: Type '(a: number, b: any) => void' is not assignable to type '() => any'. + method(a = 0, b) { } + } \ No newline at end of file diff --git a/tests/baselines/reference/requiredInitializedParameter2.js b/tests/baselines/reference/requiredInitializedParameter2.js new file mode 100644 index 00000000000..3c69d54e1d9 --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter2.js @@ -0,0 +1,18 @@ +//// [requiredInitializedParameter2.ts] +interface I1 { + method(); +} + +class C1 implements I1 { + method(a = 0, b) { } +} + +//// [requiredInitializedParameter2.js] +var C1 = (function () { + function C1() { + } + C1.prototype.method = function (a, b) { + if (a === void 0) { a = 0; } + }; + return C1; +})(); diff --git a/tests/baselines/reference/requiredInitializedParameter3.js b/tests/baselines/reference/requiredInitializedParameter3.js new file mode 100644 index 00000000000..68e1aa696ea --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter3.js @@ -0,0 +1,27 @@ +//// [requiredInitializedParameter3.ts] +interface I1 { + method(); +} + +class C1 implements I1 { + method(a = 0, b?) { } +} + +//// [requiredInitializedParameter3.js] +var C1 = (function () { + function C1() { + } + C1.prototype.method = function (a, b) { + if (a === void 0) { a = 0; } + }; + return C1; +})(); + + +//// [requiredInitializedParameter3.d.ts] +interface I1 { + method(): any; +} +declare class C1 implements I1 { + method(a?: number, b?: any): void; +} diff --git a/tests/baselines/reference/requiredInitializedParameter3.symbols b/tests/baselines/reference/requiredInitializedParameter3.symbols new file mode 100644 index 00000000000..e9f35b21bcf --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter3.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/requiredInitializedParameter3.ts === +interface I1 { +>I1 : Symbol(I1, Decl(requiredInitializedParameter3.ts, 0, 0)) + + method(); +>method : Symbol(method, Decl(requiredInitializedParameter3.ts, 0, 14)) +} + +class C1 implements I1 { +>C1 : Symbol(C1, Decl(requiredInitializedParameter3.ts, 2, 1)) +>I1 : Symbol(I1, Decl(requiredInitializedParameter3.ts, 0, 0)) + + method(a = 0, b?) { } +>method : Symbol(method, Decl(requiredInitializedParameter3.ts, 4, 24)) +>a : Symbol(a, Decl(requiredInitializedParameter3.ts, 5, 11)) +>b : Symbol(b, Decl(requiredInitializedParameter3.ts, 5, 17)) +} diff --git a/tests/baselines/reference/requiredInitializedParameter3.types b/tests/baselines/reference/requiredInitializedParameter3.types new file mode 100644 index 00000000000..aa37f5e13dd --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter3.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/requiredInitializedParameter3.ts === +interface I1 { +>I1 : I1 + + method(); +>method : () => any +} + +class C1 implements I1 { +>C1 : C1 +>I1 : I1 + + method(a = 0, b?) { } +>method : (a?: number, b?: any) => void +>a : number +>0 : number +>b : any +} diff --git a/tests/cases/compiler/requiredInitializedParameter1.ts b/tests/cases/compiler/requiredInitializedParameter1.ts new file mode 100644 index 00000000000..35d606426f0 --- /dev/null +++ b/tests/cases/compiler/requiredInitializedParameter1.ts @@ -0,0 +1,19 @@ +function f1(a, b = 0, c) { } +function f2(a, b = 0, c = 0) { } +function f3(a, b = 0, c?) { } +function f4(a, b = 0, ...c) { } + +f1(0, 1, 2); +f2(0, 1, 2); +f3(0, 1, 2); +f4(0, 1, 2); + +f1(0, 1); +f2(0, 1); +f3(0, 1); +f4(0, 1); + +f1(0); +f2(0); +f3(0); +f4(0); \ No newline at end of file diff --git a/tests/cases/compiler/requiredInitializedParameter2.ts b/tests/cases/compiler/requiredInitializedParameter2.ts new file mode 100644 index 00000000000..48d42869ee7 --- /dev/null +++ b/tests/cases/compiler/requiredInitializedParameter2.ts @@ -0,0 +1,7 @@ +interface I1 { + method(); +} + +class C1 implements I1 { + method(a = 0, b) { } +} \ No newline at end of file diff --git a/tests/cases/compiler/requiredInitializedParameter3.ts b/tests/cases/compiler/requiredInitializedParameter3.ts new file mode 100644 index 00000000000..803eefb6342 --- /dev/null +++ b/tests/cases/compiler/requiredInitializedParameter3.ts @@ -0,0 +1,8 @@ +//@declaration: true +interface I1 { + method(); +} + +class C1 implements I1 { + method(a = 0, b?) { } +} \ No newline at end of file From 442855f7e1fc91b8e70f07e5eac83ed9ce2b32cf Mon Sep 17 00:00:00 2001 From: Yui T Date: Sun, 26 Jul 2015 20:46:03 -0700 Subject: [PATCH 71/85] Address CR --- src/compiler/checker.ts | 10 +++++----- src/compiler/diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 4 ++-- tests/baselines/reference/classExtendsNull.errors.txt | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0ccf23164cb..2932de8e99b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10250,25 +10250,25 @@ namespace ts { // constructors of derived classes must contain at least one super call somewhere in their function body. let containingClassDecl = node.parent; if (getClassExtendsHeritageClauseElement(containingClassDecl)) { - let symbol = getSymbolOfNode(containingClassDecl); - let type = getDeclaredTypeOfSymbol(symbol); - let baseConstructorType = getBaseConstructorTypeOfClass(type); + let containingClassSymbol = getSymbolOfNode(containingClassDecl); + let containingClassInstanceType = getDeclaredTypeOfSymbol(containingClassSymbol); + let baseConstructorType = getBaseConstructorTypeOfClass(containingClassInstanceType); if (containsSuperCall(node.body)) { if (baseConstructorType === nullType) { - error(node, Diagnostics.A_constructor_cannot_contain_super_call_when_a_class_extends_null); + error(node, Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); } // The first statement in the body of a constructor must be a super call if both of the following are true: // - The containing class is a derived class. // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. - let statements = (node.body).statements; let superCallShouldBeFirst = forEach((node.parent).members, isInstancePropertyWithInitializer) || forEach(node.parameters, p => p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)); if (superCallShouldBeFirst) { + let statements = (node.body).statements; if (!statements.length || statements[0].kind !== SyntaxKind.ExpressionStatement || !isSuperCallExpression((statements[0]).expression)) { error(node, Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties); } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 44f14ac0995..cdfe28eb781 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -613,6 +613,6 @@ namespace ts { Expected_corresponding_JSX_closing_tag_for_0: { code: 17002, category: DiagnosticCategory.Error, key: "Expected corresponding JSX closing tag for '{0}'." }, JSX_attribute_expected: { code: 17003, category: DiagnosticCategory.Error, key: "JSX attribute expected." }, Cannot_use_JSX_unless_the_jsx_flag_is_provided: { code: 17004, category: DiagnosticCategory.Error, key: "Cannot use JSX unless the '--jsx' flag is provided." }, - A_constructor_cannot_contain_super_call_when_a_class_extends_null: { code: 17005, category: DiagnosticCategory.Error, key: "A constructor cannot contain 'super' call when a class extends 'null'" }, + A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: { code: 17005, category: DiagnosticCategory.Error, key: "A constructor cannot contain a 'super' call when its class extends 'null'" }, }; } \ No newline at end of file diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 1203c5ef61e..d0023ce6cfd 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1,4 +1,4 @@ -{ + { "Unterminated string literal.": { "category": "Error", "code": 1002 @@ -2446,7 +2446,7 @@ "category": "Error", "code": 17004 }, - "A constructor cannot contain 'super' call when a class extends 'null'": { + "A constructor cannot contain a 'super' call when its class extends 'null'": { "category": "Error", "code": 17005 } diff --git a/tests/baselines/reference/classExtendsNull.errors.txt b/tests/baselines/reference/classExtendsNull.errors.txt index cc5de5cda83..7bb44774826 100644 --- a/tests/baselines/reference/classExtendsNull.errors.txt +++ b/tests/baselines/reference/classExtendsNull.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor cannot contain 'super' call when a class extends 'null' +tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' ==== tests/cases/compiler/classExtendsNull.ts (1 errors) ==== @@ -11,7 +11,7 @@ tests/cases/compiler/classExtendsNull.ts(2,5): error TS17005: A constructor cann ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } ~~~~~ -!!! error TS17005: A constructor cannot contain 'super' call when a class extends 'null' +!!! error TS17005: A constructor cannot contain a 'super' call when its class extends 'null' } class D extends null { From 1251b46eb647d91312ba07e159afc16b4aaca8e6 Mon Sep 17 00:00:00 2001 From: Basarat Ali Syed Date: Mon, 27 Jul 2015 17:42:49 +1000 Subject: [PATCH 72/85] SourceFile.fileWatcher should be optional --- src/compiler/tsc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index a657cc8c314..6872c4c876e 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -3,7 +3,7 @@ namespace ts { export interface SourceFile { - fileWatcher: FileWatcher; + fileWatcher?: FileWatcher; } /** From cf801efb20ab0b1045350280febc297177fbfc65 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 27 Jul 2015 10:12:52 -0700 Subject: [PATCH 73/85] Added test. --- .../modules/defaultExportsCannotMerge03.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts diff --git a/tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts new file mode 100644 index 00000000000..dad8431812b --- /dev/null +++ b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts @@ -0,0 +1,26 @@ +// @module: commonjs +// @target: ES5 + +// @filename: m1.ts +export default class Decl { +} + +interface Decl { + p1: number; + p2: number; +} + +namespace Decl { + interface I { + } +} + +// @filename: m2.ts +import Entity from "m1" + +Entity(); + +var x: Entity; +var y: Entity.I; +var z = new Entity(); +var sum = z.p1 + z.p2 \ No newline at end of file From b84e4071a543254a0c6980489eb48dc834497f00 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 27 Jul 2015 10:23:05 -0700 Subject: [PATCH 74/85] Accepted baselines. --- .../defaultExportsCannotMerge03.errors.txt | 47 +++++++++++++++++++ .../reference/defaultExportsCannotMerge03.js | 42 +++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 tests/baselines/reference/defaultExportsCannotMerge03.errors.txt create mode 100644 tests/baselines/reference/defaultExportsCannotMerge03.js diff --git a/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt new file mode 100644 index 00000000000..5babb6ac743 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +tests/cases/conformance/es6/modules/m1.ts(5,11): error TS2518: Only an ambient class can be merged with an interface. +tests/cases/conformance/es6/modules/m1.ts(5,11): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? +tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. +tests/cases/conformance/es6/modules/m2.ts(8,13): error TS2339: Property 'p1' does not exist on type 'Decl'. +tests/cases/conformance/es6/modules/m2.ts(8,20): error TS2339: Property 'p2' does not exist on type 'Decl'. + + +==== tests/cases/conformance/es6/modules/m1.ts (3 errors) ==== + + export default class Decl { + ~~~~ +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. + } + + interface Decl { + ~~~~ +!!! error TS2518: Only an ambient class can be merged with an interface. + ~~~~ +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. + p1: number; + p2: number; + } + + namespace Decl { + interface I { + } + } + +==== tests/cases/conformance/es6/modules/m2.ts (4 errors) ==== + import Entity from "m1" + + Entity(); + ~~~~~~~~ +!!! error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? + + var x: Entity; + var y: Entity.I; + ~~~~~~ +!!! error TS2503: Cannot find namespace 'Entity'. + var z = new Entity(); + var sum = z.p1 + z.p2 + ~~ +!!! error TS2339: Property 'p1' does not exist on type 'Decl'. + ~~ +!!! error TS2339: Property 'p2' does not exist on type 'Decl'. \ No newline at end of file diff --git a/tests/baselines/reference/defaultExportsCannotMerge03.js b/tests/baselines/reference/defaultExportsCannotMerge03.js new file mode 100644 index 00000000000..05e7de94120 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge03.js @@ -0,0 +1,42 @@ +//// [tests/cases/conformance/es6/modules/defaultExportsCannotMerge03.ts] //// + +//// [m1.ts] + +export default class Decl { +} + +interface Decl { + p1: number; + p2: number; +} + +namespace Decl { + interface I { + } +} + +//// [m2.ts] +import Entity from "m1" + +Entity(); + +var x: Entity; +var y: Entity.I; +var z = new Entity(); +var sum = z.p1 + z.p2 + +//// [m1.js] +var Decl = (function () { + function Decl() { + } + return Decl; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = Decl; +//// [m2.js] +var m1_1 = require("m1"); +m1_1.default(); +var x; +var y; +var z = new m1_1.default(); +var sum = z.p1 + z.p2; From bad5919fa88246556e8380aecee51c9937226800 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 27 Jul 2015 11:14:13 -0700 Subject: [PATCH 75/85] Addressed CR feedback. --- src/compiler/checker.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 206d263522a..cad42974a33 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4363,11 +4363,11 @@ namespace ts { return getInferredType(context, i); } } - return t; + return t; }; mapper.context = context; - return mapper; + return mapper; } function identityMapper(type: Type): Type { @@ -10870,14 +10870,14 @@ namespace ts { // to denote disjoint declarationSpaces (without making new enum type). let exportedDeclarationSpaces = SymbolFlags.None; let nonExportedDeclarationSpaces = SymbolFlags.None; - let defaultExportedDeclarationFlags = SymbolFlags.None; + let defaultExportedDeclarationSpaces = SymbolFlags.None; for (let d of symbol.declarations) { let declarationSpaces = getDeclarationSpaces(d); let effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, NodeFlags.Export | NodeFlags.Default); if (effectiveDeclarationFlags & NodeFlags.Export) { if (effectiveDeclarationFlags & NodeFlags.Default) { - defaultExportedDeclarationFlags |= declarationSpaces; + defaultExportedDeclarationSpaces |= declarationSpaces; } else { exportedDeclarationSpaces |= declarationSpaces; @@ -10888,17 +10888,22 @@ namespace ts { } } - let commonDeclarationSpace = exportedDeclarationSpaces & nonExportedDeclarationSpaces; - let commonDeclarationSpaceForDefault = defaultExportedDeclarationFlags & (exportedDeclarationSpaces | nonExportedDeclarationSpaces); + // Spaces for anyting not declared a 'default export'. + let nonDefaultExportedDeclarationsSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces; + + let commonDeclarationSpaceForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces; + let commonDeclarationSpaceForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationsSpaces; - if (commonDeclarationSpace || commonDeclarationSpaceForDefault) { + if (commonDeclarationSpaceForExportsAndLocals || commonDeclarationSpaceForDefaultAndNonDefault) { // declaration spaces for exported and non-exported declarations intersect for (let d of symbol.declarations) { let declarationSpaces = getDeclarationSpaces(d); - if (declarationSpaces & commonDeclarationSpaceForDefault) { + + // Only error on the declarations that conributed to the intersecting spaces. + if (declarationSpaces & commonDeclarationSpaceForDefaultAndNonDefault) { error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration, declarationNameToString(d.name)); } - else if (declarationSpaces & commonDeclarationSpace) { + else if (declarationSpaces & commonDeclarationSpaceForExportsAndLocals) { error(d.name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(d.name)); } } From a8f0491d62af9fadcb6c5ac4f6319e992febfe29 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 27 Jul 2015 11:17:23 -0700 Subject: [PATCH 76/85] space -> spaces --- src/compiler/checker.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cad42974a33..1b8cd56e12c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10889,21 +10889,21 @@ namespace ts { } // Spaces for anyting not declared a 'default export'. - let nonDefaultExportedDeclarationsSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces; + let nonDefaultExportedDeclarationSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces; - let commonDeclarationSpaceForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces; - let commonDeclarationSpaceForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationsSpaces; + let commonDeclarationSpacesForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces; + let commonDeclarationSpacesForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationSpaces; - if (commonDeclarationSpaceForExportsAndLocals || commonDeclarationSpaceForDefaultAndNonDefault) { + if (commonDeclarationSpacesForExportsAndLocals || commonDeclarationSpacesForDefaultAndNonDefault) { // declaration spaces for exported and non-exported declarations intersect for (let d of symbol.declarations) { let declarationSpaces = getDeclarationSpaces(d); // Only error on the declarations that conributed to the intersecting spaces. - if (declarationSpaces & commonDeclarationSpaceForDefaultAndNonDefault) { + if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) { error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration, declarationNameToString(d.name)); } - else if (declarationSpaces & commonDeclarationSpaceForExportsAndLocals) { + else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) { error(d.name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(d.name)); } } From 079047c60bcdc67f84174641fd1dd591efaf3b4d Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 27 Jul 2015 11:21:27 -0700 Subject: [PATCH 77/85] Simplify code a bit. --- src/compiler/checker.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 83581be5552..7f22693ee25 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4363,11 +4363,11 @@ namespace ts { return getInferredType(context, i); } } - return t; + return t; }; mapper.context = context; - return mapper; + return mapper; } function identityMapper(type: Type): Type { @@ -7324,7 +7324,9 @@ namespace ts { */ function getJsxElementInstanceType(node: JsxOpeningLikeElement) { if (!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement)) { - // There is no such thing as an instance type for a non-class element + // There is no such thing as an instance type for a non-class element. This + // line shouldn't be hit. + Debug.fail('Should not call getJsxElementInstanceType on non-class Element'); return undefined; } @@ -7349,11 +7351,11 @@ namespace ts { if (signatures.length === 0) { // We found no signatures at all, which is an error error(node.tagName, Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, getTextOfNode(node.tagName)); - return undefined; + return unknownType; } } - let returnType = getUnionType(signatures.map(s => getReturnTypeOfSignature(s))); + let returnType = getUnionType(signatures.map(getReturnTypeOfSignature)); // Issue an error if this return type isn't assignable to JSX.ElementClass let elemClassType = getJsxGlobalElementClassType(); @@ -7413,7 +7415,7 @@ namespace ts { if (links.jsxFlags & JsxFlags.ClassElement) { let elemInstanceType = getJsxElementInstanceType(node); - if (!elemInstanceType || isTypeAny(elemInstanceType)) { + if (isTypeAny(elemInstanceType)) { return links.resolvedJsxType = anyType; } From 92902011ce09d0059d04cf7e6a7cd804b46aa895 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 27 Jul 2015 11:45:10 -0700 Subject: [PATCH 78/85] Added a test. --- .../es6/modules/defaultExportsCannotMerge04.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts diff --git a/tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts new file mode 100644 index 00000000000..ab72d10504a --- /dev/null +++ b/tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts @@ -0,0 +1,15 @@ +// @module: commonjs +// @target: ES5 + +export default function Foo() { +} + +namespace Foo { + export var x; +} + +interface Foo { +} + +export interface Foo { +} \ No newline at end of file From 157235f5dab788663a78a28f1279859ea3cd69a6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 27 Jul 2015 11:45:22 -0700 Subject: [PATCH 79/85] Fixed test message. --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1b8cd56e12c..32b67123a68 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10901,7 +10901,7 @@ namespace ts { // Only error on the declarations that conributed to the intersecting spaces. if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) { - error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration, declarationNameToString(d.name)); + error(d.name, Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, declarationNameToString(d.name)); } else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) { error(d.name, Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, declarationNameToString(d.name)); diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index f6f50c3ba8e..b7526a1dd43 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -425,7 +425,7 @@ namespace ts { JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" }, The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" }, Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" }, - Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration: { code: 2651, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0};' declaration." }, + Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2651, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fecfbb7dcab..f28ad54b58e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1689,7 +1689,7 @@ "category": "Error", "code": 2650 }, - "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0};' declaration.": { + "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead.": { "category": "Error", "code": 2651 }, From 28ce0a1a84eb5d46d05269e2cb0377eb91d2a755 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 27 Jul 2015 11:51:53 -0700 Subject: [PATCH 80/85] Accepted baselines. --- .../defaultExportsCannotMerge01.errors.txt | 8 +++--- .../defaultExportsCannotMerge02.errors.txt | 8 +++--- .../defaultExportsCannotMerge03.errors.txt | 8 +++--- .../defaultExportsCannotMerge04.errors.txt | 28 +++++++++++++++++++ .../reference/defaultExportsCannotMerge04.js | 23 +++++++++++++++ 5 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/defaultExportsCannotMerge04.errors.txt create mode 100644 tests/baselines/reference/defaultExportsCannotMerge04.js diff --git a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt index ee0f549aa97..6e3955b4ef8 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. -tests/cases/conformance/es6/modules/m1.ts(11,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +tests/cases/conformance/es6/modules/m1.ts(11,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. tests/cases/conformance/es6/modules/m2.ts(5,8): error TS2304: Cannot find name 'Entity'. tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,8): error TS2339: Property 'x' does not exist on type '() => number'. @@ -10,7 +10,7 @@ tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does export default function Decl() { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. return 0; } @@ -21,7 +21,7 @@ tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does export namespace Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. export var x = 10; export var y = 20; diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt index fbf7076eb51..ef4ecdccfc3 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. -tests/cases/conformance/es6/modules/m1.ts(5,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +tests/cases/conformance/es6/modules/m1.ts(5,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,13): error TS2339: Property 'p1' does not exist on type 'Decl'. @@ -10,12 +10,12 @@ tests/cases/conformance/es6/modules/m2.ts(8,20): error TS2339: Property 'p2' doe export default class Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. } export interface Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. p1: number; p2: number; } diff --git a/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt index 5babb6ac743..219b59a5633 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. tests/cases/conformance/es6/modules/m1.ts(5,11): error TS2518: Only an ambient class can be merged with an interface. -tests/cases/conformance/es6/modules/m1.ts(5,11): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +tests/cases/conformance/es6/modules/m1.ts(5,11): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,13): error TS2339: Property 'p1' does not exist on type 'Decl'. @@ -11,14 +11,14 @@ tests/cases/conformance/es6/modules/m2.ts(8,20): error TS2339: Property 'p2' doe export default class Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. } interface Decl { ~~~~ !!! error TS2518: Only an ambient class can be merged with an interface. ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl;' declaration. +!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. p1: number; p2: number; } diff --git a/tests/baselines/reference/defaultExportsCannotMerge04.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge04.errors.txt new file mode 100644 index 00000000000..ee36491e0c7 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge04.errors.txt @@ -0,0 +1,28 @@ +tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(2,25): error TS2651: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. +tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(5,11): error TS2651: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. +tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(9,11): error TS2395: Individual declarations in merged declaration 'Foo' must be all exported or all local. +tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(12,18): error TS2395: Individual declarations in merged declaration 'Foo' must be all exported or all local. + + +==== tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts (4 errors) ==== + + export default function Foo() { + ~~~ +!!! error TS2651: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. + } + + namespace Foo { + ~~~ +!!! error TS2651: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. + export var x; + } + + interface Foo { + ~~~ +!!! error TS2395: Individual declarations in merged declaration 'Foo' must be all exported or all local. + } + + export interface Foo { + ~~~ +!!! error TS2395: Individual declarations in merged declaration 'Foo' must be all exported or all local. + } \ No newline at end of file diff --git a/tests/baselines/reference/defaultExportsCannotMerge04.js b/tests/baselines/reference/defaultExportsCannotMerge04.js new file mode 100644 index 00000000000..eb1122a8197 --- /dev/null +++ b/tests/baselines/reference/defaultExportsCannotMerge04.js @@ -0,0 +1,23 @@ +//// [defaultExportsCannotMerge04.ts] + +export default function Foo() { +} + +namespace Foo { + export var x; +} + +interface Foo { +} + +export interface Foo { +} + +//// [defaultExportsCannotMerge04.js] +function Foo() { +} +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = Foo; +var Foo; +(function (Foo) { +})(Foo || (Foo = {})); From 4e3751c07c1e7a89966c6efe962f6c790d11438f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 27 Jul 2015 12:31:53 -0700 Subject: [PATCH 81/85] Use Debug.assert instead of Debug.fail; preserve 'any' variants --- src/compiler/checker.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7f22693ee25..6cf0893d7c7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7323,12 +7323,9 @@ namespace ts { * For example, in the element , the element instance type is `MyClass` (not `typeof MyClass`). */ function getJsxElementInstanceType(node: JsxOpeningLikeElement) { - if (!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement)) { - // There is no such thing as an instance type for a non-class element. This - // line shouldn't be hit. - Debug.fail('Should not call getJsxElementInstanceType on non-class Element'); - return undefined; - } + // There is no such thing as an instance type for a non-class element. This + // line shouldn't be hit. + Debug.assert(!!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement), 'Should not call getJsxElementInstanceType on non-class Element'); let classSymbol = getJsxElementTagSymbol(node); if (classSymbol === unknownSymbol) { @@ -7416,7 +7413,7 @@ namespace ts { let elemInstanceType = getJsxElementInstanceType(node); if (isTypeAny(elemInstanceType)) { - return links.resolvedJsxType = anyType; + return links.resolvedJsxType = elemInstanceType; } let propsName = getJsxElementPropertiesName(); From 7c024aba56621c1a578126f7d01265a6ef1cdf0b Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 27 Jul 2015 13:19:14 -0700 Subject: [PATCH 82/85] cleanup --- src/services/services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 4645aeb3103..8e670268498 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -262,7 +262,7 @@ namespace ts { public getFirstToken(sourceFile?: SourceFile): Node { let children = this.getChildren(sourceFile); - if (!(children.length > 0)) { + if (!children.length) { return undefined; } From 4c3d21f8f3c532ed89331b290d890edbf9049c06 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 27 Jul 2015 18:03:07 -0700 Subject: [PATCH 83/85] updated baselines --- .../reference/defaultExportsCannotMerge01.errors.txt | 8 ++++---- .../reference/defaultExportsCannotMerge02.errors.txt | 8 ++++---- .../reference/defaultExportsCannotMerge03.errors.txt | 8 ++++---- .../reference/defaultExportsCannotMerge04.errors.txt | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt index 6e3955b4ef8..be08d976eeb 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge01.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. -tests/cases/conformance/es6/modules/m1.ts(11,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +tests/cases/conformance/es6/modules/m1.ts(11,18): error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. tests/cases/conformance/es6/modules/m2.ts(5,8): error TS2304: Cannot find name 'Entity'. tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,8): error TS2339: Property 'x' does not exist on type '() => number'. @@ -10,7 +10,7 @@ tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does export default function Decl() { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +!!! error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. return 0; } @@ -21,7 +21,7 @@ tests/cases/conformance/es6/modules/m2.ts(9,8): error TS2339: Property 'y' does export namespace Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +!!! error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. export var x = 10; export var y = 20; diff --git a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt index ef4ecdccfc3..ad9b85c7e94 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge02.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. -tests/cases/conformance/es6/modules/m1.ts(5,18): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +tests/cases/conformance/es6/modules/m1.ts(5,18): error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,13): error TS2339: Property 'p1' does not exist on type 'Decl'. @@ -10,12 +10,12 @@ tests/cases/conformance/es6/modules/m2.ts(8,20): error TS2339: Property 'p2' doe export default class Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +!!! error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. } export interface Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +!!! error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. p1: number; p2: number; } diff --git a/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt index 219b59a5633..b1d405671e3 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge03.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +tests/cases/conformance/es6/modules/m1.ts(2,22): error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. tests/cases/conformance/es6/modules/m1.ts(5,11): error TS2518: Only an ambient class can be merged with an interface. -tests/cases/conformance/es6/modules/m1.ts(5,11): error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +tests/cases/conformance/es6/modules/m1.ts(5,11): error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. tests/cases/conformance/es6/modules/m2.ts(3,1): error TS2348: Value of type 'typeof Decl' is not callable. Did you mean to include 'new'? tests/cases/conformance/es6/modules/m2.ts(6,8): error TS2503: Cannot find namespace 'Entity'. tests/cases/conformance/es6/modules/m2.ts(8,13): error TS2339: Property 'p1' does not exist on type 'Decl'. @@ -11,14 +11,14 @@ tests/cases/conformance/es6/modules/m2.ts(8,20): error TS2339: Property 'p2' doe export default class Decl { ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +!!! error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. } interface Decl { ~~~~ !!! error TS2518: Only an ambient class can be merged with an interface. ~~~~ -!!! error TS2651: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. +!!! error TS2652: Merged declaration 'Decl' cannot include a default export declaration. Consider adding a separate 'export default Decl' declaration instead. p1: number; p2: number; } diff --git a/tests/baselines/reference/defaultExportsCannotMerge04.errors.txt b/tests/baselines/reference/defaultExportsCannotMerge04.errors.txt index ee36491e0c7..000a9b8f30e 100644 --- a/tests/baselines/reference/defaultExportsCannotMerge04.errors.txt +++ b/tests/baselines/reference/defaultExportsCannotMerge04.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(2,25): error TS2651: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. -tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(5,11): error TS2651: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. +tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(2,25): error TS2652: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. +tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(5,11): error TS2652: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(9,11): error TS2395: Individual declarations in merged declaration 'Foo' must be all exported or all local. tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(12,18): error TS2395: Individual declarations in merged declaration 'Foo' must be all exported or all local. @@ -8,12 +8,12 @@ tests/cases/conformance/es6/modules/defaultExportsCannotMerge04.ts(12,18): error export default function Foo() { ~~~ -!!! error TS2651: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. +!!! error TS2652: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. } namespace Foo { ~~~ -!!! error TS2651: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. +!!! error TS2652: Merged declaration 'Foo' cannot include a default export declaration. Consider adding a separate 'export default Foo' declaration instead. export var x; } From 4673d618a7e92c1c49bdf47c655428033543bbe6 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 28 Jul 2015 14:42:08 -0700 Subject: [PATCH 84/85] Make declaration emitter call resolver.isOptionalParameter --- src/compiler/checker.ts | 4 +++- src/compiler/declarationEmitter.ts | 2 +- src/compiler/types.ts | 4 +++- src/services/signatureHelp.ts | 20 +++---------------- .../requiredInitializedParameter4.js | 20 +++++++++++++++++++ .../requiredInitializedParameter4.symbols | 9 +++++++++ .../requiredInitializedParameter4.types | 10 ++++++++++ .../compiler/requiredInitializedParameter4.ts | 4 ++++ 8 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 tests/baselines/reference/requiredInitializedParameter4.js create mode 100644 tests/baselines/reference/requiredInitializedParameter4.symbols create mode 100644 tests/baselines/reference/requiredInitializedParameter4.types create mode 100644 tests/cases/compiler/requiredInitializedParameter4.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 05e1f1963c9..a98dfc1805e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -91,7 +91,8 @@ namespace ts { getExportsOfModule: getExportsOfModuleAsArray, getJsxElementAttributesType, - getJsxIntrinsicTagNames + getJsxIntrinsicTagNames, + isOptionalParameter }; let unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown"); @@ -14402,6 +14403,7 @@ namespace ts { getBlockScopedVariableId, getReferencedValueDeclaration, getTypeReferenceSerializationKind, + isOptionalParameter }; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 6c0803f8761..63d71b0339e 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1371,7 +1371,7 @@ namespace ts { else { writeTextOfNode(currentSourceFile, node.name); } - if (node.initializer || hasQuestionToken(node)) { + if (resolver.isOptionalParameter(node)) { write("?"); } decreaseIndent(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 21eed30c244..fb3003b9c78 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1431,6 +1431,7 @@ namespace ts { getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type; getJsxIntrinsicTagNames(): Symbol[]; + isOptionalParameter(node: ParameterDeclaration): boolean; // Should not be called directly. Should only be accessed through the Program instance. /* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; @@ -1574,7 +1575,8 @@ namespace ts { getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number; getBlockScopedVariableId(node: Identifier): number; getReferencedValueDeclaration(reference: Identifier): Declaration; - getTypeReferenceSerializationKind(node: TypeReferenceNode): TypeReferenceSerializationKind; + getTypeReferenceSerializationKind(node: TypeReferenceNode): TypeReferenceSerializationKind; + isOptionalParameter(node: ParameterDeclaration): boolean; } export const enum SymbolFlags { diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 6230a66910e..df321647e5c 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -569,15 +569,7 @@ namespace ts.SignatureHelp { prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); let parameters = candidateSignature.parameters; - if (parameters.length > 0) { - signatureHelpParameters = []; - for (let i = 0; i < parameters.length; i++) { - signatureHelpParameters.push(createSignatureHelpParameterAtIndex(candidateSignature, i)); - } - } - else { - signatureHelpParameters = emptyArray; - } + signatureHelpParameters = parameters.length > 0 ? map(parameters, createSignatureHelpParameterForParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } @@ -615,21 +607,15 @@ namespace ts.SignatureHelp { argumentCount }; - function createSignatureHelpParameterAtIndex(signature: Signature, parameterIndex: number): SignatureHelpParameter { - let parameter = signature.parameters[parameterIndex]; + function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { let displayParts = mapToDisplayParts(writer => typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation)); - let parameterDeclaration = parameter.valueDeclaration; - let isOptional = - hasQuestionToken(parameterDeclaration) || - parameterDeclaration.initializer && parameterIndex >= signature.minArgumentCount; - return { name: parameter.name, documentation: parameter.getDocumentationComment(), displayParts, - isOptional + isOptional: typeChecker.isOptionalParameter(parameter.valueDeclaration) }; } diff --git a/tests/baselines/reference/requiredInitializedParameter4.js b/tests/baselines/reference/requiredInitializedParameter4.js new file mode 100644 index 00000000000..3b23f119391 --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter4.js @@ -0,0 +1,20 @@ +//// [requiredInitializedParameter4.ts] +class C1 { + method(a = 0, b) { } +} + +//// [requiredInitializedParameter4.js] +var C1 = (function () { + function C1() { + } + C1.prototype.method = function (a, b) { + if (a === void 0) { a = 0; } + }; + return C1; +})(); + + +//// [requiredInitializedParameter4.d.ts] +declare class C1 { + method(a: number, b: any): void; +} diff --git a/tests/baselines/reference/requiredInitializedParameter4.symbols b/tests/baselines/reference/requiredInitializedParameter4.symbols new file mode 100644 index 00000000000..2790b33698c --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter4.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/requiredInitializedParameter4.ts === +class C1 { +>C1 : Symbol(C1, Decl(requiredInitializedParameter4.ts, 0, 0)) + + method(a = 0, b) { } +>method : Symbol(method, Decl(requiredInitializedParameter4.ts, 0, 10)) +>a : Symbol(a, Decl(requiredInitializedParameter4.ts, 1, 11)) +>b : Symbol(b, Decl(requiredInitializedParameter4.ts, 1, 17)) +} diff --git a/tests/baselines/reference/requiredInitializedParameter4.types b/tests/baselines/reference/requiredInitializedParameter4.types new file mode 100644 index 00000000000..c483146a1ba --- /dev/null +++ b/tests/baselines/reference/requiredInitializedParameter4.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/requiredInitializedParameter4.ts === +class C1 { +>C1 : C1 + + method(a = 0, b) { } +>method : (a: number, b: any) => void +>a : number +>0 : number +>b : any +} diff --git a/tests/cases/compiler/requiredInitializedParameter4.ts b/tests/cases/compiler/requiredInitializedParameter4.ts new file mode 100644 index 00000000000..4ba15878e43 --- /dev/null +++ b/tests/cases/compiler/requiredInitializedParameter4.ts @@ -0,0 +1,4 @@ +//@declaration: true +class C1 { + method(a = 0, b) { } +} \ No newline at end of file From 71a7c19cea04183adc541bf43767ad8aae4c574a Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 28 Jul 2015 14:49:28 -0700 Subject: [PATCH 85/85] Fix naming and update comment --- src/compiler/checker.ts | 23 ++++++++++++----------- src/compiler/types.ts | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 544a1e2d4b0..8dd22626872 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -114,7 +114,7 @@ namespace ts { let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated - // in getContainsLiteralFlagsOfTypes, and it is checked in inferFromTypes. + // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes. anyFunctionType.flags |= TypeFlags.ContainsAnyFunctionType; let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -3761,22 +3761,23 @@ namespace ts { } } - // This function is used to propagate widening flags when creating new object types references and union types. - // It is only necessary to do so if a constituent type might be the undefined type, the null type, or the type - // of an object literal (since those types have widening related information we need to track). - function getContainsLiteralFlagsOfTypes(types: Type[]): TypeFlags { + // This function is used to propagate certain flags when creating new object type references and union types. + // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type + // of an object literal or the anyFunctionType. This is because there are operations in the type checker + // that care about the presence of such types at arbitrary depth in a containing type. + function getPropagatingFlagsOfTypes(types: Type[]): TypeFlags { let result: TypeFlags = 0; for (let type of types) { result |= type.flags; } - return result & TypeFlags.ContainsLiteralFlags; + return result & TypeFlags.PropagatingFlags; } function createTypeReference(target: GenericType, typeArguments: Type[]): TypeReference { let id = getTypeListId(typeArguments); let type = target.instantiations[id]; if (!type) { - let flags = TypeFlags.Reference | getContainsLiteralFlagsOfTypes(typeArguments); + let flags = TypeFlags.Reference | getPropagatingFlagsOfTypes(typeArguments); type = target.instantiations[id] = createObjectType(flags, target.symbol); type.target = target; type.typeArguments = typeArguments; @@ -4030,7 +4031,7 @@ namespace ts { let id = getTypeListId(elementTypes); let type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(TypeFlags.Tuple | getContainsLiteralFlagsOfTypes(elementTypes)); + type = tupleTypes[id] = createObjectType(TypeFlags.Tuple | getPropagatingFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -4179,7 +4180,7 @@ namespace ts { let id = getTypeListId(typeSet); let type = unionTypes[id]; if (!type) { - type = unionTypes[id] = createObjectType(TypeFlags.Union | getContainsLiteralFlagsOfTypes(typeSet)); + type = unionTypes[id] = createObjectType(TypeFlags.Union | getPropagatingFlagsOfTypes(typeSet)); type.types = typeSet; } return type; @@ -4213,7 +4214,7 @@ namespace ts { let id = getTypeListId(typeSet); let type = intersectionTypes[id]; if (!type) { - type = intersectionTypes[id] = createObjectType(TypeFlags.Intersection | getContainsLiteralFlagsOfTypes(typeSet)); + type = intersectionTypes[id] = createObjectType(TypeFlags.Intersection | getPropagatingFlagsOfTypes(typeSet)); type.types = typeSet; } return type; @@ -7103,7 +7104,7 @@ namespace ts { let stringIndexType = getIndexType(IndexKind.String); let numberIndexType = getIndexType(IndexKind.Number); let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); - result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsLiteralFlags); + result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.PropagatingFlags); return result; function getIndexType(kind: IndexKind) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 57706357bf7..e125fffc5bf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1784,7 +1784,7 @@ namespace ts { /* @internal */ RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral, /* @internal */ - ContainsLiteralFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType + PropagatingFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType } // Properties common to all types