diff --git a/.gitignore b/.gitignore index 19d96d0b046..5125de360b8 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,7 @@ internal/ !tests/baselines/reference/project/nodeModules*/**/* .idea yarn.lock +yarn-error.log .parallelperf.* tests/cases/user/*/package-lock.json tests/cases/user/*/node_modules/ diff --git a/.mailmap b/.mailmap index 98f004c58dc..80487998c95 100644 --- a/.mailmap +++ b/.mailmap @@ -140,7 +140,7 @@ Mike Busyrev Mine Starks Mine Starks Mohamed Hegazy ncoley # Natalie Coley -Nathan Shively-Sanders +Nathan Shively-Sanders Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Nathan Yee Nima Zahedi Noah Chen @@ -287,4 +287,28 @@ Stas Vilchik Taras Mankovski Thomas den Hollander Vakhurin Sergey -Zeeshan Ahmed \ No newline at end of file +Zeeshan Ahmed +Orta # Orta Therox +IdeaHunter # @IdeaHunter +kujon # Jakub Korzeniowski +Matt @begincalendar +meyer # @meyer +micbou # @micbou +Alan Agius +Alex Khomchenko +Oussama Ben Brahim benbraou +Cameron Taggart +csigs csigs +Eugene Timokhov +Kris Zyp +Jing Ma +Martin Hiller +Mike Morearty +Priyantha Lankapura <403912+lankaapura@users.noreply.github.com> +Remo H. Jansen +Sean Barag +Sharon Rolel +Stanislav Iliev +Wenlu Wang <805037171@163.com> wenlu.wang <805037171@163.com> kingwl <805037171@163.com> +Wilson Hobbs +Yuval Greenfield \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 06e912c55f5..b4a5227c34a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ branches: - master - release-2.5 - release-2.6 + - release-2.7 install: - npm uninstall typescript --no-save diff --git a/AUTHORS.md b/AUTHORS.md index c554a588715..0dfaddb7a25 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -6,8 +6,10 @@ TypeScript is authored by: * Adrian Leonhard * Ahmad Farid * Akshar Patel +* Alan Agius * Alex Chugaev * Alex Eagle +* Alex Khomchenko * Alexander Kuvaev * Alexander Rusakov * Ali Sabzevari @@ -47,6 +49,7 @@ TypeScript is authored by: * Brett Mayen * Bryan Forbes * Caitlin Potter +* Cameron Taggart * @cedvdb * Charles Pierce * Charly POLY @@ -56,6 +59,7 @@ TypeScript is authored by: * Colby Russell * Colin Snover * Cotton Hou +* csigs * Cyrus Najmabadi * Dafrok Zhang * Dahan Gong @@ -85,6 +89,7 @@ TypeScript is authored by: * Erik McClenney * Ethan Resnick * Ethan Rubio +* Eugene Timokhov * Evan Martin * Evan Sebastian * Eyas Sharaiha @@ -111,6 +116,7 @@ TypeScript is authored by: * Herrington Darkholme * Homa Wong * Iain Monro +* @IdeaHunter * Igor Novozhilov * Ika * Ingvar Stepanyan @@ -118,6 +124,7 @@ TypeScript is authored by: * Ivan Enderlin * Ivo Gabe de Wolff * Iwata Hidetaka +* Jakub Korzeniowski * Jakub Młokosiewicz * James Henry * James Whitney @@ -130,6 +137,7 @@ TypeScript is authored by: * Jed Mao * Jeffrey Morlan * Jesse Schalken +* Jing Ma * Jiri Tobisek * Joe Calzaretta * Joe Chung @@ -160,6 +168,7 @@ TypeScript is authored by: * Kevin Lang * Kitson Kelly * Klaus Meinhardt +* Kris Zyp * Kyle Kelley * Kārlis Gaņģis * Lorant Pinter @@ -170,8 +179,10 @@ TypeScript is authored by: * Manish Giri * Marin Marinov * Marius Schulz +* Martin Hiller * Martin Vseticka * Masahiro Wakame +* Matt * Matt Bierner * Matt McCutchen * Matt Mitchell @@ -179,10 +190,13 @@ TypeScript is authored by: * Mattias Buelens * Max Deepfield * Maxwell Paul Brickner +* @meyer * Micah Zoltu +* @micbou * Michael * Michael Bromley * Mike Busyrev +* Mike Morearty * Mine Starks * Mohamed Hegazy * Mohsen Azimi @@ -198,7 +212,9 @@ TypeScript is authored by: * Oleg Mihailik * Oleksandr Chekhovskyi * Omer Sheikh +* Orta Therox * Oskar Segersva¨rd +* Oussama Ben Brahim * Patrick Zhong * Paul Jolly * Paul van Brenk @@ -210,11 +226,13 @@ TypeScript is authored by: * Piero Cangianiello * @piloopin * Prayag Verma +* Priyantha Lankapura * @progre * Punya Biswal * Rado Kirov * Raj Dosanjh * Reiner Dolp +* Remo H. Jansen * Richard Karmazín * Richard Knoll * Richard Sentino @@ -227,8 +245,10 @@ TypeScript is authored by: * Ryohei Ikegami * Sam El-Husseini * Sarangan Rajamanickam +* Sean Barag * Sergey Rubanov * Sergey Shandar +* Sharon Rolel * Sheetal Nandi * Shengping Zhong * Shyyko Serhiy @@ -237,6 +257,7 @@ TypeScript is authored by: * Solal Pirelli * Soo Jae Hwang * Stan Thomas +* Stanislav Iliev * Stanislav Sysoev * Stas Vilchik * Steve Lucco @@ -268,11 +289,14 @@ TypeScript is authored by: * Vilic Vane * Vladimir Kurchatkin * Vladimir Matveev +* Wenlu Wang * Wesley Wigham * William Orr +* Wilson Hobbs * York Yao * @yortus * Yuichi Nukiyama +* Yuval Greenfield * Zeeshan Ahmed * Zev Spitz * Zhengbo Li \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6dbb7e514a0..1d11db2f87b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,14 @@ Issues that ask questions answered in the FAQ will be closed without elaboration ## 2. Search for Duplicates -[Search the existing issues](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=is%3Aissue) before logging a new one. +[Search the existing issues](https://github.com/Microsoft/TypeScript/search?type=Issues) before logging a new one. + +Some search tips: + * *Don't* restrict your search to only open issues. An issue with a title similar to yours may have been closed as a duplicate of one with a less-findable title. + * Check for synonyms. For example, if your bug involves an interface, it likely also occurs with type aliases or classes. + * Search for the title of the issue you're about to log. This sounds obvious but 80% of the time this is sufficient to find a duplicate when one exists. + * Read more than the first page of results. Many bugs here use the same words so relevancy sorting is not particularly strong. + * If you have a crash, search for the first few topmost function names shown in the call stack. ## 3. Do you have a question? @@ -183,3 +190,10 @@ jake baseline-accept ``` to establish the new baselines as the desired behavior. This will change the files in `tests\baselines\reference`, which should be included as part of your commit. It's important to carefully validate changes in the baselines. + +## Localization + +All strings the user may see are stored in [`diagnosticMessages.json`](./src/compiler/diagnosticMessages.json). +If you make changes to it, run `jake generate-diagnostics` to push them to the `Diagnostic` interface in [`diagnosticInformationMap.generated.ts`](./src/compiler/diagnosticInformationMap.generated.ts). + +See [coding guidelines on diagnostic messages](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#diagnostic-messages). diff --git a/Gulpfile.ts b/Gulpfile.ts index 4d90d5cf24a..0c410bdfb08 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -150,7 +150,9 @@ const es2018LibrarySourceMap = es2018LibrarySource.map(source => ({ target: "lib." + source, sources: ["header.d.ts", source] })); const esnextLibrarySource = [ - "esnext.asynciterable.d.ts" + "esnext.asynciterable.d.ts", + "esnext.array.d.ts", + "esnext.promise.d.ts" ]; const esnextLibrarySourceMap = esnextLibrarySource.map(source => @@ -526,7 +528,7 @@ gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (do const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ true)); const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src() .pipe(sourcemaps.init()) - .pipe(newer(tsserverLibraryFile)) + .pipe(newer({ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] })) .pipe(serverLibraryProject()); return merge2([ @@ -679,14 +681,14 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: workerCount = cmdLineOptions.workers; } - if (tests || runners || light || taskConfigsFolder) { - writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit); - } - if (tests && tests.toLocaleLowerCase() === "rwc") { testTimeout = 400000; } + if (tests || runners || light || testTimeout || taskConfigsFolder) { + writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout); + } + const colors = cmdLineOptions.colors; const reporter = cmdLineOptions.reporter || defaultReporter; @@ -871,8 +873,17 @@ function cleanTestDirs(done: (e?: any) => void) { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests: string, runners: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string) { - const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, runner: runners ? runners.split(",") : undefined, light, workerCount, stackTraceLimit, taskConfigsFolder, noColor: !cmdLineOptions.colors }); +function writeTestConfigFile(tests: string, runners: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string, timeout?: number) { + const testConfigContents = JSON.stringify({ + test: tests ? [tests] : undefined, + runner: runners ? runners.split(",") : undefined, + light, + workerCount, + stackTraceLimit, + taskConfigsFolder, + noColor: !cmdLineOptions.colors, + timeout, + }); console.log("Running tests with config: " + testConfigContents); fs.writeFileSync("test.config", testConfigContents); } diff --git a/Jakefile.js b/Jakefile.js index e016c1bd0bd..2026544a249 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -213,7 +213,9 @@ var es2018LibrarySourceMap = es2018LibrarySource.map(function (source) { }); var esnextLibrarySource = [ - "esnext.asynciterable.d.ts" + "esnext.asynciterable.d.ts", + "esnext.array.d.ts", + "esnext.promise.d.ts" ]; var esnextLibrarySourceMap = esnextLibrarySource.map(function (source) { @@ -857,7 +859,7 @@ function cleanTestDirs() { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors) { +function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors, testTimeout) { var testConfigContents = JSON.stringify({ runners: runners ? runners.split(",") : undefined, test: tests ? [tests] : undefined, @@ -865,7 +867,8 @@ function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCou workerCount: workerCount, taskConfigsFolder: taskConfigsFolder, stackTraceLimit: stackTraceLimit, - noColor: !colors + noColor: !colors, + timeout: testTimeout }); fs.writeFileSync('test.config', testConfigContents); } @@ -907,14 +910,14 @@ function runConsoleTests(defaultReporter, runInParallel) { workerCount = process.env.workerCount || process.env.p || os.cpus().length; } - if (tests || runners || light || taskConfigsFolder) { - writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors); - } - if (tests && tests.toLocaleLowerCase() === "rwc") { testTimeout = 800000; } + if (tests || runners || light || testTimeout || taskConfigsFolder) { + writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors, testTimeout); + } + var colorsFlag = process.env.color || process.env.colors; var colors = colorsFlag !== "false" && colorsFlag !== "0"; var reporter = process.env.reporter || process.env.r || defaultReporter; @@ -1201,6 +1204,7 @@ var tslintRules = [ "debugAssertRule", "nextLineRule", "noBomRule", + "noDoubleSpaceRule", "noIncrementDecrementRule", "noInOperatorRule", "noTypeAssertionWhitespaceRule", diff --git a/issue_template.md b/issue_template.md index dbc021c28ad..22acf3e9cc5 100644 --- a/issue_template.md +++ b/issue_template.md @@ -15,3 +15,5 @@ **Expected behavior:** **Actual behavior:** + +**Related:** diff --git a/package-lock.json b/package-lock.json index 2f651895c08..736551168ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,13 +4,30 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@browserify/acorn5-object-spread": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@browserify/acorn5-object-spread/-/acorn5-object-spread-5.0.1.tgz", + "integrity": "sha512-sFCUPzgeEjdq3rinwy4TFXtak2YZdhqpj6MdNusxkdTFr9TXAUEYK4YQSamR8Joqt/yii1drgl5hk8q/AtJDKA==", + "dev": true, + "requires": { + "acorn": "5.3.0" + }, + "dependencies": { + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true + } + } + }, "@gulp-sourcemaps/identity-map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz", "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", "dev": true, "requires": { - "acorn": "5.2.1", + "acorn": "5.3.0", "css": "2.2.1", "normalize-path": "2.1.1", "source-map": "0.5.7", @@ -18,9 +35,9 @@ }, "dependencies": { "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", "dev": true } } @@ -42,13 +59,13 @@ "dev": true, "requires": { "@types/insert-module-globals": "7.0.0", - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/chai": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.10.tgz", - "integrity": "sha512-Ejh1AXTY8lm+x91X/yar3G2z4x9RyKwdTVdyyu7Xj3dNB35fMNCnEWqTO9FgS3zjzlRNqk1MruYhgb8yhRN9rA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.0.tgz", + "integrity": "sha512-OuYBlXWHYthxIudMXMeQr92f6D97YoT9CUYCRb0BEP4OavC95jNcczjjr4Ob3H5E1IqlWqwj+leUZPSeth27Qw==", "dev": true }, "@types/convert-source-map": { @@ -63,7 +80,7 @@ "integrity": "sha512-18mSs54BvzV8+TTQxt0ancig6tsuPZySnhp3cQkWFFDmDMavU4pmWwR+bHHqRBWODYqpzIzVkqKLuk/fP6yypQ==", "dev": true, "requires": { - "@types/glob": "5.0.33" + "@types/glob": "5.0.34" } }, "@types/events": { @@ -73,24 +90,25 @@ "dev": true }, "@types/glob": { - "version": "5.0.33", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.33.tgz", - "integrity": "sha512-BcD4yyWz+qmCggaYMSFF0Xn7GkO6tgwm3Fh9Gxk/kQmEU3Z7flQTnVlMyKBUNvXXNTCCyjqK4XT4/2hLd1gQ2A==", + "version": "5.0.34", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.34.tgz", + "integrity": "sha512-sUvpieq+HsWTLdkeOI8Mi8u22Ag3AoGuM3sv+XMP1bKtbaIAHpEA2f52K2mz6vK5PVhTa3bFyRZLZMqTxOo2Cw==", "dev": true, "requires": { - "@types/minimatch": "3.0.1", - "@types/node": "8.0.54" + "@types/events": "1.1.0", + "@types/minimatch": "3.0.3", + "@types/node": "8.5.5" } }, "@types/gulp": { - "version": "3.8.35", - "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-3.8.35.tgz", - "integrity": "sha512-h9clNJu8X6+zW74ZLa5zhh5HP0LxnvlelVXdXby6pM/DDEj/gKqmmFXKwjzvupZKlMpof02jr6c3JokPbHXQgg==", + "version": "3.8.36", + "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-3.8.36.tgz", + "integrity": "sha512-u6/zWPzYRNPAtvyFJ3/RSXjmBaBM1dVs5kW22/jU6J786ZGLfSndhLoNOpFI6FGQvqTA+QzFHjSMhpkAN+wxcQ==", "dev": true, "requires": { - "@types/node": "8.0.54", + "@types/node": "8.5.5", "@types/orchestrator": "0.3.2", - "@types/vinyl": "2.0.1" + "@types/vinyl": "2.0.2" } }, "@types/gulp-concat": { @@ -99,7 +117,7 @@ "integrity": "sha512-CUCFADlITzzBfBa2bdGzhKtvBr4eFh+evb+4igVbvPoO5RyPfHifmyQlZl6lM7q19+OKncRlFXDU7B4X9Ayo2g==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/gulp-help": { @@ -108,8 +126,8 @@ "integrity": "sha512-MkW7psZznxxJg2MBk2P2qHE+T8jEZVFz3FG/qGjUYazkyJt7hBJWx5Nuewmay5RVNtUvSWPrdZLr/WTXY3T/6A==", "dev": true, "requires": { - "@types/gulp": "3.8.35", - "@types/node": "8.0.54", + "@types/gulp": "3.8.36", + "@types/node": "8.5.5", "@types/orchestrator": "0.3.2" } }, @@ -119,7 +137,7 @@ "integrity": "sha512-e7J/Zv5Wd7CC0WpuA2syWVitgwrkG0u221e41w7r07XUR6hMH6kHPkq9tUrusHkbeW8QbuLbis5fODOwQCyggQ==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/gulp-sourcemaps": { @@ -128,7 +146,7 @@ "integrity": "sha512-+7BAmptW2bxyJnJcCEuie7vLoop3FwWgCdBMzyv7MYXED/HeNMeQuX7uPCkp4vfU1TTu4CYFH0IckNPvo0VePA==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/insert-module-globals": { @@ -137,7 +155,7 @@ "integrity": "sha512-zudCJPwluh1VUDB6Gl/OQdRp+fYy3+47huJB/JMQubMS2p+sH18MCVK4WUz3FqaWLB12yh5ELxVR/+tqwlm/qA==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/merge2": { @@ -146,13 +164,13 @@ "integrity": "sha512-GjaXY4OultxbaOOk7lCLO7xvEcFpdjExC605YmfI6X29vhHKpJfMWKCDZd3x+BITrZaXKg97DgV/SdGVSwdzxA==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/minimatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.1.tgz", - "integrity": "sha512-rUO/jz10KRSyA9SHoCWQ8WX9BICyj5jZYu1/ucKEJKb4KzLZCKMURdYbadP157Q6Zl1x0vHsrU+Z/O0XlhYQDw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, "@types/minimist": { @@ -167,23 +185,20 @@ "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/mocha": { - "version": "2.2.44", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", - "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "version": "2.2.46", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.46.tgz", + "integrity": "sha512-fwTTP5QLf4xHMkv7ovcKvmlLWX3GrxCa5DRQDOilVyYGCp+arZTAQJCy7/4GKezzYJjfWMpB/Cy4e8nrc9XioA==", "dev": true }, "@types/node": { - "version": "8.0.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.54.tgz", - "integrity": "sha512-qetMdTv3Ytz9u9ESLdcYs45LPI0mczYZIbC184n7kY0jczOqPNQsabBfVCh+na3B2shAfvC459JqHV771A8Rxg==", - "dev": true, - "requires": { - "@types/events": "1.1.0" - } + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz", + "integrity": "sha512-JRnfoh0Ll4ElmIXKxbUfcOodkGvcNHljct6mO1X9hE/mlrMzAx0hYCLAD7sgT53YAY1HdlpzUcV0CkmDqUqTuA==", + "dev": true }, "@types/orchestrator": { "version": "0.3.2", @@ -191,7 +206,7 @@ "integrity": "sha512-cKB4yTX0wGaRCSkdHDX2fkGQbMAA8UOshC2U7DQky1CE5o+5q2iQQ8VkbPbE/88uaTtsusvBPMcCX7dgmjxBhQ==", "dev": true, "requires": { - "@types/node": "8.0.54", + "@types/node": "8.5.5", "@types/q": "1.0.6" } }, @@ -207,26 +222,38 @@ "integrity": "sha512-XwGr1b4yCGUILKeBkzmeWcxmGHQ0vFFFpA6D6y1yLO6gKmYorF+PHqdU5KG+nWt38OvtrkDptmrSmlHX/XtpLw==", "dev": true, "requires": { - "@types/gulp": "3.8.35", - "@types/node": "8.0.54" + "@types/gulp": "3.8.36", + "@types/node": "8.5.5" } }, + "@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", + "dev": true + }, + "@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, "@types/through2": { "version": "2.0.33", "resolved": "https://registry.npmjs.org/@types/through2/-/through2-2.0.33.tgz", "integrity": "sha1-H/LoihAN+1sUDnu5h5HxGUQA0TE=", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/vinyl": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.1.tgz", - "integrity": "sha512-Joudabfn2ZofU2usW04y8OLmN75u7ZQkW0MCT3AnoBf5oUBp5iQ3Pgfz9+y1RdWkzhCPZo9/wBJ7FMWW2JrY0g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.2.tgz", + "integrity": "sha512-2iYpNuOl98SrLPBZfEN9Mh2JCJ2EI9HU35SfgBEb51DcmaHkhp8cKMblYeBqMQiwXMgAD3W60DbQ4i/UdLiXhw==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "@types/xml2js": { @@ -235,13 +262,13 @@ "integrity": "sha512-8aKUBSj3oGcnuiBmDLm3BIk09RYg01mz9HlQ2u4aS17oJ25DxjQrEUVGFSBVNOfM45pQW4OjcBPplq6r/exJdA==", "dev": true, "requires": { - "@types/node": "8.0.54" + "@types/node": "8.5.5" } }, "JSONStream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", - "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", "dev": true, "requires": { "jsonparse": "1.3.1", @@ -269,6 +296,17 @@ "kind-of": "3.2.2", "longest": "1.0.1", "repeat-string": "1.6.1" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } } }, "amdefine": { @@ -277,6 +315,33 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -292,6 +357,12 @@ "color-convert": "1.9.1" } }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -308,13 +379,10 @@ } }, "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -322,6 +390,12 @@ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, "array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", @@ -340,12 +414,6 @@ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", "dev": true }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, "array-map": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", @@ -380,9 +448,9 @@ "dev": true }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "arrify": { @@ -412,9 +480,15 @@ } }, "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, "astw": { @@ -433,9 +507,9 @@ "dev": true }, "atob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", - "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz", + "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=", "dev": true }, "babel-code-frame": { @@ -482,6 +556,21 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "1.0.1", + "class-utils": "0.3.5", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.0", + "pascalcase": "0.1.1" + } + }, "base64-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", @@ -511,14 +600,22 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz", + "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "define-property": "1.0.0", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.1", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.1" } }, "brorand": { @@ -533,7 +630,7 @@ "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "combine-source-map": "0.7.2", "defined": "1.0.0", "through2": "2.0.3", @@ -556,12 +653,12 @@ "dev": true }, "browserify": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz", - "integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-15.0.0.tgz", + "integrity": "sha512-dERxjzl4yacUzaB4XVVXDFFHARzDr6tLRhjqpE/NJUv0SkS3QVmZKiYTiKEQZhQ2HygCL02FUzSS5r3sY/SlTg==", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "assert": "1.4.1", "browser-pack": "6.0.2", "browser-resolve": "1.11.2", @@ -584,7 +681,7 @@ "inherits": "2.0.3", "insert-module-globals": "7.0.1", "labeled-stream-splicer": "2.0.0", - "module-deps": "4.1.1", + "module-deps": "5.0.1", "os-browserify": "0.3.0", "parents": "1.0.1", "path-browserify": "0.0.0", @@ -714,6 +811,23 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" + } + }, "cached-path-relative": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", @@ -721,20 +835,11 @@ "dev": true }, "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true, - "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" - } + "optional": true }, "center-align": { "version": "0.1.3", @@ -745,6 +850,15 @@ "requires": { "align-text": "0.1.4", "lazy-cache": "1.0.4" + }, + "dependencies": { + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "optional": true + } } }, "chai": { @@ -753,7 +867,7 @@ "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { - "assertion-error": "1.0.2", + "assertion-error": "1.1.0", "check-error": "1.0.2", "deep-eql": "3.0.1", "get-func-name": "2.0.0", @@ -788,6 +902,87 @@ "safe-buffer": "5.1.1" } }, + "class-utils": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.5.tgz", + "integrity": "sha1-F+eTEDdQ+WJ7IXbqNM/RtWWQPIA=", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "lazy-cache": "2.0.2", + "static-extend": "0.1.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -838,6 +1033,16 @@ "through2": "2.0.3" } }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "1.0.0", + "object-visit": "1.0.1" + } + }, "color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", @@ -853,6 +1058,12 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, "combine-source-map": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", @@ -879,6 +1090,12 @@ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -948,6 +1165,12 @@ "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1021,6 +1244,12 @@ "urix": "0.1.0" }, "dependencies": { + "atob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", + "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", + "dev": true + }, "source-map": { "version": "0.1.43", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", @@ -1029,18 +1258,27 @@ "requires": { "amdefine": "1.0.1" } + }, + "source-map-resolve": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", + "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", + "dev": true, + "requires": { + "atob": "1.1.3", + "resolve-url": "0.2.1", + "source-map-url": "0.3.0", + "urix": "0.1.0" + } + }, + "source-map-url": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", + "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", + "dev": true } } }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "1.0.2" - } - }, "d": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", @@ -1063,29 +1301,47 @@ "dev": true }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } }, "debug-fabulous": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.2.1.tgz", - "integrity": "sha512-u0TV6HcfLsZ03xLBhdhSViQMldaiQ2o+8/nSILaXkuNSWvxkx66vYJUAam0Eu7gAilJRX/69J4kKdqajQPaPyw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.0.0.tgz", + "integrity": "sha512-dsd50qQ1atDeurcxL7XOjPp4nZCGZzWIONDujDXzl1atSyC3hMbZD+v6440etw+Vt0Pr8ce4TQzHfX3KZM05Mw==", "dev": true, "requires": { "debug": "3.1.0", "memoizee": "0.4.11", "object-assign": "4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "optional": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, "deep-eql": { @@ -1112,6 +1368,15 @@ "clone": "1.0.3" } }, + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", @@ -1144,7 +1409,7 @@ "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "shasum": "1.0.2", "subarg": "1.0.0", "through2": "2.0.3" @@ -1161,13 +1426,10 @@ } }, "detect-file": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", - "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "dev": true, - "requires": { - "fs-exists-sync": "0.1.0" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true }, "detect-newline": { "version": "2.1.0", @@ -1176,19 +1438,20 @@ "dev": true }, "detective": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.0.tgz", - "integrity": "sha512-4mBqSEdMfBpRAo/DQZnTcAXenpiSIJmVKbCMSotS+SFWWcrP/CKM6iBRPdTiEO+wZhlfEsoZlGqpG6ycl5vTqw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.0.2.tgz", + "integrity": "sha512-NUsLoezj4wb9o7vpxS9F3L5vcO87ceyRBcl48op06YFNwkyIEY997JpSCA5lDlDuDc6JxOtaL5qfK3muoWxpMA==", "dev": true, "requires": { - "acorn": "5.2.1", + "@browserify/acorn5-object-spread": "5.0.1", + "acorn": "5.3.0", "defined": "1.0.0" }, "dependencies": { "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", "dev": true } } @@ -1283,15 +1546,6 @@ } } }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, "es5-ext": { "version": "0.10.37", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", @@ -1417,12 +1671,86 @@ } }, "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.0", + "snapdragon": "0.8.1", + "to-regex": "3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } } }, "expand-range": { @@ -1432,15 +1760,57 @@ "dev": true, "requires": { "fill-range": "2.2.3" + }, + "dependencies": { + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } } }, "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "homedir-polyfill": "1.0.1" } }, "extend": { @@ -1459,49 +1829,30 @@ } }, "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.3.tgz", + "integrity": "sha512-AyptZexgu7qppEPq59DtN/XJGZDrLcVxSHai+4hdgMMS9EpF4GBvygcWWApno8lL9qSjVpYt7Raao28qzJX1ww==", "dev": true, "requires": { - "is-extglob": "1.0.0" + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.0", + "snapdragon": "0.8.1", + "to-regex": "3.0.1" } }, "fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", + "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", "dev": true, "requires": { - "chalk": "1.1.3", + "ansi-gray": "0.1.1", + "color-support": "1.1.3", "time-stamp": "1.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } } }, "fast-levenshtein": { @@ -1535,16 +1886,15 @@ "dev": true }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" } }, "find-index": { @@ -1553,26 +1903,16 @@ "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", "dev": true }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, "findup-sync": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", - "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", "dev": true, "requires": { - "detect-file": "0.1.0", - "is-glob": "2.0.1", - "micromatch": "2.3.11", - "resolve-dir": "0.1.1" + "detect-file": "1.0.0", + "is-glob": "3.1.0", + "micromatch": "3.1.5", + "resolve-dir": "1.0.1" } }, "fined": { @@ -1585,18 +1925,7 @@ "is-plain-object": "2.0.4", "object.defaults": "1.1.0", "object.pick": "1.3.0", - "parse-filepath": "1.0.1" - }, - "dependencies": { - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" - } - } + "parse-filepath": "1.0.2" } }, "first-chunk-stream": { @@ -1606,9 +1935,9 @@ "dev": true }, "flagged-respawn": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", - "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", + "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", "dev": true }, "for-in": { @@ -1618,19 +1947,22 @@ "dev": true }, "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { "for-in": "1.0.2" } }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", - "dev": true + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "0.2.2" + } }, "fs.realpath": { "version": "1.0.0", @@ -1659,10 +1991,10 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, "glob": { @@ -1687,15 +2019,42 @@ "requires": { "glob-parent": "2.0.0", "is-glob": "2.0.1" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + } } }, "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" } }, "glob-stream": { @@ -1788,24 +2147,26 @@ } }, "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "requires": { - "global-prefix": "0.1.5", - "is-windows": "0.2.0" + "global-prefix": "1.0.2", + "is-windows": "1.0.1", + "resolve-dir": "1.0.1" } }, "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "dev": true, "requires": { + "expand-tilde": "2.0.2", "homedir-polyfill": "1.0.1", "ini": "1.3.5", - "is-windows": "0.2.0", + "is-windows": "1.0.1", "which": "1.3.0" } }, @@ -1891,7 +2252,7 @@ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", "dev": true, "requires": { - "natives": "1.1.0" + "natives": "1.1.1" } }, "growl": { @@ -1911,7 +2272,7 @@ "deprecated": "0.0.1", "gulp-util": "3.0.8", "interpret": "1.1.0", - "liftoff": "2.3.0", + "liftoff": "2.5.0", "minimist": "1.2.0", "orchestrator": "0.3.8", "pretty-hrtime": "1.0.3", @@ -1949,221 +2310,15 @@ } }, "gulp-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulp-clone/-/gulp-clone-1.0.0.tgz", - "integrity": "sha1-mubGVr2cTzae6AXu9WV4a8gQBbA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/gulp-clone/-/gulp-clone-1.1.1.tgz", + "integrity": "sha512-+9z6YKyup0pxL1nD9Hw5WjC29d280dsGkegagzt4xKAOvroyzZlA8Bs9MYs2WSSFIDqmcftMUVN/oentgBv69A==", "dev": true, "requires": { - "gulp-util": "2.2.20", - "through2": "0.4.2" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.5", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - } - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" - } - }, - "gulp-util": { - "version": "2.2.20", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", - "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "dateformat": "1.0.12", - "lodash._reinterpolate": "2.4.1", - "lodash.template": "2.4.1", - "minimist": "0.2.0", - "multipipe": "0.1.2", - "through2": "0.5.1", - "vinyl": "0.2.3" - }, - "dependencies": { - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "3.0.0" - } - } - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", - "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", - "dev": true - }, - "lodash.escape": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", - "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", - "dev": true, - "requires": { - "lodash._escapehtmlchar": "2.4.1", - "lodash._reunescapedhtml": "2.4.1", - "lodash.keys": "2.4.1" - } - }, - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - }, - "lodash.template": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", - "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", - "dev": true, - "requires": { - "lodash._escapestringchar": "2.4.1", - "lodash._reinterpolate": "2.4.1", - "lodash.defaults": "2.4.1", - "lodash.escape": "2.4.1", - "lodash.keys": "2.4.1", - "lodash.templatesettings": "2.4.1", - "lodash.values": "2.4.1" - } - }, - "lodash.templatesettings": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", - "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", - "dev": true, - "requires": { - "lodash._reinterpolate": "2.4.1", - "lodash.escape": "2.4.1" - } - }, - "minimist": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", - "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - }, - "through2": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", - "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "2.1.2" - }, - "dependencies": { - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "0.4.0" - } - } - } - }, - "vinyl": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", - "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", - "dev": true, - "requires": { - "clone-stats": "0.0.1" - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } + "chai": "4.1.2", + "mocha": "4.1.0", + "plugin-error": "0.1.2", + "through2": "2.0.3" } }, "gulp-concat": { @@ -2257,52 +2412,46 @@ } }, "gulp-newer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/gulp-newer/-/gulp-newer-1.3.0.tgz", - "integrity": "sha1-1Q7Ky7gi7aSStXMkpshaB/2aVcE=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gulp-newer/-/gulp-newer-1.4.0.tgz", + "integrity": "sha512-h79fGO55S/P9eAADbLAP9aTtVYpLSR1ONj08VPaSdVVNVYhTS8p1CO1TW7kEMu+hC+sytmCqcUr5LesvZEtDoQ==", "dev": true, "requires": { "glob": "7.1.2", - "gulp-util": "3.0.8", - "kew": "0.7.0" + "kew": "0.7.0", + "plugin-error": "0.1.2" } }, "gulp-sourcemaps": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.1.tgz", - "integrity": "sha512-1qHCI3hdmsMdq/SUotxwUh/L8YzlI6J9zQ5ifNOtx4Y6KV5y5sGuORv1KZzWhuKtz/mXNh5xLESUtwC4EndCjA==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.3.tgz", + "integrity": "sha1-EbAz91n5CeCl8Vt730esKcxU76Q=", "dev": true, "requires": { "@gulp-sourcemaps/identity-map": "1.0.1", "@gulp-sourcemaps/map-sources": "1.0.0", - "acorn": "4.0.13", + "acorn": "5.3.0", "convert-source-map": "1.5.1", "css": "2.2.1", - "debug-fabulous": "0.2.1", + "debug-fabulous": "1.0.0", "detect-newline": "2.1.0", "graceful-fs": "4.1.11", "source-map": "0.5.7", "strip-bom-string": "1.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" + "through2": "2.0.3" }, "dependencies": { + "acorn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true + }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } } } }, @@ -2318,6 +2467,50 @@ "vinyl-fs": "2.4.4" }, "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -2331,16 +2524,6 @@ "path-is-absolute": "1.0.1" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, "glob-stream": { "version": "5.3.5", "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", @@ -2401,18 +2584,18 @@ } }, "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "1.0.0" } }, "isarray": { @@ -2430,6 +2613,36 @@ "jsonify": "0.0.0" } }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, "ordered-read-streams": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", @@ -2514,7 +2727,7 @@ "beeper": "1.1.1", "chalk": "1.1.3", "dateformat": "2.2.0", - "fancy-log": "1.3.0", + "fancy-log": "1.3.2", "gulplog": "1.0.0", "has-gulplog": "0.1.0", "lodash._reescape": "3.0.0", @@ -2630,9 +2843,9 @@ "dev": true }, "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "has-gulplog": { @@ -2644,6 +2857,38 @@ "sparkles": "1.0.0" } }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, "hash-base": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", @@ -2689,12 +2934,6 @@ "parse-passwd": "1.0.0" } }, - "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", - "dev": true - }, "htmlescape": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", @@ -2713,15 +2952,6 @@ "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", "dev": true }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -2765,7 +2995,7 @@ "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "combine-source-map": "0.7.2", "concat-stream": "1.5.2", "is-buffer": "1.1.6", @@ -2782,20 +3012,23 @@ "dev": true }, "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "requires": { - "is-relative": "0.2.1", - "is-windows": "0.2.0" + "is-relative": "1.0.0", + "is-windows": "1.0.1" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } }, "is-buffer": { "version": "1.1.6", @@ -2803,13 +3036,24 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-builtin-module": { + "is-data-descriptor": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "builtin-modules": "1.1.1" + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "is-dotfile": { @@ -2834,36 +3078,47 @@ "dev": true }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "2.1.1" } }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-odd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz", + "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=", + "dev": true, + "requires": { + "is-number": "3.0.0" } }, "is-path-cwd": { @@ -2897,14 +3152,6 @@ "dev": true, "requires": { "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "is-posix-bracket": { @@ -2926,12 +3173,12 @@ "dev": true }, "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { - "is-unc-path": "0.1.2" + "is-unc-path": "1.0.0" } }, "is-stream": { @@ -2941,9 +3188,9 @@ "dev": true }, "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { "unc-path-regex": "0.1.2" @@ -2962,9 +3209,9 @@ "dev": true }, "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz", + "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=", "dev": true }, "isarray": { @@ -2980,13 +3227,10 @@ "dev": true }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "istanbul": { "version": "0.4.5", @@ -3023,6 +3267,12 @@ "path-is-absolute": "1.0.1" } }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -3130,13 +3380,10 @@ "dev": true }, "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "labeled-stream-splicer": { "version": "2.0.0", @@ -3158,11 +3405,13 @@ } }, "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", "dev": true, - "optional": true + "requires": { + "set-getter": "0.1.0" + } }, "lazystream": { "version": "1.0.0", @@ -3193,58 +3442,21 @@ } }, "liftoff": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", - "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", "dev": true, "requires": { "extend": "3.0.1", - "findup-sync": "0.4.3", + "findup-sync": "2.0.0", "fined": "1.1.0", - "flagged-respawn": "0.3.2", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.mapvalues": "4.6.0", + "flagged-respawn": "1.0.0", + "is-plain-object": "2.0.4", + "object.map": "1.0.1", "rechoir": "0.6.2", "resolve": "1.1.7" } }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - } - } - }, "lodash": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", @@ -3269,51 +3481,18 @@ "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", "dev": true }, - "lodash._escapehtmlchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", - "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1" - } - }, - "lodash._escapestringchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", - "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", - "dev": true - }, "lodash._getnative": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", "dev": true }, - "lodash._htmlescapes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", - "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", - "dev": true - }, "lodash._isiterateecall": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, - "lodash._isnative": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", - "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", - "dev": true - }, - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", - "dev": true - }, "lodash._reescape": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", @@ -3332,67 +3511,12 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, - "lodash._reunescapedhtml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", - "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "lodash._root": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", "dev": true }, - "lodash._shimkeys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", - "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - } - }, - "lodash.defaults": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", - "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "lodash.escape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", @@ -3420,27 +3544,6 @@ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", "dev": true }, - "lodash.isobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", - "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - } - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -3452,12 +3555,6 @@ "lodash.isarray": "3.0.4" } }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", - "dev": true - }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", @@ -3497,44 +3594,12 @@ "lodash.escape": "3.2.0" } }, - "lodash.values": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", - "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", - "dev": true, - "requires": { - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" - } - }, "lru-cache": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", @@ -3551,22 +3616,45 @@ } }, "make-error": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", - "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.2.tgz", + "integrity": "sha512-l9ra35l5VWLF24y75Tg8XgfGLX0ueRhph118WKM6H5denx4bB5QF59+4UAm9oJ2qsPQZas/CQUDdtDdfvYHBdQ==", "dev": true }, + "make-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.0.tgz", + "integrity": "sha1-V7713IXSOSO6I3ZzJNjo+PPZaUs=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "1.0.1" + } }, "md5.js": { "version": "1.3.4", @@ -3606,24 +3694,6 @@ "timers-ext": "0.1.2" } }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - } - }, "merge-stream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", @@ -3640,24 +3710,24 @@ "dev": true }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz", + "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.0", + "define-property": "1.0.0", + "extend-shallow": "2.0.1", + "extglob": "2.0.3", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.7", + "object.pick": "1.3.0", + "regex-not": "1.0.0", + "snapdragon": "0.8.1", + "to-regex": "3.0.1" } }, "miller-rabin": { @@ -3697,6 +3767,27 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "mixin-deep": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.0.tgz", + "integrity": "sha512-dgaCvoh6i1nosAUBKb0l0pfJ78K8+S9fluyIR2YvAeUD/QuMahnFnF3xYty5eYXMjhGSsB0DsW6A0uAZyetoAg==", + "dev": true, + "requires": { + "for-in": "1.0.2", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -3715,9 +3806,9 @@ } }, "mocha": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", - "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", "dev": true, "requires": { "browser-stdout": "1.3.0", @@ -3732,11 +3823,14 @@ "supports-color": "4.4.0" }, "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } }, "supports-color": { "version": "4.4.0", @@ -3756,17 +3850,17 @@ "dev": true }, "module-deps": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", - "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-5.0.1.tgz", + "integrity": "sha512-sigq/hm/L+Z5IGi1DDl0x2ptkw7S86aFh213QhPLD8v9Opv90IHzKIuWJrRa5bJ77DVKHco2CfIEuThcT/vDJA==", "dev": true, "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "browser-resolve": "1.11.2", "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", + "concat-stream": "1.6.0", "defined": "1.0.0", - "detective": "4.7.0", + "detective": "5.0.2", "duplexer2": "0.1.4", "inherits": "2.0.3", "parents": "1.0.1", @@ -3776,6 +3870,19 @@ "subarg": "1.0.0", "through2": "2.0.3", "xtend": "4.0.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + } } }, "ms": { @@ -3828,10 +3935,37 @@ } } }, + "nanomatch": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz", + "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "1.0.0", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "is-odd": "1.0.0", + "kind-of": "5.1.0", + "object.pick": "1.3.0", + "regex-not": "1.0.0", + "snapdragon": "0.8.1", + "to-regex": "3.0.1" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "natives": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", - "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz", + "integrity": "sha512-8eRaxn8u/4wN8tGkhlc2cgwwvOLMLUMUn4IYTexMgWd+LyUDfeXVkk2ygQR0hvIHbJQXgHujia3ieUUDwNGkEA==", "dev": true }, "next-tick": { @@ -3849,18 +3983,6 @@ "abbrev": "1.0.9" } }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "4.3.6", - "validate-npm-package-license": "3.0.1" - } - }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -3870,23 +3992,88 @@ "remove-trailing-separator": "1.1.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "3.0.1" + } }, "object.defaults": { "version": "1.1.0", @@ -3898,23 +4085,16 @@ "array-slice": "1.1.0", "for-own": "1.0.0", "isobject": "3.0.1" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "1.0.0", + "make-iterator": "1.0.0" } }, "object.omit": { @@ -3925,6 +4105,17 @@ "requires": { "for-own": "0.1.5", "is-extendable": "0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + } } }, "object.pick": { @@ -3934,14 +4125,6 @@ "dev": true, "requires": { "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "once": { @@ -4055,12 +4238,12 @@ } }, "parse-filepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", - "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "requires": { - "is-absolute": "0.2.6", + "is-absolute": "1.0.0", "map-cache": "0.2.2", "path-root": "0.1.1" } @@ -4075,15 +4258,23 @@ "is-dotfile": "1.0.3", "is-extglob": "1.0.0", "is-glob": "2.0.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "1.3.1" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + } } }, "parse-passwd": { @@ -4092,6 +4283,12 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, "path-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", @@ -4104,15 +4301,6 @@ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -4152,31 +4340,6 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", @@ -4217,6 +4380,64 @@ "pinkie": "2.0.4" } }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "requires": { + "ansi-cyan": "0.1.1", + "ansi-red": "0.1.1", + "arr-diff": "1.1.0", + "arr-union": "2.1.0", + "extend-shallow": "1.1.4" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-slice": "0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "requires": { + "kind-of": "1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -4294,26 +4515,6 @@ "kind-of": "4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -4353,27 +4554,6 @@ "readable-stream": "2.3.3" } }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - } - }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -4398,16 +4578,6 @@ "resolve": "1.1.7" } }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" - } - }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -4417,6 +4587,15 @@ "is-equal-shallow": "0.1.3" } }, + "regex-not": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz", + "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -4435,15 +4614,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, "replace-ext": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", @@ -4457,13 +4627,13 @@ "dev": true }, "resolve-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", - "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "requires": { - "expand-tilde": "1.2.2", - "global-modules": "0.2.3" + "expand-tilde": "2.0.2", + "global-modules": "1.0.0" } }, "resolve-url": { @@ -4502,13 +4672,14 @@ } }, "run-sequence": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.0.tgz", - "integrity": "sha512-xW5DmUwdvoyYQUMPKN8UW7TZSFs7AxtT59xo1m5y91jHbvwGlGgOmdV1Yw5P68fkjf3aHUZ4G1o1mZCtNe0qtw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.1.tgz", + "integrity": "sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw==", "dev": true, "requires": { "chalk": "1.1.3", - "gulp-util": "3.0.8" + "fancy-log": "1.3.2", + "plugin-error": "0.1.2" }, "dependencies": { "ansi-styles": { @@ -4582,6 +4753,27 @@ "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", "dev": true }, + "set-getter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", + "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", + "dev": true, + "requires": { + "to-object-path": "0.3.0" + } + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" + } + }, "sha.js": { "version": "2.4.9", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", @@ -4620,11 +4812,120 @@ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "snapdragon": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", + "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=", + "dev": true, + "requires": { + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.1", + "use": "2.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } }, "sorcery": { "version": "0.10.0", @@ -4645,14 +4946,15 @@ "dev": true }, "source-map-resolve": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", - "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", + "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", "dev": true, "requires": { - "atob": "1.1.3", + "atob": "2.0.3", + "decode-uri-component": "0.2.0", "resolve-url": "0.2.1", - "source-map-url": "0.3.0", + "source-map-url": "0.4.0", "urix": "0.1.0" } }, @@ -4674,9 +4976,9 @@ } }, "source-map-url": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", - "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, "sourcemap-codec": { @@ -4694,33 +4996,120 @@ "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", "dev": true }, - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "extend-shallow": "3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } } }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "0.2.5", + "object-copy": "0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "stream-browserify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", @@ -4866,15 +5255,6 @@ "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", "dev": true }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "4.0.1" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -4897,14 +5277,6 @@ "dev": true, "requires": { "has-flag": "2.0.0" - }, - "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - } } }, "syntax-error": { @@ -4991,80 +5363,139 @@ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "to-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", + "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", + "dev": true, + "requires": { + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "regex-not": "1.0.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "repeat-string": "1.6.1" + } + }, "travis-fold": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/travis-fold/-/travis-fold-0.1.2.tgz", "integrity": "sha1-/sAF+dyqJZo/lFnOWmkGq6TFRdo=", "dev": true }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, "ts-node": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", - "integrity": "sha1-wTxqMCTjC+EYDdUwOPwgkonUv2k=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-4.1.0.tgz", + "integrity": "sha512-xcZH12oVg9PShKhy3UHyDmuDLV3y7iKwX25aMVPt1SIXSuAfWkFiGPEkg+th8R4YKW/QCxDoW7lJdb15lx6QWg==", "dev": true, "requires": { "arrify": "1.0.1", "chalk": "2.3.0", "diff": "3.3.1", - "make-error": "1.3.0", + "make-error": "1.3.2", "minimist": "1.2.0", "mkdirp": "0.5.1", - "source-map-support": "0.4.18", - "tsconfig": "6.0.0", + "source-map-support": "0.5.0", + "tsconfig": "7.0.0", "v8flags": "3.0.1", "yn": "2.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - }, "v8flags": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.1.tgz", @@ -5077,11 +5508,13 @@ } }, "tsconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", - "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", "dev": true, "requires": { + "@types/strip-bom": "3.0.0", + "@types/strip-json-comments": "0.0.30", "strip-bom": "3.0.0", "strip-json-comments": "2.0.1" }, @@ -5095,9 +5528,9 @@ } }, "tslib": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz", - "integrity": "sha512-ymKWWZJST0/CkgduC2qkzjMOWr4bouhuURNXCn/inEX0L57BnRG6FhX76o7FOnsjHazCjfU2LKeSrlS2sIKQJg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.1.tgz", + "integrity": "sha1-aUavLR1lGnsYY7Ux1uWvpBqkTqw=", "dev": true }, "tslint": { @@ -5115,36 +5548,10 @@ "minimatch": "3.0.4", "resolve": "1.5.0", "semver": "5.4.1", - "tslib": "1.8.0", - "tsutils": "2.13.0" + "tslib": "1.8.1", + "tsutils": "2.16.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, "resolve": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", @@ -5159,25 +5566,16 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } } } }, "tsutils": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.13.0.tgz", - "integrity": "sha512-FuWzNJbMsp3gcZMbI3b5DomhW4Ia41vMxjN63nKWI0t7f+I3UmHfRl0TrXJTwI2LUduDG+eR1Mksp3pvtlyCFQ==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.16.0.tgz", + "integrity": "sha512-9Ier/60O7OZRNPiw+or5QAtAY4kQA+WDiO/r6xOYATEyefH9bdfvTRLCxrYnFhQlZfET2vYXKfpr3Vw2BiArZw==", "dev": true, "requires": { - "tslib": "1.8.0" + "tslib": "1.8.1" } }, "tty-browserify": { @@ -5208,9 +5606,9 @@ "dev": true }, "typescript": { - "version": "2.7.0-dev.20171209", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.0-dev.20171209.tgz", - "integrity": "sha512-4ETBmIehQBmJOVwb/awg+EHMjpq3esymYD+tKRvxHv3cW+1s9+t8kdozn3/Fk50vAH13YtOHxuOcvU7OXrdG5Q==", + "version": "2.7.0-dev.20180108", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.0-dev.20180108.tgz", + "integrity": "sha512-ZlggGsch8Y2d0LqAlCYGRzm/gdm2bqSpb4rdthY+YvpPsQqFixT0tU8sgjeRibMXW9hbS2Hz6kibS8L2oUKWfQ==", "dev": true }, "uglify-js": { @@ -5244,12 +5642,78 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" + }, + "dependencies": { + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } + } + }, "unique-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", "dev": true }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "0.3.1", + "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -5274,6 +5738,85 @@ } } }, + "use": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz", + "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=", + "dev": true, + "requires": { + "define-property": "0.2.5", + "isobject": "3.0.1", + "lazy-cache": "2.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", @@ -5324,16 +5867,6 @@ "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", "dev": true }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, "vinyl": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", @@ -5512,15 +6045,6 @@ "cliui": "2.1.0", "decamelize": "1.2.0", "window-size": "0.1.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true, - "optional": true - } } }, "yn": { diff --git a/package.json b/package.json index c87650afa8c..fb089b64918 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@types/minimist": "latest", "@types/mkdirp": "latest", "@types/mocha": "latest", - "@types/node": "latest", + "@types/node": "8.5.5", "@types/q": "latest", "@types/run-sequence": "latest", "@types/through2": "latest", diff --git a/scripts/tslint/rules/noDoubleSpaceRule.ts b/scripts/tslint/rules/noDoubleSpaceRule.ts new file mode 100644 index 00000000000..34ab470ebce --- /dev/null +++ b/scripts/tslint/rules/noDoubleSpaceRule.ts @@ -0,0 +1,54 @@ +import * as Lint from "tslint/lib"; +import * as ts from "typescript"; + +export class Rule extends Lint.Rules.AbstractRule { + public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + return this.applyWithFunction(sourceFile, walk); + } +} + +function walk(ctx: Lint.WalkContext): void { + const { sourceFile } = ctx; + const lines = sourceFile.text.split("\n"); + const strings = getLiterals(sourceFile); + lines.forEach((line, idx) => { + // Skip indentation. + const firstNonSpace = /\S/.exec(line); + if (firstNonSpace === null) { + return; + } + // Allow common uses of double spaces + // * To align `=` or `!=` signs + // * To align comments at the end of lines + // * To indent inside a comment + // * To use two spaces after a period + // * To include aligned `->` in a comment + const rgx = /[^/*. ] [^-!/= ]/g; + rgx.lastIndex = firstNonSpace.index; + const doubleSpace = rgx.exec(line); + // Also allow to align comments after `@param` + if (doubleSpace !== null && !line.includes("@param")) { + const pos = lines.slice(0, idx).reduce((len, line) => len + 1 + line.length, 0) + doubleSpace.index; + if (!strings.some(s => s.getStart() <= pos && s.end > pos)) { + ctx.addFailureAt(pos + 1, 2, "Use only one space."); + } + } + }); +} + +function getLiterals(sourceFile: ts.SourceFile): ReadonlyArray { + const out: ts.Node[] = []; + sourceFile.forEachChild(function cb(node) { + switch (node.kind) { + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.TemplateHead: + case ts.SyntaxKind.TemplateMiddle: + case ts.SyntaxKind.TemplateTail: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.RegularExpressionLiteral: + out.push(node); + } + node.forEachChild(cb); + }); + return out; +} diff --git a/scripts/tslint/rules/typeOperatorSpacingRule.ts b/scripts/tslint/rules/typeOperatorSpacingRule.ts index d7da2e6b5e8..82dccfe0eac 100644 --- a/scripts/tslint/rules/typeOperatorSpacingRule.ts +++ b/scripts/tslint/rules/typeOperatorSpacingRule.ts @@ -2,7 +2,7 @@ import * as Lint from "tslint/lib"; import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { - public static FAILURE_STRING = "The '|' and '&' operators must be surrounded by single spaces"; + public static FAILURE_STRING = "The '|' and '&' operators must be surrounded by spaces"; public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { return this.applyWithFunction(sourceFile, walk); @@ -11,26 +11,20 @@ export class Rule extends Lint.Rules.AbstractRule { function walk(ctx: Lint.WalkContext): void { const { sourceFile } = ctx; - ts.forEachChild(sourceFile, recur); - function recur(node: ts.Node): void { - if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) { - check((node as ts.UnionOrIntersectionTypeNode).types); + sourceFile.forEachChild(function cb(node: ts.Node): void { + if (ts.isUnionTypeNode(node) || ts.isIntersectionTypeNode(node)) { + check(node); } - ts.forEachChild(node, recur); - } + node.forEachChild(cb); + }); - function check(types: ReadonlyArray): void { - let expectedStart = types[0].end + 2; // space, | or & - for (let i = 1; i < types.length; i++) { - const currentType = types[i]; - if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) { - const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end); - const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos); - if (previousTypeEndPos.line === currentTypeStartPos.line) { - ctx.addFailureAtNode(currentType, Rule.FAILURE_STRING); - } + function check(node: ts.UnionTypeNode | ts.IntersectionTypeNode): void { + const list = node.getChildren().find(child => child.kind === ts.SyntaxKind.SyntaxList)!; + for (const child of list.getChildren()) { + if ((child.kind === ts.SyntaxKind.BarToken || child.kind === ts.SyntaxKind.AmpersandToken) + && (/\S/.test(sourceFile.text[child.getStart(sourceFile) - 1]) || /\S/.test(sourceFile.text[child.end]))) { + ctx.addFailureAtNode(child, Rule.FAILURE_STRING); } - expectedStart = currentType.end + 2; } } } diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5836cf0f412..9b96b78a4d3 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -303,7 +303,7 @@ namespace ts { // without names can only come from JSDocFunctionTypes. Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType); const functionType = node.parent; - const index = indexOf(functionType.parameters, node); + const index = functionType.parameters.indexOf(node as ParameterDeclaration); return "arg" + index as __String; case SyntaxKind.JSDocTypedefTag: const name = getNameOfJSDocTypedef(node as JSDocTypedefTag); @@ -746,11 +746,11 @@ namespace ts { } function isNarrowingTypeofOperands(expr1: Expression, expr2: Expression) { - return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((expr1).expression) && expr2.kind === SyntaxKind.StringLiteral; + return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((expr1).expression) && (expr2.kind === SyntaxKind.StringLiteral || expr2.kind === SyntaxKind.NoSubstitutionTemplateLiteral); } function isNarrowableInOperands(left: Expression, right: Expression) { - return left.kind === SyntaxKind.StringLiteral && isNarrowingExpression(right); + return (left.kind === SyntaxKind.StringLiteral || left.kind === SyntaxKind.NoSubstitutionTemplateLiteral) && isNarrowingExpression(right); } function isNarrowingBinaryExpression(expr: BinaryExpression) { @@ -1633,7 +1633,7 @@ namespace ts { // to the one we would get for: { <...>(...): T } // // We do that by making an anonymous type literal symbol, and then setting the function - // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable + // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable // from an actual type literal symbol you would have gotten had you used the long form. const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node)); addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); @@ -2289,30 +2289,13 @@ namespace ts { declareSymbol(file.symbol.exports, file.symbol, node.left, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None); } - function isExportsOrModuleExportsOrAlias(node: Node): boolean { - return isExportsIdentifier(node) || - isModuleExportsPropertyAccessExpression(node) || - isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node); - } - - function isNameOfExportsOrModuleExportsAliasDeclaration(node: Identifier): boolean { - const symbol = lookupSymbolForName(node.escapedText); - return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && - symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer); - } - - function isExportsOrModuleExportsOrAliasOrAssignment(node: Node): boolean { - return isExportsOrModuleExportsOrAlias(node) || - (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignment(node.left) || isExportsOrModuleExportsOrAliasOrAssignment(node.right))); - } - function bindModuleExportsAssignment(node: BinaryExpression) { // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports' // is still pointing to 'module.exports'. // We do not want to consider this as 'export=' since a module can have only one of these. // Similarly we do not want to treat 'module.exports = exports' as an 'export='. const assignedExpression = getRightMostAssignedExpression(node.right); - if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) { + if (isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) { // Mark it as a module in case there are no other exports in the file setCommonJsModuleIndicator(node); return; @@ -2393,7 +2376,7 @@ namespace ts { if (node.kind === SyntaxKind.BinaryExpression) { leftSideOfAssignment.parent = node; } - if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) { + if (container === file && isNameOfExportsOrModuleExportsAliasDeclaration(file, target)) { // This can be an alias for the 'exports' or 'module.exports' names, e.g. // var util = module.exports; // util.property = function ... @@ -2406,11 +2389,7 @@ namespace ts { } function lookupSymbolForName(name: __String) { - const local = container.locals && container.locals.get(name); - if (local) { - return local.exportSymbol || local; - } - return container.symbol && container.symbol.exports && container.symbol.exports.get(name); + return lookupSymbolForNameWorker(container, name); } function bindPropertyAssignment(functionName: __String, propertyAccess: PropertyAccessExpression, isPrototypeProperty: boolean) { @@ -2431,7 +2410,7 @@ namespace ts { if (!isPrototypeProperty && (!targetSymbol || !(targetSymbol.flags & SymbolFlags.Namespace)) && isLegalPosition) { Debug.assert(isIdentifier(propertyAccess.expression)); const identifier = propertyAccess.expression as Identifier; - const flags = SymbolFlags.Module | SymbolFlags.JSContainer; + const flags = SymbolFlags.Module | SymbolFlags.JSContainer; const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer; if (targetSymbol) { addDeclarationToSymbol(symbol, identifier, flags); @@ -2538,7 +2517,7 @@ namespace ts { } if (isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + indexOf(node.parent.parameters, node) as __String); + bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + node.parent.parameters.indexOf(node) as __String); } else { declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); @@ -2649,6 +2628,33 @@ namespace ts { } } + /* @internal */ + export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean { + return isExportsIdentifier(node) || + isModuleExportsPropertyAccessExpression(node) || + isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile, node); + } + + function isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile: SourceFile, node: Identifier): boolean { + const symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText); + return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && + symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, symbol.valueDeclaration.initializer); + } + + function isExportsOrModuleExportsOrAliasOrAssignment(sourceFile: SourceFile, node: Expression): boolean { + return isExportsOrModuleExportsOrAlias(sourceFile, node) || + (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && ( + isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.left) || isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.right))); + } + + function lookupSymbolForNameWorker(container: Node, name: __String): Symbol | undefined { + const local = container.locals && container.locals.get(name); + if (local) { + return local.exportSymbol || local; + } + return container.symbol && container.symbol.exports && container.symbol.exports.get(name); + } + /** * Computes the transform flags for a node, given the transform flags of its subtree * @@ -2734,6 +2740,9 @@ namespace ts { case SyntaxKind.PropertyAccessExpression: return computePropertyAccess(node, subtreeFlags); + case SyntaxKind.ElementAccessExpression: + return computeElementAccess(node, subtreeFlags); + default: return computeOther(node, kind, subtreeFlags); } @@ -2742,17 +2751,21 @@ namespace ts { function computeCallExpression(node: CallExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; const expression = node.expression; - const expressionKind = expression.kind; if (node.typeArguments) { transformFlags |= TransformFlags.AssertTypeScript; } if (subtreeFlags & TransformFlags.ContainsSpread - || isSuperOrSuperProperty(expression, expressionKind)) { + || (expression.transformFlags & (TransformFlags.Super | TransformFlags.ContainsSuper))) { // If the this node contains a SpreadExpression, or is a super call, then it is an ES6 // node. transformFlags |= TransformFlags.AssertES2015; + // super property or element accesses could be inside lambdas, etc, and need a captured `this`, + // while super keyword for super calls (indicated by TransformFlags.Super) does not (since it can only be top-level in a constructor) + if (expression.transformFlags & TransformFlags.ContainsSuper) { + transformFlags |= TransformFlags.ContainsLexicalThis; + } } if (expression.kind === SyntaxKind.ImportKeyword) { @@ -2769,21 +2782,6 @@ namespace ts { return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; } - function isSuperOrSuperProperty(node: Node, kind: SyntaxKind) { - switch (kind) { - case SyntaxKind.SuperKeyword: - return true; - - case SyntaxKind.PropertyAccessExpression: - case SyntaxKind.ElementAccessExpression: - const expression = (node).expression; - const expressionKind = expression.kind; - return expressionKind === SyntaxKind.SuperKeyword; - } - - return false; - } - function computeNewExpression(node: NewExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; if (node.typeArguments) { @@ -2878,7 +2876,7 @@ namespace ts { } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; + return transformFlags & ~TransformFlags.OuterExpressionExcludes; } function computeClassDeclaration(node: ClassDeclaration, subtreeFlags: TransformFlags) { @@ -3197,17 +3195,32 @@ namespace ts { function computePropertyAccess(node: PropertyAccessExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const expression = node.expression; - const expressionKind = expression.kind; // If a PropertyAccessExpression starts with a super keyword, then it is // ES6 syntax, and requires a lexical `this` binding. - if (expressionKind === SyntaxKind.SuperKeyword) { - transformFlags |= TransformFlags.ContainsLexicalThis; + if (transformFlags & TransformFlags.Super) { + transformFlags ^= TransformFlags.Super; + transformFlags |= TransformFlags.ContainsSuper; } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; - return transformFlags & ~TransformFlags.NodeExcludes; + return transformFlags & ~TransformFlags.PropertyAccessExcludes; + } + + function computeElementAccess(node: ElementAccessExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + const expression = node.expression; + const expressionFlags = expression.transformFlags; // We do not want to aggregate flags from the argument expression for super/this capturing + + // If an ElementAccessExpression starts with a super keyword, then it is + // ES6 syntax, and requires a lexical `this` binding. + if (expressionFlags & TransformFlags.Super) { + transformFlags &= ~TransformFlags.Super; + transformFlags |= TransformFlags.ContainsSuper; + } + + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.PropertyAccessExcludes; } function computeVariableDeclaration(node: VariableDeclaration, subtreeFlags: TransformFlags) { @@ -3327,6 +3340,13 @@ namespace ts { transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2017; break; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + case SyntaxKind.PartiallyEmittedExpression: + // These nodes are TypeScript syntax. + transformFlags |= TransformFlags.AssertTypeScript; + excludeFlags = TransformFlags.OuterExpressionExcludes; + break; case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.ProtectedKeyword: @@ -3335,8 +3355,6 @@ namespace ts { case SyntaxKind.ConstKeyword: case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumMember: - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: case SyntaxKind.NonNullExpression: case SyntaxKind.ReadonlyKeyword: // These nodes are TypeScript syntax. @@ -3465,7 +3483,8 @@ namespace ts { case SyntaxKind.SuperKeyword: // This node is ES6 syntax. - transformFlags |= TransformFlags.AssertES2015; + transformFlags |= TransformFlags.AssertES2015 | TransformFlags.Super; + excludeFlags = TransformFlags.OuterExpressionExcludes; // must be set to persist `Super` break; case SyntaxKind.ThisKeyword: @@ -3622,6 +3641,15 @@ namespace ts { case SyntaxKind.ObjectBindingPattern: case SyntaxKind.ArrayBindingPattern: return TransformFlags.BindingPatternExcludes; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + case SyntaxKind.PartiallyEmittedExpression: + case SyntaxKind.ParenthesizedExpression: + case SyntaxKind.SuperKeyword: + return TransformFlags.OuterExpressionExcludes; + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + return TransformFlags.PropertyAccessExcludes; default: return TransformFlags.NodeExcludes; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4f3a6225d88..0f9bb6d9cff 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -128,6 +128,11 @@ namespace ts { typeToTypeNode: nodeBuilder.typeToTypeNode, indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration, signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration, + symbolToEntityName: nodeBuilder.symbolToEntityName, + symbolToExpression: nodeBuilder.symbolToExpression, + symbolToTypeParameterDeclarations: nodeBuilder.symbolToTypeParameterDeclarations, + symbolToParameterDeclaration: nodeBuilder.symbolToParameterDeclaration, + typeParameterToDeclaration: nodeBuilder.typeParameterToDeclaration, getSymbolsInScope: (location, meaning) => { location = getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; @@ -155,16 +160,31 @@ namespace ts { location = getParseTreeNode(location, isIdentifier); return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined; }, - signatureToString: (signature, enclosingDeclaration?, flags?, kind?) => { + signatureToString: (signature, enclosingDeclaration, flags, kind) => { return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind); }, - typeToString: (type, enclosingDeclaration?, flags?) => { + typeToString: (type, enclosingDeclaration, flags) => { return typeToString(type, getParseTreeNode(enclosingDeclaration), flags); }, - getSymbolDisplayBuilder, - symbolToString: (symbol, enclosingDeclaration?, meaning?) => { - return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning); + symbolToString: (symbol, enclosingDeclaration, meaning, flags) => { + return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags); }, + typePredicateToString: (predicate, enclosingDeclaration, flags) => { + return typePredicateToString(predicate, getParseTreeNode(enclosingDeclaration), flags); + }, + writeSignature: (signature, enclosingDeclaration, flags, kind, writer) => { + return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind, writer); + }, + writeType: (type, enclosingDeclaration, flags, writer) => { + return typeToString(type, getParseTreeNode(enclosingDeclaration), flags, writer); + }, + writeSymbol: (symbol, enclosingDeclaration, meaning, flags, writer) => { + return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning, flags, writer); + }, + writeTypePredicate: (predicate, enclosingDeclaration, flags, writer) => { + return typePredicateToString(predicate, getParseTreeNode(enclosingDeclaration), flags, writer); + }, + getSymbolDisplayBuilder, // TODO (weswigham): Remove once deprecation process is complete getAugmentedPropertiesOfType, getRootSymbols, getContextualType: node => { @@ -268,11 +288,13 @@ namespace ts { getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning), getBaseConstraintOfType, getDefaultFromTypeParameter: type => type && type.flags & TypeFlags.TypeParameter ? getDefaultFromTypeParameter(type as TypeParameter) : undefined, - resolveName(name, location, meaning) { - return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); + resolveName(name, location, meaning, excludeGlobals) { + return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals); }, getJsxNamespace: () => unescapeLeadingUnderscores(getJsxNamespace()), getAccessibleSymbolChain, + getTypePredicateOfSignature, + resolveExternalModuleSymbol, }; const tupleTypes: GenericType[] = []; @@ -340,6 +362,7 @@ namespace ts { const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); const globals = createSymbolTable(); + const reverseMappedCache = createMap(); let ambientModulesCache: Symbol[] | undefined; /** * List of every ambient module with a "*" wildcard. @@ -519,9 +542,6 @@ namespace ts { const identityRelation = createMap(); const enumRelation = createMap(); - // This is for caching the result of getSymbolDisplayBuilder. Do not access directly. - let _displayBuilder: SymbolDisplayBuilder; - type TypeSystemEntity = Symbol | Type | Signature; const enum TypeSystemPropertyName { @@ -529,6 +549,7 @@ namespace ts { ResolvedBaseConstructorType, DeclaredType, ResolvedReturnType, + ResolvedBaseConstraint, } const enum CheckMode { @@ -570,6 +591,145 @@ namespace ts { return checker; + /** + * @deprecated + */ + function getSymbolDisplayBuilder(): SymbolDisplayBuilder { + return { + buildTypeDisplay(type, writer, enclosingDeclaration?, flags?) { + typeToString(type, enclosingDeclaration, flags, emitTextWriterWrapper(writer)); + }, + buildSymbolDisplay(symbol, writer, enclosingDeclaration?, meaning?, flags?) { + symbolToString(symbol, enclosingDeclaration, meaning, flags | SymbolFormatFlags.AllowAnyNodeKind, emitTextWriterWrapper(writer)); + }, + buildSignatureDisplay(signature, writer, enclosing?, flags?, kind?) { + signatureToString(signature, enclosing, flags, kind, emitTextWriterWrapper(writer)); + }, + buildIndexSignatureDisplay(info, writer, kind, enclosing?, flags?) { + const sig = nodeBuilder.indexInfoToIndexSignatureDeclaration(info, kind, enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeNode(EmitHint.Unspecified, sig, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildParameterDisplay(symbol, writer, enclosing?, flags?) { + const node = nodeBuilder.symbolToParameterDeclaration(symbol, enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeNode(EmitHint.Unspecified, node, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildTypeParameterDisplay(tp, writer, enclosing?, flags?) { + const node = nodeBuilder.typeParameterToDeclaration(tp, enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.OmitParameterModifiers, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeNode(EmitHint.Unspecified, node, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildTypePredicateDisplay(predicate, writer, enclosing?, flags?) { + typePredicateToString(predicate, enclosing, flags, emitTextWriterWrapper(writer)); + }, + buildTypeParameterDisplayFromSymbol(symbol, writer, enclosing?, flags?) { + const nodes = nodeBuilder.symbolToTypeParameterDeclarations(symbol, enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeList(ListFormat.TypeParameters, nodes, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildDisplayForParametersAndDelimiters(thisParameter, parameters, writer, enclosing?, originalFlags?) { + const printer = createPrinter({ removeComments: true }); + const flags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | toNodeBuilderFlags(originalFlags); + const thisParameterArray = thisParameter ? [nodeBuilder.symbolToParameterDeclaration(thisParameter, enclosing, flags)] : []; + const params = createNodeArray([...thisParameterArray, ...map(parameters, param => nodeBuilder.symbolToParameterDeclaration(param, enclosing, flags))]); + printer.writeList(ListFormat.CallExpressionArguments, params, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosing?, flags?) { + const printer = createPrinter({ removeComments: true }); + const args = createNodeArray(map(typeParameters, p => nodeBuilder.typeParameterToDeclaration(p, enclosing, toNodeBuilderFlags(flags)))); + printer.writeList(ListFormat.TypeParameters, args, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + }, + buildReturnTypeDisplay(signature, writer, enclosing?, flags?) { + writer.writePunctuation(":"); + writer.writeSpace(" "); + const predicate = getTypePredicateOfSignature(signature); + if (predicate) { + return typePredicateToString(predicate, enclosing, flags, emitTextWriterWrapper(writer)); + } + const node = nodeBuilder.typeToTypeNode(getReturnTypeOfSignature(signature), enclosing, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); + const printer = createPrinter({ removeComments: true }); + printer.writeNode(EmitHint.Unspecified, node, getSourceFileOfNode(getParseTreeNode(enclosing)), emitTextWriterWrapper(writer)); + } + }; + + function emitTextWriterWrapper(underlying: SymbolWriter): EmitTextWriter { + return { + write: ts.noop, + writeTextOfNode: ts.noop, + writeLine: ts.noop, + increaseIndent() { + return underlying.increaseIndent(); + }, + decreaseIndent() { + return underlying.decreaseIndent(); + }, + getText() { + return ""; + }, + rawWrite: ts.noop, + writeLiteral(s) { + return underlying.writeStringLiteral(s); + }, + getTextPos() { + return 0; + }, + getLine() { + return 0; + }, + getColumn() { + return 0; + }, + getIndent() { + return 0; + }, + isAtStartOfLine() { + return false; + }, + clear() { + return underlying.clear(); + }, + + writeKeyword(text) { + return underlying.writeKeyword(text); + }, + writeOperator(text) { + return underlying.writeOperator(text); + }, + writePunctuation(text) { + return underlying.writePunctuation(text); + }, + writeSpace(text) { + return underlying.writeSpace(text); + }, + writeStringLiteral(text) { + return underlying.writeStringLiteral(text); + }, + writeParameter(text) { + return underlying.writeParameter(text); + }, + writeProperty(text) { + return underlying.writeProperty(text); + }, + writeSymbol(text, symbol) { + return underlying.writeSymbol(text, symbol); + }, + trackSymbol(symbol, enclosing?, meaning?) { + return underlying.trackSymbol && underlying.trackSymbol(symbol, enclosing, meaning); + }, + reportInaccessibleThisError() { + return underlying.reportInaccessibleThisError && underlying.reportInaccessibleThisError(); + }, + reportPrivateInBaseOfClassExpression(name) { + return underlying.reportPrivateInBaseOfClassExpression && underlying.reportPrivateInBaseOfClassExpression(name); + }, + reportInaccessibleUniqueSymbolError() { + return underlying.reportInaccessibleUniqueSymbolError && underlying.reportInaccessibleUniqueSymbolError(); + } + }; + } + } + function getJsxNamespace(): __String { if (!_jsxNamespace) { _jsxNamespace = "React" as __String; @@ -845,7 +1005,7 @@ namespace ts { return true; } const sourceFiles = host.getSourceFiles(); - return indexOf(sourceFiles, declarationFile) <= indexOf(sourceFiles, useFile); + return sourceFiles.indexOf(declarationFile) <= sourceFiles.indexOf(useFile); } if (declaration.pos <= usage.pos) { @@ -951,8 +1111,9 @@ namespace ts { nameNotFoundMessage: DiagnosticMessage | undefined, nameArg: __String | Identifier, isUse: boolean, + excludeGlobals = false, suggestedNameNotFoundMessage?: DiagnosticMessage): Symbol { - return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, getSymbol, suggestedNameNotFoundMessage); + return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol, suggestedNameNotFoundMessage); } function resolveNameHelper( @@ -962,6 +1123,7 @@ namespace ts { nameNotFoundMessage: DiagnosticMessage, nameArg: __String | Identifier, isUse: boolean, + excludeGlobals: boolean, lookup: typeof getSymbol, suggestedNameNotFoundMessage?: DiagnosticMessage): Symbol { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location @@ -1186,7 +1348,7 @@ namespace ts { } break; } - if (location.kind !== SyntaxKind.Block) { + if (isNonBlockLocation(location)) { lastNonBlockLocation = location; } lastLocation = location; @@ -1194,7 +1356,7 @@ namespace ts { } // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. - // If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself. + // If `result === lastNonBlockLocation.symbol`, that means that we are somewhere inside `lastNonBlockLocation` looking up a name, and resolving to `lastLocation` itself. // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used. if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastNonBlockLocation.symbol) { result.isReferenced = true; @@ -1208,7 +1370,9 @@ namespace ts { } } - result = lookup(globals, name, meaning); + if (!excludeGlobals) { + result = lookup(globals, name, meaning); + } } if (!result) { @@ -1218,7 +1382,7 @@ namespace ts { !checkAndReportErrorForExtendingInterface(errorLocation) && !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) && !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) && - !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) { + !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) { let suggestion: string | undefined; if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) { suggestion = getSuggestionForNonexistentSymbol(originalLocation, name, meaning); @@ -1277,6 +1441,20 @@ namespace ts { return result; } + function isNonBlockLocation({ kind }: Node): boolean { + switch (kind) { + case SyntaxKind.Block: + case SyntaxKind.ModuleBlock: + case SyntaxKind.SwitchStatement: + case SyntaxKind.CaseBlock: + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + return false; + default: + return true; + } + } + function diagnosticName(nameArg: __String | Identifier) { return isString(nameArg) ? unescapeLeadingUnderscores(nameArg as __String) : declarationNameToString(nameArg as Identifier); } @@ -1470,6 +1648,43 @@ namespace ts { return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias); } + function resolveExportByName(moduleSymbol: Symbol, name: __String, dontResolveAlias: boolean) { + const exportValue = moduleSymbol.exports.get(InternalSymbolName.ExportEquals); + return exportValue + ? getPropertyOfType(getTypeOfSymbol(exportValue), name) + : resolveSymbol(moduleSymbol.exports.get(name), dontResolveAlias); + } + + function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean) { + if (!allowSyntheticDefaultImports) { + return false; + } + // Declaration files (and ambient modules) + if (!file || file.isDeclarationFile) { + // Definitely cannot have a synthetic default if they have a default member specified + if (resolveExportByName(moduleSymbol, InternalSymbolName.Default, dontResolveAlias)) { + return false; + } + // It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member + // So we check a bit more, + if (resolveExportByName(moduleSymbol, escapeLeadingUnderscores("__esModule"), dontResolveAlias)) { + // If there is an `__esModule` specified in the declaration (meaning someone explicitly added it or wrote it in their code), + // it definitely is a module and does not have a synthetic default + return false; + } + // There are _many_ declaration files not written with esmodules in mind that still get compiled into a format with __esModule set + // Meaning there may be no default at runtime - however to be on the permissive side, we allow access to a synthetic default member + // as there is no marker to indicate if the accompanying JS has `__esModule` or not, or is even native esm + return true; + } + // TypeScript files never have a synthetic default (as they are always emitted with an __esModule marker) _unless_ they contain an export= statement + if (!isSourceFileJavaScript(file)) { + return hasExportAssignmentSymbol(moduleSymbol); + } + // JS files have a synthetic default if they do not contain ES2015+ module syntax (export = is not valid in js) _and_ do not have an __esModule marker + return !file.externalModuleIndicator && !resolveExportByName(moduleSymbol, escapeLeadingUnderscores("__esModule"), dontResolveAlias); + } + function getTargetOfImportClause(node: ImportClause, dontResolveAlias: boolean): Symbol { const moduleSymbol = resolveExternalModuleName(node, (node.parent).moduleSpecifier); @@ -1479,16 +1694,16 @@ namespace ts { exportDefaultSymbol = moduleSymbol; } else { - const exportValue = moduleSymbol.exports.get("export=" as __String); - exportDefaultSymbol = exportValue - ? getPropertyOfType(getTypeOfSymbol(exportValue), InternalSymbolName.Default) - : resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.Default), dontResolveAlias); + exportDefaultSymbol = resolveExportByName(moduleSymbol, InternalSymbolName.Default, dontResolveAlias); } - if (!exportDefaultSymbol && !allowSyntheticDefaultImports) { + const file = find(moduleSymbol.declarations, isSourceFile); + const hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias); + if (!exportDefaultSymbol && !hasSyntheticDefault) { error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol)); } - else if (!exportDefaultSymbol && allowSyntheticDefaultImports) { + else if (!exportDefaultSymbol && hasSyntheticDefault) { + // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); } return exportDefaultSymbol; @@ -1888,8 +2103,40 @@ namespace ts { // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable). function resolveESModuleSymbol(moduleSymbol: Symbol, moduleReferenceExpression: Expression, dontResolveAlias: boolean): Symbol { const symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias); - if (!dontResolveAlias && symbol && !(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) { - error(moduleReferenceExpression, Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol)); + if (!dontResolveAlias && symbol) { + if (!(symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable))) { + error(moduleReferenceExpression, Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol)); + return symbol; + } + if (compilerOptions.esModuleInterop) { + const referenceParent = moduleReferenceExpression.parent; + if ( + (isImportDeclaration(referenceParent) && getNamespaceDeclarationNode(referenceParent)) || + isImportCall(referenceParent) + ) { + const type = getTypeOfSymbol(symbol); + let sigs = getSignaturesOfStructuredType(type, SignatureKind.Call); + if (!sigs || !sigs.length) { + sigs = getSignaturesOfStructuredType(type, SignatureKind.Construct); + } + if (sigs && sigs.length) { + const moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol); + // Create a new symbol which has the module's type less the call and construct signatures + const result = createSymbol(symbol.flags, symbol.escapedName); + result.declarations = symbol.declarations ? symbol.declarations.slice() : []; + result.parent = symbol.parent; + result.target = symbol; + result.originatingImport = referenceParent; + if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; + if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; + if (symbol.members) result.members = cloneMap(symbol.members); + if (symbol.exports) result.exports = cloneMap(symbol.exports); + const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above + result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.stringIndexInfo, resolvedModuleType.numberIndexInfo); + return result; + } + } + } } return symbol; } @@ -2285,6 +2532,11 @@ namespace ts { return access.accessibility === SymbolAccessibility.Accessible; } + function isValueSymbolAccessible(typeSymbol: Symbol, enclosingDeclaration: Node): boolean { + const access = isSymbolAccessible(typeSymbol, enclosingDeclaration, SymbolFlags.Value, /*shouldComputeAliasesToMakeVisible*/ false); + return access.accessibility === SymbolAccessibility.Accessible; + } + /** * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested * @@ -2427,100 +2679,130 @@ namespace ts { }; } - function writeKeyword(writer: SymbolWriter, kind: SyntaxKind) { - writer.writeKeyword(tokenToString(kind)); + function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags: SymbolFormatFlags = SymbolFormatFlags.AllowAnyNodeKind, writer?: EmitTextWriter): string { + let nodeFlags = NodeBuilderFlags.IgnoreErrors; + if (flags & SymbolFormatFlags.UseOnlyExternalAliasing) { + nodeFlags |= NodeBuilderFlags.UseOnlyExternalAliasing; + } + if (flags & SymbolFormatFlags.WriteTypeParametersOrArguments) { + nodeFlags |= NodeBuilderFlags.WriteTypeParametersInQualifiedName; + } + const builder = flags & SymbolFormatFlags.AllowAnyNodeKind ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName; + return writer ? symbolToStringWorker(writer).getText() : usingSingleLineStringWriter(symbolToStringWorker); + + function symbolToStringWorker(writer: EmitTextWriter) { + const entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); + const printer = createPrinter({ removeComments: true }); + const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(EmitHint.Unspecified, entity, /*sourceFile*/ sourceFile, writer); + return writer; + } } - function writePunctuation(writer: SymbolWriter, kind: SyntaxKind) { - writer.writePunctuation(tokenToString(kind)); + function signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind, writer?: EmitTextWriter): string { + return writer ? signatureToStringWorker(writer).getText() : usingSingleLineStringWriter(signatureToStringWorker); + + function signatureToStringWorker(writer: EmitTextWriter) { + let sigOutput: SyntaxKind; + if (flags & TypeFormatFlags.WriteArrowStyleSignature) { + sigOutput = kind === SignatureKind.Construct ? SyntaxKind.ConstructorType : SyntaxKind.FunctionType; + } + else { + sigOutput = kind === SignatureKind.Construct ? SyntaxKind.ConstructSignature : SyntaxKind.CallSignature; + } + const sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName); + const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true }); + const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(EmitHint.Unspecified, sig, /*sourceFile*/ sourceFile, writer); + return writer; + } } - function writeSpace(writer: SymbolWriter) { - writer.writeSpace(" "); - } - - function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string { - return usingSingleLineStringWriter(writer => { - getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning); - }); - } - - function signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string { - return usingSingleLineStringWriter(writer => { - getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind); - }); - } - - function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string { - const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName); + function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer: EmitTextWriter = createTextWriter("")): string { + const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer); Debug.assert(typeNode !== undefined, "should always get typenode"); const options = { removeComments: true }; - const writer = createTextWriter(""); const printer = createPrinter(options); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer); const result = writer.getText(); const maxLength = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation ? undefined : 100; - if (maxLength && result.length >= maxLength) { + if (maxLength && result && result.length >= maxLength) { return result.substr(0, maxLength - "...".length) + "..."; } return result; + } - function toNodeBuilderFlags(flags?: TypeFormatFlags): NodeBuilderFlags { - let result = NodeBuilderFlags.None; - if (!flags) { - return result; - } - if (flags & TypeFormatFlags.NoTruncation) { - result |= NodeBuilderFlags.NoTruncation; - } - if (flags & TypeFormatFlags.UseFullyQualifiedType) { - result |= NodeBuilderFlags.UseFullyQualifiedType; - } - if (flags & TypeFormatFlags.SuppressAnyReturnType) { - result |= NodeBuilderFlags.SuppressAnyReturnType; - } - if (flags & TypeFormatFlags.WriteArrayAsGenericType) { - result |= NodeBuilderFlags.WriteArrayAsGenericType; - } - if (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature) { - result |= NodeBuilderFlags.WriteTypeArgumentsOfSignature; - } - - return result; - } + function toNodeBuilderFlags(flags?: TypeFormatFlags): NodeBuilderFlags { + return flags & TypeFormatFlags.NodeBuilderFlagsMask; } function createNodeBuilder() { return { - typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); - const context = createNodeBuilderContext(enclosingDeclaration, flags); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); const resultingNode = typeToTypeNodeHelper(type, context); const result = context.encounteredError ? undefined : resultingNode; return result; }, - indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); - const context = createNodeBuilderContext(enclosingDeclaration, flags); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context); const result = context.encounteredError ? undefined : resultingNode; return result; }, - signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => { + signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); - const context = createNodeBuilderContext(enclosingDeclaration, flags); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); const resultingNode = signatureToSignatureDeclarationHelper(signature, kind, context); const result = context.encounteredError ? undefined : resultingNode; return result; - } + }, + symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, + symbolToExpression: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = symbolToExpression(symbol, context, meaning); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, + symbolToTypeParameterDeclarations: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = typeParametersToTypeParameterDeclarations(symbol, context); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, + symbolToParameterDeclaration: (symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = symbolToParameterDeclaration(symbol, context); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, + typeParameterToDeclaration: (parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => { + Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0); + const context = createNodeBuilderContext(enclosingDeclaration, flags, tracker); + const resultingNode = typeParameterToDeclaration(parameter, context); + const result = context.encounteredError ? undefined : resultingNode; + return result; + }, }; - function createNodeBuilderContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): NodeBuilderContext { + function createNodeBuilderContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker: SymbolTracker | undefined): NodeBuilderContext { return { enclosingDeclaration, flags, + tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: noop }, encounteredError: false, symbolStack: undefined }; @@ -2567,6 +2849,11 @@ namespace ts { return (type).intrinsicName === "true" ? createTrue() : createFalse(); } if (type.flags & TypeFlags.UniqueESSymbol) { + if (!(context.flags & NodeBuilderFlags.AllowUniqueESSymbolType)) { + if (context.tracker.reportInaccessibleUniqueSymbolError) { + context.tracker.reportInaccessibleUniqueSymbolError(); + } + } return createTypeOperatorNode(SyntaxKind.UniqueKeyword, createKeywordTypeNode(SyntaxKind.SymbolKeyword)); } if (type.flags & TypeFlags.Void) { @@ -2592,6 +2879,9 @@ namespace ts { if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowThisInObjectLiteral)) { context.encounteredError = true; } + if (context.tracker.reportInaccessibleThisError) { + context.tracker.reportInaccessibleThisError(); + } } return createThis(); } @@ -2607,7 +2897,7 @@ namespace ts { // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); } - if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { + if (!inTypeAlias && type.aliasSymbol && (context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) { const name = symbolToTypeReferenceName(type.aliasSymbol); const typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return createTypeReferenceNode(name, typeArgumentNodes); @@ -2658,7 +2948,7 @@ namespace ts { Debug.assert(!!(type.flags & TypeFlags.Object)); const readonlyToken = type.declaration && type.declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; const questionToken = type.declaration && type.declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; - const typeParameterNode = typeParameterToDeclaration(getTypeParameterFromMappedType(type), context); + const typeParameterNode = typeParameterToDeclaration(getTypeParameterFromMappedType(type), context, getConstraintTypeFromMappedType(type)); const templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context); const mappedTypeNode = createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); @@ -2669,7 +2959,7 @@ namespace ts { const symbol = type.symbol; if (symbol) { // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) || + if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) || symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || shouldWriteTypeOfFunctionSymbol()) { return createTypeQueryNodeFromSymbol(symbol, SymbolFlags.Value); @@ -2692,10 +2982,17 @@ namespace ts { if (!context.symbolStack) { context.symbolStack = []; } - context.symbolStack.push(symbol); - const result = createTypeNodeFromObjectType(type); - context.symbolStack.pop(); - return result; + + const isConstructorObject = getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class; + if (isConstructorObject) { + return createTypeNodeFromObjectType(type); + } + else { + context.symbolStack.push(symbol); + const result = createTypeNodeFromObjectType(type); + context.symbolStack.pop(); + return result; + } } } else { @@ -2712,7 +3009,8 @@ namespace ts { declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions - return contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively + return (!!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || contains(context.symbolStack, symbol)) && // it is type of the symbol uses itself recursively + (!(context.flags & NodeBuilderFlags.UseStructuralFallback) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // And the build is going to succeed without visibility error or there is no structural fallback allowed } } } @@ -2747,7 +3045,7 @@ namespace ts { const members = createTypeNodesFromResolvedType(resolved); context.flags = savedFlags; const typeLiteralNode = createTypeLiteralNode(members); - return setEmitFlags(typeLiteralNode, EmitFlags.SingleLine); + return setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine); } function createTypeQueryNodeFromSymbol(symbol: Symbol, symbolFlags: SymbolFlags) { @@ -2785,6 +3083,11 @@ namespace ts { context.encounteredError = true; return undefined; } + else if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral && + type.symbol.valueDeclaration && + type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) { + return createAnonymousTypeNode(type); + } else { const outerTypeParameters = type.target.outerTypeParameters; let i = 0; @@ -2871,7 +3174,10 @@ namespace ts { typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context)); } if (resolvedType.stringIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, context)); + const indexInfo = resolvedType.objectFlags & ObjectFlags.ReverseMapped ? + createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) : + resolvedType.stringIndexInfo; + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(indexInfo, IndexKind.String, context)); } if (resolvedType.numberIndexInfo) { typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, context)); @@ -2883,9 +3189,24 @@ namespace ts { } for (const propertySymbol of properties) { - const propertyType = getTypeOfSymbol(propertySymbol); + if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) { + if (propertySymbol.flags & SymbolFlags.Prototype) { + continue; + } + if (getDeclarationModifierFlagsFromSymbol(propertySymbol) & (ModifierFlags.Private | ModifierFlags.Protected) && context.tracker.reportPrivateInBaseOfClassExpression) { + context.tracker.reportPrivateInBaseOfClassExpression(unescapeLeadingUnderscores(propertySymbol.escapedName)); + } + } + const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped ? anyType : getTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; + if (getCheckFlags(propertySymbol) & CheckFlags.Late) { + const decl = firstOrUndefined(propertySymbol.declarations); + const name = hasLateBindableName(decl) && resolveEntityName(decl.name.expression, SymbolFlags.Value); + if (name && context.tracker.trackSymbol) { + context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value); + } + } const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true); context.enclosingDeclaration = saveEnclosingDeclaration; const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined; @@ -2941,7 +3262,10 @@ namespace ts { /*questionToken*/ undefined, indexerTypeNode, /*initializer*/ undefined); - const typeNode = typeToTypeNodeHelper(indexInfo.type, context); + const typeNode = indexInfo.type ? typeToTypeNodeHelper(indexInfo.type, context) : typeToTypeNodeHelper(anyType, context); + if (!indexInfo.type && !(context.flags & NodeBuilderFlags.AllowEmptyIndexInfoType)) { + context.encounteredError = true; + } return createIndexSignature( /*decorators*/ undefined, indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined, @@ -2950,7 +3274,14 @@ namespace ts { } function signatureToSignatureDeclarationHelper(signature: Signature, kind: SyntaxKind, context: NodeBuilderContext): SignatureDeclaration { - const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, context)); + let typeParameters: TypeParameterDeclaration[]; + let typeArguments: TypeNode[]; + if (context.flags & NodeBuilderFlags.WriteTypeArgumentsOfSignature && signature.target && signature.mapper && signature.target.typeParameters) { + typeArguments = signature.target.typeParameters.map(parameter => typeToTypeNodeHelper(instantiateType(parameter, signature.mapper), context)); + } + else { + typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, context)); + } const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter, context)); if (signature.thisParameter) { const thisParameter = symbolToParameterDeclaration(signature.thisParameter, context); @@ -2977,15 +3308,17 @@ namespace ts { else if (!returnTypeNode) { returnTypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword); } - return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode); + return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments); } - function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext): TypeParameterDeclaration { + function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintFromTypeParameter(type)): TypeParameterDeclaration { + const savedContextFlags = context.flags; + context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic const name = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ true); - const constraint = getConstraintFromTypeParameter(type); const constraintNode = constraint && typeToTypeNodeHelper(constraint, context); const defaultParameter = getDefaultFromTypeParameter(type); const defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context); + context.flags = savedContextFlags; return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } @@ -2999,7 +3332,7 @@ namespace ts { } const parameterTypeNode = typeToTypeNodeHelper(parameterType, context); - const modifiers = parameterDeclaration && parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedClone); + const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && parameterDeclaration && parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedClone); const dotDotDotToken = !parameterDeclaration || isRestParameter(parameterDeclaration) ? createToken(SyntaxKind.DotDotDotToken) : undefined; const name = parameterDeclaration ? parameterDeclaration.name ? @@ -3032,10 +3365,8 @@ namespace ts { } } - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: true): Identifier; - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: false): EntityName; - function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: boolean): EntityName { - + function lookupSymbolChain(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags) { + context.tracker.trackSymbol(symbol, context.enclosingDeclaration, meaning); // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration. let chain: Symbol[]; const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; @@ -3046,42 +3377,11 @@ namespace ts { else { chain = [symbol]; } - - if (expectsIdentifier && chain.length !== 1 - && !context.encounteredError - && !(context.flags & NodeBuilderFlags.AllowQualifedNameInPlaceOfIdentifier)) { - context.encounteredError = true; - } - return createEntityNameFromSymbolChain(chain, chain.length - 1); - - function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { - Debug.assert(chain && 0 <= index && index < chain.length); - const symbol = chain[index]; - let typeParameterNodes: ReadonlyArray | undefined; - if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) { - const parentSymbol = chain[index - 1]; - let typeParameters: TypeParameter[]; - if (getCheckFlags(symbol) & CheckFlags.Instantiated) { - typeParameters = getTypeParametersOfClassOrInterface(parentSymbol); - } - else { - const targetSymbol = getTargetSymbol(parentSymbol); - if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { - typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - } - } - - typeParameterNodes = mapToTypeNodes(typeParameters, context); - } - - const identifier = setEmitFlags(createIdentifier(getNameOfSymbolAsWritten(symbol, context), typeParameterNodes), EmitFlags.NoAsciiEscaping); - - return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; - } + return chain; /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined { - let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false); + let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & NodeBuilderFlags.UseOnlyExternalAliasing)); let parentSymbol: Symbol; if (!accessibleSymbolChain || @@ -3113,12 +3413,113 @@ namespace ts { } } } + + function typeParametersToTypeParameterDeclarations(symbol: Symbol, context: NodeBuilderContext) { + let typeParameterNodes: NodeArray | undefined; + const targetSymbol = getTargetSymbol(symbol); + if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) { + typeParameterNodes = createNodeArray(map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), tp => typeParameterToDeclaration(tp, context))); + } + return typeParameterNodes; + } + + function lookupTypeParameterNodes(chain: Symbol[], index: number, context: NodeBuilderContext) { + Debug.assert(chain && 0 <= index && index < chain.length); + const symbol = chain[index]; + let typeParameterNodes: ReadonlyArray | ReadonlyArray | undefined; + if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index < (chain.length - 1)) { + const parentSymbol = symbol; + const nextSymbol = chain[index + 1]; + if (getCheckFlags(nextSymbol) & CheckFlags.Instantiated) { + const params = getTypeParametersOfClassOrInterface( + parentSymbol.flags & SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol + ); + typeParameterNodes = mapToTypeNodes(map(params, (nextSymbol as TransientSymbol).mapper), context); + } + else { + typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context); + } + } + return typeParameterNodes; + } + + function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: true): Identifier; + function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: false): EntityName; + function symbolToName(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, expectsIdentifier: boolean): EntityName { + const chain = lookupSymbolChain(symbol, context, meaning); + + if (expectsIdentifier && chain.length !== 1 + && !context.encounteredError + && !(context.flags & NodeBuilderFlags.AllowQualifedNameInPlaceOfIdentifier)) { + context.encounteredError = true; + } + return createEntityNameFromSymbolChain(chain, chain.length - 1); + + function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { + const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); + const symbol = chain[index]; + const symbolName = getNameOfSymbolAsWritten(symbol, context); + const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + identifier.symbol = symbol; + + return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; + } + } + + function symbolToExpression(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags) { + const chain = lookupSymbolChain(symbol, context, meaning); + + return createExpressionFromSymbolChain(chain, chain.length - 1); + + function createExpressionFromSymbolChain(chain: Symbol[], index: number): Expression { + const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); + const symbol = chain[index]; + + let symbolName = getNameOfSymbolAsWritten(symbol, context); + let firstChar = symbolName.charCodeAt(0); + const canUsePropertyAccess = isIdentifierStart(firstChar, languageVersion); + if (index === 0 || canUsePropertyAccess) { + const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + identifier.symbol = symbol; + + return index > 0 ? createPropertyAccess(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier; + } + else { + if (firstChar === CharacterCodes.openBracket) { + symbolName = symbolName.substring(1, symbolName.length - 1); + firstChar = symbolName.charCodeAt(0); + } + let expression: Expression; + if (isSingleOrDoubleQuote(firstChar)) { + expression = createLiteral(symbolName.substring(1, symbolName.length - 1).replace(/\\./g, s => s.substring(1))); + (expression as StringLiteral).singleQuote = firstChar === CharacterCodes.singleQuote; + } + else if (("" + +symbolName) === symbolName) { + expression = createLiteral(+symbolName); + } + if (!expression) { + expression = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + expression.symbol = symbol; + } + return createElementAccess(createExpressionFromSymbolChain(chain, index - 1), expression); + } + } + } } - function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Declaration, flags?: TypeFormatFlags): string { - return usingSingleLineStringWriter(writer => { - getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags); - }); + function typePredicateToString(typePredicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter): string { + return writer ? typePredicateToStringWorker(writer).getText() : usingSingleLineStringWriter(typePredicateToStringWorker); + + function typePredicateToStringWorker(writer: EmitTextWriter) { + const predicate = createTypePredicateNode( + typePredicate.kind === TypePredicateKind.Identifier ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(), + nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName) + ); + const printer = createPrinter({ removeComments: true }); + const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); + printer.writeNode(EmitHint.Unspecified, predicate, /*sourceFile*/ sourceFile, writer); + return writer; + } } function formatUnionTypes(types: Type[]): Type[] { @@ -3180,6 +3581,7 @@ namespace ts { interface NodeBuilderContext { enclosingDeclaration: Node | undefined; flags: NodeBuilderFlags | undefined; + tracker: SymbolTracker | undefined; // State encounteredError: boolean; @@ -3194,6 +3596,9 @@ namespace ts { * It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`. */ function getNameOfSymbolAsWritten(symbol: Symbol, context?: NodeBuilderContext): string { + if (context && context.flags & NodeBuilderFlags.WriteDefaultSymbolWithoutName && symbol.escapedName === InternalSymbolName.Default) { + return "default"; + } if (symbol.declarations && symbol.declarations.length) { const declaration = symbol.declarations[0]; const name = getNameOfDeclaration(declaration); @@ -3223,796 +3628,6 @@ namespace ts { return symbolName(symbol); } - function getSymbolDisplayBuilder(): SymbolDisplayBuilder { - - /** - * Writes only the name of the symbol out to the writer. Uses the original source text - * for the name of the symbol if it is available to match how the user wrote the name. - */ - function appendSymbolNameOnly(symbol: Symbol, writer: SymbolWriter): void { - writer.writeSymbol(getNameOfSymbolAsWritten(symbol), symbol); - } - - /** - * Writes a property access or element access with the name of the symbol out to the writer. - * Uses the original source text for the name of the symbol if it is available to match how the user wrote the name, - * ensuring that any names written with literals use element accesses. - */ - function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void { - const symbolName = symbol.escapedName === InternalSymbolName.Default ? InternalSymbolName.Default : getNameOfSymbolAsWritten(symbol); - const firstChar = symbolName.charCodeAt(0); - const needsElementAccess = !isIdentifierStart(firstChar, languageVersion); - - if (needsElementAccess) { - if (firstChar !== CharacterCodes.openBracket) { - writePunctuation(writer, SyntaxKind.OpenBracketToken); - } - if (isSingleOrDoubleQuote(firstChar)) { - writer.writeStringLiteral(symbolName); - } - else { - writer.writeSymbol(symbolName, symbol); - } - if (firstChar !== CharacterCodes.openBracket) { - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - } - else { - writePunctuation(writer, SyntaxKind.DotToken); - writer.writeSymbol(symbolName, symbol); - } - } - - /** - * Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope - * Meaning needs to be specified if the enclosing declaration is given - */ - function buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags, typeFlags?: TypeFormatFlags): void { - let parentSymbol: Symbol; - function appendParentTypeArgumentsAndSymbolName(symbol: Symbol): void { - if (parentSymbol) { - // Write type arguments of instantiated class/interface here - if (flags & SymbolFormatFlags.WriteTypeParametersOrArguments) { - if (getCheckFlags(symbol) & CheckFlags.Instantiated) { - const params = getTypeParametersOfClassOrInterface(parentSymbol.flags & SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol); - buildDisplayForTypeArgumentsAndDelimiters(params, (symbol).mapper, writer, enclosingDeclaration); - } - else { - buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration); - } - } - appendPropertyOrElementAccessForSymbol(symbol, writer); - } - else { - appendSymbolNameOnly(symbol, writer); - } - parentSymbol = symbol; - } - - // Let the writer know we just wrote out a symbol. The declaration emitter writer uses - // this to determine if an import it has previously seen (and not written out) needs - // to be written to the file once the walk of the tree is complete. - // - // NOTE(cyrusn): This approach feels somewhat unfortunate. A simple pass over the tree - // up front (for example, during checking) could determine if we need to emit the imports - // and we could then access that data during declaration emit. - writer.trackSymbol(symbol, enclosingDeclaration, meaning); - /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ - function walkSymbol(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): void { - const accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, !!(flags & SymbolFormatFlags.UseOnlyExternalAliasing)); - - if (!accessibleSymbolChain || - needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { - - // Go up and add our parent. - const parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); - if (parent) { - walkSymbol(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); - } - } - - if (accessibleSymbolChain) { - for (const accessibleSymbol of accessibleSymbolChain) { - appendParentTypeArgumentsAndSymbolName(accessibleSymbol); - } - } - else if ( - // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. - endOfChain || - // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) - !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && - // If a parent symbol is an anonymous type, don't write it. - !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral))) { - - appendParentTypeArgumentsAndSymbolName(symbol); - } - } - - // Get qualified name if the symbol is not a type parameter - // and there is an enclosing declaration or we specifically - // asked for it - const isTypeParameter = symbol.flags & SymbolFlags.TypeParameter; - const typeFormatFlag = TypeFormatFlags.UseFullyQualifiedType & typeFlags; - if (!isTypeParameter && (enclosingDeclaration || typeFormatFlag)) { - walkSymbol(symbol, meaning, /*endOfChain*/ true); - } - else { - appendParentTypeArgumentsAndSymbolName(symbol); - } - } - - function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { - const globalFlagsToPass = globalFlags & (TypeFormatFlags.WriteOwnNameForAnyLike | TypeFormatFlags.WriteClassExpressionAsTypeLiteral); - let inObjectTypeLiteral = false; - return writeType(type, globalFlags); - - function writeType(type: Type, flags: TypeFormatFlags) { - const nextFlags = flags & ~TypeFormatFlags.InTypeAlias; - // Write undefined/null type as any - if (type.flags & TypeFlags.Intrinsic) { - // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving - writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && isTypeAny(type) - ? "any" - : (type).intrinsicName); - } - else if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { - if (inObjectTypeLiteral) { - writer.reportInaccessibleThisError(); - } - writer.writeKeyword("this"); - } - else if (getObjectFlags(type) & ObjectFlags.Reference) { - writeTypeReference(type, nextFlags); - } - else if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) { - const parent = getParentOfSymbol(type.symbol); - buildSymbolDisplay(parent, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); - // In a literal enum type with a single member E { A }, E and E.A denote the - // same type. We always display this type simply as E. - if (getDeclaredTypeOfSymbol(parent) !== type) { - writePunctuation(writer, SyntaxKind.DotToken); - appendSymbolNameOnly(type.symbol, writer); - } - } - else if (getObjectFlags(type) & ObjectFlags.ClassOrInterface || type.flags & (TypeFlags.EnumLike | TypeFlags.TypeParameter)) { - // The specified symbol flags need to be reinterpreted as type flags - buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); - } - else if (!(flags & TypeFormatFlags.InTypeAlias) && type.aliasSymbol && - ((flags & TypeFormatFlags.UseAliasDefinedOutsideCurrentScope) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { - const typeArguments = type.aliasTypeArguments; - writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, length(typeArguments), nextFlags); - } - else if (type.flags & TypeFlags.UnionOrIntersection) { - writeUnionOrIntersectionType(type, nextFlags); - } - else if (getObjectFlags(type) & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { - writeAnonymousType(type, nextFlags); - } - else if (type.flags & TypeFlags.UniqueESSymbol) { - if (flags & TypeFormatFlags.AllowUniqueESSymbolType) { - writeKeyword(writer, SyntaxKind.UniqueKeyword); - writeSpace(writer); - } - else { - writer.reportInaccessibleUniqueSymbolError(); - } - writeKeyword(writer, SyntaxKind.SymbolKeyword); - } - else if (type.flags & TypeFlags.StringOrNumberLiteral) { - writer.writeStringLiteral(literalTypeToString(type)); - } - else if (type.flags & TypeFlags.Index) { - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - writer.writeKeyword("keyof"); - writeSpace(writer); - writeType((type).type, TypeFormatFlags.InElementType); - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - } - else if (type.flags & TypeFlags.IndexedAccess) { - writeType((type).objectType, TypeFormatFlags.InElementType); - writePunctuation(writer, SyntaxKind.OpenBracketToken); - writeType((type).indexType, TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - else if (type.flags & TypeFlags.Conditional) { - writeType((type).checkType, TypeFormatFlags.InElementType); - writeSpace(writer); - writer.writeKeyword("extends"); - writeSpace(writer); - writeType((type).extendsType, TypeFormatFlags.InElementType); - writeSpace(writer); - writePunctuation(writer, SyntaxKind.QuestionToken); - writeSpace(writer); - writeType((type).trueType, TypeFormatFlags.InElementType); - writeSpace(writer); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - writeType((type).falseType, TypeFormatFlags.InElementType); - } - else if (type.flags & TypeFlags.Substitution) { - writeType((type).typeParameter, TypeFormatFlags.None); - } - else { - // Should never get here - // { ... } - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writeSpace(writer); - writePunctuation(writer, SyntaxKind.DotDotDotToken); - writeSpace(writer); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - } - } - - - function writeTypeList(types: Type[], delimiter: SyntaxKind) { - for (let i = 0; i < types.length; i++) { - if (i > 0) { - if (delimiter !== SyntaxKind.CommaToken) { - writeSpace(writer); - } - writePunctuation(writer, delimiter); - writeSpace(writer); - } - writeType(types[i], delimiter === SyntaxKind.CommaToken ? TypeFormatFlags.None : TypeFormatFlags.InElementType); - } - } - - function writeSymbolTypeReference(symbol: Symbol, typeArguments: Type[], pos: number, end: number, flags: TypeFormatFlags) { - // Unnamed function expressions and arrow functions have reserved names that we don't want to display - if (symbol.flags & SymbolFlags.Class || !isReservedMemberName(symbol.escapedName)) { - buildSymbolDisplay(symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags); - } - if (pos < end) { - writePunctuation(writer, SyntaxKind.LessThanToken); - writeType(typeArguments[pos], TypeFormatFlags.InFirstTypeArgument); - pos++; - while (pos < end) { - writePunctuation(writer, SyntaxKind.CommaToken); - writeSpace(writer); - writeType(typeArguments[pos], TypeFormatFlags.None); - pos++; - } - writePunctuation(writer, SyntaxKind.GreaterThanToken); - } - } - - function writeTypeReference(type: TypeReference, flags: TypeFormatFlags) { - const typeArguments = type.typeArguments || emptyArray; - if (type.target === globalArrayType && !(flags & TypeFormatFlags.WriteArrayAsGenericType)) { - writeType(typeArguments[0], TypeFormatFlags.InElementType | TypeFormatFlags.InArrayType); - writePunctuation(writer, SyntaxKind.OpenBracketToken); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - else if (type.target.objectFlags & ObjectFlags.Tuple) { - writePunctuation(writer, SyntaxKind.OpenBracketToken); - writeTypeList(type.typeArguments.slice(0, getTypeReferenceArity(type)), SyntaxKind.CommaToken); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - else if (flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral && - type.symbol.valueDeclaration && - type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) { - writeAnonymousType(type, flags); - } - else { - // Write the type reference in the format f.g.C where A and B are type arguments - // for outer type parameters, and f and g are the respective declaring containers of those - // type parameters. - const outerTypeParameters = type.target.outerTypeParameters; - let i = 0; - if (outerTypeParameters) { - const length = outerTypeParameters.length; - while (i < length) { - // Find group of type arguments for type parameters with the same declaring container. - const start = i; - const parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); - do { - i++; - } while (i < length && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); - // When type parameters are their own type arguments for the whole group (i.e. we have - // the default outer type arguments), we don't show the group. - if (!rangeEquals(outerTypeParameters, typeArguments, start, i)) { - writeSymbolTypeReference(parent, typeArguments, start, i, flags); - writePunctuation(writer, SyntaxKind.DotToken); - } - } - } - const typeParameterCount = (type.target.typeParameters || emptyArray).length; - writeSymbolTypeReference(type.symbol, typeArguments, i, typeParameterCount, flags); - } - } - - function writeUnionOrIntersectionType(type: UnionOrIntersectionType, flags: TypeFormatFlags) { - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - if (type.flags & TypeFlags.Union) { - writeTypeList(formatUnionTypes(type.types), SyntaxKind.BarToken); - } - else { - writeTypeList(type.types, SyntaxKind.AmpersandToken); - } - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - } - - function writeAnonymousType(type: ObjectType, flags: TypeFormatFlags) { - const symbol = type.symbol; - if (symbol) { - // Always use 'typeof T' for type of class, enum, and module objects - if (symbol.flags & SymbolFlags.Class && - !getBaseTypeVariableOfClass(symbol) && - !(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) || - symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule)) { - writeTypeOfSymbol(type.symbol, flags); - } - else if (shouldWriteTypeOfFunctionSymbol()) { - writeTypeOfSymbol(type.symbol, flags); - } - else if (contains(symbolStack, symbol)) { - // If type is an anonymous type literal in a type alias declaration, use type alias name - const typeAlias = getTypeAliasForTypeLiteral(type); - if (typeAlias) { - // The specified symbol flags need to be reinterpreted as type flags - buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags); - } - else { - // Recursive usage, use any - writeKeyword(writer, SyntaxKind.AnyKeyword); - } - } - else { - // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead - // of types allows us to catch circular references to instantiations of the same anonymous type - // However, in case of class expressions, we want to write both the static side and the instance side. - // We skip adding the static side so that the instance side has a chance to be written - // before checking for circular references. - if (!symbolStack) { - symbolStack = []; - } - const isConstructorObject = type.objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class; - if (isConstructorObject) { - writeLiteralType(type, flags); - } - else { - symbolStack.push(symbol); - writeLiteralType(type, flags); - symbolStack.pop(); - } - } - } - else { - // Anonymous types with no symbol are never circular - writeLiteralType(type, flags); - } - - function shouldWriteTypeOfFunctionSymbol() { - const isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method) && // typeof static method - some(symbol.declarations, declaration => hasModifier(declaration, ModifierFlags.Static)); - const isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && - (symbol.parent || // is exported function symbol - some(symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); - if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { - // typeof is allowed only for static/non local functions - return !!(flags & TypeFormatFlags.UseTypeOfFunction) || // use typeof if format flags specify it - contains(symbolStack, symbol); // it is type of the symbol uses itself recursively - } - } - } - - function writeTypeOfSymbol(symbol: Symbol, typeFormatFlags?: TypeFormatFlags) { - if (typeFormatFlags & TypeFormatFlags.InArrayType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - writeKeyword(writer, SyntaxKind.TypeOfKeyword); - writeSpace(writer); - buildSymbolDisplay(symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags); - if (typeFormatFlags & TypeFormatFlags.InArrayType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - } - - function writePropertyWithModifiers(prop: Symbol) { - if (isReadonlySymbol(prop)) { - writeKeyword(writer, SyntaxKind.ReadonlyKeyword); - writeSpace(writer); - } - if (getCheckFlags(prop) & CheckFlags.Late) { - const decl = firstOrUndefined(prop.declarations); - const name = hasLateBindableName(decl) && resolveEntityName(decl.name.expression, SymbolFlags.Value); - if (name) { - writer.trackSymbol(name, enclosingDeclaration, SymbolFlags.Value); - } - } - buildSymbolDisplay(prop, writer); - if (prop.flags & SymbolFlags.Optional) { - writePunctuation(writer, SyntaxKind.QuestionToken); - } - } - - function shouldAddParenthesisAroundFunctionType(callSignature: Signature, flags: TypeFormatFlags) { - if (flags & TypeFormatFlags.InElementType) { - return true; - } - else if (flags & TypeFormatFlags.InFirstTypeArgument) { - // Add parenthesis around function type for the first type argument to avoid ambiguity - const typeParameters = callSignature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature) ? - callSignature.target.typeParameters : callSignature.typeParameters; - return typeParameters && typeParameters.length !== 0; - } - return false; - } - - function writeLiteralType(type: ObjectType, flags: TypeFormatFlags) { - if (isGenericMappedType(type)) { - writeMappedType(type); - return; - } - - const resolved = resolveStructuredTypeMembers(type); - if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { - if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - return; - } - - if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { - const parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags); - if (parenthesizeSignature) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); - if (parenthesizeSignature) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - return; - } - if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - } - writeKeyword(writer, SyntaxKind.NewKeyword); - writeSpace(writer); - buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack); - if (flags & TypeFormatFlags.InElementType) { - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - return; - } - } - - const saveInObjectTypeLiteral = inObjectTypeLiteral; - inObjectTypeLiteral = true; - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writer.writeLine(); - writer.increaseIndent(); - writeObjectLiteralType(resolved); - writer.decreaseIndent(); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - inObjectTypeLiteral = saveInObjectTypeLiteral; - } - - function writeObjectLiteralType(resolved: ResolvedType) { - for (const signature of resolved.callSignatures) { - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - for (const signature of resolved.constructSignatures) { - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, SignatureKind.Construct, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack); - buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack); - for (const p of resolved.properties) { - if (globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) { - if (p.flags & SymbolFlags.Prototype) { - continue; - } - if (getDeclarationModifierFlagsFromSymbol(p) & (ModifierFlags.Private | ModifierFlags.Protected)) { - writer.reportPrivateInBaseOfClassExpression(symbolName(p)); - } - } - const t = getTypeOfSymbol(p); - if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) { - const signatures = getSignaturesOfType(t, SignatureKind.Call); - for (const signature of signatures) { - writePropertyWithModifiers(p); - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - } - else { - writePropertyWithModifiers(p); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - writeType(t, globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - } - } - - function writeMappedType(type: MappedType) { - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writer.writeLine(); - writer.increaseIndent(); - if (type.declaration.readonlyToken) { - writeKeyword(writer, SyntaxKind.ReadonlyKeyword); - writeSpace(writer); - } - writePunctuation(writer, SyntaxKind.OpenBracketToken); - appendSymbolNameOnly(getTypeParameterFromMappedType(type).symbol, writer); - writeSpace(writer); - writeKeyword(writer, SyntaxKind.InKeyword); - writeSpace(writer); - writeType(getConstraintTypeFromMappedType(type), TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - if (type.declaration.questionToken) { - writePunctuation(writer, SyntaxKind.QuestionToken); - } - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - writeType(getTemplateTypeFromMappedType(type), TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - writer.decreaseIndent(); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - } - } - - function buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags) { - const targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & SymbolFlags.Class || targetSymbol.flags & SymbolFlags.Interface || targetSymbol.flags & SymbolFlags.TypeAlias) { - buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaration, flags); - } - } - - function buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - appendSymbolNameOnly(tp.symbol, writer); - const constraint = getConstraintOfTypeParameter(tp); - if (constraint) { - writeSpace(writer); - writeKeyword(writer, SyntaxKind.ExtendsKeyword); - writeSpace(writer); - buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack); - } - const defaultType = getDefaultFromTypeParameter(tp); - if (defaultType) { - writeSpace(writer); - writePunctuation(writer, SyntaxKind.EqualsToken); - writeSpace(writer); - buildTypeDisplay(defaultType, writer, enclosingDeclaration, flags, symbolStack); - } - } - - function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - const parameterNode = p.valueDeclaration; - - if (parameterNode ? isRestParameter(parameterNode) : isTransientSymbol(p) && p.isRestParameter) { - writePunctuation(writer, SyntaxKind.DotDotDotToken); - } - if (parameterNode && isBindingPattern(parameterNode.name)) { - buildBindingPatternDisplay(parameterNode.name, writer, enclosingDeclaration, flags, symbolStack); - } - else { - appendSymbolNameOnly(p, writer); - } - if (parameterNode && isOptionalParameter(parameterNode)) { - writePunctuation(writer, SyntaxKind.QuestionToken); - } - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - - let type = getTypeOfSymbol(p); - if (parameterNode && isRequiredInitializedParameter(parameterNode)) { - type = getOptionalType(type); - } - buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack); - } - - function buildBindingPatternDisplay(bindingPattern: BindingPattern, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - // We have to explicitly emit square bracket and bracket because these tokens are not stored inside the node. - if (bindingPattern.kind === SyntaxKind.ObjectBindingPattern) { - writePunctuation(writer, SyntaxKind.OpenBraceToken); - buildDisplayForCommaSeparatedList(bindingPattern.elements, writer, e => buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack)); - writePunctuation(writer, SyntaxKind.CloseBraceToken); - } - else if (bindingPattern.kind === SyntaxKind.ArrayBindingPattern) { - writePunctuation(writer, SyntaxKind.OpenBracketToken); - const elements = bindingPattern.elements; - buildDisplayForCommaSeparatedList(elements, writer, e => buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack)); - if (elements && elements.hasTrailingComma) { - writePunctuation(writer, SyntaxKind.CommaToken); - } - writePunctuation(writer, SyntaxKind.CloseBracketToken); - } - } - - function buildBindingElementDisplay(bindingElement: ArrayBindingElement, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - if (isOmittedExpression(bindingElement)) { - return; - } - Debug.assert(bindingElement.kind === SyntaxKind.BindingElement); - if (bindingElement.propertyName) { - writer.writeProperty(getTextOfNode(bindingElement.propertyName)); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - } - if (isBindingPattern(bindingElement.name)) { - buildBindingPatternDisplay(bindingElement.name, writer, enclosingDeclaration, flags, symbolStack); - } - else { - if (bindingElement.dotDotDotToken) { - writePunctuation(writer, SyntaxKind.DotDotDotToken); - } - appendSymbolNameOnly(bindingElement.symbol, writer); - } - } - - function buildDisplayForTypeParametersAndDelimiters(typeParameters: ReadonlyArray, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - if (typeParameters && typeParameters.length) { - writePunctuation(writer, SyntaxKind.LessThanToken); - buildDisplayForCommaSeparatedList(typeParameters, writer, p => buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack)); - writePunctuation(writer, SyntaxKind.GreaterThanToken); - } - } - - function buildDisplayForCommaSeparatedList(list: ReadonlyArray, writer: SymbolWriter, action: (item: T) => void) { - for (let i = 0; i < list.length; i++) { - if (i > 0) { - writePunctuation(writer, SyntaxKind.CommaToken); - writeSpace(writer); - } - action(list[i]); - } - } - - function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: ReadonlyArray, mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node) { - if (typeParameters && typeParameters.length) { - writePunctuation(writer, SyntaxKind.LessThanToken); - let flags = TypeFormatFlags.InFirstTypeArgument; - for (let i = 0; i < typeParameters.length; i++) { - if (i > 0) { - writePunctuation(writer, SyntaxKind.CommaToken); - writeSpace(writer); - flags = TypeFormatFlags.None; - } - buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, flags); - } - writePunctuation(writer, SyntaxKind.GreaterThanToken); - } - } - - function buildDisplayForParametersAndDelimiters(thisParameter: Symbol | undefined, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - writePunctuation(writer, SyntaxKind.OpenParenToken); - if (thisParameter) { - buildParameterDisplay(thisParameter, writer, enclosingDeclaration, flags, symbolStack); - } - for (let i = 0; i < parameters.length; i++) { - if (i > 0 || thisParameter) { - writePunctuation(writer, SyntaxKind.CommaToken); - writeSpace(writer); - } - buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, symbolStack); - } - writePunctuation(writer, SyntaxKind.CloseParenToken); - } - - function buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]): void { - if (isIdentifierTypePredicate(predicate)) { - writer.writeParameter(predicate.parameterName); - } - else { - writeKeyword(writer, SyntaxKind.ThisKeyword); - } - writeSpace(writer); - writeKeyword(writer, SyntaxKind.IsKeyword); - writeSpace(writer); - buildTypeDisplay(predicate.type, writer, enclosingDeclaration, flags, symbolStack); - } - - function buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { - const returnType = getReturnTypeOfSignature(signature); - if (flags & TypeFormatFlags.SuppressAnyReturnType && isTypeAny(returnType)) { - return; - } - - if (flags & TypeFormatFlags.WriteArrowStyleSignature) { - writeSpace(writer); - writePunctuation(writer, SyntaxKind.EqualsGreaterThanToken); - } - else { - writePunctuation(writer, SyntaxKind.ColonToken); - } - writeSpace(writer); - - const typePredicate = getTypePredicateOfSignature(signature); - if (typePredicate) { - buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags, symbolStack); - } - else { - buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack); - } - } - - function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind, symbolStack?: Symbol[]) { - if (kind === SignatureKind.Construct) { - writeKeyword(writer, SyntaxKind.NewKeyword); - writeSpace(writer); - } - - if (signature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature)) { - // Instantiated signature, write type arguments instead - // This is achieved by passing in the mapper separately - buildDisplayForTypeArgumentsAndDelimiters(signature.target.typeParameters, signature.mapper, writer, enclosingDeclaration); - } - else { - buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, symbolStack); - } - - buildDisplayForParametersAndDelimiters(signature.thisParameter, signature.parameters, writer, enclosingDeclaration, flags, symbolStack); - - buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack); - } - - function buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { - if (info) { - if (info.isReadonly) { - writeKeyword(writer, SyntaxKind.ReadonlyKeyword); - writeSpace(writer); - } - writePunctuation(writer, SyntaxKind.OpenBracketToken); - writer.writeParameter(info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : "x"); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - switch (kind) { - case IndexKind.Number: - writeKeyword(writer, SyntaxKind.NumberKeyword); - break; - case IndexKind.String: - writeKeyword(writer, SyntaxKind.StringKeyword); - break; - } - - writePunctuation(writer, SyntaxKind.CloseBracketToken); - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - if (info.type) { - buildTypeDisplay(info.type, writer, enclosingDeclaration, globalFlags, symbolStack); - } - else { - writeKeyword(writer, SyntaxKind.AnyKeyword); - } - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - } - } - - return _displayBuilder || (_displayBuilder = { - buildSymbolDisplay, - buildTypeDisplay, - buildTypeParameterDisplay, - buildTypePredicateDisplay, - buildParameterDisplay, - buildDisplayForParametersAndDelimiters, - buildDisplayForTypeParametersAndDelimiters, - buildTypeParameterDisplayFromSymbol, - buildSignatureDisplay, - buildIndexSignatureDisplay, - buildReturnTypeDisplay - }); - } - function isDeclarationVisible(node: Declaration): boolean { if (node) { const links = getNodeLinks(node); @@ -4188,7 +3803,7 @@ namespace ts { return -1; } - function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): Type { + function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): Type | boolean { if (propertyName === TypeSystemPropertyName.Type) { return getSymbolLinks(target).type; } @@ -4201,6 +3816,10 @@ namespace ts { if (propertyName === TypeSystemPropertyName.ResolvedReturnType) { return (target).resolvedReturnType; } + if (propertyName === TypeSystemPropertyName.ResolvedBaseConstraint) { + const bc = (target).resolvedBaseConstraint; + return bc && bc !== circularConstraintType; + } Debug.fail("Unhandled TypeSystemPropertyName " + propertyName); } @@ -4358,7 +3977,7 @@ namespace ts { } else { // Use specific property type when parent is a tuple or numeric index type when parent is an array - const propName = "" + indexOf(pattern.elements, declaration); + const propName = "" + pattern.elements.indexOf(declaration); type = isTupleLikeType(parentType) ? getTypeOfPropertyOfType(parentType, propName as __String) : elementType; @@ -4929,6 +4548,9 @@ namespace ts { if (getCheckFlags(symbol) & CheckFlags.Instantiated) { return getTypeOfInstantiatedSymbol(symbol); } + if (getCheckFlags(symbol) & CheckFlags.ReverseMapped) { + return getTypeOfReverseMappedSymbol(symbol as ReverseMappedSymbol); + } if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { return getTypeOfVariableOrParameterOrProperty(symbol); } @@ -6139,6 +5761,23 @@ namespace ts { } } + function resolveReverseMappedTypeMembers(type: ReverseMappedType) { + const indexInfo = getIndexInfoOfType(type.source, IndexKind.String); + const readonlyMask = type.mappedType.declaration.readonlyToken ? false : true; + const optionalMask = type.mappedType.declaration.questionToken ? 0 : SymbolFlags.Optional; + const stringIndexInfo = indexInfo && createIndexInfo(inferReverseMappedType(indexInfo.type, type.mappedType), readonlyMask && indexInfo.isReadonly); + const members = createSymbolTable(); + for (const prop of getPropertiesOfType(type.source)) { + const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); + const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ReverseMappedSymbol; + inferredProp.declarations = prop.declarations; + inferredProp.propertyType = getTypeOfSymbol(prop); + inferredProp.mappedType = type.mappedType; + members.set(prop.escapedName, inferredProp); + } + setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined); + } + /** Resolve the members of a mapped type { [P in K]: T } */ function resolveMappedTypeMembers(type: MappedType) { const members: SymbolTable = createSymbolTable(); @@ -6265,7 +5904,7 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Mapped && !!(type).declaration.questionToken; } - function isGenericMappedType(type: Type) { + function isGenericMappedType(type: Type): type is MappedType { return getObjectFlags(type) & ObjectFlags.Mapped && isGenericIndexType(getConstraintTypeFromMappedType(type)); } @@ -6278,6 +5917,9 @@ namespace ts { else if ((type).objectFlags & ObjectFlags.ClassOrInterface) { resolveClassOrInterfaceMembers(type); } + else if ((type).objectFlags & ObjectFlags.ReverseMapped) { + resolveReverseMappedTypeMembers(type as ReverseMappedType); + } else if ((type).objectFlags & ObjectFlags.Anonymous) { resolveAnonymousTypeMembers(type); } @@ -6375,12 +6017,17 @@ namespace ts { } function getConstraintOfIndexedAccess(type: IndexedAccessType) { - const transformed = getTransformedIndexedAccessType(type); + const transformed = getSimplifiedIndexedAccessType(type); if (transformed) { return transformed; } const baseObjectType = getBaseConstraintOfType(type.objectType); const baseIndexType = getBaseConstraintOfType(type.indexType); + if (baseIndexType === stringType && !getIndexInfoOfType(baseObjectType || type.objectType, IndexKind.String)) { + // getIndexedAccessType returns `any` for X[string] where X doesn't have an index signature. + // to avoid this, return `undefined`. + return undefined; + } return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; } @@ -6431,31 +6078,32 @@ namespace ts { * circularly references the type variable. */ function getResolvedBaseConstraint(type: InstantiableType | UnionOrIntersectionType): Type { - let typeStack: Type[]; let circular: boolean; if (!type.resolvedBaseConstraint) { - typeStack = []; const constraint = getBaseConstraint(type); type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type); } return type.resolvedBaseConstraint; function getBaseConstraint(t: Type): Type { - if (contains(typeStack, t)) { + if (!pushTypeResolution(t, TypeSystemPropertyName.ResolvedBaseConstraint)) { circular = true; return undefined; } - typeStack.push(t); const result = computeBaseConstraint(t); - typeStack.pop(); + if (!popTypeResolution()) { + circular = true; + return undefined; + } return result; } function computeBaseConstraint(t: Type): Type { if (t.flags & TypeFlags.TypeParameter) { const constraint = getConstraintFromTypeParameter(t); - return (t).isThisType ? constraint : - constraint ? getBaseConstraint(constraint) : undefined; + return (t as TypeParameter).isThisType || !constraint ? + constraint : + getBaseConstraint(constraint); } if (t.flags & TypeFlags.UnionOrIntersection) { const types = (t).types; @@ -6474,7 +6122,7 @@ namespace ts { return stringType; } if (t.flags & TypeFlags.IndexedAccess) { - const transformed = getTransformedIndexedAccessType(t); + const transformed = getSimplifiedIndexedAccessType(t); if (transformed) { return getBaseConstraint(transformed); } @@ -6788,7 +6436,7 @@ namespace ts { if (node.initializer) { const signatureDeclaration = node.parent; const signature = getSignatureFromDeclaration(signatureDeclaration); - const parameterIndex = ts.indexOf(signatureDeclaration.parameters, node); + const parameterIndex = signatureDeclaration.parameters.indexOf(node); Debug.assert(parameterIndex >= 0); return parameterIndex >= signature.minArgumentCount; } @@ -6796,7 +6444,7 @@ namespace ts { if (iife) { return !node.type && !node.dotDotDotToken && - indexOf((node.parent as SignatureDeclaration).parameters, node) >= iife.arguments.length; + node.parent.parameters.indexOf(node) >= iife.arguments.length; } return false; @@ -8187,7 +7835,7 @@ namespace ts { } function getLiteralTypeFromPropertyName(prop: Symbol) { - return getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || startsWith(prop.escapedName as string, "__@") ? + return getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || isKnownSymbol(prop) ? neverType : getLiteralType(symbolName(prop)); } @@ -8242,6 +7890,7 @@ namespace ts { const prop = getPropertyOfType(objectType, propName); if (prop) { if (accessExpression) { + markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === SyntaxKind.ThisKeyword); if (isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) { error(accessExpression.argumentExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop)); return unknownType; @@ -8314,42 +7963,67 @@ namespace ts { return false; } + function isMappedTypeToNever(type: Type) { + return getObjectFlags(type) & ObjectFlags.Mapped && getTemplateTypeFromMappedType(type as MappedType) === neverType; + } + // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return // undefined if no transformation is possible. - function getTransformedIndexedAccessType(type: IndexedAccessType): Type { + function getSimplifiedIndexedAccessType(type: IndexedAccessType): Type { const objectType = type.objectType; - // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or - // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a - // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed - // access types with default property values as expressed by D. - if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType) && some((objectType).types, isStringIndexOnlyType)) { - const regularTypes: Type[] = []; - const stringIndexTypes: Type[] = []; - for (const t of (objectType).types) { - if (isStringIndexOnlyType(t)) { - stringIndexTypes.push(getIndexTypeOfType(t, IndexKind.String)); - } - else { - regularTypes.push(t); + if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType)) { + // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or + // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a + // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed + // access types with default property values as expressed by D. + if (some((objectType).types, isStringIndexOnlyType)) { + const regularTypes: Type[] = []; + const stringIndexTypes: Type[] = []; + for (const t of (objectType).types) { + if (isStringIndexOnlyType(t)) { + stringIndexTypes.push(getIndexTypeOfType(t, IndexKind.String)); + } + else { + regularTypes.push(t); + } } + return getUnionType([ + getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), + getIntersectionType(stringIndexTypes) + ]); + } + // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or + // more mapped types with a template type `never`, '(U & V & { [P in T]: never })[K]', return a + // transformed type that removes the never-mapped type: '(U & V)[K]'. This mirrors what would happen + // eventually anyway, but it easier to reason about. + if (some((objectType).types, isMappedTypeToNever)) { + const nonNeverTypes = filter((objectType).types, t => !isMappedTypeToNever(t)); + return getIndexedAccessType(getIntersectionType(nonNeverTypes), type.indexType); } - return getUnionType([ - getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), - getIntersectionType(stringIndexTypes) - ]); } + // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we // construct the type Box. if (isGenericMappedType(objectType)) { - const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); - const objectTypeMapper = (objectType).mapper; - const templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper; - return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); + return substituteIndexedMappedType(objectType, type); + } + if (objectType.flags & TypeFlags.TypeParameter) { + const constraint = getConstraintFromTypeParameter(objectType as TypeParameter); + if (constraint && isGenericMappedType(constraint)) { + return substituteIndexedMappedType(constraint, type); + } } return undefined; } + function substituteIndexedMappedType(objectType: MappedType, type: IndexedAccessType) { + const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); + const objectTypeMapper = (objectType).mapper; + const templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper; + return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); + } + function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode): Type { // If the index type is generic, or if the object type is generic and doesn't originate in an expression, // we are performing a higher-order index access where we cannot meaningfully access the properties of the @@ -8815,7 +8489,7 @@ namespace ts { * This is used during inference when instantiating type parameter defaults. */ function createBackreferenceMapper(typeParameters: TypeParameter[], index: number): TypeMapper { - return t => indexOf(typeParameters, t) >= index ? emptyObjectType : t; + return t => typeParameters.indexOf(t) >= index ? emptyObjectType : t; } function isInferenceContext(mapper: TypeMapper): mapper is InferenceContext { @@ -9225,7 +8899,7 @@ namespace ts { return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1); } - function checkTypeAssignableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { + function checkTypeAssignableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain); } @@ -9233,7 +8907,7 @@ namespace ts { * This is *not* a bi-directional relationship. * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'. */ - function checkTypeComparableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { + function checkTypeComparableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain); } @@ -9567,7 +9241,7 @@ namespace ts { relation: Map, errorNode: Node, headMessage?: DiagnosticMessage, - containingMessageChain?: DiagnosticMessageChain): boolean { + containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { let errorInfo: DiagnosticMessageChain; let maybeKeys: string[]; @@ -9587,11 +9261,25 @@ namespace ts { } else if (errorInfo) { if (containingMessageChain) { - errorInfo = concatenateDiagnosticMessageChains(containingMessageChain, errorInfo); + const chain = containingMessageChain(); + if (chain) { + errorInfo = concatenateDiagnosticMessageChains(chain, errorInfo); + } } diagnostics.add(createDiagnosticForNodeFromMessageChain(errorNode, errorInfo)); } + // Check if we should issue an extra diagnostic to produce a quickfix for a slightly incorrect import statement + if (headMessage && errorNode && !result && source.symbol) { + const links = getSymbolLinks(source.symbol); + if (links.originatingImport && !isImportCall(links.originatingImport)) { + const helpfulRetry = checkTypeRelatedTo(getTypeOfSymbol(links.target), target, relation, /*errorNode*/ undefined); + if (helpfulRetry) { + // Likely an incorrect import. Issue a helpful diagnostic to produce a quickfix to change the import + diagnostics.add(createDiagnosticForNode(links.originatingImport, Diagnostics.A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime)); + } + } + } return result !== Ternary.False; function reportError(message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): void { @@ -9804,7 +9492,7 @@ namespace ts { } if (target.flags & TypeFlags.Union) { const discriminantType = findMatchingDiscriminantType(source, target as UnionType); - if (discriminantType) { + if (discriminantType) { // check excess properties against discriminant type only, not the entire union return hasExcessProperties(source, discriminantType, reportErrors); } @@ -10104,7 +9792,7 @@ namespace ts { } else if (target.flags & TypeFlags.IndexedAccess) { // A type S is related to a type T[K] if S is related to A[K], where K is string-like and - // A is the apparent type of S. + // A is the apparent type of T. const constraint = getConstraintOfIndexedAccess(target); if (constraint) { if (result = isRelatedTo(source, constraint, reportErrors)) { @@ -10711,7 +10399,7 @@ namespace ts { let result = "" + type.target.id; for (const t of type.typeArguments) { if (isUnconstrainedTypeParameter(t)) { - let index = indexOf(typeParameters, t); + let index = typeParameters.indexOf(t); if (index < 0) { index = typeParameters.length; typeParameters.push(t); @@ -11339,6 +11027,9 @@ namespace ts { } diagnostic = Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type; break; + case SyntaxKind.MappedType: + error(declaration, Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type); + return; default: diagnostic = Diagnostics.Variable_0_implicitly_has_an_1_type; } @@ -11399,6 +11090,7 @@ namespace ts { return { typeParameter, candidates: undefined, + contraCandidates: undefined, inferredType: undefined, priority: undefined, topLevel: true, @@ -11410,6 +11102,7 @@ namespace ts { return { typeParameter: inference.typeParameter, candidates: inference.candidates && inference.candidates.slice(), + contraCandidates: inference.contraCandidates && inference.contraCandidates.slice(), inferredType: inference.inferredType, priority: inference.priority, topLevel: inference.topLevel, @@ -11466,42 +11159,45 @@ namespace ts { * property is computed by inferring from the source property type to X for the type * variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for). */ - function inferTypeForHomomorphicMappedType(source: Type, target: MappedType, mappedTypeStack: string[]): Type { + function inferTypeForHomomorphicMappedType(source: Type, target: MappedType): Type { + const key = source.id + "," + target.id; + if (reverseMappedCache.has(key)) { + return reverseMappedCache.get(key); + } + reverseMappedCache.set(key, undefined); + const type = createReverseMappedType(source, target); + reverseMappedCache.set(key, type); + return type; + } + + function createReverseMappedType(source: Type, target: MappedType) { const properties = getPropertiesOfType(source); - let indexInfo = getIndexInfoOfType(source, IndexKind.String); - if (properties.length === 0 && !indexInfo) { + if (properties.length === 0 && !getIndexInfoOfType(source, IndexKind.String)) { return undefined; } - const typeParameter = getIndexedAccessType((getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target)); - const inference = createInferenceInfo(typeParameter); - const inferences = [inference]; - const templateType = getTemplateTypeFromMappedType(target); - const readonlyMask = target.declaration.readonlyToken ? false : true; - const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional; - const members = createSymbolTable(); + // If any property contains context sensitive functions that have been skipped, the source type + // is incomplete and we can't infer a meaningful input type. for (const prop of properties) { - const propType = getTypeOfSymbol(prop); - // If any property contains context sensitive functions that have been skipped, the source type - // is incomplete and we can't infer a meaningful input type. - if (propType.flags & TypeFlags.ContainsAnyFunctionType) { + if (getTypeOfSymbol(prop).flags & TypeFlags.ContainsAnyFunctionType) { return undefined; } - const checkFlags = readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0; - const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags); - inferredProp.declarations = prop.declarations; - inferredProp.type = inferTargetType(propType); - members.set(prop.escapedName, inferredProp); } - if (indexInfo) { - indexInfo = createIndexInfo(inferTargetType(indexInfo.type), readonlyMask && indexInfo.isReadonly); - } - return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined); + const reversed = createObjectType(ObjectFlags.ReverseMapped | ObjectFlags.Anonymous, /*symbol*/ undefined) as ReverseMappedType; + reversed.source = source; + reversed.mappedType = target; + return reversed; + } - function inferTargetType(sourceType: Type): Type { - inference.candidates = undefined; - inferTypes(inferences, sourceType, templateType, 0, mappedTypeStack); - return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType; - } + function getTypeOfReverseMappedSymbol(symbol: ReverseMappedSymbol) { + return inferReverseMappedType(symbol.propertyType, symbol.mappedType); + } + + function inferReverseMappedType(sourceType: Type, target: MappedType): Type { + const typeParameter = getIndexedAccessType((getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target)); + const templateType = getTemplateTypeFromMappedType(target); + const inference = createInferenceInfo(typeParameter); + inferTypes([inference], sourceType, templateType); + return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType; } function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) { @@ -11517,9 +11213,10 @@ namespace ts { return undefined; } - function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, mappedTypeStack?: string[]) { + function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { let symbolStack: Symbol[]; let visited: Map; + let contravariant = false; inferFromTypes(originalSource, originalTarget); function inferFromTypes(source: Type, target: Type) { @@ -11587,18 +11284,20 @@ namespace ts { const inference = getInferenceInfoForType(target); if (inference) { if (!inference.isFixed) { - // We give lowest priority to inferences of implicitNeverType (which is used as the - // element type for empty array literals). Thus, inferences from empty array literals - // only matter when no other inferences are made. - const p = priority | (source === implicitNeverType ? InferencePriority.NeverType : 0); - if (!inference.candidates || p < inference.priority) { - inference.candidates = [source]; - inference.priority = p; + if (inference.priority === undefined || priority < inference.priority) { + inference.candidates = undefined; + inference.contraCandidates = undefined; + inference.priority = priority; } - else if (p === inference.priority) { - inference.candidates.push(source); + if (priority === inference.priority) { + if (contravariant) { + inference.contraCandidates = append(inference.contraCandidates, source); + } + else { + inference.candidates = append(inference.candidates, source); + } } - if (!(p & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) { + if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) { inference.topLevel = false; } } @@ -11621,15 +11320,15 @@ namespace ts { } } else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) { - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes((source).type, (target).type); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else if ((isLiteralType(source) || source.flags & TypeFlags.String) && target.flags & TypeFlags.Index) { const empty = createEmptyObjectTypeFromStringLiteral(source); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes(empty, (target as IndexType).type); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) { inferFromTypes((source).objectType, (target).objectType); @@ -11704,9 +11403,9 @@ namespace ts { function inferFromContravariantTypes(source: Type, target: Type) { if (strictFunctionTypes) { - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes(source, target); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else { inferFromTypes(source, target); @@ -11740,13 +11439,7 @@ namespace ts { // such that direct inferences to T get priority over inferences to Partial, for example. const inference = getInferenceInfoForType((constraintType).type); if (inference && !inference.isFixed) { - const key = (source.symbol ? getSymbolId(source.symbol) + "," : "") + getSymbolId(target.symbol); - if (contains(mappedTypeStack, key)) { - return; - } - (mappedTypeStack || (mappedTypeStack = [])).push(key); - const inferredType = inferTypeForHomomorphicMappedType(source, target, mappedTypeStack); - mappedTypeStack.pop(); + const inferredType = inferTypeForHomomorphicMappedType(source, target); if (inferredType) { const savePriority = priority; priority |= InferencePriority.MappedType; @@ -11891,10 +11584,19 @@ namespace ts { // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if // union types were requested or if all inferences were made from the return type position, infer a // union type. Otherwise, infer a common supertype. - const unwidenedType = inference.priority & InferencePriority.Contravariant ? getCommonSubtype(baseCandidates) : - context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? getUnionType(baseCandidates, UnionReduction.Subtype) : + const unwidenedType = context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? + getUnionType(baseCandidates, UnionReduction.Subtype) : getCommonSupertype(baseCandidates); inferredType = getWidenedType(unwidenedType); + // If we have inferred 'never' but have contravariant candidates. To get a more specific type we + // infer from the contravariant candidates instead. + if (inferredType.flags & TypeFlags.Never && inference.contraCandidates) { + inferredType = getCommonSubtype(inference.contraCandidates); + } + } + else if (inference.contraCandidates) { + // We only have contravariant inferences, infer the best common subtype of those + inferredType = getCommonSubtype(inference.contraCandidates); } else if (context.flags & InferenceFlags.NoDefault) { // We use silentNeverType as the wildcard that signals no inferences. @@ -11960,6 +11662,7 @@ namespace ts { Diagnostics.Cannot_find_name_0, node, !isWriteOnlyAccess(node), + /*excludeGlobals*/ false, Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol; } return links.resolvedSymbol; @@ -11996,7 +11699,7 @@ namespace ts { const container = (node as BindingElement).parent.parent; const key = container.kind === SyntaxKind.BindingElement ? getFlowCacheKey(container) : (container.initializer && getFlowCacheKey(container.initializer)); const text = getBindingElementNameText(node as BindingElement); - const result = key && text && (key + "." + text); + const result = key && text && (key + "." + text); return result; } return undefined; @@ -12290,7 +11993,7 @@ namespace ts { } function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type { - return getTypeOfDestructuredArrayElement(getAssignedType(node), indexOf(node.elements, element)); + return getTypeOfDestructuredArrayElement(getAssignedType(node), node.elements.indexOf(element)); } function getAssignedTypeOfSpreadExpression(node: SpreadElement): Type { @@ -12334,7 +12037,7 @@ namespace ts { const type = pattern.kind === SyntaxKind.ObjectBindingPattern ? getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) : !node.dotDotDotToken ? - getTypeOfDestructuredArrayElement(parentType, indexOf(pattern.elements, node)) : + getTypeOfDestructuredArrayElement(parentType, pattern.elements.indexOf(node)) : getTypeOfDestructuredSpreadExpression(parentType); return getTypeWithDefault(type, node.initializer); } @@ -12919,7 +12622,7 @@ namespace ts { firstAntecedentType = flowType; } const type = getTypeFromFlowType(flowType); - // If we see a value appear in the cache it is a sign that control flow analysis + // If we see a value appear in the cache it is a sign that control flow analysis // was restarted and completed by checkExpressionCached. We can simply pick up // the resulting type and bail out. const cached = cache.get(key); @@ -13007,10 +12710,10 @@ namespace ts { const operator = expr.operatorToken.kind; const left = getReferenceCandidate(expr.left); const right = getReferenceCandidate(expr.right); - if (left.kind === SyntaxKind.TypeOfExpression && right.kind === SyntaxKind.StringLiteral) { + if (left.kind === SyntaxKind.TypeOfExpression && (right.kind === SyntaxKind.StringLiteral || right.kind === SyntaxKind.NoSubstitutionTemplateLiteral)) { return narrowTypeByTypeof(type, left, operator, right, assumeTrue); } - if (right.kind === SyntaxKind.TypeOfExpression && left.kind === SyntaxKind.StringLiteral) { + if (right.kind === SyntaxKind.TypeOfExpression && (left.kind === SyntaxKind.StringLiteral || left.kind === SyntaxKind.NoSubstitutionTemplateLiteral)) { return narrowTypeByTypeof(type, right, operator, left, assumeTrue); } if (isMatchingReference(reference, left)) { @@ -13033,7 +12736,7 @@ namespace ts { return narrowTypeByInstanceof(type, expr, assumeTrue); case SyntaxKind.InKeyword: const target = getReferenceCandidate(expr.right); - if (expr.left.kind === SyntaxKind.StringLiteral && isMatchingReference(reference, target)) { + if ((expr.left.kind === SyntaxKind.StringLiteral || expr.left.kind === SyntaxKind.NoSubstitutionTemplateLiteral) && isMatchingReference(reference, target)) { return narrowByInKeyword(type, expr.left, assumeTrue); } break; @@ -13502,6 +13205,7 @@ namespace ts { const declarationContainer = getControlFlowContainer(declaration); let flowContainer = getControlFlowContainer(node); const isOuterVariable = flowContainer !== declarationContainer; + const isSpreadDestructuringAsignmentTarget = node.parent && node.parent.parent && isSpreadAssignment(node.parent) && isDestructuringAssignmentTarget(node.parent.parent); // When the control flow originates in a function expression or arrow function and we are referencing // a const variable or parameter from an outer function, we extend the origin of the control flow // analysis to include the immediately enclosing function. @@ -13513,7 +13217,7 @@ namespace ts { // We only look for uninitialized variables in strict null checking mode, and only when we can analyze // the entire control flow graph from the variable's declaration (i.e. when the flow container and // declaration container are the same). - const assumeInitialized = isParameter || isAlias || isOuterVariable || + const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAsignmentTarget || type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || @@ -13632,7 +13336,7 @@ namespace ts { } } - function findFirstSuperCall(n: Node): Node { + function findFirstSuperCall(n: Node): SuperCall | undefined { if (isSuperCall(n)) { return n; } @@ -13648,12 +13352,12 @@ namespace ts { * * @param constructor constructor-function to look for super statement */ - function getSuperCallInConstructor(constructor: ConstructorDeclaration): ExpressionStatement { + function getSuperCallInConstructor(constructor: ConstructorDeclaration): SuperCall | undefined { const links = getNodeLinks(constructor); // Only trying to find super-call if we haven't yet tried to find one. Once we try, we will record the result if (links.hasSuperCall === undefined) { - links.superCall = findFirstSuperCall(constructor.body); + links.superCall = findFirstSuperCall(constructor.body); links.hasSuperCall = links.superCall ? true : false; } return links.superCall; @@ -14088,7 +13792,7 @@ namespace ts { if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { const iife = getImmediatelyInvokedFunctionExpression(func); if (iife && iife.arguments) { - const indexOfParameter = indexOf(func.parameters, parameter); + const indexOfParameter = func.parameters.indexOf(parameter); if (parameter.dotDotDotToken) { const restTypes: Type[] = []; for (let i = indexOfParameter; i < iife.arguments.length; i++) { @@ -14109,7 +13813,7 @@ namespace ts { if (contextualSignature) { const funcHasRestParameters = hasRestParameter(func); const len = func.parameters.length - (funcHasRestParameters ? 1 : 0); - let indexOfParameter = indexOf(func.parameters, parameter); + let indexOfParameter = func.parameters.indexOf(parameter); if (getThisParameter(func) !== undefined && !contextualSignature.thisParameter) { Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`. indexOfParameter -= 1; @@ -14140,7 +13844,7 @@ namespace ts { // the contextual type of an initializer expression is the type annotation of the containing declaration, if present. function getContextualTypeForInitializerExpression(node: Expression): Type { const declaration = node.parent; - if (hasInitializer(declaration) && node === declaration.initializer || node.kind === SyntaxKind.EqualsToken) { + if (hasInitializer(declaration) && node === declaration.initializer) { const typeNode = getEffectiveTypeAnnotationNode(declaration); if (typeNode) { return getTypeFromTypeNode(typeNode); @@ -14240,7 +13944,7 @@ namespace ts { // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter. function getContextualTypeForArgument(callTarget: CallLikeExpression, arg: Expression): Type { const args = getEffectiveCallArguments(callTarget); - const argIndex = indexOf(args, arg); + const argIndex = args.indexOf(arg); if (argIndex >= 0) { // If we're already in the process of resolving the given signature, don't resolve again as // that could cause infinite recursion. Instead, return anySignature. @@ -14272,12 +13976,6 @@ namespace ts { case SyntaxKind.AmpersandAmpersandToken: case SyntaxKind.CommaToken: return node === right ? getContextualType(binaryExpression) : undefined; - case SyntaxKind.EqualsEqualsEqualsToken: - case SyntaxKind.EqualsEqualsToken: - case SyntaxKind.ExclamationEqualsEqualsToken: - case SyntaxKind.ExclamationEqualsToken: - // For completions after `x === ` - return node === operatorToken ? getTypeOfExpression(binaryExpression.left) : undefined; default: return undefined; } @@ -14493,12 +14191,8 @@ namespace ts { return getContextualTypeForReturnExpression(node); case SyntaxKind.YieldExpression: return getContextualTypeForYieldOperand(parent); + case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: - if (node.kind === SyntaxKind.NewKeyword) { // for completions after `new ` - return getContextualType(parent as NewExpression); - } - // falls through - case SyntaxKind.CallExpression: return getContextualTypeForArgument(parent, node); case SyntaxKind.TypeAssertionExpression: case SyntaxKind.AsExpression: @@ -14533,12 +14227,6 @@ namespace ts { case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: return getAttributesTypeFromJsxOpeningLikeElement(parent); - case SyntaxKind.CaseClause: { - if (node.kind === SyntaxKind.CaseKeyword) { // for completions after `case ` - const switchStatement = (parent as CaseClause).parent.parent; - return getTypeOfExpression(switchStatement.expression); - } - } } return undefined; } @@ -14708,7 +14396,7 @@ namespace ts { if (patternElement.kind !== SyntaxKind.OmittedExpression) { error(patternElement, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value); } - elementTypes.push(unknownType); + elementTypes.push(strictNullChecks ? implicitNeverType : undefinedWideningType); } } } @@ -15241,7 +14929,7 @@ namespace ts { * element is not a class element, or the class element type cannot be determined, returns 'undefined'. * For example, in the element , the element instance type is `MyClass` (not `typeof MyClass`). */ - function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type) { + function getJsxElementInstanceType(node: JsxOpeningLikeElement, valueType: Type, sourceAttributesType: Type | undefined) { Debug.assert(!(valueType.flags & TypeFlags.Union)); if (isTypeAny(valueType)) { // Short-circuit if the class tag is using an element type 'any' @@ -15260,19 +14948,27 @@ namespace ts { } } - const instantiatedSignatures = []; - for (const signature of signatures) { - if (signature.typeParameters) { - const isJavascript = isInJavaScriptFile(node); - const typeArguments = fillMissingTypeArguments(/*typeArguments*/ undefined, signature.typeParameters, /*minTypeArgumentCount*/ 0, isJavascript); - instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript)); + if (sourceAttributesType) { + // Instantiate in context of source type + const instantiatedSignatures = []; + for (const signature of signatures) { + if (signature.typeParameters) { + const isJavascript = isInJavaScriptFile(node); + const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : 0); + const typeArguments = inferJsxTypeArguments(signature, sourceAttributesType, inferenceContext); + instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript)); + } + else { + instantiatedSignatures.push(signature); + } } - else { - instantiatedSignatures.push(signature); - } - } - return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype); + return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype); + } + else { + // Do not instantiate if no source type is provided - type parameters and their constraints will be used by contextual typing + return getUnionType(map(signatures, getReturnTypeOfSignature), UnionReduction.Subtype); + } } /** @@ -15449,6 +15145,7 @@ namespace ts { * * @param openingLikeElement a non-intrinsic JSXOPeningLikeElement * @param shouldIncludeAllStatelessAttributesType a boolean indicating whether to include all attributes types from all stateless function signature + * @param sourceAttributesType Is the attributes type the user passed, and is used to create inferences in the target type if present * @param elementType an instance type of the given opening-like element. If undefined, the function will check type openinglikeElement's tagname. * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global (imported from react.d.ts) * @return attributes type if able to resolve the type of node @@ -15457,13 +15154,14 @@ namespace ts { */ function resolveCustomJsxElementAttributesType(openingLikeElement: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType: boolean, - elementType: Type = checkExpression(openingLikeElement.tagName), + sourceAttributesType: Type | undefined, + elementType: Type, elementClassType?: Type): Type { if (elementType.flags & TypeFlags.Union) { const types = (elementType as UnionType).types; return getUnionType(types.map(type => { - return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, type, elementClassType); + return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, sourceAttributesType, type, elementClassType); }), UnionReduction.Subtype); } @@ -15494,7 +15192,7 @@ namespace ts { } // Get the element instance type (the result of newing or invoking this tag) - const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType); + const elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType, sourceAttributesType); // If we should include all stateless attributes type, then get all attributes type from all stateless function signature. // Otherwise get only attributes type from the signature picked by choose-overload logic. @@ -15507,7 +15205,7 @@ namespace ts { } // Issue an error if this return type isn't assignable to JSX.ElementClass - if (elementClassType) { + if (elementClassType && sourceAttributesType) { checkTypeRelatedTo(elemInstanceType, elementClassType, assignableRelation, openingLikeElement, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); } @@ -15590,14 +15288,20 @@ namespace ts { * @param node a custom JSX opening-like element * @param shouldIncludeAllStatelessAttributesType a boolean value used by language service to get all possible attributes type from an overload stateless function component */ - function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType: boolean): Type { - const links = getNodeLinks(node); - const linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; - if (!links[linkLocation]) { - const elemClassType = getJsxGlobalElementClassType(); - return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType); + function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, sourceAttributesType: Type, shouldIncludeAllStatelessAttributesType: boolean): Type { + if (!sourceAttributesType) { + // This ensures we cache non-inference uses of this calculation (ie, contextual types or services) + const links = getNodeLinks(node); + const linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; + if (!links[linkLocation]) { + const elemClassType = getJsxGlobalElementClassType(); + return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, sourceAttributesType, checkExpression(node.tagName), elemClassType); + } + return links[linkLocation]; + } + else { + return resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, sourceAttributesType, checkExpression(node.tagName), getJsxGlobalElementClassType()); } - return links[linkLocation]; } /** @@ -15612,7 +15316,7 @@ namespace ts { else { // Because in language service, the given JSX opening-like element may be incomplete and therefore, // we can't resolve to exact signature if the element is a stateless function component so the best thing to do is return all attributes type from all overloads. - return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ true); + return getCustomJsxElementAttributesType(node, /*sourceAttributesType*/ undefined, /*shouldIncludeAllStatelessAttributesType*/ true); } } @@ -15626,7 +15330,7 @@ namespace ts { return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); } else { - return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ false); + return getCustomJsxElementAttributesType(node, /*sourceAttributesType*/ undefined, /*shouldIncludeAllStatelessAttributesType*/ false); } } @@ -15765,16 +15469,17 @@ namespace ts { // 2. Solved JSX attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element. // 3. Check if the two are assignable to each other - // targetAttributesType is a type of an attributes from resolving tagName of an opening-like JSX element. - const targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ? - getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) : - getCustomJsxElementAttributesType(openingLikeElement, /*shouldIncludeAllStatelessAttributesType*/ false); // sourceAttributesType is a type of an attributes properties. // i.e
// attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". const sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement, checkMode); + // targetAttributesType is a type of an attributes from resolving tagName of an opening-like JSX element. + const targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ? + getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) : + getCustomJsxElementAttributesType(openingLikeElement, sourceAttributesType, /*shouldIncludeAllStatelessAttributesType*/ false); + // If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type. // but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass. if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || (sourceAttributesType).properties.length > 0)) { @@ -15939,17 +15644,35 @@ namespace ts { }); } - function checkNonNullExpression(node: Expression | QualifiedName) { - return checkNonNullType(checkExpression(node), node); + function checkNonNullExpression( + node: Expression | QualifiedName, + nullDiagnostic?: DiagnosticMessage, + undefinedDiagnostic?: DiagnosticMessage, + nullOrUndefinedDiagnostic?: DiagnosticMessage, + ) { + return checkNonNullType( + checkExpression(node), + node, + nullDiagnostic, + undefinedDiagnostic, + nullOrUndefinedDiagnostic + ); } - function checkNonNullType(type: Type, errorNode: Node): Type { + function checkNonNullType( + type: Type, + node: Node, + nullDiagnostic?: DiagnosticMessage, + undefinedDiagnostic?: DiagnosticMessage, + nullOrUndefinedDiagnostic?: DiagnosticMessage + ): Type { const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable; if (kind) { - error(errorNode, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ? - Diagnostics.Object_is_possibly_null_or_undefined : - Diagnostics.Object_is_possibly_undefined : - Diagnostics.Object_is_possibly_null); + error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ? + (nullOrUndefinedDiagnostic || Diagnostics.Object_is_possibly_null_or_undefined) : + (undefinedDiagnostic || Diagnostics.Object_is_possibly_undefined) : + (nullDiagnostic || Diagnostics.Object_is_possibly_null) + ); const t = getNonNullableType(type); return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? unknownType : t; } @@ -16127,7 +15850,7 @@ namespace ts { function getSuggestionForNonexistentSymbol(location: Node, outerName: __String, meaning: SymbolFlags): string { Debug.assert(outerName !== undefined, "outername should always be defined"); - const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, (symbols, name, meaning) => { + const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, (symbols, name, meaning) => { Debug.assertEqual(outerName, name, "name should equal outerName"); const symbol = getSymbol(symbols, name, meaning); // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function @@ -16238,26 +15961,26 @@ namespace ts { } function markPropertyAsReferenced(prop: Symbol, nodeForCheckWriteOnly: Node | undefined, isThisAccess: boolean) { - if (prop && - noUnusedIdentifiers && - (prop.flags & SymbolFlags.ClassMember) && - prop.valueDeclaration && hasModifier(prop.valueDeclaration, ModifierFlags.Private) - && !(nodeForCheckWriteOnly && isWriteOnlyAccess(nodeForCheckWriteOnly))) { + if (!prop || !noUnusedIdentifiers || !(prop.flags & SymbolFlags.ClassMember) || !prop.valueDeclaration || !hasModifier(prop.valueDeclaration, ModifierFlags.Private)) { + return; + } + if (nodeForCheckWriteOnly && isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor))) { + return; + } - if (isThisAccess) { - // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters). - const containingMethod = findAncestor(nodeForCheckWriteOnly, isFunctionLikeDeclaration); - if (containingMethod && containingMethod.symbol === prop) { - return; - } + if (isThisAccess) { + // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters). + const containingMethod = findAncestor(nodeForCheckWriteOnly, isFunctionLikeDeclaration); + if (containingMethod && containingMethod.symbol === prop) { + return; } + } - if (getCheckFlags(prop) & CheckFlags.Instantiated) { - getSymbolLinks(prop).target.isReferenced = true; - } - else { - prop.isReferenced = true; - } + if (getCheckFlags(prop) & CheckFlags.Instantiated) { + getSymbolLinks(prop).target.isReferenced = true; + } + else { + prop.isReferenced = true; } } @@ -16272,7 +15995,7 @@ namespace ts { } function isValidMethodAccess(method: Symbol, type: Type) { const propType = getTypeOfFuncClassEnumModule(method); - const signatures = getSignaturesOfType(propType, SignatureKind.Call); + const signatures = getSignaturesOfType(getNonNullableType(propType), SignatureKind.Call); Debug.assert(signatures.length !== 0); return signatures.some(sig => { const thisType = getThisTypeOfSignature(sig); @@ -16632,6 +16355,13 @@ namespace ts { return getSignatureInstantiation(signature, getInferredTypes(context), isInJavaScriptFile(contextualSignature.declaration)); } + function inferJsxTypeArguments(signature: Signature, sourceAttributesType: Type, context: InferenceContext): Type[] { + const paramType = getTypeAtPosition(signature, 0); + inferTypes(context.inferences, sourceAttributesType, paramType); + + return getInferredTypes(context); + } + function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray, excludeArgument: boolean[], context: InferenceContext): Type[] { // Clear out all the inference results from the last time inferTypeArguments was called on this context for (const inference of context.inferences) { @@ -16730,7 +16460,7 @@ namespace ts { const constraint = getConstraintOfTypeParameter(typeParameters[i]); if (!constraint) continue; - const errorInfo = reportErrors && headMessage && chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + const errorInfo = reportErrors && headMessage && (() => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1)); const typeArgumentHeadMessage = headMessage || Diagnostics.Type_0_does_not_satisfy_the_constraint_1; if (!mapper) { mapper = createTypeMapper(typeParameters, typeArgumentTypes); @@ -17406,7 +17136,7 @@ namespace ts { } excludeCount--; if (excludeCount > 0) { - excludeArgument[indexOf(excludeArgument, /*value*/ true)] = false; + excludeArgument[excludeArgument.indexOf(/*value*/ true)] = false; } else { excludeArgument = undefined; @@ -17451,7 +17181,13 @@ namespace ts { return resolveUntypedCall(node); } - const funcType = checkNonNullExpression(node.expression); + const funcType = checkNonNullExpression( + node.expression, + Diagnostics.Cannot_invoke_an_object_which_is_possibly_null, + Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined, + Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined + ); + if (funcType === silentNeverType) { return silentNeverSignature; } @@ -17488,7 +17224,7 @@ namespace ts { error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType)); } else { - error(node, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); + invocationError(node, apparentType, SignatureKind.Call); } return resolveErrorCall(node); } @@ -17578,7 +17314,7 @@ namespace ts { return signature; } - error(node, Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature); + invocationError(node, expressionType, SignatureKind.Construct); return resolveErrorCall(node); } @@ -17625,6 +17361,28 @@ namespace ts { return true; } + function invocationError(node: Node, apparentType: Type, kind: SignatureKind) { + error(node, kind === SignatureKind.Call + ? Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures + : Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature + , typeToString(apparentType)); + invocationErrorRecovery(apparentType, kind); + } + + function invocationErrorRecovery(apparentType: Type, kind: SignatureKind) { + if (!apparentType.symbol) { + return; + } + const importNode = getSymbolLinks(apparentType.symbol).originatingImport; + // Create a diagnostic on the originating import if possible onto which we can attach a quickfix + // An import call expression cannot be rewritten into another form to correct the error - the only solution is to use `.default` at the use-site + if (importNode && !isImportCall(importNode)) { + const sigs = getSignaturesOfType(getTypeOfSymbol(getSymbolLinks(apparentType.symbol).target), kind); + if (!sigs || !sigs.length) return; + error(importNode, Diagnostics.A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime); + } + } + function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[]): Signature { const tagType = checkExpression(node.tag); const apparentType = getApparentType(tagType); @@ -17642,7 +17400,7 @@ namespace ts { } if (!callSignatures.length) { - error(node, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); + invocationError(node, apparentType, SignatureKind.Call); return resolveErrorCall(node); } @@ -17699,6 +17457,7 @@ namespace ts { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); errorInfo = chainDiagnosticMessages(errorInfo, headMessage); diagnostics.add(createDiagnosticForNodeFromMessageChain(node, errorInfo)); + invocationErrorRecovery(apparentType, SignatureKind.Call); return resolveErrorCall(node); } @@ -17953,17 +17712,19 @@ namespace ts { if (moduleSymbol) { const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true); if (esModuleSymbol) { - return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol)); + return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol)); } } return createPromiseReturnType(node, anyType); } - function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol): Type { + function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol, originalSymbol: Symbol): Type { if (allowSyntheticDefaultImports && type && type !== unknownType) { const synthType = type as SyntheticDefaultModuleType; if (!synthType.syntheticType) { - if (!getPropertyOfType(type, InternalSymbolName.Default)) { + const file = find(originalSymbol.declarations, isSourceFile); + const hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false); + if (hasSyntheticDefault) { const memberTable = createSymbolTable(); const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default); newSymbol.target = resolveSymbol(symbol); @@ -17971,7 +17732,7 @@ namespace ts { const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); anonymousSymbol.type = defaultContainingObject; - synthType.syntheticType = getIntersectionType([type, defaultContainingObject]); + synthType.syntheticType = (type.flags & TypeFlags.StructuredType && type.symbol.flags & (SymbolFlags.Module | SymbolFlags.Variable)) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*typeFLags*/ 0, /*objectFlags*/ 0) : defaultContainingObject; } else { synthType.syntheticType = type; @@ -18182,7 +17943,6 @@ namespace ts { } function getReturnTypeFromBody(func: FunctionLikeDeclaration, checkMode?: CheckMode): Type { - const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); if (!func.body) { return unknownType; } @@ -18200,9 +17960,9 @@ namespace ts { } } else { - let types: Type[]; + let types = checkAndAggregateReturnExpressionTypes(func, checkMode); if (functionFlags & FunctionFlags.Generator) { // Generator or AsyncGenerator function - types = concatenate(checkAndAggregateYieldOperandTypes(func, checkMode), checkAndAggregateReturnExpressionTypes(func, checkMode)); + types = concatenate(checkAndAggregateYieldOperandTypes(func, checkMode), types); if (!types || types.length === 0) { const iterableIteratorAny = functionFlags & FunctionFlags.Async ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function @@ -18215,7 +17975,6 @@ namespace ts { } } else { - types = checkAndAggregateReturnExpressionTypes(func, checkMode); if (!types) { // For an async function, the return type will not be never, but rather a Promise for never. return functionFlags & FunctionFlags.Async @@ -18234,6 +17993,7 @@ namespace ts { type = getUnionType(types, UnionReduction.Subtype); } + const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); if (!contextualSignature) { reportErrorsFromWidening(func, type); } @@ -18323,7 +18083,8 @@ namespace ts { return true; } - function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] { + /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means return `void`, `undefined` means return `never`. */ + function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] | undefined { const functionFlags = getFunctionFlags(func); const aggregatedTypes: Type[] = []; let hasReturnWithNoExpression = functionHasImplicitReturn(func); @@ -18348,8 +18109,7 @@ namespace ts { hasReturnWithNoExpression = true; } }); - if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || - func.kind === SyntaxKind.FunctionExpression || func.kind === SyntaxKind.ArrowFunction)) { + if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || mayReturnNever(func))) { return undefined; } if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) { @@ -18357,6 +18117,17 @@ namespace ts { } return aggregatedTypes; } + function mayReturnNever(func: FunctionLikeDeclaration): boolean { + switch (func.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + return true; + case SyntaxKind.MethodDeclaration: + return func.parent.kind === SyntaxKind.ObjectLiteralExpression; + default: + return false; + } + } /** * TypeScript Specification 1.0 (6.3) - July 2014 @@ -19502,10 +19273,11 @@ namespace ts { const ok = (node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).expression === node) || (node.parent.kind === SyntaxKind.ElementAccessExpression && (node.parent).expression === node) || - ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node)); + ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node) || + (node.parent.kind === SyntaxKind.TypeQuery && (node.parent).exprName === node)); if (!ok) { - error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment); + error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query); } } return type; @@ -19657,7 +19429,7 @@ namespace ts { error(node, Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature); } if (node.name && isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) { - if (indexOf(func.parameters, node) !== 0) { + if (func.parameters.indexOf(node) !== 0) { error(node, Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText as string); } if (func.kind === SyntaxKind.Constructor || func.kind === SyntaxKind.ConstructSignature || func.kind === SyntaxKind.ConstructorType) { @@ -19710,7 +19482,7 @@ namespace ts { Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); } else { - const leadingError = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); + const leadingError = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); checkTypeAssignableTo(typePredicate.type, getTypeOfNode(parent.parameters[typePredicate.parameterIndex]), node.type, @@ -20078,24 +19850,6 @@ namespace ts { return; } - function containsSuperCallAsComputedPropertyName(n: Declaration): boolean { - const name = getNameOfDeclaration(n); - return name && containsSuperCall(name); - } - - function containsSuperCall(n: Node): boolean { - if (isSuperCall(n)) { - return true; - } - else if (isFunctionLike(n)) { - return false; - } - else if (isClassLike(n)) { - return forEach((n).members, containsSuperCallAsComputedPropertyName); - } - return forEachChild(n, containsSuperCall); - } - function isInstancePropertyWithInitializer(n: Node): boolean { return n.kind === SyntaxKind.PropertyDeclaration && !hasModifier(n, ModifierFlags.Static) && @@ -20335,6 +20089,11 @@ namespace ts { function checkMappedType(node: MappedTypeNode) { checkSourceElement(node.typeParameter); checkSourceElement(node.type); + + if (noImplicitAny && !node.type) { + reportImplicitAnyError(node, anyType); + } + const type = getTypeFromMappedTypeNode(node); const constraintType = getConstraintTypeFromMappedType(type); checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); @@ -20786,7 +20545,7 @@ namespace ts { const promisedType = getPromisedTypeOfPromise(type); if (promisedType) { - if (type.id === promisedType.id || indexOf(awaitedTypeStack, promisedType.id) >= 0) { + if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) { // Verify that we don't have a bad actor in the form of a promise whose // promised type is the same as the promise type, or a mutually recursive // promise. If so, we return undefined as we cannot guess the shape. If this @@ -21019,7 +20778,7 @@ namespace ts { expectedReturnType, node, headMessage, - errorInfo); + () => errorInfo); } /** @@ -21421,20 +21180,33 @@ namespace ts { function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void { if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) { - if (node.members) { - for (const member of node.members) { - if (member.kind === SyntaxKind.MethodDeclaration || member.kind === SyntaxKind.PropertyDeclaration) { - if (!member.symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { - error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(member.symbol)); + for (const member of node.members) { + switch (member.kind) { + case SyntaxKind.MethodDeclaration: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + if (member.kind === SyntaxKind.SetAccessor && member.symbol.flags & SymbolFlags.GetAccessor) { + // Already would have reported an error on the getter. + break; } - } - else if (member.kind === SyntaxKind.Constructor) { + const symbol = getSymbolOfNode(member); + if (!symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) { + error(member.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)); + } + break; + case SyntaxKind.Constructor: for (const parameter of (member).parameters) { if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) { error(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)); } } - } + break; + case SyntaxKind.IndexSignature: + // Can't be private + break; + default: + Debug.fail(); } } } @@ -22081,7 +21853,7 @@ namespace ts { checkGrammarForInOrForOfStatement(node); const rightType = checkNonNullExpression(node.expression); - // TypeScript 1.0 spec (April 2014): 5.4 + // TypeScript 1.0 spec (April 2014): 5.4 // In a 'for-in' statement of the form // for (let VarDecl in Expr) Statement // VarDecl must be a variable declaration without a type annotation that declares a variable of type Any, @@ -22710,7 +22482,8 @@ namespace ts { indexType: Type, indexKind: IndexKind): void { - if (!indexType) { + // ESSymbol properties apply to neither string nor numeric indexers. + if (!indexType || isKnownSymbol(prop)) { return; } @@ -22843,9 +22616,11 @@ namespace ts { // type parameter at this position, we report an error. const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint); const targetConstraint = getConstraintFromTypeParameter(target); - if ((sourceConstraint || targetConstraint) && - (!sourceConstraint || !targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint))) { - return false; + if (sourceConstraint) { + // relax check if later interface augmentation has no constraint + if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) { + return false; + } } // If the type parameter node has a default and it is not identical to the default @@ -22927,7 +22702,10 @@ namespace ts { } } } - checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name || node, Diagnostics.Class_0_incorrectly_extends_base_class_1); + const baseWithThis = getTypeWithThisArgument(baseType, type.thisType); + if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) { + issueMemberSpecificError(node, typeWithThis, baseWithThis, Diagnostics.Class_0_incorrectly_extends_base_class_1); + } checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); if (baseConstructorType.flags & TypeFlags.TypeVariable && !isMixinConstructorType(staticType)) { @@ -22959,12 +22737,13 @@ namespace ts { const t = getTypeFromTypeNode(typeRefNode); if (t !== unknownType) { if (isValidBaseType(t)) { - checkTypeAssignableTo(typeWithThis, - getTypeWithThisArgument(t, type.thisType), - node.name || node, - t.symbol && t.symbol.flags & SymbolFlags.Class ? - Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass : - Diagnostics.Class_0_incorrectly_implements_interface_1); + const genericDiag = t.symbol && t.symbol.flags & SymbolFlags.Class ? + Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass : + Diagnostics.Class_0_incorrectly_implements_interface_1; + const baseWithThis = getTypeWithThisArgument(t, type.thisType); + if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) { + issueMemberSpecificError(node, typeWithThis, baseWithThis, genericDiag); + } } else { error(typeRefNode, Diagnostics.A_class_may_only_implement_another_class_or_interface); @@ -22981,6 +22760,37 @@ namespace ts { } } + function issueMemberSpecificError(node: ClassLikeDeclaration, typeWithThis: Type, baseWithThis: Type, broadDiag: DiagnosticMessage) { + // iterate over all implemented properties and issue errors on each one which isn't compatible, rather than the class as a whole, if possible + let issuedMemberError = false; + for (const member of node.members) { + if (hasStaticModifier(member)) { + continue; + } + const declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member); + if (declaredProp) { + const prop = getPropertyOfType(typeWithThis, declaredProp.escapedName); + const baseProp = getPropertyOfType(baseWithThis, declaredProp.escapedName); + if (prop && baseProp) { + const rootChain = () => chainDiagnosticMessages( + /*details*/ undefined, + Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, + unescapeLeadingUnderscores(declaredProp.escapedName), + typeToString(typeWithThis), + typeToString(baseWithThis) + ); + if (!checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(baseProp), member.name || member, /*message*/ undefined, rootChain)) { + issuedMemberError = true; + } + } + } + } + if (!issuedMemberError) { + // check again with diagnostics to generate a less-specific error + checkTypeAssignableTo(typeWithThis, baseWithThis, node.name || node, broadDiag); + } + } + function checkBaseTypeAccessibility(type: Type, node: ExpressionWithTypeArguments) { const signatures = getSignaturesOfType(type, SignatureKind.Construct); if (signatures.length) { @@ -24673,6 +24483,7 @@ namespace ts { return undefined; case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: // 1). import x = require("./mo/*gotToDefinitionHere*/d") // 2). External module name in an import declaration // 3). Dynamic import call or require in javascript @@ -24818,7 +24629,7 @@ namespace ts { const typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent); const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType; return checkArrayLiteralDestructuringElementAssignment(expr.parent, typeOfArrayLiteral, - indexOf((expr.parent).elements, expr), elementType || unknownType); + (expr.parent).elements.indexOf(expr), elementType || unknownType); } // Gets the property symbol corresponding to the property in destructuring assignment @@ -25013,7 +24824,7 @@ namespace ts { // AND // - binding is not declared in loop, should be renamed to avoid name reuse across siblings // let a, b - // { let x = 1; a = () => x; } + // { let x = 1; a = () => x; } // { let x = 100; b = () => x; } // console.log(a()); // should print '1' // console.log(b()); // should print '100' @@ -25275,7 +25086,7 @@ namespace ts { } } - function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { + function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter) { // Get type of the symbol if this is the valid symbol otherwise get type at location const symbol = getSymbolOfNode(declaration); let type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature)) @@ -25288,18 +25099,17 @@ namespace ts { if (flags & TypeFormatFlags.AddUndefined) { type = getOptionalType(type); } - - getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); + typeToString(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals, writer); } - function writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { + function writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter) { const signature = getSignatureFromDeclaration(signatureDeclaration); - getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags); + typeToString(getReturnTypeOfSignature(signature), enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals, writer); } - function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { + function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter) { const type = getWidenedType(getRegularTypeOfExpression(expr)); - getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); + typeToString(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals, writer); } function hasGlobalName(name: string): boolean { @@ -25347,7 +25157,7 @@ namespace ts { return false; } - function writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter) { + function writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: EmitTextWriter) { const type = getTypeOfSymbol(getSymbolOfNode(node)); writer.writeStringLiteral(literalTypeToString(type)); } @@ -25474,7 +25284,7 @@ namespace ts { // walk the parent chain for symbols to make sure that top level parent symbol is in the global scope // external modules cannot define or contribute to type declaration files - let current = symbol; + let current = symbol; while (true) { const parent = getParentOfSymbol(current); if (parent) { @@ -25938,10 +25748,6 @@ namespace ts { } function checkGrammarTypeParameterList(typeParameters: NodeArray, file: SourceFile): boolean { - if (checkGrammarForDisallowedTrailingComma(typeParameters)) { - return true; - } - if (typeParameters && typeParameters.length === 0) { const start = typeParameters.pos - "<".length; const end = skipTrivia(file.text, typeParameters.end) + ">".length; @@ -26035,6 +25841,21 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } if (parameter.type.kind !== SyntaxKind.StringKeyword && parameter.type.kind !== SyntaxKind.NumberKeyword) { + const type = getTypeFromTypeNode(parameter.type); + + if (type.flags & TypeFlags.String || type.flags & TypeFlags.Number) { + return grammarErrorOnNode(parameter.name, + Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, + getTextOfNode(parameter.name), + typeToString(type), + typeToString(getTypeFromTypeNode(node.type))); + } + + if (allTypesAssignableToKind(type, TypeFlags.StringLiteral, /*strict*/ true)) { + return grammarErrorOnNode(parameter.name, + Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); + } + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_or_number); } if (!node.type) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index a0f91e3d0e9..eb9f1e3cf34 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -144,12 +144,14 @@ namespace ts { "es2017.string": "lib.es2017.string.d.ts", "es2017.intl": "lib.es2017.intl.d.ts", "es2017.typedarrays": "lib.es2017.typedarrays.d.ts", + "esnext.array": "lib.esnext.array.d.ts", "esnext.asynciterable": "lib.esnext.asynciterable.d.ts", + "esnext.promise": "lib.esnext.promise.d.ts", }), }, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, - description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon + description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation }, { name: "allowJs", @@ -400,6 +402,13 @@ namespace ts { category: Diagnostics.Module_Resolution_Options, description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, + { + name: "esModuleInterop", + type: "boolean", + showInSimplifiedHelpView: true, + category: Diagnostics.Module_Resolution_Options, + description: Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports + }, { name: "preserveSymlinks", type: "boolean", @@ -702,7 +711,8 @@ namespace ts { export const defaultInitCompilerOptions: CompilerOptions = { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, - strict: true + strict: true, + esModuleInterop: true }; let optionNameMapCache: OptionNameMap; @@ -1863,7 +1873,7 @@ namespace ts { return normalizeNonListOptionValue(option, basePath, value); } - function normalizeNonListOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue { + function normalizeNonListOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue { if (option.isFilePath) { value = normalizePath(combinePaths(basePath, value)); if (value === "") { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 2d59e9f5dd7..b35653f08c2 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -335,17 +335,6 @@ namespace ts { return false; } - export function indexOf(array: ReadonlyArray, value: T): number { - if (array) { - for (let i = 0; i < array.length; i++) { - if (array[i] === value) { - return i; - } - } - } - return -1; - } - export function indexOfAnyCharCode(text: string, charCodes: ReadonlyArray, start?: number): number { for (let i = start || 0; i < text.length; i++) { if (contains(charCodes, text.charCodeAt(i))) { @@ -423,12 +412,14 @@ namespace ts { return result; } + export function mapIterator(iter: Iterator, mapFn: (x: T) => U): Iterator { - return { next }; - function next(): { value: U, done: false } | { value: never, done: true } { - const iterRes = iter.next(); - return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false }; - } + return { + next() { + const iterRes = iter.next(); + return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false }; + } + }; } // Maps from T to T and avoids allocation if all elements map to themselves @@ -560,12 +551,23 @@ namespace ts { return result || array; } + export function mapAllOrFail(array: ReadonlyArray, mapFn: (x: T, i: number) => U | undefined): U[] | undefined { + const result: U[] = []; + for (let i = 0; i < array.length; i++) { + const mapped = mapFn(array[i], i); + if (mapped === undefined) { + return undefined; + } + result.push(mapped); + } + return result; + } + export function mapDefined(array: ReadonlyArray | undefined, mapFn: (x: T, i: number) => U | undefined): U[] { const result: U[] = []; if (array) { for (let i = 0; i < array.length; i++) { - const item = array[i]; - const mapped = mapFn(item, i); + const mapped = mapFn(array[i], i); if (mapped !== undefined) { result.push(mapped); } @@ -889,7 +891,7 @@ namespace ts { export function sum, K extends string>(array: ReadonlyArray, prop: K): number { let result = 0; for (const v of array) { - // Note: we need the following type assertion because of GH #17069 + // TODO: Remove the following type assertion once the fix for #17069 is merged result += v[prop] as number; } return result; @@ -2014,7 +2016,9 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); return compilerOptions.allowSyntheticDefaultImports !== undefined ? compilerOptions.allowSyntheticDefaultImports - : moduleKind === ModuleKind.System; + : compilerOptions.esModuleInterop + ? moduleKind !== ModuleKind.None && moduleKind < ModuleKind.ES2015 + : moduleKind === ModuleKind.System; } export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict"; @@ -2078,7 +2082,7 @@ namespace ts { function getNormalizedPathComponentsOfUrl(url: string) { // Get root length of http://www.website.com/folder1/folder2/ - // In this example the root is: http://www.website.com/ + // In this example the root is: http://www.website.com/ // normalized path components should be ["http://www.website.com/", "folder1", "folder2"] const urlLength = url.length; @@ -2111,7 +2115,7 @@ namespace ts { } else { // Can't find the host assume the rest of the string as component - // but make sure we append "/" to it as root is not joined using "/" + // but make sure we append "/" to it as root is not joined using "/" // eg. if url passed in was http://website.com we want to use root as [http://website.com/] // so that other path manipulations will be correct and it can be merged with relative paths correctly return [url + directorySeparator]; @@ -2132,7 +2136,7 @@ namespace ts { const directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory); if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") { // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name - // that is ["test", "cases", ""] needs to be actually ["test", "cases"] + // that is ["test", "cases", ""] needs to be actually ["test", "cases"] directoryComponents.pop(); } @@ -2765,10 +2769,10 @@ namespace ts { function Signature() {} // tslint:disable-line no-empty function Node(this: Node, kind: SyntaxKind, pos: number, end: number) { - this.id = 0; - this.kind = kind; this.pos = pos; this.end = end; + this.kind = kind; + this.id = 0; this.flags = NodeFlags.None; this.modifierFlagsCache = ModifierFlags.None; this.transformFlags = TransformFlags.None; @@ -3040,6 +3044,10 @@ namespace ts { return (arg: T) => f(arg) && g(arg); } + export function or(f: (arg: T) => boolean, g: (arg: T) => boolean) { + return (arg: T) => f(arg) || g(arg); + } + export function assertTypeIsNever(_: never): void { } // tslint:disable-line no-empty export interface FileAndDirectoryExistence { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 75b4ccf9ba8..1e69ce748fa 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -20,14 +20,14 @@ namespace ts { type GetSymbolAccessibilityDiagnostic = (symbolAccessibilityResult: SymbolAccessibilityResult) => SymbolAccessibilityDiagnostic; - interface EmitTextWriterWithSymbolWriter extends EmitTextWriter, SymbolWriter { + interface EmitTextWriterWithSymbolWriter extends EmitTextWriter { getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic; } interface SymbolAccessibilityDiagnostic { errorNode: Node; diagnosticMessage: DiagnosticMessage; - typeName?: DeclarationName; + typeName?: DeclarationName | QualifiedName; } export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[] { @@ -148,8 +148,8 @@ namespace ts { moduleElementDeclarationEmitInfo = []; } - if (!isBundledEmit && isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) { - // if file was external module with augmentations - this fact should be preserved in .d.ts as well. + if (!isBundledEmit && isExternalModule(sourceFile) && !resultHasExternalModuleIndicator) { + // if file was external module this fact should be preserved in .d.ts as well. // in case if we didn't write any external module specifiers in .d.ts we need to emit something // that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here. write("export {};"); @@ -358,7 +358,7 @@ namespace ts { } else { errorNameNode = declaration.name; - const format = TypeFormatFlags.UseTypeOfFunction | + const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteDefaultSymbolWithoutName | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | (shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0); resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer); @@ -378,7 +378,7 @@ namespace ts { resolver.writeReturnTypeOfSignatureDeclaration( signature, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, writer); errorNameNode = undefined; } @@ -655,7 +655,7 @@ namespace ts { resolver.writeTypeOfExpression( expr, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, writer); write(";"); writeLine(); @@ -663,6 +663,9 @@ namespace ts { } function emitExportAssignment(node: ExportAssignment) { + if (isSourceFile(node.parent)) { + resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators + } if (node.expression.kind === SyntaxKind.Identifier) { write(node.isExportEquals ? "export = " : "export default "); writeTextOfNode(currentText, node.expression); @@ -757,6 +760,7 @@ namespace ts { const modifiers = getModifierFlags(node); // If the node is exported if (modifiers & ModifierFlags.Export) { + resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators write("export "); } @@ -913,6 +917,7 @@ namespace ts { } function emitExportDeclaration(node: ExportDeclaration) { + resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators emitJsDocComments(node); write("export "); if (node.exportClause) { @@ -1211,7 +1216,7 @@ namespace ts { write(">"); } } - else { + else { emitHeritageClause([baseTypeNode], /*isImplementsList*/ false); } } @@ -1878,6 +1883,7 @@ namespace ts { // it allows emitSeparatedList to write separator appropriately) // Example: // original: function foo([, x, ,]) {} + // tslint:disable-next-line no-double-space // emit : function foo([ , x, , ]) {} write(" "); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 826efa6994b..6a14aab2aee 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -939,6 +939,14 @@ "category": "Error", "code": 1335 }, + "An index signature parameter type cannot be a type alias. Consider writing '[{0}: {1}]: {2}' instead.": { + "category": "Error", + "code": 1336 + }, + "An index signature parameter type cannot be a union type. Consider using a mapped object type instead.": { + "category": "Error", + "code": 1337 + }, "Duplicate identifier '{0}'.": { "category": "Error", @@ -1396,6 +1404,10 @@ "category": "Error", "code": 2415 }, + "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.": { + "category": "Error", + "code": 2416 + }, "Class static side '{0}' incorrectly extends base class static side '{1}'.": { "category": "Error", "code": 2417 @@ -1612,7 +1624,7 @@ "category": "Error", "code": 2474 }, - "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.": { + "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.": { "category": "Error", "code": 2475 }, @@ -2280,7 +2292,18 @@ "category": "Error", "code": 2720 }, - + "Cannot invoke an object which is possibly 'null'.": { + "category": "Error", + "code": 2721 + }, + "Cannot invoke an object which is possibly 'undefined'.": { + "category": "Error", + "code": 2722 + }, + "Cannot invoke an object which is possibly 'null' or 'undefined'.": { + "category": "Error", + "code": 2723 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 @@ -2992,7 +3015,7 @@ "category": "Message", "code": 6078 }, - "Specify library files to be included in the compilation: ": { + "Specify library files to be included in the compilation.": { "category": "Message", "code": 6079 }, @@ -3428,6 +3451,10 @@ "category": "Error", "code": 6189 }, + "Found 'package.json' at '{0}'. Package ID is '{1}'.": { + "category": "Message", + "code": 6190 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 @@ -3540,7 +3567,18 @@ "category": "Error", "code": 7036 }, - + "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.": { + "category": "Message", + "code": 7037 + }, + "A namespace-style import cannot be called or constructed, and will cause a failure at runtime.": { + "category": "Error", + "code": 7038 + }, + "Mapped object type implicitly has an 'any' template type.": { + "category": "Error", + "code": 7039 + }, "You cannot rename this element.": { "category": "Error", "code": 8000 @@ -3843,6 +3881,10 @@ "category": "Message", "code": 90028 }, + "Add async modifier to containing function": { + "category": "Message", + "code": 90029 + }, "Convert function to an ES2015 class": { "category": "Message", "code": 95001 @@ -3898,5 +3940,17 @@ "Install '{0}'": { "category": "Message", "code": 95014 + }, + "Replace import with '{0}'.": { + "category": "Message", + "code": 95015 + }, + "Use synthetic 'default' member.": { + "category": "Message", + "code": 95016 + }, + "Convert to ES6 module": { + "category": "Message", + "code": 95017 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 10ecd3c8ffe..eac1a35164b 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5,7 +5,6 @@ /// namespace ts { - const delimiters = createDelimiterMap(); const brackets = createBracketsMap(); /*@internal*/ @@ -18,8 +17,8 @@ namespace ts { * If an array, the full list of source files to emit. * Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit. */ - export function forEachEmittedFile( - host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void, + export function forEachEmittedFile( + host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => T, sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile, emitOnlyDtsFiles?: boolean) { @@ -30,7 +29,10 @@ namespace ts { const jsFilePath = options.outFile || options.out; const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + Extension.Dts : ""; - action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles); + const result = action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles); + if (result) { + return result; + } } } else { @@ -38,7 +40,10 @@ namespace ts { const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options)); const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; - action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles); + const result = action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles); + if (result) { + return result; + } } } } @@ -194,7 +199,7 @@ namespace ts { // Reset state sourceMap.reset(); - writer.reset(); + writer.clear(); currentSourceFile = undefined; bundledHelpers = undefined; @@ -284,18 +289,32 @@ namespace ts { let generatedNames: Map; // Set of names generated by the NameGenerator. let tempFlagsStack: TempFlags[]; // Stack of enclosing name generation scopes. let tempFlags: TempFlags; // TempFlags for the current name generation scope. + let reservedNamesStack: Map[]; // Stack of TempFlags reserved in enclosing name generation scopes. + let reservedNames: Map; // TempFlags to reserve in nested name generation scopes. + let writer: EmitTextWriter; let ownWriter: EmitTextWriter; + let write = writeBase; + let commitPendingSemicolon: typeof commitPendingSemicolonInternal = noop; + let writeSemicolon: typeof writeSemicolonInternal = writeSemicolonInternal; + let pendingSemicolon = false; + if (printerOptions.omitTrailingSemicolon) { + commitPendingSemicolon = commitPendingSemicolonInternal; + writeSemicolon = deferWriteSemicolon; + } + const syntheticParent: TextRange = { pos: -1, end: -1 }; reset(); return { // public API printNode, + printList, printFile, printBundle, // internal API writeNode, + writeList, writeFile, writeBundle }; @@ -320,6 +339,11 @@ namespace ts { return endPrint(); } + function printList(format: ListFormat, nodes: NodeArray, sourceFile: SourceFile) { + writeList(format, nodes, sourceFile, beginPrint()); + return endPrint(); + } + function printBundle(bundle: Bundle): string { writeBundle(bundle, beginPrint()); return endPrint(); @@ -343,6 +367,17 @@ namespace ts { writer = previousWriter; } + function writeList(format: ListFormat, nodes: NodeArray, sourceFile: SourceFile | undefined, output: EmitTextWriter) { + const previousWriter = writer; + setWriter(output); + if (sourceFile) { + setSourceFile(sourceFile); + } + emitList(syntheticParent, nodes, format); + reset(); + writer = previousWriter; + } + function writeBundle(bundle: Bundle, output: EmitTextWriter) { const previousWriter = writer; setWriter(output); @@ -372,7 +407,7 @@ namespace ts { function endPrint() { const text = ownWriter.getText(); - ownWriter.reset(); + ownWriter.clear(); return text; } @@ -402,6 +437,7 @@ namespace ts { generatedNames = createMap(); tempFlagsStack = []; tempFlags = TempFlags.Auto; + reservedNamesStack = []; comments.reset(); setWriter(/*output*/ undefined); } @@ -476,7 +512,9 @@ namespace ts { function emitMappedTypeParameter(node: TypeParameterDeclaration): void { emit(node.name); - write(" in "); + writeSpace(); + writeKeyword("in"); + writeSpace(); emit(node.constraint); } @@ -487,7 +525,7 @@ namespace ts { // Strict mode reserved words // Contextual keywords if (isKeyword(kind)) { - writeTokenNode(node); + writeTokenNode(node, writeKeyword); return; } @@ -748,7 +786,7 @@ namespace ts { } if (isToken(node)) { - writeTokenNode(node); + writeTokenNode(node, writePunctuation); return; } } @@ -776,7 +814,7 @@ namespace ts { case SyntaxKind.TrueKeyword: case SyntaxKind.ThisKeyword: case SyntaxKind.ImportKeyword: - writeTokenNode(node); + writeTokenNode(node, writeKeyword); return; // Expressions @@ -881,10 +919,11 @@ namespace ts { const text = getLiteralTextOfNode(node); if ((printerOptions.sourceMap || printerOptions.inlineSourceMap) && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) { - writer.writeLiteral(text); + writeLiteral(text); } else { - write(text); + // Quick info expects all literals to be called with writeStringLiteral, as there's no specific type for numberLiterals + writeStringLiteral(text); } } @@ -893,8 +932,9 @@ namespace ts { // function emitIdentifier(node: Identifier) { - write(getTextOfNode(node, /*includeTrivia*/ false)); - emitTypeArguments(node, node.typeArguments); + const writeText = node.symbol ? writeSymbol : write; + writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol); + emitList(node, node.typeArguments, ListFormat.TypeParameters); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments } // @@ -903,7 +943,7 @@ namespace ts { function emitQualifiedName(node: QualifiedName) { emitEntityName(node.left); - write("."); + writePunctuation("."); emit(node.right); } @@ -917,9 +957,9 @@ namespace ts { } function emitComputedPropertyName(node: ComputedPropertyName) { - write("["); + writePunctuation("["); emitExpression(node.expression); - write("]"); + writePunctuation("]"); } // @@ -928,8 +968,18 @@ namespace ts { function emitTypeParameter(node: TypeParameterDeclaration) { emit(node.name); - emitWithPrefix(" extends ", node.constraint); - emitWithPrefix(" = ", node.default); + if (node.constraint) { + writeSpace(); + writeKeyword("extends"); + writeSpace(); + emit(node.constraint); + } + if (node.default) { + writeSpace(); + writeOperator("="); + writeSpace(); + emit(node.default); + } } function emitParameter(node: ParameterDeclaration) { @@ -937,20 +987,20 @@ namespace ts { emitModifiers(node, node.modifiers); emitIfPresent(node.dotDotDotToken); if (node.name) { - emit(node.name); + emitNodeWithWriter(node.name, writeParameter); } emitIfPresent(node.questionToken); if (node.parent && node.parent.kind === SyntaxKind.JSDocFunctionType && !node.name) { emit(node.type); } else { - emitWithPrefix(": ", node.type); + emitTypeAnnotation(node.type); } - emitExpressionWithPrefix(" = ", node.initializer); + emitInitializer(node.initializer); } function emitDecorator(decorator: Decorator) { - write("@"); + writePunctuation("@"); emitExpression(decorator.expression); } @@ -961,10 +1011,10 @@ namespace ts { function emitPropertySignature(node: PropertySignature) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - emit(node.name); + emitNodeWithWriter(node.name, writeProperty); emitIfPresent(node.questionToken); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitPropertyDeclaration(node: PropertyDeclaration) { @@ -972,9 +1022,9 @@ namespace ts { emitModifiers(node, node.modifiers); emit(node.name); emitIfPresent(node.questionToken); - emitWithPrefix(": ", node.type); - emitExpressionWithPrefix(" = ", node.initializer); - write(";"); + emitTypeAnnotation(node.type); + emitInitializer(node.initializer); + writeSemicolon(); } function emitMethodSignature(node: MethodSignature) { @@ -984,8 +1034,8 @@ namespace ts { emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitMethodDeclaration(node: MethodDeclaration) { @@ -999,14 +1049,15 @@ namespace ts { function emitConstructor(node: ConstructorDeclaration) { emitModifiers(node, node.modifiers); - write("constructor"); + writeKeyword("constructor"); emitSignatureAndBody(node, emitSignatureHead); } function emitAccessorDeclaration(node: AccessorDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write(node.kind === SyntaxKind.GetAccessor ? "get " : "set "); + writeKeyword(node.kind === SyntaxKind.GetAccessor ? "get" : "set"); + writeSpace(); emit(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -1016,30 +1067,31 @@ namespace ts { emitModifiers(node, node.modifiers); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitConstructSignature(node: ConstructSignatureDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("new "); + writeKeyword("new"); + writeSpace(); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitIndexSignature(node: IndexSignatureDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitParametersForIndexSignature(node, node.parameters); - emitWithPrefix(": ", node.type); - write(";"); + emitTypeAnnotation(node.type); + writeSemicolon(); } function emitSemicolonClassElement() { - write(";"); + writeSemicolon(); } // @@ -1048,7 +1100,9 @@ namespace ts { function emitTypePredicate(node: TypePredicateNode) { emit(node.parameterName); - write(" is "); + writeSpace(); + writeKeyword("is"); + writeSpace(); emit(node.type); } @@ -1060,7 +1114,9 @@ namespace ts { function emitFunctionType(node: FunctionTypeNode) { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); - write(" => "); + writeSpace(); + writePunctuation("=>"); + writeSpace(); emit(node.type); } @@ -1088,28 +1144,33 @@ namespace ts { } function emitConstructorType(node: ConstructorTypeNode) { - write("new "); + writeKeyword("new"); + writeSpace(); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - write(" => "); + writeSpace(); + writePunctuation("=>"); + writeSpace(); emit(node.type); } function emitTypeQuery(node: TypeQueryNode) { - write("typeof "); + writeKeyword("typeof"); + writeSpace(); emit(node.exprName); } function emitTypeLiteral(node: TypeLiteralNode) { - write("{"); + writePunctuation("{"); const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers; emitList(node, node.members, flags | ListFormat.NoSpaceIfEmpty); - write("}"); + writePunctuation("}"); } function emitArrayType(node: ArrayTypeNode) { emit(node.elementType); - write("[]"); + writePunctuation("["); + writePunctuation("]"); } function emitJSDocVariadicType(node: JSDocVariadicType) { @@ -1118,9 +1179,9 @@ namespace ts { } function emitTupleType(node: TupleTypeNode) { - write("["); + writePunctuation("["); emitList(node, node.elementTypes, ListFormat.TupleTypeElements); - write("]"); + writePunctuation("]"); } function emitUnionType(node: UnionTypeNode) { @@ -1142,33 +1203,33 @@ namespace ts { } function emitParenthesizedType(node: ParenthesizedTypeNode) { - write("("); + writePunctuation("("); emit(node.type); - write(")"); + writePunctuation(")"); } function emitThisType() { - write("this"); + writeKeyword("this"); } function emitTypeOperator(node: TypeOperatorNode) { - writeTokenText(node.operator); - write(" "); + writeTokenText(node.operator, writeKeyword); + writeSpace(); emit(node.type); } function emitIndexedAccessType(node: IndexedAccessTypeNode) { emit(node.objectType); - write("["); + writePunctuation("["); emit(node.indexType); - write("]"); + writePunctuation("]"); } function emitMappedType(node: MappedTypeNode) { const emitFlags = getEmitFlags(node); - write("{"); + writePunctuation("{"); if (emitFlags & EmitFlags.SingleLine) { - write(" "); + writeSpace(); } else { writeLine(); @@ -1176,25 +1237,26 @@ namespace ts { } if (node.readonlyToken) { emit(node.readonlyToken); - write(" "); + writeSpace(); } - write("["); + writePunctuation("["); pipelineEmitWithNotification(EmitHint.MappedTypeParameter, node.typeParameter); - write("]"); + writePunctuation("]"); emitIfPresent(node.questionToken); - write(": "); + writePunctuation(":"); + writeSpace(); emit(node.type); - write(";"); + writeSemicolon(); if (emitFlags & EmitFlags.SingleLine) { - write(" "); + writeSpace(); } else { writeLine(); decreaseIndent(); } - write("}"); + writePunctuation("}"); } function emitLiteralType(node: LiteralTypeNode) { @@ -1206,34 +1268,26 @@ namespace ts { // function emitObjectBindingPattern(node: ObjectBindingPattern) { - const elements = node.elements; - if (elements.length === 0) { - write("{}"); - } - else { - write("{"); - emitList(node, elements, ListFormat.ObjectBindingPatternElements); - write("}"); - } + writePunctuation("{"); + emitList(node, node.elements, ListFormat.ObjectBindingPatternElements); + writePunctuation("}"); } function emitArrayBindingPattern(node: ArrayBindingPattern) { - const elements = node.elements; - if (elements.length === 0) { - write("[]"); - } - else { - write("["); - emitList(node, node.elements, ListFormat.ArrayBindingPatternElements); - write("]"); - } + writePunctuation("["); + emitList(node, node.elements, ListFormat.ArrayBindingPatternElements); + writePunctuation("]"); } function emitBindingElement(node: BindingElement) { - emitWithSuffix(node.propertyName, ": "); + if (node.propertyName) { + emit(node.propertyName); + writePunctuation(":"); + writeSpace(); + } emitIfPresent(node.dotDotDotToken); emit(node.name); - emitExpressionWithPrefix(" = ", node.initializer); + emitInitializer(node.initializer); } // @@ -1278,7 +1332,7 @@ namespace ts { increaseIndentIf(indentBeforeDot); const shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression); - write(shouldEmitDotDot ? ".." : "."); + writePunctuation(shouldEmitDotDot ? ".." : "."); increaseIndentIf(indentAfterDot); emit(node.name); @@ -1307,9 +1361,9 @@ namespace ts { function emitElementAccessExpression(node: ElementAccessExpression) { emitExpression(node.expression); - write("["); + writePunctuation("["); emitExpression(node.argumentExpression); - write("]"); + writePunctuation("]"); } function emitCallExpression(node: CallExpression) { @@ -1319,7 +1373,8 @@ namespace ts { } function emitNewExpression(node: NewExpression) { - write("new "); + writeKeyword("new"); + writeSpace(); emitExpression(node.expression); emitTypeArguments(node, node.typeArguments); emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments); @@ -1327,21 +1382,21 @@ namespace ts { function emitTaggedTemplateExpression(node: TaggedTemplateExpression) { emitExpression(node.tag); - write(" "); + writeSpace(); emitExpression(node.template); } function emitTypeAssertionExpression(node: TypeAssertion) { - write("<"); + writePunctuation("<"); emit(node.type); - write(">"); + writePunctuation(">"); emitExpression(node.expression); } function emitParenthesizedExpression(node: ParenthesizedExpression) { - write("("); + writePunctuation("("); emitExpression(node.expression); - write(")"); + writePunctuation(")"); } function emitFunctionExpression(node: FunctionExpression) { @@ -1357,35 +1412,39 @@ namespace ts { function emitArrowFunctionHead(node: ArrowFunction) { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); - emitWithPrefix(": ", node.type); - write(" "); + emitTypeAnnotation(node.type); + writeSpace(); emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node: DeleteExpression) { - write("delete "); + writeKeyword("delete"); + writeSpace(); emitExpression(node.expression); } function emitTypeOfExpression(node: TypeOfExpression) { - write("typeof "); + writeKeyword("typeof"); + writeSpace(); emitExpression(node.expression); } function emitVoidExpression(node: VoidExpression) { - write("void "); + writeKeyword("void"); + writeSpace(); emitExpression(node.expression); } function emitAwaitExpression(node: AwaitExpression) { - write("await "); + writeKeyword("await"); + writeSpace(); emitExpression(node.expression); } function emitPrefixUnaryExpression(node: PrefixUnaryExpression) { - writeTokenText(node.operator); + writeTokenText(node.operator, writeOperator); if (shouldEmitWhitespaceBeforeOperand(node)) { - write(" "); + writeSpace(); } emitExpression(node.operand); } @@ -1411,7 +1470,7 @@ namespace ts { function emitPostfixUnaryExpression(node: PostfixUnaryExpression) { emitExpression(node.operand); - writeTokenText(node.operator); + writeTokenText(node.operator, writeOperator); } function emitBinaryExpression(node: BinaryExpression) { @@ -1422,7 +1481,7 @@ namespace ts { emitExpression(node.left); increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined); emitLeadingCommentsOfPosition(node.operatorToken.pos); - writeTokenNode(node.operatorToken); + writeTokenNode(node.operatorToken, writeOperator); emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts increaseIndentIf(indentAfterOperator, " "); emitExpression(node.right); @@ -1455,13 +1514,13 @@ namespace ts { } function emitYieldExpression(node: YieldExpression) { - write("yield"); + writeKeyword("yield"); emit(node.asteriskToken); - emitExpressionWithPrefix(" ", node.expression); + emitExpressionWithLeadingSpace(node.expression); } function emitSpreadExpression(node: SpreadElement) { - write("..."); + writePunctuation("..."); emitExpression(node.expression); } @@ -1477,19 +1536,21 @@ namespace ts { function emitAsExpression(node: AsExpression) { emitExpression(node.expression); if (node.type) { - write(" as "); + writeSpace(); + writeKeyword("as"); + writeSpace(); emit(node.type); } } function emitNonNullExpression(node: NonNullExpression) { emitExpression(node.expression); - write("!"); + writeOperator("!"); } function emitMetaProperty(node: MetaProperty) { - writeToken(node.keywordToken, node.pos); - write("."); + writeToken(node.keywordToken, node.pos, writePunctuation); + writePunctuation("."); emit(node.name); } @@ -1507,13 +1568,13 @@ namespace ts { // function emitBlock(node: Block) { - writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node); + writeToken(SyntaxKind.OpenBraceToken, node.pos, writePunctuation, /*contextNode*/ node); emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node)); // We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted increaseIndent(); emitLeadingCommentsOfPosition(node.statements.end); decreaseIndent(); - writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node); + writeToken(SyntaxKind.CloseBraceToken, node.statements.end, writePunctuation, /*contextNode*/ node); } function emitBlockStatements(node: BlockLike, forceSingleLine: boolean) { @@ -1524,30 +1585,30 @@ namespace ts { function emitVariableStatement(node: VariableStatement) { emitModifiers(node, node.modifiers); emit(node.declarationList); - write(";"); + writeSemicolon(); } function emitEmptyStatement() { - write(";"); + writeSemicolon(); } function emitExpressionStatement(node: ExpressionStatement) { emitExpression(node.expression); - write(";"); + writeSemicolon(); } function emitIfStatement(node: IfStatement) { - const openParenPos = writeToken(SyntaxKind.IfKeyword, node.pos, node); - write(" "); - writeToken(SyntaxKind.OpenParenToken, openParenPos, node); + const openParenPos = writeToken(SyntaxKind.IfKeyword, node.pos, writeKeyword, node); + writeSpace(); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, node); emitExpression(node.expression); - writeToken(SyntaxKind.CloseParenToken, node.expression.end, node); + writeToken(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation, node); emitEmbeddedStatement(node, node.thenStatement); if (node.elseStatement) { writeLineOrSpace(node); - writeToken(SyntaxKind.ElseKeyword, node.thenStatement.end, node); + writeToken(SyntaxKind.ElseKeyword, node.thenStatement.end, writeKeyword, node); if (node.elseStatement.kind === SyntaxKind.IfStatement) { - write(" "); + writeSpace(); emit(node.elseStatement); } else { @@ -1557,60 +1618,68 @@ namespace ts { } function emitDoStatement(node: DoStatement) { - write("do"); + writeKeyword("do"); emitEmbeddedStatement(node, node.statement); if (isBlock(node.statement)) { - write(" "); + writeSpace(); } else { writeLineOrSpace(node); } - write("while ("); + writeKeyword("while"); + writeSpace(); + writePunctuation("("); emitExpression(node.expression); - write(");"); + writePunctuation(");"); } function emitWhileStatement(node: WhileStatement) { - write("while ("); + writeKeyword("while"); + writeSpace(); + writePunctuation("("); emitExpression(node.expression); - write(")"); + writePunctuation(")"); emitEmbeddedStatement(node, node.statement); } function emitForStatement(node: ForStatement) { - const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos); - write(" "); - writeToken(SyntaxKind.OpenParenToken, openParenPos, /*contextNode*/ node); + const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos, writeKeyword); + writeSpace(); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation, /*contextNode*/ node); emitForBinding(node.initializer); - write(";"); - emitExpressionWithPrefix(" ", node.condition); - write(";"); - emitExpressionWithPrefix(" ", node.incrementor); - write(")"); + writeSemicolon(); + emitExpressionWithLeadingSpace(node.condition); + writeSemicolon(); + emitExpressionWithLeadingSpace(node.incrementor); + writePunctuation(")"); emitEmbeddedStatement(node, node.statement); } function emitForInStatement(node: ForInStatement) { - const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos); - write(" "); - writeToken(SyntaxKind.OpenParenToken, openParenPos); + const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos, writeKeyword); + writeSpace(); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation); emitForBinding(node.initializer); - write(" in "); + writeSpace(); + writeKeyword("in"); + writeSpace(); emitExpression(node.expression); - writeToken(SyntaxKind.CloseParenToken, node.expression.end); + writeToken(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation); emitEmbeddedStatement(node, node.statement); } function emitForOfStatement(node: ForOfStatement) { - const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos); - write(" "); - emitWithSuffix(node.awaitModifier, " "); - writeToken(SyntaxKind.OpenParenToken, openParenPos); + const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos, writeKeyword); + writeSpace(); + emitWithTrailingSpace(node.awaitModifier); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation); emitForBinding(node.initializer); - write(" of "); + writeSpace(); + writeKeyword("of"); + writeSpace(); emitExpression(node.expression); - writeToken(SyntaxKind.CloseParenToken, node.expression.end); + writeToken(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation); emitEmbeddedStatement(node, node.statement); } @@ -1626,23 +1695,23 @@ namespace ts { } function emitContinueStatement(node: ContinueStatement) { - writeToken(SyntaxKind.ContinueKeyword, node.pos); - emitWithPrefix(" ", node.label); - write(";"); + writeToken(SyntaxKind.ContinueKeyword, node.pos, writeKeyword); + emitWithLeadingSpace(node.label); + writeSemicolon(); } function emitBreakStatement(node: BreakStatement) { - writeToken(SyntaxKind.BreakKeyword, node.pos); - emitWithPrefix(" ", node.label); - write(";"); + writeToken(SyntaxKind.BreakKeyword, node.pos, writeKeyword); + emitWithLeadingSpace(node.label); + writeSemicolon(); } - function emitTokenWithComment(token: SyntaxKind, pos: number, contextNode?: Node) { + function emitTokenWithComment(token: SyntaxKind, pos: number, writer: (s: string) => void, contextNode?: Node) { const node = contextNode && getParseTreeNode(contextNode); if (node && node.kind === contextNode.kind) { pos = skipTrivia(currentSourceFile.text, pos); } - pos = writeToken(token, pos, /*contextNode*/ contextNode); + pos = writeToken(token, pos, writer, /*contextNode*/ contextNode); if (node && node.kind === contextNode.kind) { emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true); } @@ -1650,42 +1719,46 @@ namespace ts { } function emitReturnStatement(node: ReturnStatement) { - emitTokenWithComment(SyntaxKind.ReturnKeyword, node.pos, /*contextNode*/ node); - emitExpressionWithPrefix(" ", node.expression); - write(";"); + emitTokenWithComment(SyntaxKind.ReturnKeyword, node.pos, writeKeyword, /*contextNode*/ node); + emitExpressionWithLeadingSpace(node.expression); + writeSemicolon(); } function emitWithStatement(node: WithStatement) { - write("with ("); + writeKeyword("with"); + writeSpace(); + writePunctuation("("); emitExpression(node.expression); - write(")"); + writePunctuation(")"); emitEmbeddedStatement(node, node.statement); } function emitSwitchStatement(node: SwitchStatement) { - const openParenPos = writeToken(SyntaxKind.SwitchKeyword, node.pos); - write(" "); - writeToken(SyntaxKind.OpenParenToken, openParenPos); + const openParenPos = writeToken(SyntaxKind.SwitchKeyword, node.pos, writeKeyword); + writeSpace(); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation); emitExpression(node.expression); - writeToken(SyntaxKind.CloseParenToken, node.expression.end); - write(" "); + writeToken(SyntaxKind.CloseParenToken, node.expression.end, writePunctuation); + writeSpace(); emit(node.caseBlock); } function emitLabeledStatement(node: LabeledStatement) { emit(node.label); - write(": "); + writePunctuation(":"); + writeSpace(); emit(node.statement); } function emitThrowStatement(node: ThrowStatement) { - write("throw"); - emitExpressionWithPrefix(" ", node.expression); - write(";"); + writeKeyword("throw"); + emitExpressionWithLeadingSpace(node.expression); + writeSemicolon(); } function emitTryStatement(node: TryStatement) { - write("try "); + writeKeyword("try"); + writeSpace(); emit(node.tryBlock); if (node.catchClause) { writeLineOrSpace(node); @@ -1693,14 +1766,15 @@ namespace ts { } if (node.finallyBlock) { writeLineOrSpace(node); - write("finally "); + writeKeyword("finally"); + writeSpace(); emit(node.finallyBlock); } } function emitDebuggerStatement(node: DebuggerStatement) { - writeToken(SyntaxKind.DebuggerKeyword, node.pos); - write(";"); + writeToken(SyntaxKind.DebuggerKeyword, node.pos, writeKeyword); + writeSemicolon(); } // @@ -1709,12 +1783,13 @@ namespace ts { function emitVariableDeclaration(node: VariableDeclaration) { emit(node.name); - emitWithPrefix(": ", node.type); - emitExpressionWithPrefix(" = ", node.initializer); + emitTypeAnnotation(node.type); + emitInitializer(node.initializer); } function emitVariableDeclarationList(node: VariableDeclarationList) { - write(isLet(node) ? "let " : isConst(node) ? "const " : "var "); + writeKeyword(isLet(node) ? "let" : isConst(node) ? "const" : "var"); + writeSpace(); emitList(node, node.declarations, ListFormat.VariableDeclarationList); } @@ -1725,9 +1800,9 @@ namespace ts { function emitFunctionDeclarationOrExpression(node: FunctionDeclaration | FunctionExpression) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("function"); + writeKeyword("function"); emitIfPresent(node.asteriskToken); - write(" "); + writeSpace(); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } @@ -1761,13 +1836,13 @@ namespace ts { } else { emitSignatureHead(node); - write(" "); + writeSpace(); emitExpression(body); } } else { emitSignatureHead(node); - write(";"); + writeSemicolon(); } } @@ -1775,7 +1850,7 @@ namespace ts { function emitSignatureHead(node: FunctionDeclaration | FunctionExpression | MethodDeclaration | AccessorDeclaration | ConstructorDeclaration) { emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); - emitWithPrefix(": ", node.type); + emitTypeAnnotation(node.type); } function shouldEmitBlockFunctionBodyOnSingleLine(body: Block) { @@ -1817,7 +1892,8 @@ namespace ts { } function emitBlockFunctionBody(body: Block) { - write(" {"); + writeSpace(); + writePunctuation("{"); increaseIndent(); const emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body) @@ -1832,7 +1908,7 @@ namespace ts { } decreaseIndent(); - writeToken(SyntaxKind.CloseBraceToken, body.statements.end, body); + writeToken(SyntaxKind.CloseBraceToken, body.statements.end, writePunctuation, body); } function emitBlockFunctionBodyOnSingleLine(body: Block) { @@ -1861,8 +1937,11 @@ namespace ts { function emitClassDeclarationOrExpression(node: ClassDeclaration | ClassExpression) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("class"); - emitNodeWithPrefix(" ", node.name, emitIdentifierName); + writeKeyword("class"); + if (node.name) { + writeSpace(); + emitIdentifierName(node.name); + } const indentedFlag = getEmitFlags(node) & EmitFlags.Indented; if (indentedFlag) { @@ -1872,9 +1951,10 @@ namespace ts { emitTypeParameters(node, node.typeParameters); emitList(node, node.heritageClauses, ListFormat.ClassHeritageClauses); - write(" {"); + writeSpace(); + writePunctuation("{"); emitList(node, node.members, ListFormat.ClassMembers); - write("}"); + writePunctuation("}"); if (indentedFlag) { decreaseIndent(); @@ -1884,74 +1964,86 @@ namespace ts { function emitInterfaceDeclaration(node: InterfaceDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("interface "); + writeKeyword("interface"); + writeSpace(); emit(node.name); emitTypeParameters(node, node.typeParameters); emitList(node, node.heritageClauses, ListFormat.HeritageClauses); - write(" {"); + writeSpace(); + writePunctuation("{"); emitList(node, node.members, ListFormat.InterfaceMembers); - write("}"); + writePunctuation("}"); } function emitTypeAliasDeclaration(node: TypeAliasDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); - write("type "); + writeKeyword("type"); + writeSpace(); emit(node.name); emitTypeParameters(node, node.typeParameters); - write(" = "); + writeSpace(); + writePunctuation("="); + writeSpace(); emit(node.type); - write(";"); + writeSemicolon(); } function emitEnumDeclaration(node: EnumDeclaration) { emitModifiers(node, node.modifiers); - write("enum "); + writeKeyword("enum"); + writeSpace(); emit(node.name); - write(" {"); + + writeSpace(); + writePunctuation("{"); emitList(node, node.members, ListFormat.EnumMembers); - write("}"); + writePunctuation("}"); } function emitModuleDeclaration(node: ModuleDeclaration) { emitModifiers(node, node.modifiers); if (~node.flags & NodeFlags.GlobalAugmentation) { - write(node.flags & NodeFlags.Namespace ? "namespace " : "module "); + writeKeyword(node.flags & NodeFlags.Namespace ? "namespace" : "module"); + writeSpace(); } emit(node.name); let body = node.body; while (body.kind === SyntaxKind.ModuleDeclaration) { - write("."); + writePunctuation("."); emit((body).name); body = (body).body; } - write(" "); + writeSpace(); emit(body); } function emitModuleBlock(node: ModuleBlock) { pushNameGenerationScope(node); - write("{"); + writePunctuation("{"); emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node)); - write("}"); + writePunctuation("}"); popNameGenerationScope(node); } function emitCaseBlock(node: CaseBlock) { - writeToken(SyntaxKind.OpenBraceToken, node.pos); + writeToken(SyntaxKind.OpenBraceToken, node.pos, writePunctuation); emitList(node, node.clauses, ListFormat.CaseBlockClauses); - writeToken(SyntaxKind.CloseBraceToken, node.clauses.end); + writeToken(SyntaxKind.CloseBraceToken, node.clauses.end, writePunctuation); } function emitImportEqualsDeclaration(node: ImportEqualsDeclaration) { emitModifiers(node, node.modifiers); - write("import "); + writeKeyword("import"); + writeSpace(); emit(node.name); - write(" = "); + writeSpace(); + writePunctuation("="); + writeSpace(); emitModuleReference(node.moduleReference); - write(";"); + writeSemicolon(); } function emitModuleReference(node: ModuleReference) { @@ -1965,25 +2057,32 @@ namespace ts { function emitImportDeclaration(node: ImportDeclaration) { emitModifiers(node, node.modifiers); - write("import "); + writeKeyword("import"); + writeSpace(); if (node.importClause) { emit(node.importClause); - write(" from "); + writeSpace(); + writeKeyword("from"); + writeSpace(); } emitExpression(node.moduleSpecifier); - write(";"); + writeSemicolon(); } function emitImportClause(node: ImportClause) { emit(node.name); if (node.name && node.namedBindings) { - write(", "); + writePunctuation(","); + writeSpace(); } emit(node.namedBindings); } function emitNamespaceImport(node: NamespaceImport) { - write("* as "); + writePunctuation("*"); + writeSpace(); + writeKeyword("as"); + writeSpace(); emit(node.name); } @@ -1996,30 +2095,46 @@ namespace ts { } function emitExportAssignment(node: ExportAssignment) { - write(node.isExportEquals ? "export = " : "export default "); + writeKeyword("export"); + writeSpace(); + if (node.isExportEquals) { + writeOperator("="); + } + else { + writeKeyword("default"); + } + writeSpace(); emitExpression(node.expression); - write(";"); + writeSemicolon(); } function emitExportDeclaration(node: ExportDeclaration) { - write("export "); + writeKeyword("export"); + writeSpace(); if (node.exportClause) { emit(node.exportClause); } else { - write("*"); + writePunctuation("*"); } if (node.moduleSpecifier) { - write(" from "); + writeSpace(); + writeKeyword("from"); + writeSpace(); emitExpression(node.moduleSpecifier); } - write(";"); + writeSemicolon(); } function emitNamespaceExportDeclaration(node: NamespaceExportDeclaration) { - write("export as namespace "); + writeKeyword("export"); + writeSpace(); + writeKeyword("as"); + writeSpace(); + writeKeyword("namespace"); + writeSpace(); emit(node.name); - write(";"); + writeSemicolon(); } function emitNamedExports(node: NamedExports) { @@ -2031,15 +2146,17 @@ namespace ts { } function emitNamedImportsOrExports(node: NamedImportsOrExports) { - write("{"); + writePunctuation("{"); emitList(node, node.elements, ListFormat.NamedImportsOrExportsElements); - write("}"); + writePunctuation("}"); } function emitImportOrExportSpecifier(node: ImportOrExportSpecifier) { if (node.propertyName) { emit(node.propertyName); - write(" as "); + writeSpace(); + writeKeyword("as"); + writeSpace(); } emit(node.name); @@ -2050,9 +2167,10 @@ namespace ts { // function emitExternalModuleReference(node: ExternalModuleReference) { - write("require("); + writeKeyword("require"); + writePunctuation("("); emitExpression(node.expression); - write(")"); + writePunctuation(")"); } // @@ -2066,14 +2184,14 @@ namespace ts { } function emitJsxSelfClosingElement(node: JsxSelfClosingElement) { - write("<"); + writePunctuation("<"); emitJsxTagName(node.tagName); - write(" "); + writeSpace(); // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap if (node.attributes.properties && node.attributes.properties.length > 0) { emit(node.attributes); } - write("/>"); + writePunctuation("/>"); } function emitJsxFragment(node: JsxFragment) { @@ -2083,30 +2201,31 @@ namespace ts { } function emitJsxOpeningElementOrFragment(node: JsxOpeningElement | JsxOpeningFragment) { - write("<"); + writePunctuation("<"); if (isJsxOpeningElement(node)) { emitJsxTagName(node.tagName); // We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap if (node.attributes.properties && node.attributes.properties.length > 0) { - write(" "); + writeSpace(); emit(node.attributes); } } - write(">"); + writePunctuation(">"); } function emitJsxText(node: JsxText) { + commitPendingSemicolon(); writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true)); } function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) { - write(""); + writePunctuation(">"); } function emitJsxAttributes(node: JsxAttributes) { @@ -2115,21 +2234,21 @@ namespace ts { function emitJsxAttribute(node: JsxAttribute) { emit(node.name); - emitWithPrefix("=", node.initializer); + emitNodeWithPrefix("=", writePunctuation, node.initializer, emit); } function emitJsxSpreadAttribute(node: JsxSpreadAttribute) { - write("{..."); + writePunctuation("{..."); emitExpression(node.expression); - write("}"); + writePunctuation("}"); } function emitJsxExpression(node: JsxExpression) { if (node.expression) { - write("{"); + writePunctuation("{"); emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); - write("}"); + writePunctuation("}"); } } @@ -2147,15 +2266,17 @@ namespace ts { // function emitCaseClause(node: CaseClause) { - write("case "); + writeKeyword("case"); + writeSpace(); emitExpression(node.expression); - write(":"); + writePunctuation(":"); emitCaseOrDefaultClauseStatements(node, node.statements); } function emitDefaultClause(node: DefaultClause) { - write("default:"); + writeKeyword("default"); + writePunctuation(":"); emitCaseOrDefaultClauseStatements(node, node.statements); } @@ -2187,27 +2308,27 @@ namespace ts { let format = ListFormat.CaseOrDefaultClauseStatements; if (emitAsSingleStatement) { - write(" "); + writeSpace(); format &= ~(ListFormat.MultiLine | ListFormat.Indented); } emitList(parentNode, statements, format); } function emitHeritageClause(node: HeritageClause) { - write(" "); - writeTokenText(node.token); - write(" "); + writeSpace(); + writeTokenText(node.token, writeKeyword); + writeSpace(); emitList(node, node.types, ListFormat.HeritageClauseTypes); } function emitCatchClause(node: CatchClause) { - const openParenPos = writeToken(SyntaxKind.CatchKeyword, node.pos); - write(" "); + const openParenPos = writeToken(SyntaxKind.CatchKeyword, node.pos, writeKeyword); + writeSpace(); if (node.variableDeclaration) { - writeToken(SyntaxKind.OpenParenToken, openParenPos); + writeToken(SyntaxKind.OpenParenToken, openParenPos, writePunctuation); emit(node.variableDeclaration); - writeToken(SyntaxKind.CloseParenToken, node.variableDeclaration.end); - write(" "); + writeToken(SyntaxKind.CloseParenToken, node.variableDeclaration.end, writePunctuation); + writeSpace(); } emit(node.block); } @@ -2218,7 +2339,8 @@ namespace ts { function emitPropertyAssignment(node: PropertyAssignment) { emit(node.name); - write(": "); + writePunctuation(":"); + writeSpace(); // This is to ensure that we emit comment in the following case: // For example: // obj = { @@ -2237,14 +2359,16 @@ namespace ts { function emitShorthandPropertyAssignment(node: ShorthandPropertyAssignment) { emit(node.name); if (node.objectAssignmentInitializer) { - write(" = "); + writeSpace(); + writePunctuation("="); + writeSpace(); emitExpression(node.objectAssignmentInitializer); } } function emitSpreadAssignment(node: SpreadAssignment) { if (node.expression) { - write("..."); + writePunctuation("..."); emitExpression(node.expression); } } @@ -2255,7 +2379,7 @@ namespace ts { function emitEnumMember(node: EnumMember) { emit(node.name); - emitExpressionWithPrefix(" = ", node.initializer); + emitInitializer(node.initializer); } // @@ -2363,38 +2487,68 @@ namespace ts { // Helpers // + function emitNodeWithWriter(node: Node, writer: typeof write) { + const savedWrite = write; + write = writer; + emit(node); + write = savedWrite; + } + function emitModifiers(node: Node, modifiers: NodeArray) { if (modifiers && modifiers.length) { emitList(node, modifiers, ListFormat.Modifiers); - write(" "); + writeSpace(); } } - function emitWithPrefix(prefix: string, node: Node) { - emitNodeWithPrefix(prefix, node, emit); - } - - function emitExpressionWithPrefix(prefix: string, node: Node) { - emitNodeWithPrefix(prefix, node, emitExpression); - } - - function emitNodeWithPrefix(prefix: string, node: Node, emit: (node: Node) => void) { + function emitTypeAnnotation(node: TypeNode | undefined) { if (node) { - write(prefix); + writePunctuation(":"); + writeSpace(); emit(node); } } - function emitWithSuffix(node: Node, suffix: string) { + function emitInitializer(node: Expression | undefined) { + if (node) { + writeSpace(); + writeOperator("="); + writeSpace(); + emitExpression(node); + } + } + + function emitNodeWithPrefix(prefix: string, prefixWriter: (s: string) => void, node: Node, emit: (node: Node) => void) { + if (node) { + prefixWriter(prefix); + emit(node); + } + } + + function emitWithLeadingSpace(node: Node | undefined) { + if (node) { + writeSpace(); + emit(node); + } + } + + function emitExpressionWithLeadingSpace(node: Expression | undefined) { + if (node) { + writeSpace(); + emitExpression(node); + } + } + + function emitWithTrailingSpace(node: Node | undefined) { if (node) { emit(node); - write(suffix); + writeSpace(); } } function emitEmbeddedStatement(parent: Node, node: Statement) { if (isBlock(node) || getEmitFlags(parent) & EmitFlags.SingleLine) { - write(" "); + writeSpace(); emit(node); } else { @@ -2413,7 +2567,10 @@ namespace ts { emitList(parentNode, typeArguments, ListFormat.TypeArguments); } - function emitTypeParameters(parentNode: Node, typeParameters: NodeArray) { + function emitTypeParameters(parentNode: SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression, typeParameters: NodeArray) { + if (isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures + return emitTypeArguments(parentNode, parentNode.typeArguments); + } emitList(parentNode, typeParameters, ListFormat.TypeParameters); } @@ -2451,15 +2608,33 @@ namespace ts { emitList(parentNode, parameters, ListFormat.IndexSignatureParameters); } - function emitList(parentNode: Node, children: NodeArray, format: ListFormat, start?: number, count?: number) { + function emitList(parentNode: TextRange, children: NodeArray, format: ListFormat, start?: number, count?: number) { emitNodeList(emit, parentNode, children, format, start, count); } - function emitExpressionList(parentNode: Node, children: NodeArray, format: ListFormat, start?: number, count?: number) { + function emitExpressionList(parentNode: TextRange, children: NodeArray, format: ListFormat, start?: number, count?: number) { emitNodeList(emitExpression, parentNode, children, format, start, count); } - function emitNodeList(emit: (node: Node) => void, parentNode: Node, children: NodeArray, format: ListFormat, start = 0, count = children ? children.length - start : 0) { + function writeDelimiter(format: ListFormat) { + switch (format & ListFormat.DelimitersMask) { + case ListFormat.None: + break; + case ListFormat.CommaDelimited: + writePunctuation(","); + break; + case ListFormat.BarDelimited: + writeSpace(); + writePunctuation("|"); + break; + case ListFormat.AmpersandDelimited: + writeSpace(); + writePunctuation("&"); + break; + } + } + + function emitNodeList(emit: (node: Node) => void, parentNode: TextRange, children: NodeArray, format: ListFormat, start = 0, count = children ? children.length - start : 0) { const isUndefined = children === undefined; if (isUndefined && format & ListFormat.OptionalIfUndefined) { return; @@ -2477,7 +2652,7 @@ namespace ts { } if (format & ListFormat.BracketsMask) { - write(getOpeningBracket(format)); + writePunctuation(getOpeningBracket(format)); } if (onBeforeEmitNodeArray) { @@ -2490,7 +2665,7 @@ namespace ts { writeLine(); } else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) { - write(" "); + writeSpace(); } } else { @@ -2502,7 +2677,7 @@ namespace ts { shouldEmitInterveningComments = false; } else if (format & ListFormat.SpaceBetweenBraces) { - write(" "); + writeSpace(); } // Increase the indent, if requested. @@ -2513,7 +2688,6 @@ namespace ts { // Emit each child. let previousSibling: Node; let shouldDecreaseIndentAfterEmit: boolean; - const delimiter = getDelimiter(format); for (let i = 0; i < count; i++) { const child = children[start + i]; @@ -2525,10 +2699,10 @@ namespace ts { // a // /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline // , - if (delimiter && previousSibling.end !== parentNode.end) { + if (format & ListFormat.DelimitersMask && previousSibling.end !== parentNode.end) { emitLeadingCommentsOfPosition(previousSibling.end); } - write(delimiter); + writeDelimiter(format); // Write either a line terminator or whitespace to separate the elements. if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) { @@ -2543,7 +2717,7 @@ namespace ts { shouldEmitInterveningComments = false; } else if (previousSibling && format & ListFormat.SpaceBetweenSiblings) { - write(" "); + writeSpace(); } } @@ -2571,7 +2745,7 @@ namespace ts { // Write a trailing comma, if requested. const hasTrailingComma = (format & ListFormat.AllowTrailingComma) && children.hasTrailingComma; if (format & ListFormat.CommaDelimited && hasTrailingComma) { - write(","); + writePunctuation(","); } @@ -2581,7 +2755,7 @@ namespace ts { // 2 // /* end of element 2 */ // ]; - if (previousSibling && delimiter && previousSibling.end !== parentNode.end && !(getEmitFlags(previousSibling) & EmitFlags.NoTrailingComments)) { + if (previousSibling && format & ListFormat.DelimitersMask && previousSibling.end !== parentNode.end && !(getEmitFlags(previousSibling) & EmitFlags.NoTrailingComments)) { emitLeadingCommentsOfPosition(previousSibling.end); } @@ -2595,7 +2769,7 @@ namespace ts { writeLine(); } else if (format & ListFormat.SpaceBetweenBraces) { - write(" "); + writeSpace(); } } @@ -2604,51 +2778,115 @@ namespace ts { } if (format & ListFormat.BracketsMask) { - write(getClosingBracket(format)); + writePunctuation(getClosingBracket(format)); } } - function write(s: string) { + function commitPendingSemicolonInternal() { + if (pendingSemicolon) { + writeSemicolonInternal(); + pendingSemicolon = false; + } + } + + function writeLiteral(s: string) { + commitPendingSemicolon(); + writer.writeLiteral(s); + } + + function writeStringLiteral(s: string) { + commitPendingSemicolon(); + writer.writeStringLiteral(s); + } + + function writeBase(s: string) { + commitPendingSemicolon(); writer.write(s); } + function writeSymbol(s: string, sym: Symbol) { + commitPendingSemicolon(); + writer.writeSymbol(s, sym); + } + + function writePunctuation(s: string) { + commitPendingSemicolon(); + writer.writePunctuation(s); + } + + function deferWriteSemicolon() { + pendingSemicolon = true; + } + + function writeSemicolonInternal() { + writer.writePunctuation(";"); + } + + function writeKeyword(s: string) { + commitPendingSemicolon(); + writer.writeKeyword(s); + } + + function writeOperator(s: string) { + commitPendingSemicolon(); + writer.writeOperator(s); + } + + function writeParameter(s: string) { + commitPendingSemicolon(); + writer.writeParameter(s); + } + + function writeSpace() { + commitPendingSemicolon(); + writer.writeSpace(" "); + } + + function writeProperty(s: string) { + commitPendingSemicolon(); + writer.writeProperty(s); + } + function writeLine() { + commitPendingSemicolon(); writer.writeLine(); } function increaseIndent() { + commitPendingSemicolon(); writer.increaseIndent(); } function decreaseIndent() { + commitPendingSemicolon(); writer.decreaseIndent(); } - function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) { + function writeToken(token: SyntaxKind, pos: number, writer: (s: string) => void, contextNode?: Node) { return onEmitSourceMapOfToken - ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) - : writeTokenText(token, pos); + ? onEmitSourceMapOfToken(contextNode, token, writer, pos, writeTokenText) + : writeTokenText(token, writer, pos); } - function writeTokenNode(node: Node) { + function writeTokenNode(node: Node, writer: (s: string) => void) { if (onBeforeEmitToken) { onBeforeEmitToken(node); } - write(tokenToString(node.kind)); + writer(tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } } - function writeTokenText(token: SyntaxKind, pos?: number) { + function writeTokenText(token: SyntaxKind, writer: (s: string) => void, pos?: number) { const tokenString = tokenToString(token); - write(tokenString); + writer(tokenString); return pos < 0 ? pos : pos + tokenString.length; } function writeLineOrSpace(node: Node) { if (getEmitFlags(node) & EmitFlags.SingleLine) { - write(" "); + writeSpace(); } else { writeLine(); @@ -2706,7 +2944,7 @@ namespace ts { } } - function shouldWriteLeadingLineTerminator(parentNode: Node, children: NodeArray, format: ListFormat) { + function shouldWriteLeadingLineTerminator(parentNode: TextRange, children: NodeArray, format: ListFormat) { if (format & ListFormat.MultiLine) { return true; } @@ -2752,7 +2990,7 @@ namespace ts { } } - function shouldWriteClosingLineTerminator(parentNode: Node, children: NodeArray, format: ListFormat) { + function shouldWriteClosingLineTerminator(parentNode: TextRange, children: NodeArray, format: ListFormat) { if (format & ListFormat.MultiLine) { return (format & ListFormat.NoTrailingNewLine) === 0; } @@ -2861,6 +3099,7 @@ namespace ts { } tempFlagsStack.push(tempFlags); tempFlags = 0; + reservedNamesStack.push(reservedNames); } /** @@ -2871,16 +3110,24 @@ namespace ts { return; } tempFlags = tempFlagsStack.pop(); + reservedNames = reservedNamesStack.pop(); + } + + function reserveNameInNestedScopes(name: string) { + if (!reservedNames || reservedNames === lastOrUndefined(reservedNamesStack)) { + reservedNames = createMap(); + } + reservedNames.set(name, true); } /** * Generate the text for a generated identifier. */ function generateName(name: GeneratedIdentifier) { - if (name.autoGenerateKind === GeneratedIdentifierKind.Node) { + if ((name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) === GeneratedIdentifierFlags.Node) { // Node names generate unique names based on their original node // and are cached based on that node's id. - if (name.skipNameGenerationScope) { + if (name.autoGenerateFlags & GeneratedIdentifierFlags.SkipNameGenerationScope) { const savedTempFlags = tempFlags; popNameGenerationScope(/*node*/ undefined); const result = generateNameCached(getNodeForGeneratedName(name)); @@ -2912,7 +3159,8 @@ namespace ts { function isUniqueName(name: string): boolean { return !(hasGlobalName && hasGlobalName(name)) && !currentSourceFile.identifiers.has(name) - && !generatedNames.has(name); + && !generatedNames.has(name) + && !(reservedNames && reservedNames.has(name)); } /** @@ -2936,11 +3184,14 @@ namespace ts { * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name. * Note that names generated by makeTempVariableName and makeUniqueName will never conflict. */ - function makeTempVariableName(flags: TempFlags): string { + function makeTempVariableName(flags: TempFlags, reservedInNestedScopes?: boolean): string { if (flags && !(tempFlags & flags)) { const name = flags === TempFlags._i ? "_i" : "_n"; if (isUniqueName(name)) { tempFlags |= flags; + if (reservedInNestedScopes) { + reserveNameInNestedScopes(name); + } return name; } } @@ -2953,6 +3204,9 @@ namespace ts { ? "_" + String.fromCharCode(CharacterCodes.a + count) : "_" + (count - 26); if (isUniqueName(name)) { + if (reservedInNestedScopes) { + reserveNameInNestedScopes(name); + } return name; } } @@ -3053,12 +3307,12 @@ namespace ts { * Generates a unique identifier for a node. */ function makeName(name: GeneratedIdentifier) { - switch (name.autoGenerateKind) { - case GeneratedIdentifierKind.Auto: - return makeTempVariableName(TempFlags.Auto); - case GeneratedIdentifierKind.Loop: - return makeTempVariableName(TempFlags._i); - case GeneratedIdentifierKind.Unique: + switch (name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) { + case GeneratedIdentifierFlags.Auto: + return makeTempVariableName(TempFlags.Auto, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes)); + case GeneratedIdentifierFlags.Loop: + return makeTempVariableName(TempFlags._i, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes)); + case GeneratedIdentifierFlags.Unique: return makeUniqueName(idText(name)); } @@ -3078,7 +3332,7 @@ namespace ts { // if "node" is a different generated name (having a different // "autoGenerateId"), use it and stop traversing. if (isIdentifier(node) - && node.autoGenerateKind === GeneratedIdentifierKind.Node + && node.autoGenerateFlags === GeneratedIdentifierFlags.Node && node.autoGenerateId !== autoGenerateId) { break; } @@ -3091,19 +3345,6 @@ namespace ts { } } - function createDelimiterMap() { - const delimiters: string[] = []; - delimiters[ListFormat.None] = ""; - delimiters[ListFormat.CommaDelimited] = ","; - delimiters[ListFormat.BarDelimited] = " |"; - delimiters[ListFormat.AmpersandDelimited] = " &"; - return delimiters; - } - - function getDelimiter(format: ListFormat) { - return delimiters[format & ListFormat.DelimitersMask]; - } - function createBracketsMap() { const brackets: string[][] = []; brackets[ListFormat.Braces] = ["{", "}"]; @@ -3127,86 +3368,4 @@ namespace ts { CountMask = 0x0FFFFFFF, // Temp variable counter _i = 0x10000000, // Use/preference flag for '_i' } - - const enum ListFormat { - None = 0, - - // Line separators - SingleLine = 0, // Prints the list on a single line (default). - MultiLine = 1 << 0, // Prints the list on multiple lines. - PreserveLines = 1 << 1, // Prints the list using line preservation if possible. - LinesMask = SingleLine | MultiLine | PreserveLines, - - // Delimiters - NotDelimited = 0, // There is no delimiter between list items (default). - BarDelimited = 1 << 2, // Each list item is space-and-bar (" |") delimited. - AmpersandDelimited = 1 << 3, // Each list item is space-and-ampersand (" &") delimited. - CommaDelimited = 1 << 4, // Each list item is comma (",") delimited. - DelimitersMask = BarDelimited | AmpersandDelimited | CommaDelimited, - - AllowTrailingComma = 1 << 5, // Write a trailing comma (",") if present. - - // Whitespace - Indented = 1 << 6, // The list should be indented. - SpaceBetweenBraces = 1 << 7, // Inserts a space after the opening brace and before the closing brace. - SpaceBetweenSiblings = 1 << 8, // Inserts a space between each sibling node. - - // Brackets/Braces - Braces = 1 << 9, // The list is surrounded by "{" and "}". - Parenthesis = 1 << 10, // The list is surrounded by "(" and ")". - AngleBrackets = 1 << 11, // The list is surrounded by "<" and ">". - SquareBrackets = 1 << 12, // The list is surrounded by "[" and "]". - BracketsMask = Braces | Parenthesis | AngleBrackets | SquareBrackets, - - OptionalIfUndefined = 1 << 13, // Do not emit brackets if the list is undefined. - OptionalIfEmpty = 1 << 14, // Do not emit brackets if the list is empty. - Optional = OptionalIfUndefined | OptionalIfEmpty, - - // Other - PreferNewLine = 1 << 15, // Prefer adding a LineTerminator between synthesized nodes. - NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list. - NoInterveningComments = 1 << 17, // Do not emit comments between each node - - NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces. - SingleElement = 1 << 19, - - // Precomputed Formats - Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments, - HeritageClauses = SingleLine | SpaceBetweenSiblings, - SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings | Indented, - MultiLineTypeLiteralMembers = MultiLine | Indented, - - TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented, - UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine, - IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, - ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings, - ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings, - ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, - ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, - CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, - CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, - NewExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis | OptionalIfUndefined, - TemplateExpressionSpans = SingleLine | NoInterveningComments, - SingleLineBlockStatements = SpaceBetweenBraces | SpaceBetweenSiblings | SingleLine, - MultiLineBlockStatements = Indented | MultiLine, - VariableDeclarationList = CommaDelimited | SpaceBetweenSiblings | SingleLine, - SingleLineFunctionBodyStatements = SingleLine | SpaceBetweenSiblings | SpaceBetweenBraces, - MultiLineFunctionBodyStatements = MultiLine, - ClassHeritageClauses = SingleLine | SpaceBetweenSiblings, - ClassMembers = Indented | MultiLine, - InterfaceMembers = Indented | MultiLine, - EnumMembers = CommaDelimited | Indented | MultiLine, - CaseBlockClauses = Indented | MultiLine, - NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces, - JsxElementOrFragmentChildren = SingleLine | NoInterveningComments, - JsxElementAttributes = SingleLine | SpaceBetweenSiblings | NoInterveningComments, - CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty, - HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine, - SourceFileStatements = MultiLine | NoTrailingNewLine, - Decorators = MultiLine | Optional, - TypeArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | AngleBrackets | Optional, - TypeParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | AngleBrackets | Optional, - Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | Parenthesis, - IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets, - } } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 070715d8ea3..f9e61249f77 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -71,11 +71,11 @@ namespace ts { // Literals /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - export function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; export function createLiteral(value: number): NumericLiteral; export function createLiteral(value: boolean): BooleanLiteral; export function createLiteral(value: string | number | boolean): PrimaryExpression; - export function createLiteral(value: string | number | boolean | StringLiteral | NumericLiteral | Identifier): PrimaryExpression { + export function createLiteral(value: string | number | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): PrimaryExpression { if (typeof value === "number") { return createNumericLiteral(value + ""); } @@ -101,7 +101,7 @@ namespace ts { return node; } - function createLiteralFromNode(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral { + function createLiteralFromNode(sourceNode: StringLiteralLike | NumericLiteral | Identifier): StringLiteral { const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode)); node.textSourceNode = sourceNode; return node; @@ -112,21 +112,23 @@ namespace ts { export function createIdentifier(text: string): Identifier; /* @internal */ - // tslint:disable-next-line unified-signatures - export function createIdentifier(text: string, typeArguments: ReadonlyArray): Identifier; - export function createIdentifier(text: string, typeArguments?: ReadonlyArray): Identifier { + export function createIdentifier(text: string, typeArguments: ReadonlyArray): Identifier; // tslint:disable-line unified-signatures + export function createIdentifier(text: string, typeArguments?: ReadonlyArray): Identifier { const node = createSynthesizedNode(SyntaxKind.Identifier); node.escapedText = escapeLeadingUnderscores(text); node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; - node.autoGenerateKind = GeneratedIdentifierKind.None; + node.autoGenerateFlags = GeneratedIdentifierFlags.None; node.autoGenerateId = 0; if (typeArguments) { - node.typeArguments = createNodeArray(typeArguments); + node.typeArguments = createNodeArray(typeArguments as ReadonlyArray); } return node; } - export function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier { + export function updateIdentifier(node: Identifier): Identifier; + /* @internal */ + export function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; // tslint:disable-line unified-signatures + export function updateIdentifier(node: Identifier, typeArguments?: NodeArray | undefined): Identifier { return node.typeArguments !== typeArguments ? updateNode(createIdentifier(idText(node), typeArguments), node) : node; @@ -135,21 +137,26 @@ namespace ts { let nextAutoGenerateId = 0; /** Create a unique temporary variable. */ - export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier { + export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; + /* @internal */ export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes: boolean): Identifier; // tslint:disable-line unified-signatures + export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Auto; + name.autoGenerateFlags = GeneratedIdentifierFlags.Auto; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; if (recordTempVariable) { recordTempVariable(name); } + if (reservedInNestedScopes) { + name.autoGenerateFlags |= GeneratedIdentifierFlags.ReservedInNestedScopes; + } return name; } /** Create a unique temporary variable for use in a loop. */ export function createLoopVariable(): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Loop; + name.autoGenerateFlags = GeneratedIdentifierFlags.Loop; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; @@ -158,7 +165,7 @@ namespace ts { /** Create a unique name based on the supplied text. */ export function createUniqueName(text: string): Identifier { const name = createIdentifier(text); - name.autoGenerateKind = GeneratedIdentifierKind.Unique; + name.autoGenerateFlags = GeneratedIdentifierFlags.Unique; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; @@ -166,14 +173,15 @@ namespace ts { /** Create a unique name generated for a node. */ export function getGeneratedNameForNode(node: Node): Identifier; - // tslint:disable-next-line unified-signatures - /*@internal*/ export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier; + /* @internal */ export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier; // tslint:disable-line unified-signatures export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Node; + name.autoGenerateFlags = GeneratedIdentifierFlags.Node; name.autoGenerateId = nextAutoGenerateId; name.original = node; - name.skipNameGenerationScope = !!shouldSkipNameGenerationScope; + if (shouldSkipNameGenerationScope) { + name.autoGenerateFlags |= GeneratedIdentifierFlags.SkipNameGenerationScope; + } nextAutoGenerateId++; return name; } @@ -578,11 +586,12 @@ namespace ts { } /* @internal */ - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined) { + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined, typeArguments?: TypeNode[] | undefined) { const node = createSynthesizedNode(kind) as SignatureDeclaration; node.typeParameters = asNodeArray(typeParameters); node.parameters = asNodeArray(parameters); node.type = type; + node.typeArguments = asNodeArray(typeArguments); return node; } @@ -3644,7 +3653,7 @@ namespace ts { return qualifiedName; } - export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean) { + export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean): Block { return isBlock(node) ? node : setTextRange(createBlock([setTextRange(createReturn(node), node)], multiLine), node); } @@ -3849,13 +3858,13 @@ namespace ts { if (isLeftSideOfBinary) { // No need to parenthesize the left operand when the binary operator is // left associative: - // (a*b)/x -> a*b/x - // (a**b)/x -> a**b/x + // (a*b)/x -> a*b/x + // (a**b)/x -> a**b/x // // Parentheses are needed for the left operand when the binary operator is // right associative: - // (a/b)**x -> (a/b)**x - // (a**b)**x -> (a**b)**x + // (a/b)**x -> (a/b)**x + // (a**b)**x -> (a**b)**x return binaryOperatorAssociativity === Associativity.Right; } else { @@ -3969,7 +3978,9 @@ namespace ts { // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions // so in case when comma expression is introduced as a part of previous transformations // if should be wrapped in parens since comma operator has the lowest precedence - return e.kind === SyntaxKind.BinaryExpression && (e).operatorToken.kind === SyntaxKind.CommaToken + const emittedExpression = skipPartiallyEmittedExpressions(e); + return emittedExpression.kind === SyntaxKind.BinaryExpression && (emittedExpression).operatorToken.kind === SyntaxKind.CommaToken || + emittedExpression.kind === SyntaxKind.CommaListExpression ? createParen(e) : e; } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 1cc11acd32d..f72876bd5fc 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -801,7 +801,9 @@ namespace ts { } const resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return noPackageId(resolvedFromFile); + const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile.path) : undefined; + const packageId = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, failedLookupLocations, /*onlyRecordFailures*/ false, state).packageId; + return withPackageId(packageId, resolvedFromFile); } } if (!onlyRecordFailures) { @@ -816,6 +818,45 @@ namespace ts { return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); } + const nodeModulesPathPart = "/node_modules/"; + + /** + * This will be called on the successfully resolved path from `loadModuleFromFile`. + * (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.) + * + * packageDirectory is the directory of the package itself. + * subModuleName is the path within the package. + * For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "" }. (Part before "/node_modules/" is ignored.) + * For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar" }. + * For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar" }. + */ + function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { + path = normalizePath(path); + const idx = path.lastIndexOf(nodeModulesPathPart); + if (idx === -1) { + return undefined; + } + + const indexAfterNodeModules = idx + nodeModulesPathPart.length; + let indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules); + if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) { + indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName); + } + const packageDirectory = path.slice(0, indexAfterPackageName); + const subModuleName = removeExtensionAndIndex(path.slice(indexAfterPackageName + 1)); + return { packageDirectory, subModuleName }; + } + + function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number { + const nextSeparatorIndex = path.indexOf(directorySeparator, prevSeparatorIndex + 1); + return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex; + } + + function removeExtensionAndIndex(path: string): string { + const noExtension = removeFileExtension(path); + return noExtension === "index" ? "" : removeSuffix(noExtension, "/index"); + } + /* @internal */ export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean { // if host does not support 'directoryExists' assume that directory will exist @@ -919,13 +960,18 @@ namespace ts { const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host); const packageJsonPath = pathToPackageJson(nodeModuleDirectory); if (directoryExists && host.fileExists(packageJsonPath)) { - if (traceEnabled) { - trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); - } const packageJsonContent = readJson(packageJsonPath, host); const packageId: PackageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string" ? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version } : undefined; + if (traceEnabled) { + if (packageId) { + trace(host, Diagnostics.Found_package_json_at_0_Package_ID_is_1, packageJsonPath, packageIdToString(packageId)); + } + else { + trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); + } + } return { found: true, packageJsonContent, packageId }; } else { @@ -1097,13 +1143,18 @@ namespace ts { export function getPackageNameFromAtTypesDirectory(mangledName: string): string { const withoutAtTypePrefix = removePrefix(mangledName, "@types/"); if (withoutAtTypePrefix !== mangledName) { - return stringContains(withoutAtTypePrefix, mangledScopedPackageSeparator) ? - "@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) : - withoutAtTypePrefix; + return getUnmangledNameForScopedPackage(withoutAtTypePrefix); } return mangledName; } + /* @internal */ + export function getUnmangledNameForScopedPackage(typesPackageName: string): string { + return stringContains(typesPackageName, mangledScopedPackageSeparator) ? + "@" + typesPackageName.replace(mangledScopedPackageSeparator, ts.directorySeparator) : + typesPackageName; + } + function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult { const result = cache && cache.get(containingDirectory); if (result) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 82b85444bc5..ed286891ded 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -590,7 +590,7 @@ namespace ts { // 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost // all nodes would need extra state on them to store this info. // - // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6 + // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6 // grammar specification. // // An important thing about these context concepts. By default they are effectively inherited @@ -706,7 +706,7 @@ namespace ts { function getLanguageVariant(scriptKind: ScriptKind) { // .tsx and .jsx files are treated as jsx language variant. - return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; + return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; } function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) { @@ -791,15 +791,7 @@ namespace ts { const comments = getJSDocCommentRanges(node, sourceFile.text); if (comments) { for (const comment of comments) { - const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); - if (jsDoc) { - if (!node.jsDoc) { - node.jsDoc = [jsDoc]; - } - else { - node.jsDoc.push(jsDoc); - } - } + node.jsDoc = append(node.jsDoc, JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); } } @@ -1434,9 +1426,13 @@ namespace ts { return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isIdentifierOrPattern(); case ParsingContext.TypeParameters: return isIdentifier(); - case ParsingContext.ArgumentExpressions: case ParsingContext.ArrayLiteralMembers: - return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isStartOfExpression(); + if (token() === SyntaxKind.CommaToken) { + return true; + } + // falls through + case ParsingContext.ArgumentExpressions: + return token() === SyntaxKind.DotDotDotToken || isStartOfExpression(); case ParsingContext.Parameters: return isStartOfParameter(); case ParsingContext.TypeArguments: @@ -1458,7 +1454,7 @@ namespace ts { function isValidHeritageClauseObjectLiteral() { Debug.assert(token() === SyntaxKind.OpenBraceToken); if (nextToken() === SyntaxKind.CloseBraceToken) { - // if we see "extends {}" then only treat the {} as what we're extending (and not + // if we see "extends {}" then only treat the {} as what we're extending (and not // the class body) if we have: // // extends {} { @@ -1559,7 +1555,7 @@ namespace ts { function isVariableDeclaratorListTerminator(): boolean { // If we can consume a semicolon (either explicitly, or with ASI), then consider us done - // with parsing the list of variable declarators. + // with parsing the list of variable declarators. if (canParseSemicolon()) { return true; } @@ -1685,6 +1681,11 @@ namespace ts { return undefined; } + if ((node as JSDocContainer).jsDocCache) { + // jsDocCache may include tags from parent nodes, which might have been modified. + (node as JSDocContainer).jsDocCache = undefined; + } + return node; } @@ -2279,7 +2280,7 @@ namespace ts { // // // - // We do *not* want to consume the > as we're consuming the expression for "". + // We do *not* want to consume the `>` as we're consuming the expression for "". node.expression = parseUnaryExpressionOrHigher(); } } @@ -3118,7 +3119,7 @@ namespace ts { // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression". // // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is - // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done + // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done // with AssignmentExpression if we see one. const arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression(); if (arrowExpression) { @@ -3148,7 +3149,7 @@ namespace ts { // we're in '2' or '3'. Consume the assignment and return. // // Note: we call reScanGreaterToken so that we get an appropriately merged token - // for cases like > > = becoming >>= + // for cases like `> > =` becoming `>>=` if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); } @@ -3304,7 +3305,7 @@ namespace ts { if (first === SyntaxKind.OpenParenToken) { if (second === SyntaxKind.CloseParenToken) { - // Simple cases: "() =>", "(): ", and "() {". + // Simple cases: "() =>", "(): ", and "() {". // This is an arrow function with no parameters. // The last one is not actually an arrow function, // but this is probably what the user intended. @@ -3529,7 +3530,9 @@ namespace ts { node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher); node.colonToken = parseExpectedToken(SyntaxKind.ColonToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); - node.whenFalse = parseAssignmentExpressionOrHigher(); + node.whenFalse = nodeIsPresent(node.colonToken) + ? parseAssignmentExpressionOrHigher() + : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); return finishNode(node); } @@ -3924,7 +3927,8 @@ namespace ts { // We don't want to eagerly consume all import keyword as import call expression so we look a head to find "(" // For example: // var foo3 = require("subfolder - // import * as foo1 from "module-from-node -> we want this import to be a statement rather than import call expression + // import * as foo1 from "module-from-node + // We want this import to be a statement rather than import call expression sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport; expression = parseTokenNode(); } @@ -3974,7 +3978,7 @@ namespace ts { // treated as the invocation of "new Foo". We disambiguate that in code (to match // the original grammar) by making sure that if we see an ObjectCreationExpression // we always consume arguments if they are there. So we treat "new Foo()" as an - // object creation only, and not at all as an invocation) Another way to think + // object creation only, and not at all as an invocation. Another way to think // about this is that for every "new" that we see, we will consume an argument list if // it is there as part of the *associated* object creation node. Any additional // argument lists we see, will become invocation expressions. @@ -4390,7 +4394,7 @@ namespace ts { const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); if (!parseExpected(SyntaxKind.GreaterThanToken)) { - // If it doesn't have the closing > then it's definitely not an type argument list. + // If it doesn't have the closing `>` then it's definitely not an type argument list. return undefined; } @@ -5423,8 +5427,8 @@ namespace ts { // off. The grammar would look something like this: // // MemberVariableDeclaration[Yield]: - // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initializer_opt[In]; - // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initializer_opt[In, ?Yield]; + // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initializer_opt[In]; + // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initializer_opt[In, ?Yield]; // // The checker may still error in the static case to explicitly disallow the yield expression. node.initializer = hasModifier(node, ModifierFlags.Static) @@ -6285,7 +6289,6 @@ namespace ts { scanner.scanRange(start + 3, length - 5, () => { // Initially we can parse out a tag. We also have seen a starting asterisk. // This is so that /** * @type */ doesn't parse. - let advanceToken = true; let state = JSDocState.SawAsterisk; let margin: number | undefined = undefined; // + 4 for leading '/** ' @@ -6298,17 +6301,17 @@ namespace ts { indent += text.length; } - nextJSDocToken(); - while (token() === SyntaxKind.WhitespaceTrivia) { - nextJSDocToken(); + let t = nextJSDocToken(); + while (t === SyntaxKind.WhitespaceTrivia) { + t = nextJSDocToken(); } - if (token() === SyntaxKind.NewLineTrivia) { + if (t === SyntaxKind.NewLineTrivia) { state = JSDocState.BeginningOfLine; indent = 0; - nextJSDocToken(); + t = nextJSDocToken(); } - while (token() !== SyntaxKind.EndOfFileToken) { - switch (token()) { + loop: while (true) { + switch (t) { case SyntaxKind.AtToken: if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) { removeTrailingNewlines(comments); @@ -6317,7 +6320,6 @@ namespace ts { // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning // for malformed examples like `/** @param {string} x @returns {number} the length */` state = JSDocState.BeginningOfLine; - advanceToken = false; margin = undefined; indent++; } @@ -6362,19 +6364,14 @@ namespace ts { indent += whitespace.length; break; case SyntaxKind.EndOfFileToken: - break; + break loop; default: // anything other than whitespace or asterisk at the beginning of the line starts the comment text state = JSDocState.SavingComments; pushComment(scanner.getTokenText()); break; } - if (advanceToken) { - nextJSDocToken(); - } - else { - advanceToken = true; - } + t = nextJSDocToken(); } removeLeadingNewlines(comments); removeTrailingNewlines(comments); @@ -6470,10 +6467,11 @@ namespace ts { // a badly malformed tag should not be added to the list of tags return; } - addTag(tag, parseTagComments(indent + tag.end - tag.pos)); + tag.comment = parseTagComments(indent + tag.end - tag.pos); + addTag(tag); } - function parseTagComments(indent: number) { + function parseTagComments(indent: number): string | undefined { const comments: string[] = []; let state = JSDocState.BeginningOfLine; let margin: number | undefined; @@ -6484,8 +6482,9 @@ namespace ts { comments.push(text); indent += text.length; } - while (token() !== SyntaxKind.AtToken && token() !== SyntaxKind.EndOfFileToken) { - switch (token()) { + let tok = token() as JsDocSyntaxKind; + loop: while (true) { + switch (tok) { case SyntaxKind.NewLineTrivia: if (state >= JSDocState.SawAsterisk) { state = JSDocState.BeginningOfLine; @@ -6494,8 +6493,11 @@ namespace ts { indent = 0; break; case SyntaxKind.AtToken: + scanner.setTextPos(scanner.getTextPos() - 1); + // falls through + case SyntaxKind.EndOfFileToken: // Done - break; + break loop; case SyntaxKind.WhitespaceTrivia: if (state === JSDocState.SavingComments) { pushComment(scanner.getTokenText()); @@ -6513,7 +6515,7 @@ namespace ts { if (state === JSDocState.BeginningOfLine) { // leading asterisks start recording on the *next* (non-whitespace) token state = JSDocState.SawAsterisk; - indent += scanner.getTokenText().length; + indent += 1; break; } // record the * as a comment @@ -6523,16 +6525,12 @@ namespace ts { pushComment(scanner.getTokenText()); break; } - if (token() === SyntaxKind.AtToken) { - // Done - break; - } - nextJSDocToken(); + tok = nextJSDocToken(); } removeLeadingNewlines(comments); removeTrailingNewlines(comments); - return comments; + return comments.length === 0 ? undefined : comments.join(""); } function parseUnknownTag(atToken: AtToken, tagName: Identifier) { @@ -6542,9 +6540,7 @@ namespace ts { return finishNode(result); } - function addTag(tag: JSDocTag, comments: string[]): void { - tag.comment = comments.join(""); - + function addTag(tag: JSDocTag): void { if (!tags) { tags = [tag]; tagsPos = tag.pos; @@ -6589,9 +6585,7 @@ namespace ts { } } - function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse.Parameter): JSDocParameterTag; - function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse.Property): JSDocPropertyTag; - function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse): JSDocPropertyLikeTag { + function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse): JSDocParameterTag | JSDocPropertyTag { let typeExpression = tryParseTypeExpression(); let isNameFirst = !typeExpression; skipWhitespace(); @@ -6603,7 +6597,7 @@ namespace ts { typeExpression = tryParseTypeExpression(); } - const result: JSDocPropertyLikeTag = target === PropertyLikeParse.Parameter ? + const result = target === PropertyLikeParse.Parameter ? createNode(SyntaxKind.JSDocParameterTag, atToken.pos) : createNode(SyntaxKind.JSDocPropertyTag, atToken.pos); const nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name); @@ -6618,7 +6612,6 @@ namespace ts { result.isNameFirst = isNameFirst; result.isBracketed = isBracketed; return finishNode(result); - } function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression, name: EntityName) { @@ -6629,10 +6622,7 @@ namespace ts { const start = scanner.getStartPos(); let children: JSDocParameterTag[]; while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Parameter, name))) { - if (!children) { - children = []; - } - children.push(child); + children = append(children, child); } if (children) { jsdocTypeLiteral = createNode(SyntaxKind.JSDocTypeLiteral, start); @@ -6749,10 +6739,7 @@ namespace ts { } } else { - if (!jsdocTypeLiteral.jsDocPropertyTags) { - jsdocTypeLiteral.jsDocPropertyTags = [] as MutableNodeArray; - } - (jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray).push(child); + jsdocTypeLiteral.jsDocPropertyTags = append(jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray, child); } } if (jsdocTypeLiteral) { @@ -6805,8 +6792,7 @@ namespace ts { let canParseTag = true; let seenAsterisk = false; while (true) { - nextJSDocToken(); - switch (token()) { + switch (nextJSDocToken()) { case SyntaxKind.AtToken: if (canParseTag) { const child = tryParseChildTag(target); @@ -6848,18 +6834,28 @@ namespace ts { if (!tagName) { return false; } + let t: PropertyLikeParse; switch (tagName.escapedText) { case "type": return target === PropertyLikeParse.Property && parseTypeTag(atToken, tagName); case "prop": case "property": - return target === PropertyLikeParse.Property && parseParameterOrPropertyTag(atToken, tagName, target); + t = PropertyLikeParse.Property; + break; case "arg": case "argument": case "param": - return target === PropertyLikeParse.Parameter && parseParameterOrPropertyTag(atToken, tagName, target); + t = PropertyLikeParse.Parameter; + break; + default: + return false; } - return false; + if (target !== t) { + return false; + } + const tag = parseParameterOrPropertyTag(atToken, tagName, target); + tag.comment = parseTagComments(tag.end - tag.pos); + return tag; } function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined { @@ -6902,7 +6898,7 @@ namespace ts { return result; } - function nextJSDocToken(): SyntaxKind { + function nextJSDocToken(): JsDocSyntaxKind { return currentToken = scanner.scanJSDocToken(); } @@ -7106,7 +7102,7 @@ namespace ts { // If the 'pos' is before the start of the change, then we don't need to touch it. // If it isn't, then the 'pos' must be inside the change. How we update it will - // depend if delta is positive or negative. If delta is positive then we have + // depend if delta is positive or negative. If delta is positive then we have // something like: // // -------------------AAA----------------- @@ -7131,7 +7127,7 @@ namespace ts { // If the 'end' is after the change range, then we always adjust it by the delta // amount. However, if the end is in the change range, then how we adjust it - // will depend on if delta is positive or negative. If delta is positive then we + // will depend on if delta is positive or negative. If delta is positive then we // have something like: // // -------------------AAA----------------- diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 3274e81ce81..37fae7195ab 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -6,7 +6,7 @@ namespace ts { const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/; - export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string { + export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined { return forEachAncestorDirectory(searchPath, ancestor => { const fileName = combinePaths(ancestor, configName); return fileExists(fileName) ? fileName : undefined; @@ -331,11 +331,11 @@ namespace ts { } output += formatColorAndReset(relativeFileName, ForegroundColorEscapeSequences.Cyan); - output += "("; + output += ":"; output += formatColorAndReset(`${ firstLine + 1 }`, ForegroundColorEscapeSequences.Yellow); - output += ","; + output += ":"; output += formatColorAndReset(`${ firstLineChar + 1 }`, ForegroundColorEscapeSequences.Yellow); - output += "): "; + output += " - "; } const categoryColor = getCategoryFormat(diagnostic.category); @@ -667,7 +667,8 @@ namespace ts { dropDiagnosticsProducingTypeChecker, getSourceFileFromReference, sourceFileToPackageName, - redirectTargetsSet + redirectTargetsSet, + isEmittedFile }; verifyCompilerOptions(); @@ -1601,6 +1602,7 @@ namespace ts { // synthesize 'import "tslib"' declaration const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText); const importDecl = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined); + addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); externalHelpersModuleReference.parent = importDecl; importDecl.parent = file; imports = [externalHelpersModuleReference]; @@ -1815,7 +1817,7 @@ namespace ts { }, shouldCreateNewSourceFile); if (packageId) { - const packageIdKey = `${packageId.name}/${packageId.subModuleName}@${packageId.version}`; + const packageIdKey = packageIdToString(packageId); const fileFromPackageId = packageIdToSourceFile.get(packageIdKey); if (fileFromPackageId) { // Some other SourceFile already exists with this package name and version. @@ -2342,6 +2344,20 @@ namespace ts { hasEmitBlockingDiagnostics.set(toPath(emitFileName), true); programDiagnostics.add(diag); } + + function isEmittedFile(file: string) { + if (options.noEmit) { + return false; + } + + return forEachEmittedFile(getEmitHost(), ({ jsFilePath, declarationFilePath }) => + isSameFile(jsFilePath, file) || + (declarationFilePath && isSameFile(declarationFilePath, file))); + } + + function isSameFile(file1: string, file2: string) { + return comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; + } } /* @internal */ diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index e21e81a2e88..aac25c5d596 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -52,6 +52,7 @@ namespace ts { getGlobalCache?(): string | undefined; writeLog(s: string): void; maxNumberOfFilesToIterateForInvalidation?: number; + getCurrentProgram(): Program; } interface DirectoryWatchesOfFailedLookup { @@ -472,6 +473,11 @@ namespace ts { resolutionHost.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath); } + // Ignore emits from the program + if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectory)) { + return; + } + // If the files are added to project root or node_modules directory, always run through the invalidation process // Otherwise run through invalidation only if adding to the immediate directory if (!allFilesHaveInvalidatedResolution && diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 1cd64931153..5001ea58336 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -35,7 +35,7 @@ namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): SyntaxKind; scanJsxToken(): SyntaxKind; - scanJSDocToken(): SyntaxKind; + scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; getText(): string; // Sets the text for the scanner to scan. An optional subrange starting point and length @@ -193,7 +193,7 @@ namespace ts { /* As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers IdentifierStart :: - Can contain Unicode 3.0.0 categories: + Can contain Unicode 3.0.0 categories: Uppercase letter (Lu), Lowercase letter (Ll), Titlecase letter (Lt), @@ -201,7 +201,7 @@ namespace ts { Other letter (Lo), or Letter number (Nl). IdentifierPart :: = - Can contain IdentifierStart + Unicode 3.0.0 categories: + Can contain IdentifierStart + Unicode 3.0.0 categories: Non-spacing mark (Mn), Combining spacing mark (Mc), Decimal number (Nd), or @@ -216,7 +216,7 @@ namespace ts { /* As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers IdentifierStart :: - Can contain Unicode 6.2 categories: + Can contain Unicode 6.2 categories: Uppercase letter (Lu), Lowercase letter (Ll), Titlecase letter (Lt), @@ -224,7 +224,7 @@ namespace ts { Other letter (Lo), or Letter number (Nl). IdentifierPart :: - Can contain IdentifierStart + Unicode 6.2 categories: + Can contain IdentifierStart + Unicode 6.2 categories: Non-spacing mark (Mn), Combining spacing mark (Mc), Decimal number (Nd), @@ -725,10 +725,14 @@ namespace ts { return accumulator; } + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state); } + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state); } @@ -1594,7 +1598,7 @@ namespace ts { return token = SyntaxKind.NumericLiteral; case CharacterCodes.colon: pos++; - return token = SyntaxKind.ColonToken; + return token = SyntaxKind.ColonToken; case CharacterCodes.semicolon: pos++; return token = SyntaxKind.SemicolonToken; @@ -1905,7 +1909,7 @@ namespace ts { break; } } - tokenValue += text.substr(firstCharPosition, pos - firstCharPosition); + tokenValue += text.substring(firstCharPosition, pos); } return token; } @@ -1924,7 +1928,7 @@ namespace ts { } } - function scanJSDocToken(): SyntaxKind { + function scanJSDocToken(): JsDocSyntaxKind { if (pos >= end) { return token = SyntaxKind.EndOfFileToken; } @@ -1933,6 +1937,7 @@ namespace ts { tokenPos = pos; const ch = text.charCodeAt(pos); + pos++; switch (ch) { case CharacterCodes.tab: case CharacterCodes.verticalTab: @@ -1943,56 +1948,31 @@ namespace ts { } return token = SyntaxKind.WhitespaceTrivia; case CharacterCodes.at: - pos++; return token = SyntaxKind.AtToken; case CharacterCodes.lineFeed: case CharacterCodes.carriageReturn: - pos++; return token = SyntaxKind.NewLineTrivia; case CharacterCodes.asterisk: - pos++; return token = SyntaxKind.AsteriskToken; case CharacterCodes.openBrace: - pos++; return token = SyntaxKind.OpenBraceToken; case CharacterCodes.closeBrace: - pos++; return token = SyntaxKind.CloseBraceToken; case CharacterCodes.openBracket: - pos++; return token = SyntaxKind.OpenBracketToken; case CharacterCodes.closeBracket: - pos++; return token = SyntaxKind.CloseBracketToken; case CharacterCodes.lessThan: - pos++; return token = SyntaxKind.LessThanToken; - case CharacterCodes.greaterThan: - pos++; - return token = SyntaxKind.GreaterThanToken; case CharacterCodes.equals: - pos++; return token = SyntaxKind.EqualsToken; case CharacterCodes.comma: - pos++; return token = SyntaxKind.CommaToken; case CharacterCodes.dot: - pos++; - if (text.substr(tokenPos, pos + 2) === "...") { - pos += 2; - return token = SyntaxKind.DotDotDotToken; - } return token = SyntaxKind.DotToken; - case CharacterCodes.exclamation: - pos++; - return token = SyntaxKind.ExclamationToken; - case CharacterCodes.question: - pos++; - return token = SyntaxKind.QuestionToken; } if (isIdentifierStart(ch, ScriptTarget.Latest)) { - pos++; while (isIdentifierPart(text.charCodeAt(pos), ScriptTarget.Latest) && pos < end) { pos++; } @@ -2000,7 +1980,7 @@ namespace ts { return token = SyntaxKind.Identifier; } else { - return pos += 1, token = SyntaxKind.Unknown; + return token = SyntaxKind.Unknown; } } diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index b5cd1d9e322..2dabb97b08d 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -51,7 +51,7 @@ namespace ts { * @param tokenStartPos The start pos of the token. * @param emitCallback The callback used to emit the token. */ - emitTokenWithSourceMap(node: Node, token: SyntaxKind, tokenStartPos: number, emitCallback: (token: SyntaxKind, tokenStartPos: number) => number): number; + emitTokenWithSourceMap(node: Node, token: SyntaxKind, writer: (s: string) => void, tokenStartPos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, tokenStartPos: number) => number): number; /** * Gets the text for the source map. @@ -372,9 +372,9 @@ namespace ts { * @param tokenStartPos The start pos of the token. * @param emitCallback The callback used to emit the token. */ - function emitTokenWithSourceMap(node: Node, token: SyntaxKind, tokenPos: number, emitCallback: (token: SyntaxKind, tokenStartPos: number) => number) { + function emitTokenWithSourceMap(node: Node, token: SyntaxKind, writer: (s: string) => void, tokenPos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, tokenStartPos: number) => number) { if (disabled) { - return emitCallback(token, tokenPos); + return emitCallback(token, writer, tokenPos); } const emitNode = node && node.emitNode; @@ -386,7 +386,7 @@ namespace ts { emitPos(tokenPos); } - tokenPos = emitCallback(token, tokenPos); + tokenPos = emitCallback(token, writer, tokenPos); if (range) tokenPos = range.end; if ((emitFlags & EmitFlags.NoTokenTrailingSourceMaps) === 0 && tokenPos >= 0) { @@ -420,7 +420,7 @@ namespace ts { host.getCanonicalFileName, /*isAbsolutePathAnUrl*/ true); - sourceMapSourceIndex = indexOf(sourceMapData.sourceMapSources, source); + sourceMapSourceIndex = sourceMapData.sourceMapSources.indexOf(source); if (sourceMapSourceIndex === -1) { sourceMapSourceIndex = sourceMapData.sourceMapSources.length; sourceMapData.sourceMapSources.push(source); diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index a283275d066..bafe43b0b15 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -70,7 +70,13 @@ namespace ts { if (value) { value = visitNode(value, visitor, isExpression); - if (needsValue) { + + if (isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText)) { + // If the right-hand value of the assignment is also an assignment target then + // we need to cache the right-hand value. + value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ false, location); + } + else if (needsValue) { // If the right-hand value of the destructuring assignment needs to be preserved (as // is the case when the destructuring assignment is part of a larger expression), // then we need to cache the right-hand value. @@ -123,6 +129,27 @@ namespace ts { } } + function bindingOrAssignmentElementAssignsToName(element: BindingOrAssignmentElement, escapedName: __String): boolean { + const target = getTargetOfBindingOrAssignmentElement(element); + if (isBindingOrAssignmentPattern(target)) { + return bindingOrAssignmentPatternAssignsToName(target, escapedName); + } + else if (isIdentifier(target)) { + return target.escapedText === escapedName; + } + return false; + } + + function bindingOrAssignmentPatternAssignsToName(pattern: BindingOrAssignmentPattern, escapedName: __String): boolean { + const elements = getElementsOfBindingOrAssignmentPattern(pattern); + for (const element of elements) { + if (bindingOrAssignmentElementAssignsToName(element, escapedName)) { + return true; + } + } + return false; + } + /** * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations. * @@ -157,6 +184,17 @@ namespace ts { createArrayBindingOrAssignmentElement: makeBindingElement, visitor }; + + if (isVariableDeclaration(node)) { + let initializer = getInitializerOfBindingOrAssignmentElement(node); + if (initializer && isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText)) { + // If the right-hand value of the assignment is also an assignment target then + // we need to cache the right-hand value. + initializer = ensureIdentifier(flattenContext, initializer, /*reuseIdentifierExpressions*/ false, initializer); + node = updateVariableDeclaration(node, node.name, node.type, initializer); + } + } + flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer); if (pendingExpressions) { const temp = createTempVariable(/*recordTempVariable*/ undefined); diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 65771410ea2..da0fcc73a98 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -859,7 +859,7 @@ namespace ts { statements.push( setTextRange( createStatement( - createExtendsHelper(context, getLocalName(node)) + createExtendsHelper(context, getInternalName(node)) ), /*location*/ extendsClauseElement ) diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 5b4c12b4f23..5d46c8430d2 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -968,7 +968,7 @@ namespace ts { name: "typescript:asyncValues", scoped: false, text: ` - var __asyncValues = (this && this.__asyncIterator) || function (o) { + var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index bd2a4ef554d..8df05e4f3ab 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -3190,8 +3190,8 @@ namespace ts { // `throw` methods that step through the generator when invoked. // // parameters: - // thisArg The value to use as the `this` binding for the transformed generator body. - // body A function that acts as the transformed generator body. + // @param thisArg The value to use as the `this` binding for the transformed generator body. + // @param body A function that acts as the transformed generator body. // // variables: // _ Persistent state for the generator that is shared between the helper and the diff --git a/src/compiler/transformers/module/es2015.ts b/src/compiler/transformers/module/es2015.ts index 3951d08109d..4f218e4fdcf 100644 --- a/src/compiler/transformers/module/es2015.ts +++ b/src/compiler/transformers/module/es2015.ts @@ -25,14 +25,14 @@ namespace ts { if (externalHelpersModuleName) { const statements: Statement[] = []; const statementOffset = addPrologue(statements, node.statements); - append(statements, - createImportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), - createLiteral(externalHelpersModuleNameText) - ) + const tslibImport = createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), + createLiteral(externalHelpersModuleNameText) ); + addEmitFlags(tslibImport, EmitFlags.NeverApplyImportHelper); + append(statements, tslibImport); addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); return updateSourceFileNode( diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 0c8e2cda0f5..0d4e5b6864a 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -148,7 +148,7 @@ namespace ts { // Create an updated SourceFile: // // define(moduleName?, ["module1", "module2"], function ... - return updateSourceFileNode(node, + const updated = updateSourceFileNode(node, setTextRange( createNodeArray([ createStatement( @@ -192,6 +192,9 @@ namespace ts { /*location*/ node.statements ) ); + + addEmitHelpers(updated, context.readEmitHelpers()); + return updated; } /** @@ -296,7 +299,7 @@ namespace ts { // } // })(function ...) - return updateSourceFileNode( + const updated = updateSourceFileNode( node, setTextRange( createNodeArray([ @@ -328,6 +331,9 @@ namespace ts { /*location*/ node.statements ) ); + + addEmitHelpers(updated, context.readEmitHelpers()); + return updated; } /** @@ -385,6 +391,18 @@ namespace ts { return { aliasedModuleNames, unaliasedModuleNames, importAliasNames }; } + function getAMDImportExpressionForImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration) { + if (isImportEqualsDeclaration(node) || isExportDeclaration(node) || !getExternalModuleNameLiteral(node, currentSourceFile, host, resolver, compilerOptions)) { + return undefined; + } + const name = getLocalNameForExternalImport(node, currentSourceFile); + const expr = getHelperExpressionForImport(node, name); + if (expr === name) { + return undefined; + } + return createStatement(createAssignment(name, expr)); + } + /** * Transforms a SourceFile into an AMD or UMD module body. * @@ -402,6 +420,9 @@ namespace ts { // Visit each statement of the module body. append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement)); + if (moduleKind === ModuleKind.AMD) { + addRange(statements, mapDefined(currentModuleInfo.externalImports, getAMDImportExpressionForImport)); + } addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset)); // Append the 'export =' statement if provided. @@ -617,7 +638,12 @@ namespace ts { } } - return createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); + const promise = createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); + if (compilerOptions.esModuleInterop) { + context.requestEmitHelper(importStarHelper); + return createCall(createPropertyAccess(promise, createIdentifier("then")), /*typeArguments*/ undefined, [getHelperName("__importStar")]); + } + return promise; } function createImportCallExpressionCommonJS(arg: Expression | undefined, containsLexicalThis: boolean): Expression { @@ -627,7 +653,11 @@ namespace ts { // We have to wrap require in then callback so that require is done in asynchronously // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately const promiseResolveCall = createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []); - const requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); + let requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); + if (compilerOptions.esModuleInterop) { + context.requestEmitHelper(importStarHelper); + requireCall = createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]); + } let func: FunctionExpression | ArrowFunction; if (languageVersion >= ScriptTarget.ES2015) { @@ -660,6 +690,22 @@ namespace ts { return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]); } + + function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) { + if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) { + return innerExpr; + } + if (getNamespaceDeclarationNode(node)) { + context.requestEmitHelper(importStarHelper); + return createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]); + } + if (isDefaultImport(node)) { + context.requestEmitHelper(importDefaultHelper); + return createCall(getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]); + } + return innerExpr; + } + /** * Visits an ImportDeclaration node. * @@ -681,7 +727,7 @@ namespace ts { createVariableDeclaration( getSynthesizedClone(namespaceDeclaration.name), /*type*/ undefined, - createRequireCall(node) + getHelperExpressionForImport(node, createRequireCall(node)) ) ); } @@ -694,7 +740,7 @@ namespace ts { createVariableDeclaration( getGeneratedNameForNode(node), /*type*/ undefined, - createRequireCall(node) + getHelperExpressionForImport(node, createRequireCall(node)) ) ); @@ -1671,4 +1717,28 @@ namespace ts { text: ` var __syncRequire = typeof module === "object" && typeof module.exports === "object";` }; + + // emit helper for `import * as Name from "foo"` + const importStarHelper: EmitHelper = { + name: "typescript:commonjsimportstar", + scoped: false, + text: ` +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}` + }; + + // emit helper for `import Name from "foo"` + const importDefaultHelper: EmitHelper = { + name: "typescript:commonjsimportdefault", + scoped: false, + text: ` +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}` + }; } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index e5d638cf04d..2e6f6d84b51 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -24,6 +24,7 @@ namespace ts { context.onSubstituteNode = onSubstituteNode; context.onEmitNode = onEmitNode; context.enableSubstitution(SyntaxKind.Identifier); // Substitutes expression identifiers for imported symbols. + context.enableSubstitution(SyntaxKind.ShorthandPropertyAssignment); // Substitutes expression identifiers for imported symbols context.enableSubstitution(SyntaxKind.BinaryExpression); // Substitutes assignments to exported symbols. context.enableSubstitution(SyntaxKind.PrefixUnaryExpression); // Substitutes updates to exported symbols. context.enableSubstitution(SyntaxKind.PostfixUnaryExpression); // Substitutes updates to exported symbols. @@ -1625,10 +1626,64 @@ namespace ts { if (hint === EmitHint.Expression) { return substituteExpression(node); } + else if (hint === EmitHint.Unspecified) { + return substituteUnspecified(node); + } return node; } + /** + * Substitute the node, if necessary. + * + * @param node The node to substitute. + */ + function substituteUnspecified(node: Node) { + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return substituteShorthandPropertyAssignment(node); + } + return node; + } + /** + * Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol. + * + * @param node The node to substitute. + */ + function substituteShorthandPropertyAssignment(node: ShorthandPropertyAssignment) { + const name = node.name; + if (!isGeneratedIdentifier(name) && !isLocalName(name)) { + const importDeclaration = resolver.getReferencedImportDeclaration(name); + if (importDeclaration) { + if (isImportClause(importDeclaration)) { + return setTextRange( + createPropertyAssignment( + getSynthesizedClone(name), + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent), + createIdentifier("default") + ) + ), + /*location*/ node + ); + } + else if (isImportSpecifier(importDeclaration)) { + return setTextRange( + createPropertyAssignment( + getSynthesizedClone(name), + createPropertyAccess( + getGeneratedNameForNode(importDeclaration.parent.parent.parent), + getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name) + ), + ), + /*location*/ node + ); + } + } + } + return node; + } + /** * Substitute the expression, if necessary. * diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 20bc77c5e17..0e70b3099c0 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -81,7 +81,7 @@ namespace ts { let classAliases: Identifier[]; /** - * Keeps track of whether we are within any containing namespaces when performing + * Keeps track of whether we are within any containing namespaces when performing * just-in-time substitution while printing an expression identifier. */ let applicableSubstitutions: TypeScriptSubstitutionFlags; @@ -894,11 +894,14 @@ namespace ts { if (some(staticProperties) || some(pendingExpressions)) { const expressions: Expression[] = []; - const temp = createTempVariable(hoistVariableDeclaration); - if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { + const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference; + const temp = createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference); + if (isClassWithConstructorReference) { // record an alias as the class name is not in scope for statics. enableSubstitutionForClassAliases(); - classAliases[getOriginalNodeId(node)] = getSynthesizedClone(temp); + const alias = getSynthesizedClone(temp); + alias.autoGenerateFlags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes; + classAliases[getOriginalNodeId(node)] = alias; } // To preserve the behavior of the old emitter, we explicitly indent diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index a012c9be7db..15e91d755ca 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -143,6 +143,7 @@ namespace ts { createLiteral(externalHelpersModuleNameText)); if (externalHelpersImportDeclaration) { + addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper); externalImports.unshift(externalHelpersImportDeclaration); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c544334b7dd..d32176d7be9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -58,6 +58,23 @@ namespace ts { end: number; } + export type JsDocSyntaxKind = + | SyntaxKind.EndOfFileToken + | SyntaxKind.WhitespaceTrivia + | SyntaxKind.AtToken + | SyntaxKind.NewLineTrivia + | SyntaxKind.AsteriskToken + | SyntaxKind.OpenBraceToken + | SyntaxKind.CloseBraceToken + | SyntaxKind.LessThanToken + | SyntaxKind.OpenBracketToken + | SyntaxKind.CloseBracketToken + | SyntaxKind.EqualsToken + | SyntaxKind.CommaToken + | SyntaxKind.DotToken + | SyntaxKind.Identifier + | SyntaxKind.Unknown; + // token > SyntaxKind.Identifer => token is a keyword // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync export const enum SyntaxKind { @@ -439,24 +456,24 @@ namespace ts { } export const enum NodeFlags { - None = 0, - Let = 1 << 0, // Variable declaration - Const = 1 << 1, // Variable declaration - NestedNamespace = 1 << 2, // Namespace declaration - Synthesized = 1 << 3, // Node was synthesized during transformation - Namespace = 1 << 4, // Namespace declaration - ExportContext = 1 << 5, // Export context (initialized by binding) - ContainsThis = 1 << 6, // Interface contains references to "this" - HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) - HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) + None = 0, + Let = 1 << 0, // Variable declaration + Const = 1 << 1, // Variable declaration + NestedNamespace = 1 << 2, // Namespace declaration + Synthesized = 1 << 3, // Node was synthesized during transformation + Namespace = 1 << 4, // Namespace declaration + ExportContext = 1 << 5, // Export context (initialized by binding) + ContainsThis = 1 << 6, // Interface contains references to "this" + HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) + HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope - HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) - DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed - YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator - DecoratorContext = 1 << 13, // If node was parsed as part of a decorator - AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function - ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node - JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript + HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) + DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed + YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator + DecoratorContext = 1 << 13, // If node was parsed as part of a decorator + AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function + ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node + JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node @@ -660,12 +677,18 @@ namespace ts { export type ModifiersArray = NodeArray; /*@internal*/ - export const enum GeneratedIdentifierKind { - None, // Not automatically generated. - Auto, // Automatically generated identifier. - Loop, // Automatically generated identifier with a preference for '_i'. - Unique, // Unique name based on the 'text' property. - Node, // Unique name based on the node in the 'original' property. + export const enum GeneratedIdentifierFlags { + // Kinds + None = 0, // Not automatically generated. + Auto = 1, // Automatically generated identifier. + Loop = 2, // Automatically generated identifier with a preference for '_i'. + Unique = 3, // Unique name based on the 'text' property. + Node = 4, // Unique name based on the node in the 'original' property. + KindMask = 7, // Mask to extract the kind of identifier from its flags. + + // Flags + SkipNameGenerationScope = 1 << 3, // Should skip a name generation scope when generating the name for this identifier + ReservedInNestedScopes = 1 << 4, // Reserve the generated name in nested scopes } export interface Identifier extends PrimaryExpression, Declaration { @@ -676,12 +699,11 @@ namespace ts { */ escapedText: __String; originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later - /*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier. + /*@internal*/ autoGenerateFlags?: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace - /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics. + /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. - /*@internal*/ skipNameGenerationScope?: boolean; // Should skip a name generation scope when generating the name for this identifier } // Transient identifier node (marked by id === -1) @@ -691,10 +713,7 @@ namespace ts { /*@internal*/ export interface GeneratedIdentifier extends Identifier { - autoGenerateKind: GeneratedIdentifierKind.Auto - | GeneratedIdentifierKind.Loop - | GeneratedIdentifierKind.Unique - | GeneratedIdentifierKind.Node; + autoGenerateFlags: GeneratedIdentifierFlags; } export interface QualifiedName extends Node { @@ -767,6 +786,7 @@ namespace ts { typeParameters?: NodeArray; parameters: NodeArray; type: TypeNode | undefined; + /* @internal */ typeArguments?: NodeArray; // Used for quick info, replaces typeParameters for instantiated signatures } export type SignatureDeclaration = @@ -950,7 +970,8 @@ namespace ts { | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration - | CallSignatureDeclaration; + | CallSignatureDeclaration + | JSDocFunctionType; export interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { kind: SyntaxKind.FunctionDeclaration; @@ -1141,11 +1162,13 @@ namespace ts { export interface StringLiteral extends LiteralExpression { kind: SyntaxKind.StringLiteral; - /* @internal */ textSourceNode?: Identifier | StringLiteral | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). + /* @internal */ textSourceNode?: Identifier | StringLiteralLike | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms). /** Note: this is only set when synthesizing a node, not during parsing. */ /* @internal */ singleQuote?: boolean; } + /* @internal */ export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral; + // Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing. // Consider 'Expression'. Without the brand, 'Expression' is actually no different // (structurally) than 'Node'. Because of this you can pass any Node to a function that @@ -1403,7 +1426,7 @@ namespace ts { export type BinaryOperatorToken = Token; - export interface BinaryExpression extends Expression, Declaration { + export interface BinaryExpression extends Expression, Declaration { kind: SyntaxKind.BinaryExpression; left: Expression; operatorToken: BinaryOperatorToken; @@ -1453,7 +1476,7 @@ namespace ts { | SpreadAssignment // AssignmentRestProperty ; - export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; export type ObjectBindingOrAssignmentPattern = ObjectBindingPattern @@ -1491,6 +1514,7 @@ namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, @@ -2148,6 +2172,7 @@ namespace ts { export interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -2549,7 +2574,7 @@ namespace ts { export interface ParseConfigHost { useCaseSensitiveFileNames: boolean; - readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray, includes: ReadonlyArray, depth: number): string[]; + readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray | undefined, includes: ReadonlyArray, depth?: number): string[]; /** * Gets a value indicating whether the specified path exists and is a file. @@ -2647,6 +2672,8 @@ namespace ts { /* @internal */ sourceFileToPackageName: Map; /** Set of all source files that some other source file redirects to. */ /* @internal */ redirectTargetsSet: Map; + /** Is the file emitted file */ + /* @internal */ isEmittedFile(file: string): boolean; } /* @internal */ @@ -2748,6 +2775,16 @@ namespace ts { signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; + /** Note that the resulting nodes cannot be checked. */ + symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName; + /** Note that the resulting nodes cannot be checked. */ + symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression; + /** Note that the resulting nodes cannot be checked. */ + symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray | undefined; + /** Note that the resulting nodes cannot be checked. */ + symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration; + /** Note that the resulting nodes cannot be checked. */ + typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol | undefined; @@ -2766,9 +2803,17 @@ namespace ts { getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined; getTypeAtLocation(node: Node): Type; getTypeFromTypeNode(node: TypeNode): Type; + signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; - symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): string; + typePredicateToString(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; + + /* @internal */ writeSignature(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind, writer?: EmitTextWriter): string; + /* @internal */ writeType(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter): string; + /* @internal */ writeSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags, writer?: EmitTextWriter): string; + /* @internal */ writeTypePredicate(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags, writer?: EmitTextWriter): string; + /** * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead * This will be removed in a future version. @@ -2870,7 +2915,7 @@ namespace ts { */ /* @internal */ isArrayLikeType(type: Type): boolean; /* @internal */ getAllPossiblePropertiesOfTypes(type: ReadonlyArray): Symbol[]; - /* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags): Symbol | undefined; + /* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags, excludeGlobals: boolean): Symbol | undefined; /* @internal */ getJsxNamespace(): string; /** @@ -2883,6 +2928,8 @@ namespace ts { * This should be called in a loop climbing parents of the symbol, so we'll get `N`. */ /* @internal */ getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined; + /* @internal */ getTypePredicateOfSignature(signature: Signature): TypePredicate; + /* @internal */ resolveExternalModuleSymbol(symbol: Symbol): Symbol; } /* @internal */ @@ -2892,30 +2939,100 @@ namespace ts { Subtype } - export enum NodeBuilderFlags { + export const enum NodeBuilderFlags { None = 0, // Options NoTruncation = 1 << 0, // Don't truncate result WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] + WriteDefaultSymbolWithoutName = 1 << 2, // Write `default`-named symbols as `default` instead of how they were written + UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible + // empty space WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) + UseOnlyExternalAliasing = 1 << 7, // Only use external aliases for a symbol SuppressAnyReturnType = 1 << 8, // If the return type is any-like, don't offer a return type. WriteTypeParametersInQualifiedName = 1 << 9, + MultilineObjectLiterals = 1 << 10, // Always write object literals across multiple lines + WriteClassExpressionAsTypeLiteral = 1 << 11, // Write class {} as { new(): {} } - used for mixin declaration emit + UseTypeOfFunction = 1 << 12, // Build using typeof instead of function type literal + OmitParameterModifiers = 1 << 13, // Omit modifiers on parameters + UseAliasDefinedOutsideCurrentScope = 1 << 14, // Allow non-visible aliases // Error handling - AllowThisInObjectLiteral = 1 << 10, - AllowQualifedNameInPlaceOfIdentifier = 1 << 11, - AllowAnonymousIdentifier = 1 << 13, - AllowEmptyUnionOrIntersection = 1 << 14, - AllowEmptyTuple = 1 << 15, + AllowThisInObjectLiteral = 1 << 15, + AllowQualifedNameInPlaceOfIdentifier = 1 << 16, + AllowAnonymousIdentifier = 1 << 17, + AllowEmptyUnionOrIntersection = 1 << 18, + AllowEmptyTuple = 1 << 19, + AllowUniqueESSymbolType = 1 << 20, + AllowEmptyIndexInfoType = 1 << 21, - IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple, + IgnoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple | AllowEmptyIndexInfoType, // State - InObjectTypeLiteral = 1 << 20, + InObjectTypeLiteral = 1 << 22, InTypeAlias = 1 << 23, // Writing type in type alias declaration } + // Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment + export const enum TypeFormatFlags { + None = 0, + NoTruncation = 1 << 0, // Don't truncate typeToString result + WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] + WriteDefaultSymbolWithoutName = 1 << 2, // Write all `defaut`-named symbols as `default` instead of their written name + UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible + // hole because there's a hole in node builder flags + WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature + UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) + // hole because `UseOnlyExternalAliasing` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` instead + SuppressAnyReturnType = 1 << 8, // If the return type is any-like, don't offer a return type. + // hole because `WriteTypeParametersInQualifiedName` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` for this instead + MultilineObjectLiterals = 1 << 10, // Always print object literals across multiple lines (only used to map into node builder flags) + WriteClassExpressionAsTypeLiteral = 1 << 11, // Write a type literal instead of (Anonymous class) + UseTypeOfFunction = 1 << 12, // Write typeof instead of function type literal + OmitParameterModifiers = 1 << 13, // Omit modifiers on parameters + UseAliasDefinedOutsideCurrentScope = 1 << 14, // For a `type T = ... ` defined in a different file, write `T` instead of its value, + // even though `T` can't be accessed in the current scope. + + // Error Handling + AllowUniqueESSymbolType = 1 << 20, // This is bit 20 to align with the same bit in `NodeBuilderFlags` + + // TypeFormatFlags exclusive + AddUndefined = 1 << 17, // Add undefined to types of initialized, non-optional parameters + WriteArrowStyleSignature = 1 << 18, // Write arrow style signature + + // State + InArrayType = 1 << 19, // Writing an array element type + InElementType = 1 << 21, // Writing an array or union element type + InFirstTypeArgument = 1 << 22, // Writing first type argument of the instantiated type + InTypeAlias = 1 << 23, // Writing type in type alias declaration + + /** @deprecated */ WriteOwnNameForAnyLike = 0, // Does nothing + + NodeBuilderFlagsMask = + NoTruncation | WriteArrayAsGenericType | WriteDefaultSymbolWithoutName | UseStructuralFallback | WriteTypeArgumentsOfSignature | + UseFullyQualifiedType | SuppressAnyReturnType | MultilineObjectLiterals | WriteClassExpressionAsTypeLiteral | + UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias, + } + + export const enum SymbolFormatFlags { + None = 0x00000000, + + // Write symbols's type argument if it is instantiated symbol + // eg. class C { p: T } <-- Show p as C.p here + // var a: C; + // var p = a.p; <--- Here p is property of C so show it as C.p instead of just C.p + WriteTypeParametersOrArguments = 0x00000001, + + // Use only external alias information to get the symbol name in the given context + // eg. module m { export class c { } } import x = m.c; + // When this flag is specified m.c will be used to refer to the class instead of alias symbol x + UseOnlyExternalAliasing = 0x00000002, + + // Build symbol name using any nodes needed, instead of just components of an entity name + AllowAnyNodeKind = 0x00000004, + } + /* @internal */ export interface SymbolWalker { /** Note: Return values are not ordered. */ @@ -2924,21 +3041,27 @@ namespace ts { walkSymbol(root: Symbol): { visitedTypes: ReadonlyArray, visitedSymbols: ReadonlyArray }; } + /** + * @deprecated + */ export interface SymbolDisplayBuilder { - buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; - buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; - buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; - buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; + /** @deprecated */ buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; + /** @deprecated */ buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; + /** @deprecated */ buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; } - export interface SymbolWriter { + /** + * @deprecated Migrate to other methods of generating symbol names, ex symbolToEntityName + a printer or symbolToString + */ + export interface SymbolWriter extends SymbolTracker { writeKeyword(text: string): void; writeOperator(text: string): void; writePunctuation(text: string): void; @@ -2951,50 +3074,6 @@ namespace ts { increaseIndent(): void; decreaseIndent(): void; clear(): void; - - // Called when the symbol writer encounters a symbol to write. Currently only used by the - // declaration emitter to help determine if it should patch up the final declaration file - // with import statements it previously saw (but chose not to emit). - trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; - reportInaccessibleThisError(): void; - reportPrivateInBaseOfClassExpression(propertyName: string): void; - reportInaccessibleUniqueSymbolError(): void; - } - - export const enum TypeFormatFlags { - None = 0, - WriteArrayAsGenericType = 1 << 0, // Write Array instead T[] - UseTypeOfFunction = 1 << 2, // Write typeof instead of function type literal - NoTruncation = 1 << 3, // Don't truncate typeToString result - WriteArrowStyleSignature = 1 << 4, // Write arrow style signature - WriteOwnNameForAnyLike = 1 << 5, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc) - WriteTypeArgumentsOfSignature = 1 << 6, // Write the type arguments instead of type parameters of the signature - InElementType = 1 << 7, // Writing an array or union element type - UseFullyQualifiedType = 1 << 8, // Write out the fully qualified type name (eg. Module.Type, instead of Type) - InFirstTypeArgument = 1 << 9, // Writing first type argument of the instantiated type - InTypeAlias = 1 << 10, // Writing type in type alias declaration - SuppressAnyReturnType = 1 << 12, // If the return type is any-like, don't offer a return type. - AddUndefined = 1 << 13, // Add undefined to types of initialized, non-optional parameters - WriteClassExpressionAsTypeLiteral = 1 << 14, // Write a type literal instead of (Anonymous class) - InArrayType = 1 << 15, // Writing an array element type - UseAliasDefinedOutsideCurrentScope = 1 << 16, // For a `type T = ... ` defined in a different file, write `T` instead of its value, - // even though `T` can't be accessed in the current scope. - AllowUniqueESSymbolType = 1 << 17, - } - - export const enum SymbolFormatFlags { - None = 0x00000000, - - // Write symbols's type argument if it is instantiated symbol - // eg. class C { p: T } <-- Show p as C.p here - // var a: C; - // var p = a.p; <--- Here p is property of C so show it as C.p instead of just C.p - WriteTypeParametersOrArguments = 0x00000001, - - // Use only external alias information to get the symbol name in the given context - // eg. module m { export class c { } } import x = m.c; - // When this flag is specified m.c will be used to refer to the class instead of alias symbol x - UseOnlyExternalAliasing = 0x00000002, } /* @internal */ @@ -3086,9 +3165,9 @@ namespace ts { isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean; - writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; - writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; - writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; + writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter): void; + writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter): void; + writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: EmitTextWriter): void; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult; isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; // Returns the constant value this property access resolves to, or 'undefined' for a non-constant @@ -3102,7 +3181,7 @@ namespace ts { getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[]; getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[]; isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean; - writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter): void; + writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: EmitTextWriter): void; getJsxFactoryEntity(): EntityName; } @@ -3238,6 +3317,7 @@ namespace ts { bindingElement?: BindingElement; // Binding element associated with property symbol exportsSomeValue?: boolean; // True if module exports some value (not just types) enumKind?: EnumKind; // Enum declaration classification + originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol` lateSymbol?: Symbol; // Late-bound symbol for a computed property } @@ -3260,6 +3340,7 @@ namespace ts { ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s) ContainsStatic = 1 << 9, // Synthetic property with static constituent(s) Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name + ReverseMapped = 1 << 11, // property of reverse-inferred homomorphic mapped type. Synthetic = SyntheticProperty | SyntheticMethod } @@ -3269,6 +3350,12 @@ namespace ts { isRestParameter?: boolean; } + /* @internal */ + export interface ReverseMappedSymbol extends TransientSymbol { + propertyType: Type; + mappedType: MappedType; + } + export const enum InternalSymbolName { Call = "__call", // Call signatures Constructor = "__constructor", // Constructor implementations @@ -3374,7 +3461,7 @@ namespace ts { resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt. - superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing + superCall?: SuperCall; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing switchTypes?: Type[]; // Cached array of switch case expression types } @@ -3508,8 +3595,9 @@ namespace ts { EvolvingArray = 1 << 8, // Evolving array type ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties ContainsSpread = 1 << 10, // Object literal contains spread operation - JsxAttributes = 1 << 11, // Jsx attributes type - MarkerType = 1 << 12, // Marker type used for variance probing + ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type + JsxAttributes = 1 << 12, // Jsx attributes type + MarkerType = 1 << 13, // Marker type used for variance probing ClassOrInterface = Class | Interface } @@ -3617,6 +3705,12 @@ namespace ts { finalArrayType?: Type; // Final array type of evolving array type } + /* @internal */ + export interface ReverseMappedType extends ObjectType { + source: Type; + mappedType: MappedType; + } + /* @internal */ // Resolved object, union, or intersection type export interface ResolvedType extends ObjectType, UnionOrIntersectionType { @@ -3630,7 +3724,7 @@ namespace ts { /* @internal */ // Object literals are initially marked fresh. Freshness disappears following an assignment, - // before a type assertion, or when an object literal's type is widened. The regular + // before a type assertion, or when an object literal's type is widened. The regular // version of a fresh type is identical except for the TypeFlags.FreshObjectLiteral flag. export interface FreshObjectLiteralType extends ResolvedType { regularType: ResolvedType; // Regular version of fresh type @@ -3768,20 +3862,19 @@ namespace ts { export type TypeMapper = (t: TypeParameter) => Type; export const enum InferencePriority { - Contravariant = 1 << 0, // Inference from contravariant position - NakedTypeVariable = 1 << 1, // Naked type variable in union or intersection type - MappedType = 1 << 2, // Reverse inference for mapped type - ReturnType = 1 << 3, // Inference made from return type of generic function - NeverType = 1 << 4, // Inference made from the never type + NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type + MappedType = 1 << 1, // Reverse inference for mapped type + ReturnType = 1 << 2, // Inference made from return type of generic function } export interface InferenceInfo { - typeParameter: TypeParameter; - candidates: Type[]; - inferredType: Type; - priority: InferencePriority; - topLevel: boolean; - isFixed: boolean; + typeParameter: TypeParameter; // Type parameter for which inferences are being made + candidates: Type[]; // Candidates in covariant positions (or undefined) + contraCandidates: Type[]; // Candidates in contravariant positions (or undefined) + inferredType: Type; // Cache for resolved inferred type + priority: InferencePriority; // Priority of current inference set + topLevel: boolean; // True if all inferences are to top level occurrences + isFixed: boolean; // True if inferences are fixed } export const enum InferenceFlags { @@ -3979,6 +4072,7 @@ namespace ts { typeRoots?: string[]; /*@internal*/ version?: boolean; /*@internal*/ watch?: boolean; + esModuleInterop?: boolean; [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; } @@ -4400,11 +4494,11 @@ namespace ts { * If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just * 'throw new Error("NotImplemented")' */ - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[]; /** * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files */ - resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; + resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[]; getEnvironmentVariable?(name: string): string; /* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions): void; /* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution; @@ -4449,6 +4543,8 @@ namespace ts { ContainsYield = 1 << 24, ContainsHoistedDeclarationOrCompletion = 1 << 25, ContainsDynamicImport = 1 << 26, + Super = 1 << 27, + ContainsSuper = 1 << 28, // Please leave this as 1 << 29. // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system. @@ -4469,7 +4565,9 @@ namespace ts { // Scope Exclusions // - Bitmasks that exclude flags from propagating out of a specific context // into the subtree flags of their container. - NodeExcludes = TypeScript | ES2015 | DestructuringAssignment | Generator | HasComputedFlags, + OuterExpressionExcludes = TypeScript | ES2015 | DestructuringAssignment | Generator | HasComputedFlags, + PropertyAccessExcludes = OuterExpressionExcludes | Super, + NodeExcludes = PropertyAccessExcludes | ContainsSuper, ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest, FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest, ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion | ContainsBindingPattern | ContainsObjectRest, @@ -4546,6 +4644,7 @@ namespace ts { Iterator = 1 << 23, // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable. NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions. /*@internal*/ TypeScriptClassWrapper = 1 << 25, // The node is an IIFE class wrapper created by the ts transform. + /*@internal*/ NeverApplyImportHelper = 1 << 26, // Indicates the node should never be wrapped with an import star helper (because, for example, it imports tslib itself) } export interface EmitHelper { @@ -4753,6 +4852,10 @@ namespace ts { * collisions. */ printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; + /** + * Prints a list of nodes using the given format flags + */ + printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): string; /** * Prints a source file as-is, without any emit transformations. */ @@ -4762,6 +4865,7 @@ namespace ts { */ printBundle(bundle: Bundle): string; /*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void; + /*@internal*/ writeList(format: ListFormat, list: NodeArray, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void; /*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void; /*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter): void; } @@ -4809,7 +4913,7 @@ namespace ts { */ substituteNode?(hint: EmitHint, node: Node): Node; /*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void; - /*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number; + /*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, writer: (s: string) => void, pos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, pos: number) => number) => number; /*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void; /*@internal*/ onEmitHelpers?: (node: Node, writeLines: (text: string) => void) => void; /*@internal*/ onSetSourceFile?: (node: SourceFile) => void; @@ -4822,13 +4926,14 @@ namespace ts { export interface PrinterOptions { removeComments?: boolean; newLine?: NewLineKind; + omitTrailingSemicolon?: boolean; /*@internal*/ sourceMap?: boolean; /*@internal*/ inlineSourceMap?: boolean; /*@internal*/ extendedDiagnostics?: boolean; } - /*@internal*/ - export interface EmitTextWriter { + /* @internal */ + export interface EmitTextWriter extends SymbolTracker, SymbolWriter { write(s: string): void; writeTextOfNode(text: string, node: Node): void; writeLine(): void; @@ -4842,7 +4947,26 @@ namespace ts { getColumn(): number; getIndent(): number; isAtStartOfLine(): boolean; - reset(): void; + clear(): void; + + writeKeyword(text: string): void; + writeOperator(text: string): void; + writePunctuation(text: string): void; + writeSpace(text: string): void; + writeStringLiteral(text: string): void; + writeParameter(text: string): void; + writeProperty(text: string): void; + writeSymbol(text: string, symbol: Symbol): void; + } + + export interface SymbolTracker { + // Called when the symbol writer encounters a symbol to write. Currently only used by the + // declaration emitter to help determine if it should patch up the final declaration file + // with import statements it previously saw (but chose not to emit). + trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; + reportInaccessibleThisError?(): void; + reportPrivateInBaseOfClassExpression?(propertyName: string): void; + reportInaccessibleUniqueSymbolError?(): void; } export interface TextSpan { @@ -4881,4 +5005,86 @@ namespace ts { export interface SyntaxList extends Node { _children: Node[]; } + + export const enum ListFormat { + None = 0, + + // Line separators + SingleLine = 0, // Prints the list on a single line (default). + MultiLine = 1 << 0, // Prints the list on multiple lines. + PreserveLines = 1 << 1, // Prints the list using line preservation if possible. + LinesMask = SingleLine | MultiLine | PreserveLines, + + // Delimiters + NotDelimited = 0, // There is no delimiter between list items (default). + BarDelimited = 1 << 2, // Each list item is space-and-bar (" |") delimited. + AmpersandDelimited = 1 << 3, // Each list item is space-and-ampersand (" &") delimited. + CommaDelimited = 1 << 4, // Each list item is comma (",") delimited. + DelimitersMask = BarDelimited | AmpersandDelimited | CommaDelimited, + + AllowTrailingComma = 1 << 5, // Write a trailing comma (",") if present. + + // Whitespace + Indented = 1 << 6, // The list should be indented. + SpaceBetweenBraces = 1 << 7, // Inserts a space after the opening brace and before the closing brace. + SpaceBetweenSiblings = 1 << 8, // Inserts a space between each sibling node. + + // Brackets/Braces + Braces = 1 << 9, // The list is surrounded by "{" and "}". + Parenthesis = 1 << 10, // The list is surrounded by "(" and ")". + AngleBrackets = 1 << 11, // The list is surrounded by "<" and ">". + SquareBrackets = 1 << 12, // The list is surrounded by "[" and "]". + BracketsMask = Braces | Parenthesis | AngleBrackets | SquareBrackets, + + OptionalIfUndefined = 1 << 13, // Do not emit brackets if the list is undefined. + OptionalIfEmpty = 1 << 14, // Do not emit brackets if the list is empty. + Optional = OptionalIfUndefined | OptionalIfEmpty, + + // Other + PreferNewLine = 1 << 15, // Prefer adding a LineTerminator between synthesized nodes. + NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list. + NoInterveningComments = 1 << 17, // Do not emit comments between each node + + NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces. + SingleElement = 1 << 19, + + // Precomputed Formats + Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments, + HeritageClauses = SingleLine | SpaceBetweenSiblings, + SingleLineTypeLiteralMembers = SingleLine | SpaceBetweenBraces | SpaceBetweenSiblings | Indented, + MultiLineTypeLiteralMembers = MultiLine | Indented, + + TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented, + UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine, + IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine, + ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, + ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty, + ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty, + ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets, + CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine, + CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, + NewExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis | OptionalIfUndefined, + TemplateExpressionSpans = SingleLine | NoInterveningComments, + SingleLineBlockStatements = SpaceBetweenBraces | SpaceBetweenSiblings | SingleLine, + MultiLineBlockStatements = Indented | MultiLine, + VariableDeclarationList = CommaDelimited | SpaceBetweenSiblings | SingleLine, + SingleLineFunctionBodyStatements = SingleLine | SpaceBetweenSiblings | SpaceBetweenBraces, + MultiLineFunctionBodyStatements = MultiLine, + ClassHeritageClauses = SingleLine | SpaceBetweenSiblings, + ClassMembers = Indented | MultiLine, + InterfaceMembers = Indented | MultiLine, + EnumMembers = CommaDelimited | Indented | MultiLine, + CaseBlockClauses = Indented | MultiLine, + NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces, + JsxElementOrFragmentChildren = SingleLine | NoInterveningComments, + JsxElementAttributes = SingleLine | SpaceBetweenSiblings | NoInterveningComments, + CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty, + HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine, + SourceFileStatements = MultiLine | NoTrailingNewLine, + Decorators = MultiLine | Optional, + TypeArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | AngleBrackets | Optional, + TypeParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | AngleBrackets | Optional, + Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis, + IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets, + } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a111016dd8f..7fd142d981a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5,6 +5,7 @@ namespace ts { export const emptyArray: never[] = [] as never[]; export const resolvingEmptyArray: never[] = [] as never[]; export const emptyMap: ReadonlyMap = createMap(); + export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap = emptyMap as ReadonlyUnderscoreEscapedMap; export const externalHelpersModuleNameText = "tslib"; @@ -28,26 +29,31 @@ namespace ts { return undefined; } - export interface StringSymbolWriter extends SymbolWriter { - string(): string; - } - const stringWriter = createSingleLineStringWriter(); - function createSingleLineStringWriter(): StringSymbolWriter { + function createSingleLineStringWriter(): EmitTextWriter { let str = ""; const writeText: (text: string) => void = text => str += text; return { - string: () => str, + getText: () => str, + write: writeText, + rawWrite: writeText, + writeTextOfNode: writeText, writeKeyword: writeText, writeOperator: writeText, writePunctuation: writeText, writeSpace: writeText, writeStringLiteral: writeText, + writeLiteral: writeText, writeParameter: writeText, writeProperty: writeText, writeSymbol: writeText, + getTextPos: () => str.length, + getLine: () => 0, + getColumn: () => 0, + getIndent: () => 0, + isAtStartOfLine: () => false, // Completely ignore indentation for string writers. And map newlines to // a single space. @@ -62,11 +68,11 @@ namespace ts { }; } - export function usingSingleLineStringWriter(action: (writer: StringSymbolWriter) => void): string { - const oldString = stringWriter.string(); + export function usingSingleLineStringWriter(action: (writer: EmitTextWriter) => void): string { + const oldString = stringWriter.getText(); try { action(stringWriter); - return stringWriter.string(); + return stringWriter.getText(); } finally { stringWriter.clear(); @@ -110,6 +116,11 @@ namespace ts { return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version; } + export function packageIdToString({ name, subModuleName, version }: PackageId): string { + const fullName = subModuleName ? `${name}/${subModuleName}` : name; + return `${fullName}@${version}`; + } + export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirective, newResolution: ResolvedTypeReferenceDirective): boolean { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } @@ -803,7 +814,7 @@ namespace ts { return node === (parent).type; case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: - return (parent).typeArguments && indexOf((parent).typeArguments, node) >= 0; + return contains((parent).typeArguments, node); case SyntaxKind.TaggedTemplateExpression: // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments. return false; @@ -1419,6 +1430,8 @@ namespace ts { * exactly one argument (of the form 'require("name")'). * This function does not test if the node is in a JavaScript file or not. */ + export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: true): callExpression is CallExpression & { expression: Identifier, arguments: [StringLiteralLike] }; + export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression; export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression { if (callExpression.kind !== SyntaxKind.CallExpression) { return false; @@ -1456,7 +1469,7 @@ namespace ts { return false; } - export function getRightMostAssignedExpression(node: Node) { + export function getRightMostAssignedExpression(node: Expression): Expression { while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) { node = node.right; } @@ -1583,42 +1596,35 @@ namespace ts { ((node as JSDocFunctionType).parameters[0].name as Identifier).escapedText === "new"; } - export function getAllJSDocs(node: Node): (JSDoc | JSDocTag)[] { - if (isJSDocTypedefTag(node)) { - return [node.parent]; - } - return getJSDocCommentsAndTags(node); - } - - export function getSourceOfAssignment(node: Node): Node { + function getSourceOfAssignment(node: Node): Node { return isExpressionStatement(node) && node.expression && isBinaryExpression(node.expression) && node.expression.operatorToken.kind === SyntaxKind.EqualsToken && node.expression.right; } - export function getSingleInitializerOfVariableStatement(node: Node, child?: Node): Node { + function getSingleInitializerOfVariableStatement(node: Node, child?: Node): Node { return isVariableStatement(node) && node.declarationList.declarations.length > 0 && (!child || node.declarationList.declarations[0].initializer === child) && node.declarationList.declarations[0].initializer; } - export function getSingleVariableOfVariableStatement(node: Node, child?: Node): Node { + function getSingleVariableOfVariableStatement(node: Node, child?: Node): Node { return isVariableStatement(node) && node.declarationList.declarations.length > 0 && (!child || node.declarationList.declarations[0] === child) && node.declarationList.declarations[0]; } - export function getNestedModuleDeclaration(node: Node): Node { + function getNestedModuleDeclaration(node: Node): Node { return node.kind === SyntaxKind.ModuleDeclaration && (node as ModuleDeclaration).body && (node as ModuleDeclaration).body.kind === SyntaxKind.ModuleDeclaration && (node as ModuleDeclaration).body; } - export function getJSDocCommentsAndTags(node: Node): (JSDoc | JSDocTag)[] { + export function getJSDocCommentsAndTags(node: Node): ReadonlyArray { let result: (JSDoc | JSDocTag)[] | undefined; getJSDocCommentsAndTagsWorker(node); return result || emptyArray; @@ -2119,6 +2125,10 @@ namespace ts { return "__@" + symbolName as __String; } + export function isKnownSymbol(symbol: Symbol): boolean { + return startsWith(symbol.escapedName as string, "__@"); + } + /** * Includes the word "Symbol" with unicode escapes */ @@ -2606,7 +2616,19 @@ namespace ts { getColumn: () => lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1, getText: () => output, isAtStartOfLine: () => lineStart, - reset + clear: reset, + reportInaccessibleThisError: noop, + reportPrivateInBaseOfClassExpression: noop, + reportInaccessibleUniqueSymbolError: noop, + trackSymbol: noop, + writeKeyword: write, + writeOperator: write, + writeParameter: write, + writeProperty: write, + writePunctuation: write, + writeSpace: write, + writeStringLiteral: write, + writeSymbol: write }; } @@ -3917,8 +3939,8 @@ namespace ts { // // { // oldStart3: Min(oldStart1, oldStart2), - // oldEnd3 : Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)), - // newEnd3 : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)) + // oldEnd3: Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)), + // newEnd3: Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)) // } const oldStart1 = oldStartN; @@ -4403,7 +4425,7 @@ namespace ts { return node.kind === SyntaxKind.RegularExpressionLiteral; } - export function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression { + export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral { return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral; } @@ -5121,7 +5143,7 @@ namespace ts { /* @internal */ export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier { // Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`. - return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None; + return isIdentifier(node) && (node.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) > GeneratedIdentifierFlags.None; } // Keywords @@ -5847,4 +5869,19 @@ namespace ts { export function hasOnlyExpressionInitializer(node: Node): node is HasExpressionInitializer { return hasInitializer(node) && !isForStatement(node) && !isForInStatement(node) && !isForOfStatement(node) && !isJsxAttribute(node); } + + export function isObjectLiteralElement(node: Node): node is ObjectLiteralElement { + switch (node.kind) { + case SyntaxKind.JsxAttribute: + case SyntaxKind.JsxSpreadAttribute: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return true; + default: + return false; + } + } } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index b047a778015..db37749caea 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -3,6 +3,8 @@ /// namespace ts { + const isTypeNodeOrTypeParameterDeclaration = or(isTypeNode, isTypeParameterDeclaration); + /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -222,7 +224,7 @@ namespace ts { // Names case SyntaxKind.Identifier: - return updateIdentifier(node, nodesVisitor((node).typeArguments, visitor, isTypeNode)); + return updateIdentifier(node, nodesVisitor((node).typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration)); case SyntaxKind.QualifiedName: return updateQualifiedName(node, @@ -629,7 +631,7 @@ namespace ts { case SyntaxKind.ForOfStatement: return updateForOf(node, - (node).awaitModifier, + visitNode((node).awaitModifier, visitor, isToken), visitNode((node).initializer, visitor, isForInitializer), visitNode((node).expression, visitor, isExpression), visitNode((node).statement, visitor, isStatement, liftToBlock)); diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index b4ed1c1ac1b..79e26f5986c 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -20,6 +20,9 @@ namespace ts { // Callbacks to do custom action before creating program and after creating program beforeCompile(compilerOptions: CompilerOptions): void; afterCompile(host: DirectoryStructureHost, program: Program, builder: Builder): void; + + // Only for testing + maxNumberOfFilesToIterateForInvalidation?: number; } const defaultFormatDiagnosticsHost: FormatDiagnosticsHost = sys ? { @@ -301,6 +304,8 @@ namespace ts { hasChangedAutomaticTypeDirectiveNames = true; scheduleProgramUpdate(); }, + maxNumberOfFilesToIterateForInvalidation: watchingHost.maxNumberOfFilesToIterateForInvalidation, + getCurrentProgram, writeLog }; // Cache for the module resolution @@ -318,7 +323,11 @@ namespace ts { // Update the wild card directory watch watchConfigFileWildCardDirectories(); - return () => program; + return getCurrentProgram; + + function getCurrentProgram() { + return program; + } function synchronizeProgram() { writeLog(`Synchronizing program`); diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index 0cf38f372d9..0bc6920479b 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -82,6 +82,14 @@ namespace ts { } } + export function isEmittedFileOfProgram(program: Program | undefined, file: string) { + if (!program) { + return false; + } + + return program.isEmittedFile(file); + } + export function addFileWatcher(host: System, file: string, cb: FileWatcherCallback): FileWatcher { return host.watchFile(file, cb); } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index fefee7ca3bd..4c0c72a200f 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -170,11 +170,7 @@ namespace FourSlash { // This function creates IScriptSnapshot object for testing getPreProcessedFileInfo // Return object may lack some functionalities for other purposes. function createScriptSnapShot(sourceText: string): ts.IScriptSnapshot { - return { - getText: (start: number, end: number) => sourceText.substr(start, end - start), - getLength: () => sourceText.length, - getChangeRange: () => undefined - }; + return ts.ScriptSnapshot.fromString(sourceText); } export class TestState { @@ -262,13 +258,13 @@ namespace FourSlash { let startResolveFileRef: FourSlashFile; let configFileName: string; - ts.forEach(testData.files, file => { + for (const file of testData.files) { // Create map between fileName and its content for easily looking up when resolveReference flag is specified this.inputFiles.set(file.fileName, file.content); - if (ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json") { + if (isConfig(file)) { const configJson = ts.parseConfigFileTextToJson(file.fileName, file.content); if (configJson.config === undefined) { - throw new Error(`Failed to parse test tsconfig.json: ${configJson.error.messageText}`); + throw new Error(`Failed to parse test ${file.fileName}: ${configJson.error.messageText}`); } // Extend our existing compiler options so that we can also support tsconfig only options @@ -290,7 +286,7 @@ namespace FourSlash { // If entry point for resolving file references is already specified, report duplication error throw new Error("There exists a Fourslash file which has resolveReference flag specified; remove duplicated resolveReference flag"); } - }); + } if (configFileName) { const baseDir = ts.normalizePath(ts.getDirectoryPath(configFileName)); @@ -299,12 +295,7 @@ namespace FourSlash { const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName)); assert.isTrue(configJsonObj.config !== undefined); - const { options, errors } = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir); - - // Extend our existing compiler options so that we can also support tsconfig only options - if (!errors || errors.length === 0) { - compilationOptions = ts.extend(compilationOptions, options); - } + compilationOptions = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir, compilationOptions, configFileName).options; } @@ -381,6 +372,7 @@ namespace FourSlash { insertSpaceAfterTypeAssertion: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, + insertSpaceBeforeTypeAnnotation: false }; // Open the first file by default @@ -441,12 +433,11 @@ namespace FourSlash { this.goToPosition(marker.position); } - public goToEachMarker(action: () => void) { - const markers = this.getMarkers(); + public goToEachMarker(markers: ReadonlyArray, action: (marker: FourSlash.Marker, index: number) => void) { assert(markers.length); - for (const marker of markers) { - this.goToMarker(marker); - action(); + for (let i = 0; i < markers.length; i++) { + this.goToMarker(markers[i]); + action(markers[i], i); } } @@ -454,7 +445,7 @@ namespace FourSlash { const ranges = this.getRanges(); assert(ranges.length); for (const range of ranges) { - this.goToRangeStart(range); + this.selectRange(range); action(); } } @@ -482,6 +473,11 @@ namespace FourSlash { this.selectionEnd = end.position; } + public selectRange(range: Range): void { + this.goToRangeStart(range); + this.selectionEnd = range.end; + } + public moveCaretRight(count = 1) { this.currentCaretPosition += count; this.currentCaretPosition = Math.min(this.currentCaretPosition, this.getFileContent(this.activeFile.fileName).length); @@ -511,7 +507,7 @@ namespace FourSlash { } } - private raiseError(message: string) { + private raiseError(message: string): never { throw new Error(this.messageAtLastKnownMarker(message)); } @@ -848,10 +844,10 @@ namespace FourSlash { } } - public verifyCompletionsAt(markerName: string, expected: string[], options?: FourSlashInterface.CompletionsAtOptions) { + public verifyCompletionsAt(markerName: string, expected: ReadonlyArray, options?: FourSlashInterface.CompletionsAtOptions) { this.goToMarker(markerName); - const actualCompletions = this.getCompletionListAtCaret(); + const actualCompletions = this.getCompletionListAtCaret(options); if (!actualCompletions) { this.raiseError(`No completions at position '${this.currentCaretPosition}'.`); } @@ -867,13 +863,24 @@ namespace FourSlash { } ts.zipWith(actual, expected, (completion, expectedCompletion, index) => { - if (completion.name !== expectedCompletion) { + const { name, insertText, replacementSpan } = typeof expectedCompletion === "string" ? { name: expectedCompletion, insertText: undefined, replacementSpan: undefined } : expectedCompletion; + if (completion.name !== name) { this.raiseError(`Expected completion at index ${index} to be ${expectedCompletion}, got ${completion.name}`); } + if (completion.insertText !== insertText) { + this.raiseError(`Expected completion insert text at index ${index} to be ${insertText}, got ${completion.insertText}`); + } + const convertedReplacementSpan = replacementSpan && textSpanFromRange(replacementSpan); + try { + assert.deepEqual(completion.replacementSpan, convertedReplacementSpan); + } + catch { + this.raiseError(`Expected completion replacementSpan at index ${index} to be ${stringify(convertedReplacementSpan)}, got ${stringify(completion.replacementSpan)}`); + } }); } - public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) { + public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) { const completions = this.getCompletionListAtCaret(options); if (completions) { this.assertItemInCompletionList(completions.entries, entryId, text, documentation, kind, spanIndex, hasAction, options); @@ -894,7 +901,7 @@ namespace FourSlash { * @param expectedKind the kind of symbol (see ScriptElementKind) * @param spanIndex the index of the range that the completion item's replacement text span should match */ - public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number, options?: FourSlashInterface.CompletionsAtOptions) { + public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, options?: FourSlashInterface.CompletionsAtOptions) { let replacementSpan: ts.TextSpan; if (spanIndex !== undefined) { replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex); @@ -903,7 +910,7 @@ namespace FourSlash { const completions = this.getCompletionListAtCaret(options); if (completions) { let filterCompletions = completions.entries.filter(e => e.name === entryId.name && e.source === entryId.source); - filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions; + filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind || (typeof expectedKind === "object" && e.kind === expectedKind.kind)) : filterCompletions; filterCompletions = filterCompletions.filter(entry => { const details = this.getCompletionEntryDetails(entry.name); const documentation = details && ts.displayPartsToString(details.documentation); @@ -1808,7 +1815,7 @@ Actual: ${stringify(fullActual)}`); } else if (prevChar === " " && /A-Za-z_/.test(ch)) { /* Completions */ - this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, { includeExternalModuleExports: false }); + this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); } if (i % checkCadence === 0) { @@ -2383,7 +2390,8 @@ Actual: ${stringify(fullActual)}`); public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) { this.goToMarker(markerName); - const actualCompletion = this.getCompletionListAtCaret({ includeExternalModuleExports: true }).entries.find(e => e.name === options.name && e.source === options.source); + const actualCompletion = this.getCompletionListAtCaret({ includeExternalModuleExports: true, includeInsertTextCompletions: false }).entries.find(e => + e.name === options.name && e.source === options.source); if (!actualCompletion.hasAction) { this.raiseError(`Completion for ${options.name} does not have an associated action.`); @@ -3090,7 +3098,7 @@ Actual: ${stringify(fullActual)}`); entryId: ts.Completions.CompletionEntryIdentifier, text: string | undefined, documentation: string | undefined, - kind: string | undefined, + kind: string | undefined | { kind?: string, kindModifiers?: string }, spanIndex: number | undefined, hasAction: boolean | undefined, options: FourSlashInterface.VerifyCompletionListContainsOptions | undefined, @@ -3124,9 +3132,21 @@ Actual: ${stringify(fullActual)}`); } if (kind !== undefined) { - assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId)); + if (typeof kind === "string") { + assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId)); + } + else { + if (kind.kind) { + assert.equal(item.kind, kind.kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId)); + } + if (kind.kindModifiers !== undefined) { + assert.equal(item.kindModifiers, kind.kindModifiers, this.assertionMessageAtLastKnownMarker("completion item kindModifiers for " + entryId)); + } + } } + + if (spanIndex !== undefined) { const span = this.getTextSpanForRangeAtIndex(spanIndex); assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId)); @@ -3183,8 +3203,7 @@ Actual: ${stringify(fullActual)}`); private getTextSpanForRangeAtIndex(index: number): ts.TextSpan { const ranges = this.getRanges(); if (ranges && ranges.length > index) { - const range = ranges[index]; - return { start: range.start, length: range.end - range.start }; + return textSpanFromRange(ranges[index]); } else { this.raiseError("Supplied span index: " + index + " does not exist in range list of size: " + (ranges ? 0 : ranges.length)); @@ -3214,6 +3233,10 @@ Actual: ${stringify(fullActual)}`); } } + function textSpanFromRange(range: FourSlash.Range): ts.TextSpan { + return ts.createTextSpanFromBounds(range.start, range.end); + } + export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) { const content = Harness.IO.readFile(fileName); runFourSlashTestContent(basePath, testType, content, fileName); @@ -3373,13 +3396,14 @@ ${code} } // @Filename is the only directive that can be used in a test that contains tsconfig.json file. - if (containTSConfigJson(files)) { + const config = ts.find(files, isConfig); + if (config) { let directive = getNonFileNameOptionInFileList(files); if (!directive) { directive = getNonFileNameOptionInObject(globalOptions); } if (directive) { - throw Error("It is not allowed to use tsconfig.json along with directive '" + directive + "'"); + throw Error(`It is not allowed to use ${config.fileName} along with directive '${directive}'`); } } @@ -3392,8 +3416,8 @@ ${code} }; } - function containTSConfigJson(files: FourSlashFile[]): boolean { - return ts.forEach(files, f => f.fileOptions.Filename === "tsconfig.json"); + function isConfig(file: FourSlashFile): boolean { + return Harness.getConfigNameFromFileName(file.fileName) !== undefined; } function getNonFileNameOptionInFileList(files: FourSlashFile[]): string { @@ -3764,8 +3788,11 @@ namespace FourSlashInterface { this.state.goToMarker(name); } - public eachMarker(action: () => void) { - this.state.goToEachMarker(action); + public eachMarker(markers: ReadonlyArray, action: (marker: FourSlash.Marker, index: number) => void): void; + public eachMarker(action: (marker: FourSlash.Marker, index: number) => void): void; + public eachMarker(a: ReadonlyArray | ((marker: FourSlash.Marker, index: number) => void), b?: (marker: FourSlash.Marker, index: number) => void): void { + const markers = typeof a === "function" ? this.state.getMarkers() : a.map(m => this.state.getMarkerByName(m)); + this.state.goToEachMarker(markers, typeof a === "function" ? a : b); } public rangeStart(range: FourSlash.Range) { @@ -3805,6 +3832,10 @@ namespace FourSlashInterface { public select(startMarker: string, endMarker: string) { this.state.select(startMarker, endMarker); } + + public selectRange(range: FourSlash.Range): void { + this.state.selectRange(range); + } } export class VerifyNegatable { @@ -3840,7 +3871,7 @@ namespace FourSlashInterface { // Verifies the completion list contains the specified symbol. The // completion list is brought up if necessary - public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: VerifyCompletionListContainsOptions) { + public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: VerifyCompletionListContainsOptions) { if (typeof entryId === "string") { entryId = { name: entryId, source: undefined }; } @@ -3952,7 +3983,7 @@ namespace FourSlashInterface { super(state); } - public completionsAt(markerName: string, completions: string[], options?: CompletionsAtOptions) { + public completionsAt(markerName: string, completions: ReadonlyArray, options?: CompletionsAtOptions) { this.state.verifyCompletionsAt(markerName, completions, options); } @@ -4576,6 +4607,7 @@ namespace FourSlashInterface { newContent: string; } + export type ExpectedCompletionEntry = string | { name: string, insertText?: string, replacementSpan?: FourSlash.Range }; export interface CompletionsAtOptions extends ts.GetCompletionsAtPositionOptions { isNewIdentifierLocation?: boolean; } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index b38bd523fae..f2f8587d834 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -63,7 +63,7 @@ declare var window: {}; declare var XMLHttpRequest: { new(): XMLHttpRequest; }; -interface XMLHttpRequest { +interface XMLHttpRequest { readonly readyState: number; readonly responseText: string; readonly status: number; @@ -874,7 +874,7 @@ namespace Harness { // Cache of lib files from "built/local" let libFileNameSourceFileMap: ts.Map | undefined; - // Cache of lib files from "tests/lib/" + // Cache of lib files from "tests/lib/" const testLibFileNameSourceFileMap = ts.createMap(); const es6TestLibFileNameSourceFileMap = ts.createMap(); @@ -1961,7 +1961,7 @@ namespace Harness { let tsConfigFileUnitData: TestUnitData; for (let i = 0; i < testUnitData.length; i++) { const data = testUnitData[i]; - if (ts.getBaseFileName(data.name).toLowerCase() === "tsconfig.json") { + if (getConfigNameFromFileName(data.name)) { const configJson = ts.parseJsonText(data.name, data.content); assert.isTrue(configJson.endOfFileToken !== undefined); let baseDir = ts.normalizePath(ts.getDirectoryPath(data.name)); @@ -2172,5 +2172,10 @@ namespace Harness { return { unitName: libFile, content: io.readFile(libFile) }; } + export function getConfigNameFromFileName(filename: string): "tsconfig.json" | "jsconfig.json" | undefined { + const flc = ts.getBaseFileName(filename).toLowerCase(); + return ts.find(["tsconfig.json" as "tsconfig.json", "jsconfig.json" as "jsconfig.json"], x => x === flc); + } + if (Error) (Error).stackTraceLimit = 100; } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index d51517c159b..0e142debedc 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -84,7 +84,7 @@ namespace Harness.LanguageService { } class ScriptSnapshotProxy implements ts.ScriptSnapshotShim { - constructor(public scriptSnapshot: ts.IScriptSnapshot) { + constructor(private readonly scriptSnapshot: ts.IScriptSnapshot) { } public getText(start: number, end: number): string { @@ -96,14 +96,8 @@ namespace Harness.LanguageService { } public getChangeRange(oldScript: ts.ScriptSnapshotShim): string { - const oldShim = oldScript; - - const range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot); - if (range === undefined) { - return undefined; - } - - return JSON.stringify({ span: { start: range.span.start, length: range.span.length }, newLength: range.newLength }); + const range = this.scriptSnapshot.getChangeRange((oldScript as ScriptSnapshotProxy).scriptSnapshot); + return range && JSON.stringify(range); } } @@ -236,12 +230,7 @@ namespace Harness.LanguageService { } readFile(path: string): string | undefined { const target = this.symlinks.get(path); - if (target !== undefined) { - return this.readFile(target); - } - - const snapshot = this.getScriptSnapshot(path); - return snapshot.getText(0, snapshot.getLength()); + return target !== undefined ? this.readFile(target) : ts.getSnapshotText(this.getScriptSnapshot(path)); } addSymlink(from: string, target: string) { this.symlinks.set(from, target); } realpath(path: string): string { @@ -350,7 +339,7 @@ namespace Harness.LanguageService { fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; } readFile(fileName: string) { const snapshot = this.nativeHost.getScriptSnapshot(fileName); - return snapshot && snapshot.getText(0, snapshot.getLength()); + return snapshot && ts.getSnapshotText(snapshot); } log(s: string): void { this.nativeHost.log(s); } trace(s: string): void { this.nativeHost.trace(s); } @@ -654,7 +643,7 @@ namespace Harness.LanguageService { } const snapshot = this.host.getScriptSnapshot(fileName); - return snapshot && snapshot.getText(0, snapshot.getLength()); + return snapshot && ts.getSnapshotText(snapshot); } writeFile = ts.noop; diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts index eca719628c7..59105cd5b08 100644 --- a/src/harness/parallel/host.ts +++ b/src/harness/parallel/host.ts @@ -9,6 +9,8 @@ namespace Harness.Parallel.Host { on(event: "error", listener: (err: Error) => void): this; on(event: "exit", listener: (code: number, signal: string) => void): this; on(event: "message", listener: (message: ParallelClientMessage) => void): this; + kill(signal?: string): void; + currentTasks?: {file: string}[]; // Custom monkeypatch onto child process handle } interface ProgressBarsOptions { @@ -134,6 +136,11 @@ namespace Harness.Parallel.Host { const newPerfData: {[testHash: string]: number} = {}; const workers: ChildProcessPartial[] = []; + const defaultTimeout = globalTimeout !== undefined + ? globalTimeout + : mocha && mocha.suite && mocha.suite._timeout + ? mocha.suite._timeout + : 20000; // 20 seconds let closedWorkers = 0; for (let i = 0; i < workerCount; i++) { // TODO: Just send the config over the IPC channel or in the command line arguments @@ -141,6 +148,14 @@ namespace Harness.Parallel.Host { const configPath = ts.combinePaths(taskConfigsFolder, `task-config${i}.json`); Harness.IO.writeFile(configPath, JSON.stringify(config)); const child = fork(__filename, [`--config="${configPath}"`]); + let currentTimeout = defaultTimeout; + const killChild = () => { + child.kill(); + console.error(`Worker exceeded ${currentTimeout}ms timeout ${child.currentTasks && child.currentTasks.length ? `while running test '${child.currentTasks[0].file}'.` : `during test setup.`}`); + return process.exit(2); + }; + let timer = setTimeout(killChild, currentTimeout); + const timeoutStack: number[] = []; child.on("error", err => { console.error("Unexpected error in child process:"); console.error(err); @@ -160,8 +175,25 @@ namespace Harness.Parallel.Host { Stack: ${data.payload.stack}`); return process.exit(2); } + case "timeout": { + clearTimeout(timer); + if (data.payload.duration === "reset") { + currentTimeout = timeoutStack.pop() || defaultTimeout; + } + else { + timeoutStack.push(currentTimeout); + currentTimeout = data.payload.duration; + } + timer = setTimeout(killChild, currentTimeout); // Reset timeout on timeout update, for when a timeout changes while a suite is executing + break; + } case "progress": case "result": { + clearTimeout(timer); + timer = setTimeout(killChild, currentTimeout); + if (child.currentTasks) { + child.currentTasks.shift(); + } totalPassing += data.payload.passing; if (data.payload.errors.length) { errorResults = errorResults.concat(data.payload.errors); @@ -195,6 +227,7 @@ namespace Harness.Parallel.Host { while (tasks.length && taskList.reduce((p, c) => p + c.size, 0) < chunkSize) { taskList.push(tasks.pop()); } + child.currentTasks = taskList; if (taskList.length === 1) { child.send({ type: "test", payload: taskList[0] }); } @@ -252,18 +285,22 @@ namespace Harness.Parallel.Host { for (const worker of workers) { const payload = batches.pop(); if (payload) { + worker.currentTasks = payload; worker.send({ type: "batch", payload }); } else { // Out of batches, send off just one test const payload = tasks.pop(); ts.Debug.assert(!!payload); // The reserve kept above should ensure there is always an initial task available, even in suboptimal scenarios + worker.currentTasks = [payload]; worker.send({ type: "test", payload }); } } } else { for (let i = 0; i < workerCount; i++) { - workers[i].send({ type: "test", payload: tasks.pop() }); + const task = tasks.pop(); + workers[i].currentTasks = [task]; + workers[i].send({ type: "test", payload: task }); } } diff --git a/src/harness/parallel/shared.ts b/src/harness/parallel/shared.ts index 2eb7777f828..26b03ac6234 100644 --- a/src/harness/parallel/shared.ts +++ b/src/harness/parallel/shared.ts @@ -10,5 +10,6 @@ namespace Harness.Parallel { export type ErrorInfo = ParallelErrorMessage["payload"] & { name: string[] }; export type ParallelResultMessage = { type: "result", payload: { passing: number, errors: ErrorInfo[], duration: number, runner: TestRunnerKind | "unittest", file: string } } | never; export type ParallelBatchProgressMessage = { type: "progress", payload: ParallelResultMessage["payload"] } | never; - export type ParallelClientMessage = ParallelErrorMessage | ParallelResultMessage | ParallelBatchProgressMessage; + export type ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: number | "reset" } } | never; + export type ParallelClientMessage = ParallelErrorMessage | ParallelResultMessage | ParallelBatchProgressMessage | ParallelTimeoutChangeMessage; } \ No newline at end of file diff --git a/src/harness/parallel/worker.ts b/src/harness/parallel/worker.ts index 013992a8e35..1902ff70b19 100644 --- a/src/harness/parallel/worker.ts +++ b/src/harness/parallel/worker.ts @@ -36,11 +36,28 @@ namespace Harness.Parallel.Worker { }) as Mocha.ITestDefinition; } + function setTimeoutAndExecute(timeout: number | undefined, f: () => void) { + if (timeout !== undefined) { + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: timeout } }; + process.send(timeoutMsg); + } + f(); + if (timeout !== undefined) { + // Reset timeout + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } }; + process.send(timeoutMsg); + } + } + function executeSuiteCallback(name: string, callback: MochaCallback) { + let timeout: number; const fakeContext: Mocha.ISuiteCallbackContext = { retries() { return this; }, slow() { return this; }, - timeout() { return this; }, + timeout(n) { + timeout = n as number; + return this; + }, }; namestack.push(name); let beforeFunc: Callable; @@ -71,7 +88,10 @@ namespace Harness.Parallel.Worker { finally { beforeFunc = undefined; } - testList.forEach(({ name, callback, kind }) => executeCallback(name, callback, kind)); + + setTimeoutAndExecute(timeout, () => { + testList.forEach(({ name, callback, kind }) => executeCallback(name, callback, kind)); + }); try { if (afterFunc) { @@ -103,9 +123,15 @@ namespace Harness.Parallel.Worker { } function executeTestCallback(name: string, callback: MochaCallback) { + let timeout: number; const fakeContext: Mocha.ITestCallbackContext = { skip() { return this; }, - timeout() { return this; }, + timeout(n) { + timeout = n as number; + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: timeout } }; + process.send(timeoutMsg); + return this; + }, retries() { return this; }, slow() { return this; }, }; @@ -131,6 +157,10 @@ namespace Harness.Parallel.Worker { } finally { namestack.pop(); + if (timeout !== undefined) { + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } }; + process.send(timeoutMsg); + } } passing++; } @@ -157,6 +187,10 @@ namespace Harness.Parallel.Worker { } finally { namestack.pop(); + if (timeout !== undefined) { + const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } }; + process.send(timeoutMsg); + } } if (!completed) { errors.push({ error: "Test completes asynchronously, which is unsupported by the parallel harness", stack: "", name: [...namestack] }); diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index c617cc7a0a3..f8d4d171f01 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -186,7 +186,7 @@ class ProjectRunner extends RunnerBase { getCanonicalFileName: Harness.Compiler.getCanonicalFileName, useCaseSensitiveFileNames: () => Harness.IO.useCaseSensitiveFileNames(), getNewLine: () => Harness.IO.newLine(), - fileExists: fileName => fileName === Harness.Compiler.defaultLibFileName || getSourceFileText(fileName) !== undefined, + fileExists: fileName => fileName === Harness.Compiler.defaultLibFileName || getSourceFileText(fileName) !== undefined, readFile: fileName => Harness.IO.readFile(fileName), getDirectories: path => Harness.IO.getDirectories(path) }; diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 2bd098b742d..76d65090f02 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -100,6 +100,7 @@ interface TestConfig { runners?: string[]; runUnitTests?: boolean; noColors?: boolean; + timeout?: number; } interface TaskSet { @@ -108,12 +109,16 @@ interface TaskSet { } let configOption: string; +let globalTimeout: number; function handleTestConfig() { if (testConfigContent !== "") { const testConfig = JSON.parse(testConfigContent); if (testConfig.light) { Harness.lightMode = true; } + if (testConfig.timeout) { + globalTimeout = testConfig.timeout; + } runUnitTests = testConfig.runUnitTests; if (testConfig.workerCount) { workerCount = +testConfig.workerCount; diff --git a/src/harness/unittests/builder.ts b/src/harness/unittests/builder.ts index bfdeb1a4067..a5d880fa551 100644 --- a/src/harness/unittests/builder.ts +++ b/src/harness/unittests/builder.ts @@ -43,7 +43,7 @@ namespace ts { }); }); - function makeAssertChanges(getProgram: () => Program): (fileNames: ReadonlyArray) => void { + function makeAssertChanges(getProgram: () => Program): (fileNames: ReadonlyArray) => void { const builder = createBuilder({ getCanonicalFileName: identity, computeHash: identity diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 82c2af7f64e..050178f63b3 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -60,7 +60,7 @@ namespace ts { assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -263,7 +263,7 @@ namespace ts { assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -283,7 +283,7 @@ namespace ts { assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index 2a8f1fe3a89..0bad2ba1e3a 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -266,7 +266,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -297,7 +297,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -328,7 +328,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -359,7 +359,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'esnext.array', 'esnext.asynciterable', 'esnext.promise'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/harness/unittests/hostNewLineSupport.ts b/src/harness/unittests/hostNewLineSupport.ts index 95a05f101f7..e7e5c11e33e 100644 --- a/src/harness/unittests/hostNewLineSupport.ts +++ b/src/harness/unittests/hostNewLineSupport.ts @@ -4,27 +4,10 @@ namespace ts { function testLSWithFiles(settings: CompilerOptions, files: Harness.Compiler.TestFile[]) { function snapFor(path: string): IScriptSnapshot { if (path === "lib.d.ts") { - return { - dispose: noop, - getChangeRange() { return undefined; }, - getLength() { return 0; }, - getText() { - return ""; - } - }; + return ScriptSnapshot.fromString(""); } - const result = forEach(files, f => f.unitName === path ? f : undefined); - if (result) { - return { - dispose: noop, - getChangeRange() { return undefined; }, - getLength() { return result.content.length; }, - getText(start, end) { - return result.content.substring(start, end); - } - }; - } - return undefined; + const result = find(files, f => f.unitName === path); + return result && ScriptSnapshot.fromString(result.content); } const lshost: LanguageServiceHost = { getCompilationSettings: () => settings, diff --git a/src/harness/unittests/incrementalParser.ts b/src/harness/unittests/incrementalParser.ts index c71b89d3da6..cdccce418bc 100644 --- a/src/harness/unittests/incrementalParser.ts +++ b/src/harness/unittests/incrementalParser.ts @@ -5,7 +5,7 @@ namespace ts { ts.disableIncrementalParsing = false; function withChange(text: IScriptSnapshot, start: number, length: number, newText: string): { text: IScriptSnapshot; textChangeRange: TextChangeRange; } { - const contents = text.getText(0, text.getLength()); + const contents = getSnapshotText(text); const newContents = contents.substr(0, start) + newText + contents.substring(start + length); return { text: ScriptSnapshot.fromString(newContents), textChangeRange: createTextChangeRange(createTextSpan(start, length), newText.length) }; @@ -105,7 +105,7 @@ namespace ts { const newTextAndChange = withDelete(oldText, index, 1); const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree).incrementalNewTree; - source = newTextAndChange.text.getText(0, newTextAndChange.text.getLength()); + source = getSnapshotText(newTextAndChange.text); oldTree = newTree; } } @@ -118,7 +118,7 @@ namespace ts { const newTextAndChange = withInsert(oldText, index + i, toInsert.charAt(i)); const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree).incrementalNewTree; - source = newTextAndChange.text.getText(0, newTextAndChange.text.getLength()); + source = getSnapshotText(newTextAndChange.text); oldTree = newTree; } } diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index d9a39aeba65..0dd016b2f22 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -441,7 +441,7 @@ export = C; "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" }); - test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "/a/b/d.ts"], []); + test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "/a/b/d.ts"], []); }); it("should fail when two files used in program differ only in casing (tripleslash references)", () => { @@ -449,7 +449,7 @@ export = C; "/a/b/c.ts": `/// `, "/a/b/d.ts": "var x" }); - test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]); + test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]); }); it("should fail when two files used in program differ only in casing (imports)", () => { @@ -457,7 +457,7 @@ export = C; "/a/b/c.ts": `import {x} from "D"`, "/a/b/d.ts": "export var x" }); - test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]); + test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]); }); it("should fail when two files used in program differ only in casing (imports, relative module names)", () => { @@ -465,7 +465,7 @@ export = C; "moduleA.ts": `import {x} from "./ModuleB"`, "moduleB.ts": "export var x" }); - test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts"], [1149]); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts"], [1149]); }); it("should fail when two files exist on disk that differs only in casing", () => { @@ -474,7 +474,7 @@ export = C; "/a/b/D.ts": "export var x", "/a/b/d.ts": "export var y" }); - test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ true, ["c.ts", "d.ts"], [1149]); + test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ true, ["c.ts", "d.ts"], [1149]); }); it("should fail when module name in 'require' calls has inconsistent casing", () => { @@ -483,7 +483,7 @@ export = C; "moduleB.ts": `import a = require("./moduleC")`, "moduleC.ts": "export var x" }); - test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], [1149, 1149]); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], [1149, 1149]); }); it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => { @@ -496,7 +496,7 @@ import a = require("./moduleA"); import b = require("./moduleB"); ` }); - test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], [1149]); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], [1149]); }); it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => { const files = createMapFromTemplate({ @@ -508,7 +508,7 @@ import a = require("./moduleA"); import b = require("./moduleB"); ` }); - test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], []); + test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], []); }); }); diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 758a55b8f95..9e01021155c 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -30,8 +30,9 @@ namespace ts.tscWatch { return ts.parseConfigFile(configFileName, {}, watchingSystemHost.system, watchingSystemHost.reportDiagnostic, watchingSystemHost.reportWatchDiagnostic); } - function createWatchModeWithConfigFile(configFilePath: string, host: WatchedSystem) { + function createWatchModeWithConfigFile(configFilePath: string, host: WatchedSystem, maxNumberOfFilesToIterateForInvalidation?: number) { const watchingSystemHost = createWatchingSystemHost(host); + watchingSystemHost.maxNumberOfFilesToIterateForInvalidation = maxNumberOfFilesToIterateForInvalidation; const configFileResult = parseConfigFile(configFilePath, watchingSystemHost); return ts.createWatchModeWithConfigFile(configFileResult, {}, watchingSystemHost); } @@ -1067,6 +1068,36 @@ namespace ts.tscWatch { assert.equal(nowErrors[0].start, intialErrors[0].start - configFileContentComment.length); assert.equal(nowErrors[1].start, intialErrors[1].start - configFileContentComment.length); }); + + it("should not trigger recompilation because of program emit", () => { + const proj = "/user/username/projects/myproject"; + const file1: FileOrFolder = { + path: `${proj}/file1.ts`, + content: "export const c = 30;" + }; + const file2: FileOrFolder = { + path: `${proj}/src/file2.ts`, + content: `import {c} from "file1"; export const d = 30;` + }; + const tsconfig: FileOrFolder = { + path: `${proj}/tsconfig.json`, + content: JSON.stringify({ + compilerOptions: { + module: "amd", + outDir: "build" + } + }) + }; + const host = createWatchedSystem([file1, file2, libFile, tsconfig], { currentDirectory: proj }); + const watch = createWatchModeWithConfigFile(tsconfig.path, host, /*maxNumberOfFilesToIterateForInvalidation*/1); + checkProgramActualFiles(watch(), [file1.path, file2.path, libFile.path]); + + assert.isTrue(host.fileExists("build/file1.js")); + assert.isTrue(host.fileExists("build/src/file2.js")); + + // This should be 0 + host.checkTimeoutQueueLengthAndRun(0); + }); }); describe("tsc-watch emit with outFile or out setting", () => { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 34c8f9e9656..565c20ac9cd 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1302,13 +1302,13 @@ namespace ts.projectSystem { service.checkNumberOfProjects({ externalProjects: 1 }); checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]); - const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false }); + const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); // should contain completions for string assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'"); assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'"); service.closeClientFile(f2.path); - const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false }); + const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); // should contain completions for string assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'"); assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'"); @@ -1334,11 +1334,11 @@ namespace ts.projectSystem { service.checkNumberOfProjects({ externalProjects: 1 }); checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]); - const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false }); + const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'"); service.closeClientFile(f2.path); - const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false }); + const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); assert.isFalse(completions2.entries.some(e => e.name === "somelongname"), "should not contain 'somelongname'"); const sf2 = service.externalProjects[0].getLanguageService().getProgram().getSourceFile(f2.path); assert.equal(sf2.text, ""); @@ -1943,7 +1943,7 @@ namespace ts.projectSystem { // Check identifiers defined in HTML content are available in .ts file const project = configuredProjectAt(projectService, 0); - let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, { includeExternalModuleExports: false }); + let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); assert(completions && completions.entries[0].name === "hello", `expected entry hello to be in completion list`); // Close HTML file @@ -1957,7 +1957,7 @@ namespace ts.projectSystem { checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]); // Check identifiers defined in HTML content are not available in .ts file - completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, { includeExternalModuleExports: false }); + completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, { includeExternalModuleExports: false, includeInsertTextCompletions: false }); assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`); }); @@ -2116,7 +2116,7 @@ namespace ts.projectSystem { const scriptInfo = project.getScriptInfo(file1.path); const snap = scriptInfo.getSnapshot(); - const actualText = snap.getText(0, snap.getLength()); + const actualText = getSnapshotText(snap); assert.equal(actualText, "", `expected content to be empty string, got "${actualText}"`); projectService.openClientFile(file1.path, `var x = 1;`); @@ -2128,8 +2128,7 @@ namespace ts.projectSystem { projectService.closeClientFile(file1.path); const scriptInfo2 = project.getScriptInfo(file1.path); - const snap2 = scriptInfo2.getSnapshot(); - const actualText2 = snap2.getText(0, snap.getLength()); + const actualText2 = getSnapshotText(scriptInfo2.getSnapshot()); assert.equal(actualText2, "", `expected content to be empty string, got "${actualText2}"`); }); @@ -4178,7 +4177,7 @@ namespace ts.projectSystem { // verify content const projectServiice = session.getProjectService(); const snap1 = projectServiice.getScriptInfo(f1.path).getSnapshot(); - assert.equal(snap1.getText(0, snap1.getLength()), tmp.content, "content should be equal to the content of temp file"); + assert.equal(getSnapshotText(snap1), tmp.content, "content should be equal to the content of temp file"); // reload from original file file session.executeCommand({ @@ -4190,7 +4189,7 @@ namespace ts.projectSystem { // verify content const snap2 = projectServiice.getScriptInfo(f1.path).getSnapshot(); - assert.equal(snap2.getText(0, snap2.getLength()), f1.content, "content should be equal to the content of original file"); + assert.equal(getSnapshotText(snap2), f1.content, "content should be equal to the content of original file"); }); @@ -4280,7 +4279,7 @@ namespace ts.projectSystem { function checkScriptInfoContents(contentsOfInfo: string, captionForContents: string) { const snap = info.getSnapshot(); - assert.equal(snap.getText(0, snap.getLength()), contentsOfInfo, "content should be equal to " + captionForContents); + assert.equal(getSnapshotText(snap), contentsOfInfo, "content should be equal to " + captionForContents); } }); }); @@ -6488,4 +6487,76 @@ namespace ts.projectSystem { verifyWatchedDirectories(/*useProjectAtRoot*/ false); }); }); + + describe("tsserverProjectSystem typingsInstaller on inferred Project", () => { + it("when projectRootPath is provided", () => { + const projects = "/users/username/projects"; + const projectRootPath = `${projects}/san2`; + const file: FileOrFolder = { + path: `${projectRootPath}/x.js`, + content: "const aaaaaaav = 1;" + }; + + const currentDirectory = `${projects}/anotherProject`; + const packageJsonInCurrentDirectory: FileOrFolder = { + path: `${currentDirectory}/package.json`, + content: JSON.stringify({ + devDependencies: { + pkgcurrentdirectory: "" + }, + }) + }; + const packageJsonOfPkgcurrentdirectory: FileOrFolder = { + path: `${currentDirectory}/node_modules/pkgcurrentdirectory/package.json`, + content: JSON.stringify({ + name: "pkgcurrentdirectory", + main: "index.js", + typings: "index.d.ts" + }) + }; + const indexOfPkgcurrentdirectory: FileOrFolder = { + path: `${currentDirectory}/node_modules/pkgcurrentdirectory/index.d.ts`, + content: "export function foo() { }" + }; + + const typingsCache = `/users/username/Library/Caches/typescript/2.7`; + const typingsCachePackageJson: FileOrFolder = { + path: `${typingsCache}/package.json`, + content: JSON.stringify({ + devDependencies: { + }, + }) + }; + + const files = [file, packageJsonInCurrentDirectory, packageJsonOfPkgcurrentdirectory, indexOfPkgcurrentdirectory, typingsCachePackageJson]; + const host = createServerHost(files, { currentDirectory }); + + const typesRegistry = createMap(); + typesRegistry.set("pkgcurrentdirectory", void 0); + const typingsInstaller = new TestTypingsInstaller(typingsCache, /*throttleLimit*/ 5, host, typesRegistry); + + const projectService = createProjectService(host, { typingsInstaller }); + + projectService.setCompilerOptionsForInferredProjects({ + module: ModuleKind.CommonJS, + target: ScriptTarget.ES2016, + jsx: JsxEmit.Preserve, + experimentalDecorators: true, + allowJs: true, + allowSyntheticDefaultImports: true, + allowNonTsExtensions: true + }); + + projectService.openClientFile(file.path, file.content, ScriptKind.JS, projectRootPath); + + const project = projectService.inferredProjects[0]; + assert.isDefined(project); + + // Ensure that we use result from types cache when getting ls + assert.isDefined(project.getLanguageService()); + + // Verify that the pkgcurrentdirectory from the current directory isnt picked up + checkProjectActualFiles(project, [file.path]); + }); + }); } diff --git a/src/harness/unittests/versionCache.ts b/src/harness/unittests/versionCache.ts index bbd23f25dac..3062a55170c 100644 --- a/src/harness/unittests/versionCache.ts +++ b/src/harness/unittests/versionCache.ts @@ -284,9 +284,7 @@ and grew 1cm per day`; svc.edit(ersa[i], elas[i], insertString); checkText = editFlat(ersa[i], elas[i], insertString, checkText); if (0 === (i % 4)) { - const snap = svc.getSnapshot(); - const snapText = snap.getText(0, checkText.length); - assert.equal(checkText, snapText); + assert.equal(checkText, getSnapshotText(svc.getSnapshot())); } } }); diff --git a/src/harness/virtualFileSystem.ts b/src/harness/virtualFileSystem.ts index 8accd6f621e..54572814d8e 100644 --- a/src/harness/virtualFileSystem.ts +++ b/src/harness/virtualFileSystem.ts @@ -162,7 +162,7 @@ namespace Utils { /** * Reads the directory at the given path and retrieves a list of file names and a list * of directory names within it. Suitable for use with ts.matchFiles() - * @param path The path to the directory to be read + * @param path The path to the directory to be read */ getAccessibleFileSystemEntries(path: string) { const entry = this.traversePath(path); diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index a6fe27ca9c6..921d4674231 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -547,7 +547,7 @@ interface Array {}` } readDirectory(path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray, depth?: number): string[] { - return ts.matchFiles(this.toNormalizedAbsolutePath(path), extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, (dir) => { + return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, (dir) => { const directories: string[] = []; const files: string[] = []; const dirEntry = this.fs.get(this.toPath(dir)); diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 001c63b44a1..951d34377a6 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -761,7 +761,7 @@ interface ProgressEventInit extends EventInit { } interface PushSubscriptionOptionsInit { - applicationServerKey?: any; + applicationServerKey?: BufferSource | null; userVisibleOnly?: boolean; } @@ -770,7 +770,8 @@ interface RegistrationOptions { } interface RequestInit { - body?: any; + signal?: AbortSignal; + body?: Blob | BufferSource | FormData | string | null; cache?: RequestCache; credentials?: RequestCredentials; headers?: HeadersInit; @@ -1088,7 +1089,7 @@ interface RTCTransportStats extends RTCStats { } interface ScopedCredentialDescriptor { - id: any; + id: BufferSource; transports?: Transport[]; type: ScopedCredentialType; } @@ -3596,11 +3597,11 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec slot: string; readonly shadowRoot: ShadowRoot | null; getAttribute(name: string): string | null; - getAttributeNode(name: string): Attr; - getAttributeNodeNS(namespaceURI: string, localName: string): Attr; + getAttributeNode(name: string): Attr | null; + getAttributeNodeNS(namespaceURI: string, localName: string): Attr | null; getAttributeNS(namespaceURI: string, localName: string): string; - getBoundingClientRect(): ClientRect; - getClientRects(): ClientRectList; + getBoundingClientRect(): ClientRect | DOMRect; + getClientRects(): ClientRectList | DOMRectList; getElementsByTagName(name: K): NodeListOf; getElementsByTagName(name: K): NodeListOf; getElementsByTagName(name: string): NodeListOf; @@ -3757,9 +3758,10 @@ declare var External: { }; interface File extends Blob { - readonly lastModifiedDate: any; + readonly lastModifiedDate: Date; readonly name: string; readonly webkitRelativePath: string; + readonly lastModified: number; } declare var File: { @@ -4897,6 +4899,7 @@ interface HTMLFormElement extends HTMLElement { */ submit(): void; reportValidity(): boolean; + reportValidity(): boolean; addEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; @@ -5200,6 +5203,10 @@ interface HTMLIFrameElement extends HTMLElement, GetSVGDocument { * Sets or retrieves the width of the object. */ width: string; + /** + * Sets or retrives the content of the page that is to contain. + */ + srcdoc: string; addEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLIFrameElement, ev: HTMLIFrameElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; @@ -5495,8 +5502,9 @@ interface HTMLInputElement extends HTMLElement { * Sets the start and end positions of a selection in a text field. * @param start The offset into the text field for the start of the selection. * @param end The offset into the text field for the end of the selection. + * @param direction The direction in which the selection is performed. */ - setSelectionRange(start?: number, end?: number, direction?: string): void; + setSelectionRange(start: number, end: number, direction?: "forward" | "backward" | "none"): void; /** * Decrements a range input control's value by the value given by the Step attribute. If the optional parameter is used, it will decrement the input control's step value multiplied by the parameter's value. * @param n Value to decrement the value by. @@ -6057,6 +6065,7 @@ interface HTMLObjectElement extends HTMLElement, GetSVGDocument { * Returns whether an element will successfully validate based on forms validation rules and constraints. */ readonly willValidate: boolean; + typemustmatch: boolean; /** * Returns whether a form will validate when it is submitted, without having to submit it. */ @@ -6958,8 +6967,9 @@ interface HTMLTextAreaElement extends HTMLElement { * Sets the start and end positions of a selection in a text field. * @param start The offset into the text field for the start of the selection. * @param end The offset into the text field for the end of the selection. + * @param direction The direction in which the selection is performed. */ - setSelectionRange(start: number, end: number): void; + setSelectionRange(start: number, end: number, direction?: "forward" | "backward" | "none"): void; addEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; @@ -7362,10 +7372,10 @@ declare var IntersectionObserver: { }; interface IntersectionObserverEntry { - readonly boundingClientRect: ClientRect; + readonly boundingClientRect: ClientRect | DOMRect; readonly intersectionRatio: number; - readonly intersectionRect: ClientRect; - readonly rootBounds: ClientRect; + readonly intersectionRect: ClientRect | DOMRect; + readonly rootBounds: ClientRect | DOMRect; readonly target: Element; readonly time: number; readonly isIntersecting: boolean; @@ -7534,7 +7544,7 @@ declare var MediaKeyMessageEvent: { interface MediaKeys { createSession(sessionType?: MediaKeySessionType): MediaKeySession; - setServerCertificate(serverCertificate: any): Promise; + setServerCertificate(serverCertificate: BufferSource): Promise; } declare var MediaKeys: { @@ -7548,10 +7558,10 @@ interface MediaKeySession extends EventTarget { readonly keyStatuses: MediaKeyStatusMap; readonly sessionId: string; close(): Promise; - generateRequest(initDataType: string, initData: any): Promise; + generateRequest(initDataType: string, initData: BufferSource): Promise; load(sessionId: string): Promise; remove(): Promise; - update(response: any): Promise; + update(response: BufferSource): Promise; } declare var MediaKeySession: { @@ -7562,8 +7572,8 @@ declare var MediaKeySession: { interface MediaKeyStatusMap { readonly size: number; forEach(callback: ForEachCallback): void; - get(keyId: any): MediaKeyStatus; - has(keyId: any): boolean; + get(keyId: BufferSource): MediaKeyStatus; + has(keyId: BufferSource): boolean; } declare var MediaKeyStatusMap: { @@ -9163,8 +9173,8 @@ interface Range { detach(): void; expand(Unit: ExpandGranularity): boolean; extractContents(): DocumentFragment; - getBoundingClientRect(): ClientRect; - getClientRects(): ClientRectList; + getBoundingClientRect(): ClientRect | DOMRect; + getClientRects(): ClientRectList | DOMRectList; insertNode(newNode: Node): void; selectNode(refNode: Node): void; selectNodeContents(refNode: Node): void; @@ -9227,6 +9237,7 @@ interface Request extends Object, Body { readonly referrerPolicy: ReferrerPolicy; readonly type: RequestType; readonly url: string; + readonly signal: AbortSignal; clone(): Request; } @@ -12213,7 +12224,7 @@ interface URL { declare var URL: { prototype: URL; - new(url: string, base?: string): URL; + new(url: string, base?: string | URL): URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; }; @@ -12301,8 +12312,8 @@ declare var WaveShaperNode: { }; interface WebAuthentication { - getAssertion(assertionChallenge: any, options?: AssertionOptions): Promise; - makeCredential(accountInformation: Account, cryptoParameters: ScopedCredentialParameters[], attestationChallenge: any, options?: ScopedCredentialOptions): Promise; + getAssertion(assertionChallenge: BufferSource, options?: AssertionOptions): Promise; + makeCredential(accountInformation: Account, cryptoParameters: ScopedCredentialParameters[], attestationChallenge: BufferSource, options?: ScopedCredentialOptions): Promise; } declare var WebAuthentication: { @@ -14657,6 +14668,23 @@ declare var HTMLSummaryElement: { new(): HTMLSummaryElement; }; +interface DOMRectReadOnly { + readonly bottom: number; + readonly height: number; + readonly left: number; + readonly right: number; + readonly top: number; + readonly width: number; + readonly x: number; + readonly y: number; +} + +declare var DOMRectReadOnly: { + prototype: DOMRectReadOnly; + new (x?: number, y?: number, width?: number, height?: number): DOMRectReadOnly; + fromRect(rectangle?: DOMRectInit): DOMRectReadOnly; +}; + interface EXT_blend_minmax { readonly MIN_EXT: number; readonly MAX_EXT: number; @@ -14675,6 +14703,25 @@ interface EXT_sRGB { readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: number; } +interface DOMRect extends DOMRectReadOnly { + height: number; + width: number; + x: number; + y: number; +} + +declare var DOMRect: { + prototype: DOMRect; + new (x?: number, y?: number, width?: number, height?: number): DOMRect; + fromRect(rectangle?: DOMRectInit): DOMRect; +}; + +interface DOMRectList { + readonly length: number; + item(index: number): DOMRect | null; + [index: number]: DOMRect; +} + interface OES_vertex_array_object { readonly VERTEX_ARRAY_BINDING_OES: number; createVertexArrayOES(): WebGLVertexArrayObjectOES; @@ -14779,6 +14826,43 @@ interface WEBGL_lose_context { restoreContext(): void; } +interface AbortController { + readonly signal: AbortSignal; + abort(): void; +} + +declare var AbortController: { + prototype: AbortController; + new(): AbortController; +}; + +interface AbortSignal extends EventTarget { + readonly aborted: boolean; + onabort: (ev: Event) => any; +} + +interface EventSource extends EventTarget { + readonly url: string; + readonly withCredentials: boolean; + readonly CONNECTING: number; + readonly OPEN: number; + readonly CLOSED: number; + readonly readyState: number; + onopen: (evt: MessageEvent) => any; + onmessage: (evt: MessageEvent) => any; + onerror: (evt: MessageEvent) => any; + close(): void; +} + +declare var EventSource: { + prototype: EventSource; + new(url: string, eventSourceInitDict?: EventSourceInit): EventSource; +}; + +interface EventSourceInit { + readonly withCredentials: boolean; +} + declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; interface DecodeErrorCallback { @@ -14791,7 +14875,7 @@ interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?: Error): void; } interface ForEachCallback { - (keyId: any, status: MediaKeyStatus): void; + (keyId: BufferSource, status: MediaKeyStatus): void; } interface FrameRequestCallback { (time: number): void; @@ -15029,6 +15113,7 @@ interface SVGElementTagNameMap { "view": SVGViewElement; } +/** @deprecated Directly use HTMLElementTagNameMap or SVGElementTagNameMap as appropriate, instead. */ interface ElementTagNameMap extends HTMLElementTagNameMap, SVGElementTagNameMap { } declare var Audio: { new(src?: string): HTMLAudioElement; }; @@ -15246,7 +15331,7 @@ declare function removeEventListener(type: K, li declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; type AAGUID = string; type AlgorithmIdentifier = string | Algorithm; -type BodyInit = any; +type BodyInit = Blob | BufferSource | FormData | string; type ByteString = string; type ConstrainBoolean = boolean | ConstrainBooleanParameters; type ConstrainDOMString = string | string[] | ConstrainDOMStringParameters; diff --git a/src/lib/es2015.collection.d.ts b/src/lib/es2015.collection.d.ts index 9b35fcbeffb..74759107851 100644 --- a/src/lib/es2015.collection.d.ts +++ b/src/lib/es2015.collection.d.ts @@ -10,7 +10,7 @@ interface Map { interface MapConstructor { new (): Map; - new (entries?: [K, V][]): Map; + new (entries?: ReadonlyArray<[K, V]>): Map; readonly prototype: Map; } declare var Map: MapConstructor; @@ -31,7 +31,7 @@ interface WeakMap { interface WeakMapConstructor { new (): WeakMap; - new (entries?: [K, V][]): WeakMap; + new (entries?: ReadonlyArray<[K, V]>): WeakMap; readonly prototype: WeakMap; } declare var WeakMap: WeakMapConstructor; @@ -47,7 +47,7 @@ interface Set { interface SetConstructor { new (): Set; - new (values?: T[]): Set; + new (values?: ReadonlyArray): Set; readonly prototype: Set; } declare var Set: SetConstructor; @@ -58,7 +58,7 @@ interface ReadonlySet { readonly size: number; } -interface WeakSet { +interface WeakSet { add(value: T): this; delete(value: T): boolean; has(value: T): boolean; @@ -66,7 +66,7 @@ interface WeakSet { interface WeakSetConstructor { new (): WeakSet; - new (values?: T[]): WeakSet; + new (values?: ReadonlyArray): WeakSet; readonly prototype: WeakSet; } declare var WeakSet: WeakSetConstructor; diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts index ccff68968f1..eef20591a84 100644 --- a/src/lib/es2015.core.d.ts +++ b/src/lib/es2015.core.d.ts @@ -118,8 +118,9 @@ interface Math { log1p(x: number): number; /** - * Returns the result of (e^x - 1) of x (e raised to the power of x, where e is the base of - * the natural logarithms). + * Returns the result of (e^x - 1), which is an implementation-dependent approximation to + * subtracting 1 from the exponential function of x (e raised to the power of x, where e + * is the base of the natural logarithms). * @param x A numeric expression. */ expm1(x: number): number; diff --git a/src/lib/es2015.iterable.d.ts b/src/lib/es2015.iterable.d.ts index 26722b5ab2f..ccb7df6be69 100644 --- a/src/lib/es2015.iterable.d.ts +++ b/src/lib/es2015.iterable.d.ts @@ -180,7 +180,7 @@ interface SetConstructor { new (iterable: Iterable): Set; } -interface WeakSet { } +interface WeakSet { } interface WeakSetConstructor { new (iterable: Iterable): WeakSet; diff --git a/src/lib/es2015.symbol.wellknown.d.ts b/src/lib/es2015.symbol.wellknown.d.ts index 23d836c6515..681b6e8edfa 100644 --- a/src/lib/es2015.symbol.wellknown.d.ts +++ b/src/lib/es2015.symbol.wellknown.d.ts @@ -118,7 +118,7 @@ interface Set { readonly [Symbol.toStringTag]: "Set"; } -interface WeakSet { +interface WeakSet { readonly [Symbol.toStringTag]: "WeakSet"; } diff --git a/src/lib/es2017.object.d.ts b/src/lib/es2017.object.d.ts index 4014e8c2927..775aaece7f6 100644 --- a/src/lib/es2017.object.d.ts +++ b/src/lib/es2017.object.d.ts @@ -9,7 +9,7 @@ interface ObjectConstructor { * Returns an array of values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - values(o: any): any[]; + values(o: {}): any[]; /** * Returns an array of key/values of the enumerable properties of an object @@ -21,7 +21,7 @@ interface ObjectConstructor { * Returns an array of key/values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - entries(o: any): [string, any][]; + entries(o: {}): [string, any][]; /** * Returns an object containing all own property descriptors of an object diff --git a/src/lib/es2018.d.ts b/src/lib/es2018.d.ts index 71d6e190b15..90f6d4931f4 100644 --- a/src/lib/es2018.d.ts +++ b/src/lib/es2018.d.ts @@ -1 +1 @@ -/// \ No newline at end of file +/// diff --git a/src/lib/esnext.array.d.ts b/src/lib/esnext.array.d.ts new file mode 100644 index 00000000000..ddba47badaa --- /dev/null +++ b/src/lib/esnext.array.d.ts @@ -0,0 +1,203 @@ +interface ReadonlyArray { + + /** + * Calls a defined callback function on each element of an array. Then, flattens the result into + * a new array. + * This is identical to a map followed by a flatten of depth 1. + * + * @param callback A function that accepts up to three arguments. The flatMap method calls the + * callback function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callback function. If + * thisArg is omitted, undefined is used as the this value. + */ + flatMap ( + callback: (this: This, value: T, index: number, array: T[]) => U|U[], + thisArg?: This + ): U[] + + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray> | + ReadonlyArray[]> | + ReadonlyArray[][]> | + ReadonlyArray[][][]> | + + ReadonlyArray>> | + ReadonlyArray[][]>> | + ReadonlyArray>[][]> | + ReadonlyArray[]>[]> | + ReadonlyArray>[]> | + ReadonlyArray[]>> | + + ReadonlyArray>>> | + ReadonlyArray[]>>> | + ReadonlyArray>[]>> | + ReadonlyArray>>[]> | + + ReadonlyArray>>>>, + depth: 4): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray[][]> | + ReadonlyArray[]> | + ReadonlyArray> | + + ReadonlyArray>> | + ReadonlyArray[]>> | + ReadonlyArray>[]> | + + ReadonlyArray>>>, + depth: 3): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + + ReadonlyArray> | + ReadonlyArray[]> | + + ReadonlyArray>>, + depth: 2): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray | + ReadonlyArray>, + depth?: 1 + ): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: + ReadonlyArray, + depth: 0 + ): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. If no depth is provided, flatten method defaults to the depth of 1. + * + * @param depth The maximum recursion depth + */ + flatten(depth?: number): any[]; + } + +interface Array { + + /** + * Calls a defined callback function on each element of an array. Then, flattens the result into + * a new array. + * This is identical to a map followed by a flatten of depth 1. + * + * @param callback A function that accepts up to three arguments. The flatMap method calls the + * callback function one time for each element in the array. + * @param thisArg An object to which the this keyword can refer in the callback function. If + * thisArg is omitted, undefined is used as the this value. + */ + flatMap ( + callback: (this: This, value: T, index: number, array: T[]) => U|U[], + thisArg?: This + ): U[] + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][][][], depth: 7): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][][], depth: 6): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][][], depth: 5): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][][], depth: 4): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][][], depth: 3): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][][], depth: 2): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[][], depth?: 1): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. + * + * @param depth The maximum recursion depth + */ + flatten(this: U[], depth: 0): U[]; + + /** + * Returns a new array with all sub-array elements concatenated into it recursively up to the + * specified depth. If no depth is provided, flatten method defaults to the depth of 1. + * + * @param depth The maximum recursion depth + */ + flatten(depth?: number): any[]; +} diff --git a/src/lib/esnext.d.ts b/src/lib/esnext.d.ts index 71fab82a866..bbfb9535aa7 100644 --- a/src/lib/esnext.d.ts +++ b/src/lib/esnext.d.ts @@ -1,2 +1,4 @@ -/// +/// /// +/// +/// diff --git a/src/lib/esnext.promise.d.ts b/src/lib/esnext.promise.d.ts new file mode 100644 index 00000000000..28f903870b6 --- /dev/null +++ b/src/lib/esnext.promise.d.ts @@ -0,0 +1,12 @@ +/** + * Represents the completion of an asynchronous operation + */ +interface Promise { + /** + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The + * resolved value cannot be modified from the callback. + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). + * @returns A Promise for the completion of the callback. + */ + finally(onfinally?: (() => void) | undefined | null): Promise +} diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index 6eb17c33c5e..1b0ce074f00 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -66,12 +66,13 @@ interface ObjectURLOptions { } interface PushSubscriptionOptionsInit { - applicationServerKey?: any; + applicationServerKey?: BufferSource | null; userVisibleOnly?: boolean; } interface RequestInit { - body?: any; + signal?: AbortSignal; + body?: Blob | BufferSource | FormData | string | null; cache?: RequestCache; credentials?: RequestCredentials; headers?: HeadersInit; @@ -119,7 +120,7 @@ interface NotificationEventInit extends ExtendableEventInit { } interface PushEventInit extends ExtendableEventInit { - data?: any; + data?: BufferSource | USVString; } interface SyncEventInit extends ExtendableEventInit { @@ -414,9 +415,10 @@ declare var EventTarget: { }; interface File extends Blob { - readonly lastModifiedDate: any; + readonly lastModifiedDate: Date; readonly name: string; readonly webkitRelativePath: string; + readonly lastModified: number; } declare var File: { @@ -959,6 +961,7 @@ interface Request extends Object, Body { readonly referrerPolicy: ReferrerPolicy; readonly type: RequestType; readonly url: string; + readonly signal: AbortSignal; clone(): Request; } @@ -1061,7 +1064,7 @@ interface URL { declare var URL: { prototype: URL; - new(url: string, base?: string): URL; + new(url: string, base?: string | URL): URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; }; @@ -1821,6 +1824,43 @@ interface AddEventListenerOptions extends EventListenerOptions { once?: boolean; } +interface AbortController { + readonly signal: AbortSignal; + abort(): void; +} + +declare var AbortController: { + prototype: AbortController; + new(): AbortController; +}; + +interface AbortSignal extends EventTarget { + readonly aborted: boolean; + onabort: (ev: Event) => any; +} + +interface EventSource extends EventTarget { + readonly url: string; + readonly withCredentials: boolean; + readonly CONNECTING: number; + readonly OPEN: number; + readonly CLOSED: number; + readonly readyState: number; + onopen: (evt: MessageEvent) => any; + onmessage: (evt: MessageEvent) => any; + onerror: (evt: MessageEvent) => any; + close(): void; +} + +declare var EventSource: { + prototype: EventSource; + new(url: string, eventSourceInitDict?: EventSourceInit): EventSource; +}; + +interface EventSourceInit { + readonly withCredentials: boolean; +} + declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; interface DecodeErrorCallback { @@ -1833,7 +1873,7 @@ interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?: Error): void; } interface ForEachCallback { - (keyId: any, status: MediaKeyStatus): void; + (keyId: BufferSource, status: MediaKeyStatus): void; } interface FunctionStringCallback { (data: string): void; @@ -1883,7 +1923,7 @@ declare function addEventListener(type: string, listener: EventListenerOrEventLi declare function removeEventListener(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void; declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; type AlgorithmIdentifier = string | Algorithm; -type BodyInit = any; +type BodyInit = Blob | BufferSource | FormData | string; type IDBKeyPath = string; type RequestInfo = Request | string; type USVString = string; diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index b01830dcac5..093c228c5a4 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 921ca600aa6..f6a140a47f7 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 44e5ea6192f..66702cf999d 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -483,6 +483,15 @@ + + + + + + + + + @@ -885,6 +894,12 @@ + + + + + + @@ -1290,6 +1305,24 @@ + + + + + + + + + + + + + + + + + + @@ -1839,6 +1872,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2082,6 +2142,9 @@ + + + @@ -2304,6 +2367,15 @@ + + + + + + + + + @@ -2901,6 +2973,15 @@ + + + + + + + + + @@ -4545,6 +4626,12 @@ + + + + + + @@ -5580,6 +5667,15 @@ + + + + + + + + + @@ -5937,6 +6033,15 @@ + + + + + + + + + @@ -8001,6 +8106,15 @@ + + + + + + + + + @@ -8504,10 +8618,13 @@ - + - + + + + diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 8131e17425e..00fd63f90f9 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -873,6 +882,12 @@ + + + + + + @@ -1278,6 +1293,24 @@ + + + + + + + + + + + + + + + + + + @@ -1827,6 +1860,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2067,6 +2127,15 @@ + + + + + + + + + @@ -2286,6 +2355,15 @@ + + + + + + + + + @@ -2883,6 +2961,15 @@ + + + + + + + + + @@ -4527,6 +4614,12 @@ + + + + + + @@ -5559,6 +5652,15 @@ + + + + + + + + + @@ -5916,6 +6018,15 @@ + + + + + + + + + @@ -7977,6 +8088,15 @@ + + + + + + + + + @@ -8480,10 +8600,13 @@ - + + + + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 8c388d5fd73..93c54090734 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -483,6 +483,15 @@ + + + + + + + + + @@ -885,6 +894,12 @@ + + + + + + @@ -1290,6 +1305,24 @@ + + + + + + + + + + + + + + + + + + @@ -1839,6 +1872,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2082,6 +2142,9 @@ + + + @@ -2304,6 +2367,15 @@ + + + + + + + + + @@ -2901,6 +2973,15 @@ + + + + + + + + + @@ -4545,6 +4626,12 @@ + + + + + + @@ -5580,6 +5667,15 @@ + + + + + + + + + @@ -5937,6 +6033,15 @@ + + + + + + + + + @@ -8001,6 +8106,15 @@ + + + + + + + + + @@ -8504,10 +8618,13 @@ - + - + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index efd7b273f5d..d6048a235f5 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -483,6 +483,15 @@ + + + + + + + + + @@ -885,6 +894,12 @@ + + + + + + @@ -1290,6 +1305,24 @@ + + + + + + + + + + + + + + + + + + @@ -1839,6 +1872,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2307,6 +2367,15 @@ + + + + + + + + + @@ -2904,6 +2973,15 @@ + + + + + + + + + @@ -4548,6 +4626,12 @@ + + + + + + @@ -5583,6 +5667,15 @@ + + + + + + + + + @@ -5940,6 +6033,15 @@ + + + + + + + + + @@ -8004,6 +8106,15 @@ + + + + + + + + + @@ -8507,10 +8618,13 @@ - + - + + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 8f52506d6b9..4d76091f527 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 76488c39e76..2ac1ab23150 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 2418583bb98..dcd9d3695fc 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -474,6 +474,15 @@ + + + + + + + + + @@ -876,6 +885,12 @@ + + + + + + @@ -1281,6 +1296,24 @@ + + + + + + + + + + + + + + + + + + @@ -1830,6 +1863,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2298,6 +2358,15 @@ + + + + + + + + + @@ -2895,6 +2964,15 @@ + + + + + + + + + @@ -4539,6 +4617,12 @@ + + + + + + @@ -5574,6 +5658,15 @@ + + + + + + + + + @@ -5931,6 +6024,15 @@ + + + + + + + + + @@ -7995,6 +8097,15 @@ + + + + + + + + + @@ -8498,10 +8609,13 @@ - + - + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 42685f7a45e..a36010b60e3 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -467,6 +467,15 @@ + + + + + + + + + @@ -866,6 +875,12 @@ + + + + + + @@ -1271,6 +1286,24 @@ + + + + + + + + + + + + + + + + + + @@ -1820,6 +1853,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2288,6 +2348,15 @@ + + + + + + + + + @@ -2885,6 +2954,15 @@ + + + + + + + + + @@ -4529,6 +4607,12 @@ + + + + + + @@ -5561,6 +5645,15 @@ + + + + + + + + + @@ -5918,6 +6011,15 @@ + + + + + + + + + @@ -7979,6 +8081,15 @@ + + + + + + + + + @@ -8482,10 +8593,13 @@ - + - + + + + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index bcace1bd162..8eed7be8b99 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -467,6 +467,15 @@ + + + + + + + + + @@ -866,6 +875,12 @@ + + + + + + @@ -1271,6 +1286,24 @@ + + + + + + + + + + + + + + + + + + @@ -1820,6 +1853,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2288,6 +2348,15 @@ + + + + + + + + + @@ -2885,6 +2954,15 @@ + + + + + + + + + @@ -4529,6 +4607,12 @@ + + + + + + @@ -5561,6 +5645,15 @@ + + + + + + + + + @@ -5918,6 +6011,15 @@ + + + + + + + + + @@ -7979,6 +8081,15 @@ + + + + + + + + + @@ -8482,10 +8593,13 @@ - + - + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index ca1dcf2d4cb..a8529c74fd0 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -473,6 +473,15 @@ + + + + + + + + + @@ -875,6 +884,12 @@ + + + + + + @@ -1280,6 +1295,24 @@ + + + + + + + + + + + + + + + + + + @@ -1829,6 +1862,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2297,6 +2357,15 @@ + + + + + + + + + @@ -2894,6 +2963,15 @@ + + + + + + + + + @@ -4538,6 +4616,12 @@ + + + + + + @@ -5573,6 +5657,15 @@ + + + + + + + + + @@ -5930,6 +6023,15 @@ + + + + + + + + + @@ -7994,6 +8096,15 @@ + + + + + + + + + @@ -8497,10 +8608,13 @@ - + - + + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index daf741d6980..c8c49d28117 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -467,6 +467,15 @@ + + + + + + + + + @@ -869,6 +878,12 @@ + + + + + + @@ -1274,6 +1289,24 @@ + + + + + + + + + + + + + + + + + + @@ -1823,6 +1856,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2066,6 +2126,9 @@ + + + @@ -2288,6 +2351,15 @@ + + + + + + + + + @@ -2885,6 +2957,15 @@ + + + + + + + + + @@ -4529,6 +4610,12 @@ + + + + + + @@ -5564,6 +5651,15 @@ + + + + + + + + + @@ -5921,6 +6017,15 @@ + + + + + + + + + @@ -7985,6 +8090,15 @@ + + + + + + + + + @@ -8488,10 +8602,13 @@ - + - + + + + diff --git a/src/server/cancellationToken/cancellationToken.ts b/src/server/cancellationToken/cancellationToken.ts index 6f2f4a8897c..b7243ccd871 100644 --- a/src/server/cancellationToken/cancellationToken.ts +++ b/src/server/cancellationToken/cancellationToken.ts @@ -46,7 +46,7 @@ function createCancellationToken(args: string[]): ServerCancellationToken { let perRequestPipeName: string; let currentRequestId: number; return { - isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName), + isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName), setRequest(requestId: number) { currentRequestId = requestId; perRequestPipeName = namePrefix + requestId; diff --git a/src/server/client.ts b/src/server/client.ts index f34516ac4fd..7a64d9b528c 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -52,8 +52,7 @@ namespace ts.server { private getLineMap(fileName: string): number[] { let lineMap = this.lineMaps.get(fileName); if (!lineMap) { - const scriptSnapshot = this.host.getScriptSnapshot(fileName); - lineMap = computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength())); + lineMap = computeLineStarts(getSnapshotText(this.host.getScriptSnapshot(fileName))); this.lineMaps.set(fileName, lineMap); } return lineMap; diff --git a/src/server/project.ts b/src/server/project.ts index 11c023415ef..a25e6870bda 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -121,6 +121,7 @@ namespace ts.server { private program: Program; private externalFiles: SortedReadonlyArray; private missingFilesMap: Map; + private plugins: PluginModule[] = []; private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap(); private lastCachedUnresolvedImportsList: SortedReadonlyArray; @@ -515,7 +516,18 @@ namespace ts.server { } getExternalFiles(): SortedReadonlyArray { - return emptyArray as SortedReadonlyArray; + return toSortedArray(flatMap(this.plugins, plugin => { + if (typeof plugin.getExternalFiles !== "function") return; + try { + return plugin.getExternalFiles(this); + } + catch (e) { + this.projectService.logger.info(`A plugin threw an exception in getExternalFiles: ${e}`); + if (e.stack) { + this.projectService.logger.info(e.stack); + } + } + })); } getSourceFile(path: Path) { @@ -818,7 +830,10 @@ namespace ts.server { return !hasChanges; } - + /* @internal */ + getCurrentProgram() { + return this.program; + } protected removeExistingTypings(include: string[]): string[] { const existing = ts.getAutomaticTypeDirectiveNames(this.getCompilerOptions(), this.directoryStructureHost); @@ -1029,6 +1044,84 @@ namespace ts.server { orderedRemoveItem(this.rootFiles, info); this.rootFilesMap.delete(info.path); } + + protected enableGlobalPlugins() { + const host = this.projectService.host; + const options = this.getCompilationSettings(); + + if (!host.require) { + this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); + return; + } + + // Search our peer node_modules, then any globally-specified probe paths + // ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/ + const searchPaths = [combinePaths(this.projectService.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations]; + + if (this.projectService.globalPlugins) { + // Enable global plugins with synthetic configuration entries + for (const globalPluginName of this.projectService.globalPlugins) { + // Skip empty names from odd commandline parses + if (!globalPluginName) continue; + + // Skip already-locally-loaded plugins + if (options.plugins && options.plugins.some(p => p.name === globalPluginName)) continue; + + // Provide global: true so plugins can detect why they can't find their config + this.projectService.logger.info(`Loading global plugin ${globalPluginName}`); + this.enablePlugin({ name: globalPluginName, global: true } as PluginImport, searchPaths); + } + } + } + + protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]) { + this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`); + + const log = (message: string) => { + this.projectService.logger.info(message); + }; + + for (const searchPath of searchPaths) { + const resolvedModule = Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log); + if (resolvedModule) { + this.enableProxy(resolvedModule, pluginConfigEntry); + return; + } + } + this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name}`); + } + + private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) { + try { + if (typeof pluginModuleFactory !== "function") { + this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did expose a proper factory function`); + return; + } + + const info: PluginCreateInfo = { + config: configEntry, + project: this, + languageService: this.languageService, + languageServiceHost: this, + serverHost: this.projectService.host + }; + + const pluginModule = pluginModuleFactory({ typescript: ts }); + const newLS = pluginModule.create(info); + for (const k of Object.keys(this.languageService)) { + if (!(k in newLS)) { + this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`); + (newLS as any)[k] = (this.languageService as any)[k]; + } + } + this.projectService.logger.info(`Plugin validation succeded`); + this.languageService = newLS; + this.plugins.push(pluginModule); + } + catch (e) { + this.projectService.logger.info(`Plugin activation failed: ${e}`); + } + } } /** @@ -1092,6 +1185,7 @@ namespace ts.server { projectService.host, currentDirectory); this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath); + this.enableGlobalPlugins(); } addRoot(info: ScriptInfo) { @@ -1153,8 +1247,6 @@ namespace ts.server { /*@internal*/ configFileSpecs: ConfigFileSpecs; - private plugins: PluginModule[] = []; - /** Ref count to the project when opened from external project */ private externalProjectRefCount = 0; @@ -1236,69 +1328,7 @@ namespace ts.server { } } - if (this.projectService.globalPlugins) { - // Enable global plugins with synthetic configuration entries - for (const globalPluginName of this.projectService.globalPlugins) { - // Skip empty names from odd commandline parses - if (!globalPluginName) continue; - - // Skip already-locally-loaded plugins - if (options.plugins && options.plugins.some(p => p.name === globalPluginName)) continue; - - // Provide global: true so plugins can detect why they can't find their config - this.projectService.logger.info(`Loading global plugin ${globalPluginName}`); - this.enablePlugin({ name: globalPluginName, global: true } as PluginImport, searchPaths); - } - } - } - - private enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]) { - this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`); - - const log = (message: string) => { - this.projectService.logger.info(message); - }; - - for (const searchPath of searchPaths) { - const resolvedModule = Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log); - if (resolvedModule) { - this.enableProxy(resolvedModule, pluginConfigEntry); - return; - } - } - this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name}`); - } - - private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) { - try { - if (typeof pluginModuleFactory !== "function") { - this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did expose a proper factory function`); - return; - } - - const info: PluginCreateInfo = { - config: configEntry, - project: this, - languageService: this.languageService, - languageServiceHost: this, - serverHost: this.projectService.host - }; - - const pluginModule = pluginModuleFactory({ typescript: ts }); - const newLS = pluginModule.create(info); - for (const k of Object.keys(this.languageService)) { - if (!(k in newLS)) { - this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`); - (newLS as any)[k] = (this.languageService as any)[k]; - } - } - this.projectService.logger.info(`Plugin validation succeded`); - this.languageService = newLS; - this.plugins.push(pluginModule); - } - catch (e) { - this.projectService.logger.info(`Plugin activation failed: ${e}`); - } + this.enableGlobalPlugins(); } /** @@ -1327,21 +1357,6 @@ namespace ts.server { return this.typeAcquisition; } - getExternalFiles(): SortedReadonlyArray { - return toSortedArray(flatMap(this.plugins, plugin => { - if (typeof plugin.getExternalFiles !== "function") return; - try { - return plugin.getExternalFiles(this); - } - catch (e) { - this.projectService.logger.info(`A plugin threw an exception in getExternalFiles: ${e}`); - if (e.stack) { - this.projectService.logger.info(e.stack); - } - } - })); - } - /*@internal*/ watchWildcards(wildcardDirectories: Map) { updateWatchingWildcardDirectories( diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 4bd7a0a0967..b3cbba27a20 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -566,7 +566,7 @@ namespace ts.server.protocol { // TODO: GH#20538 /* @internal */ - export interface GetCombinedCodeFixResponse extends Response { + export interface GetCombinedCodeFixResponse extends Response { body: CombinedCodeActions; } @@ -1693,6 +1693,11 @@ namespace ts.server.protocol { * This affects lone identifier completions but not completions on the right hand side of `obj.`. */ includeExternalModuleExports: boolean; + /** + * If enabled, the completion list will include completions with invalid identifier names. + * For those entries, The `insertText` and `replacementSpan` properties will be set to change from `.x` property access to `["x"]`. + */ + includeInsertTextCompletions: boolean; } /** @@ -1768,6 +1773,12 @@ namespace ts.server.protocol { * is often the same as the name but may be different in certain circumstances. */ sortText: string; + /** + * Text to insert instead of `name`. + * This is used to support bracketed completions; If `name` might be "a-b" but `insertText` would be `["a-b"]`, + * coupled with `replacementSpan` to replace a dotted access with a bracket access. + */ + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. @@ -2556,6 +2567,7 @@ namespace ts.server.protocol { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } export interface CompilerOptions { diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index f800a1117d0..6a722b5c3e0 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -370,8 +370,7 @@ namespace ts.server { } saveTo(fileName: string) { - const snap = this.textStorage.getSnapshot(); - this.host.writeFile(fileName, snap.getText(0, snap.getLength())); + this.host.writeFile(fileName, getSnapshotText(this.textStorage.getSnapshot())); } /*@internal*/ diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index fe71040b4f6..dccf4d3267b 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -257,7 +257,7 @@ namespace ts.server { export class ScriptVersionCache { private changes: TextChange[] = []; private readonly versions: LineIndexSnapshot[] = new Array(ScriptVersionCache.maxVersions); - private minVersion = 0; // no versions earlier than min version will maintain change history + private minVersion = 0; // no versions earlier than min version will maintain change history private currentVersion = 0; @@ -371,7 +371,7 @@ namespace ts.server { } getLength() { - return this.index.root.charCount(); + return this.index.getLength(); } getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange { diff --git a/src/server/server.ts b/src/server/server.ts index 86349fa2be5..8e53c4d5109 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -979,6 +979,10 @@ namespace ts.server { allowLocalPluginLoads }; + logger.info(`Starting TS Server`); + logger.info(`Version: ${versionMajorMinor}`); + logger.info(`Arguments: ${process.argv.join(" ")}`); + const ioSession = new IOSession(options); process.on("uncaughtException", err => { ioSession.logError(err, "unknown"); diff --git a/src/server/session.ts b/src/server/session.ts index 9dcf58734a7..b66bd83c19f 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1207,10 +1207,10 @@ namespace ts.server { if (simplifiedResult) { return mapDefined(completions && completions.entries, entry => { if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { - const { name, kind, kindModifiers, sortText, replacementSpan, hasAction, source, isRecommended } = entry; + const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry; const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; // Use `hasAction || undefined` to avoid serializing `false`. - return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; + return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; } }).sort((a, b) => compareStringsCaseSensitiveUI(a.name, b.name)); } @@ -1534,9 +1534,7 @@ namespace ts.server { let mappedRenameLocation: protocol.Location | undefined; if (renameFilename !== undefined && renameLocation !== undefined) { const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename)); - const snapshot = renameScriptInfo.getSnapshot(); - const oldText = snapshot.getText(0, snapshot.getLength()); - mappedRenameLocation = getLocationInNewDocument(oldText, renameFilename, renameLocation, edits); + mappedRenameLocation = getLocationInNewDocument(getSnapshotText(renameScriptInfo.getSnapshot()), renameFilename, renameLocation, edits); } return { renameLocation: mappedRenameLocation, renameFilename, edits: this.mapTextChangesToCodeEdits(project, edits) }; } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index d76ff1bf6d0..c44419f8cf3 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -34,19 +34,6 @@ namespace ts.server { export type Types = Msg; } - function getProjectRootPath(project: Project): Path { - switch (project.projectKind) { - case ProjectKind.Configured: - return getDirectoryPath(project.getProjectName()); - case ProjectKind.Inferred: - // TODO: fixme - return ""; - case ProjectKind.External: - const projectName = normalizeSlashes(project.getProjectName()); - return getDirectoryPath(projectName); - } - } - export function createInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, cachePath?: string): DiscoverTypings { return { projectName: project.getProjectName(), @@ -54,7 +41,7 @@ namespace ts.server { compilerOptions: project.getCompilationSettings(), typeAcquisition, unresolvedImports, - projectRootPath: getProjectRootPath(project), + projectRootPath: project.getCurrentDirectory() as Path, cachePath, kind: "discover" }; diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 57dbc5711e7..26df417f879 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -262,8 +262,8 @@ namespace ts.BreakpointResolver { } // Set breakpoint on identifier element of destructuring pattern - // a or ...c or d: x from - // [a, b, ...c] or { a, b } or { d: x } from destructuring pattern + // `a` or `...c` or `d: x` from + // `[a, b, ...c]` or `{ a, b }` or `{ d: x }` from destructuring pattern if ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.SpreadElement || node.kind === SyntaxKind.PropertyAssignment || @@ -427,8 +427,9 @@ namespace ts.BreakpointResolver { } else { const functionDeclaration = parameter.parent; - const indexOfParameter = indexOf(functionDeclaration.parameters, parameter); - if (indexOfParameter) { + const indexOfParameter = functionDeclaration.parameters.indexOf(parameter); + Debug.assert(indexOfParameter !== -1); + if (indexOfParameter !== 0) { // Not a first parameter, go to previous parameter return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]); } diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 32b3dac2cca..3e4c6058a36 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -837,7 +837,7 @@ namespace ts { return ClassificationType.keyword; } - // Special case < and > If they appear in a generic context they are punctuation, + // Special case `<` and `>`: If they appear in a generic context they are punctuation, // not operators. if (tokenKind === SyntaxKind.LessThanToken || tokenKind === SyntaxKind.GreaterThanToken) { // If the node owning the token has a type argument list or type parameter list, then diff --git a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts index 3d99b571248..de4498035be 100644 --- a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts +++ b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts @@ -21,7 +21,7 @@ namespace ts.codefix { }); function getQualifiedName(sourceFile: SourceFile, pos: number): QualifiedName & { left: Identifier } | undefined { - const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isQualifiedName)!; + const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ true), isQualifiedName)!; Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name."); return isIdentifier(qualifiedName.left) ? qualifiedName as QualifiedName & { left: Identifier } : undefined; } diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts new file mode 100644 index 00000000000..883993e7b51 --- /dev/null +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -0,0 +1,74 @@ +/* @internal */ +namespace ts.codefix { + const fixId = "fixAwaitInSyncFunction"; + const errorCodes = [ + Diagnostics.await_expression_is_only_allowed_within_an_async_function.code, + Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code, + ]; + registerCodeFix({ + errorCodes, + getCodeActions(context) { + const { sourceFile, span } = context; + const nodes = getNodes(sourceFile, span.start); + if (!nodes) return undefined; + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, nodes)); + return [{ description: getLocaleSpecificMessage(Diagnostics.Add_async_modifier_to_containing_function), changes, fixId }]; + }, + fixIds: [fixId], + getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { + const nodes = getNodes(diag.file, diag.start); + if (!nodes) return; + doChange(changes, context.sourceFile, nodes); + }), + }); + + function getReturnType(expr: FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction) { + if (expr.type) { + return expr.type; + } + if (isVariableDeclaration(expr.parent) && + expr.parent.type && + isFunctionTypeNode(expr.parent.type)) { + return expr.parent.type.type; + } + } + + function getNodes(sourceFile: SourceFile, start: number): { insertBefore: Node, returnType: TypeNode | undefined } | undefined { + const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); + const containingFunction = getContainingFunction(token); + let insertBefore: Node | undefined; + switch (containingFunction.kind) { + case SyntaxKind.MethodDeclaration: + insertBefore = containingFunction.name; + break; + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + insertBefore = findChildOfKind(containingFunction, SyntaxKind.FunctionKeyword, sourceFile); + break; + case SyntaxKind.ArrowFunction: + insertBefore = findChildOfKind(containingFunction, SyntaxKind.OpenParenToken, sourceFile) || first(containingFunction.parameters); + break; + default: + return; + } + + return { + insertBefore, + returnType: getReturnType(containingFunction) + }; + } + + function doChange( + changes: textChanges.ChangeTracker, + sourceFile: SourceFile, + { insertBefore, returnType }: { insertBefore: Node | undefined, returnType: TypeNode | undefined }): void { + + if (returnType) { + const entityName = getEntityNameFromTypeNode(returnType); + if (!entityName || entityName.kind !== SyntaxKind.Identifier || entityName.text !== "Promise") { + changes.replaceNode(sourceFile, returnType, createTypeReferenceNode("Promise", createNodeArray([returnType]))); + } + } + changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, insertBefore); + } +} diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index 2a3736531b2..a28a46caf1b 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -4,9 +4,10 @@ namespace ts.codefix { const errorCodes = [Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code]; registerCodeFix({ errorCodes, - getCodeActions: context => [ - { fixId, ...tryGetCodeActionForInstallPackageTypes(context.host, context.sourceFile.fileName, getModuleName(context.sourceFile, context.span.start)) } - ], + getCodeActions: context => { + const codeAction = tryGetCodeActionForInstallPackageTypes(context.host, context.sourceFile.fileName, getModuleName(context.sourceFile, context.span.start)); + return codeAction && [{ fixId, ...codeAction }]; + }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (_, diag, commands) => { const pkg = getTypesPackageNameToInstall(context.host, getModuleName(diag.file, diag.start)); diff --git a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts index 446b0bddfab..d98ca556f47 100644 --- a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts +++ b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts @@ -27,11 +27,26 @@ namespace ts.codefix { } function doChanges(changes: textChanges.ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: ReadonlyArray): void { - changes.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword)); - // We replace existing keywords with commas. - for (let i = 1; i < heritageClauses.length; i++) { - const keywordToken = heritageClauses[i].getFirstToken()!; - changes.replaceNode(sourceFile, keywordToken, createToken(SyntaxKind.CommaToken)); + changes.replaceRange(sourceFile, { pos: extendsToken.getStart(), end: extendsToken.end }, createToken(SyntaxKind.ImplementsKeyword)); + + // If there is already an implements clause, replace the implements keyword with a comma. + if (heritageClauses.length === 2 && + heritageClauses[0].token === SyntaxKind.ExtendsKeyword && + heritageClauses[1].token === SyntaxKind.ImplementsKeyword) { + + const implementsToken = heritageClauses[1].getFirstToken()!; + const implementsFullStart = implementsToken.getFullStart(); + changes.replaceRange(sourceFile, { pos: implementsFullStart, end: implementsFullStart }, createToken(SyntaxKind.CommaToken)); + + // Rough heuristic: delete trailing whitespace after keyword so that it's not excessive. + // (Trailing because leading might be indentation, which is more sensitive.) + const text = sourceFile.text; + let end = implementsToken.end; + while (end < text.length && ts.isWhiteSpaceSingleLine(text.charCodeAt(end))) { + end++; + } + + changes.deleteRange(sourceFile, { pos: implementsToken.getStart(), end }); } } } diff --git a/src/services/codefixes/fixInvalidImportSyntax.ts b/src/services/codefixes/fixInvalidImportSyntax.ts new file mode 100644 index 00000000000..f98f1eaea7c --- /dev/null +++ b/src/services/codefixes/fixInvalidImportSyntax.ts @@ -0,0 +1,98 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: [Diagnostics.A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime.code], + getCodeActions: getActionsForInvalidImport + }); + + function getActionsForInvalidImport(context: CodeFixContext): CodeAction[] | undefined { + const sourceFile = context.sourceFile; + + // This is the whole import statement, eg: + // import * as Bluebird from 'bluebird'; + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + const node = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false).parent as ImportDeclaration; + if (!isImportDeclaration(node)) { + // No import quick fix for import calls + return []; + } + return getCodeFixesForImportDeclaration(context, node); + } + + function getCodeFixesForImportDeclaration(context: CodeFixContext, node: ImportDeclaration) { + const sourceFile = getSourceFileOfNode(node); + const namespace = getNamespaceDeclarationNode(node) as NamespaceImport; + const opts = context.program.getCompilerOptions(); + const variations: CodeAction[] = []; + + // import Bluebird from "bluebird"; + const replacement = createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(namespace.name, /*namedBindings*/ undefined), + node.moduleSpecifier + ); + const changeTracker = textChanges.ChangeTracker.fromContext(context); + changeTracker.replaceNode(sourceFile, node, replacement, { useNonAdjustedEndPosition: true }); + const changes = changeTracker.getChanges(); + variations.push({ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Replace_import_with_0), [changes[0].textChanges[0].newText]), + changes + }); + + if (getEmitModuleKind(opts) === ModuleKind.CommonJS) { + // import Bluebird = require("bluebird"); + const replacement = createImportEqualsDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + namespace.name, + createExternalModuleReference(node.moduleSpecifier) + ); + const changeTracker = textChanges.ChangeTracker.fromContext(context); + changeTracker.replaceNode(sourceFile, node, replacement, { useNonAdjustedEndPosition: true }); + const changes = changeTracker.getChanges(); + variations.push({ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Replace_import_with_0), [changes[0].textChanges[0].newText]), + changes + }); + } + + return variations; + } + + registerCodeFix({ + errorCodes: [ + Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures.code, + Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature.code, + ], + getCodeActions: getActionsForUsageOfInvalidImport + }); + + function getActionsForUsageOfInvalidImport(context: CodeFixContext): CodeAction[] | undefined { + const sourceFile = context.sourceFile; + const targetKind = Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures.code === context.errorCode ? SyntaxKind.CallExpression : SyntaxKind.NewExpression; + const node = findAncestor(getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false), a => a.kind === targetKind && a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length)) as CallExpression | NewExpression; + if (!node) { + return []; + } + const expr = node.expression; + const type = context.program.getTypeChecker().getTypeAtLocation(expr); + if (!(type.symbol && (type.symbol as TransientSymbol).originatingImport)) { + return []; + } + const fixes: CodeAction[] = []; + const relatedImport = (type.symbol as TransientSymbol).originatingImport; + if (!isImportCall(relatedImport)) { + addRange(fixes, getCodeFixesForImportDeclaration(context, relatedImport)); + } + const propertyAccess = createPropertyAccess(expr, "default"); + const changeTracker = textChanges.ChangeTracker.fromContext(context); + changeTracker.replaceNode(sourceFile, expr, propertyAccess, {}); + const changes = changeTracker.getChanges(); + fixes.push({ + description: getLocaleSpecificMessage(Diagnostics.Use_synthetic_default_member), + changes + }); + return fixes; + } +} diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts index 64cdc3181fb..729f14e9ef9 100644 --- a/src/services/codefixes/fixSpelling.ts +++ b/src/services/codefixes/fixSpelling.ts @@ -9,7 +9,7 @@ namespace ts.codefix { errorCodes, getCodeActions(context) { const { sourceFile } = context; - const info = getInfo(sourceFile, context.span.start, context.program.getTypeChecker()); + const info = getInfo(sourceFile, context.span.start, context.program.getTypeChecker()); if (!info) return undefined; const { node, suggestion } = info; const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, node, suggestion)); diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index 5b1ee8ec857..317c65b15ee 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -11,7 +11,10 @@ /// /// /// +/// /// /// /// /// +/// + diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index bd2710244e6..47e23e717d9 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -121,7 +121,7 @@ namespace ts.codefix { createStubbedMethodBody()); } - function createDummyParameters(argCount: number, names: string[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] { + function createDummyParameters(argCount: number, names: string[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] { const parameters: ParameterDeclaration[] = []; for (let i = 0; i < argCount; i++) { const newParameter = createParameter( diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index a69152ad2b5..8f69cd95c11 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -363,6 +363,10 @@ namespace ts.codefix { } } + if (isPathRelativeToParent(relativeToBaseUrl)) { + return [relativePath]; + } + /* Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. @@ -424,9 +428,10 @@ namespace ts.codefix { } } - function tryGetModuleNameFromPaths(relativeNameWithIndex: string, relativeName: string, paths: MapLike>): string | undefined { + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex: string, relativeToBaseUrl: string, paths: MapLike>): string | undefined { for (const key in paths) { - for (const pattern of paths[key]) { + for (const patternText of paths[key]) { + const pattern = removeFileExtension(normalizePath(patternText)); const indexOfStar = pattern.indexOf("*"); if (indexOfStar === 0 && pattern.length === 1) { continue; @@ -434,14 +439,14 @@ namespace ts.codefix { else if (indexOfStar !== -1) { const prefix = pattern.substr(0, indexOfStar); const suffix = pattern.substr(indexOfStar + 1); - if (relativeName.length >= prefix.length + suffix.length && - startsWith(relativeName, prefix) && - endsWith(relativeName, suffix)) { - const matchedStar = relativeName.substr(prefix.length, relativeName.length - suffix.length); - return key.replace("\*", matchedStar); + if (relativeToBaseUrl.length >= prefix.length + suffix.length && + startsWith(relativeToBaseUrl, prefix) && + endsWith(relativeToBaseUrl, suffix)) { + const matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); + return key.replace("*", matchedStar); } } - else if (pattern === relativeName || pattern === relativeNameWithIndex) { + else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { return key; } } @@ -601,7 +606,10 @@ namespace ts.codefix { } function getPathRelativeToRootDirs(path: string, rootDirs: ReadonlyArray, getCanonicalFileName: GetCanonicalFileName): string | undefined { - return firstDefined(rootDirs, rootDir => getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName)); + return firstDefined(rootDirs, rootDir => { + const relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); + return isPathRelativeToParent(relativePath) ? undefined : relativePath; + }); } function removeExtensionAndIndexPostFix(fileName: string, options: CompilerOptions, addJsExtension: boolean): string { @@ -615,7 +623,11 @@ namespace ts.codefix { function getRelativePathIfInDirectory(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName): string | undefined { const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - return isRootedDiskPath(relativePath) || startsWith(relativePath, "..") ? undefined : relativePath; + return isRootedDiskPath(relativePath) ? undefined : relativePath; + } + + function isPathRelativeToParent(path: string): boolean { + return startsWith(path, ".."); } function getRelativePath(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName) { @@ -734,7 +746,7 @@ namespace ts.codefix { } else if (isJsxOpeningLikeElement(symbolToken.parent) && symbolToken.parent.tagName === symbolToken) { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. - symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, SymbolFlags.Value)); + symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, SymbolFlags.Value, /*excludeGlobals*/ false)); symbolName = symbol.name; } else { @@ -780,8 +792,11 @@ namespace ts.codefix { const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol); if (defaultExport) { const localSymbol = getLocalSymbolForExportDefault(defaultExport); - if ((localSymbol && localSymbol.escapedName === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName) - && checkSymbolHasMeaning(localSymbol || defaultExport, currentTokenMeaning)) { + if (( + localSymbol && localSymbol.escapedName === symbolName || + getEscapedNameForExportDefault(defaultExport) === symbolName || + moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName + ) && checkSymbolHasMeaning(localSymbol || defaultExport, currentTokenMeaning)) { // check if this symbol is already used const symbolId = getUniqueSymbolId(localSymbol || defaultExport, checker); symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, { ...context, kind: ImportKind.Default })); @@ -794,6 +809,22 @@ namespace ts.codefix { const symbolId = getUniqueSymbolId(exportSymbolWithIdenticalName, checker); symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, { ...context, kind: ImportKind.Named })); } + + function getEscapedNameForExportDefault(symbol: Symbol): __String | undefined { + return firstDefined(symbol.declarations, declaration => { + if (isExportAssignment(declaration)) { + if (isIdentifier(declaration.expression)) { + return declaration.expression.escapedText; + } + } + else if (isExportSpecifier(declaration)) { + Debug.assert(declaration.name.escapedText === InternalSymbolName.Default); + if (declaration.propertyName) { + return declaration.propertyName.escapedText; + } + } + }); + } }); return symbolIdActionMap.getAllActions(); @@ -836,7 +867,7 @@ namespace ts.codefix { return moduleSpecifierToValidIdentifier(removeFileExtension(getBaseFileName(moduleSymbol.name)), target); } - function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string { + export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string { let res = ""; let lastCharWasValid = true; const firstCharCode = moduleSpecifier.charCodeAt(0); diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 95d85bc5aa0..6f6b2f3c61e 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -229,13 +229,13 @@ namespace ts.codefix { } } - function getTypeAccessiblityWriter(checker: TypeChecker): StringSymbolWriter { + function getTypeAccessiblityWriter(checker: TypeChecker): EmitTextWriter { let str = ""; let typeIsAccessible = true; const writeText: (text: string) => void = text => str += text; return { - string: () => typeIsAccessible ? str : undefined, + getText: () => typeIsAccessible ? str : undefined, writeKeyword: writeText, writeOperator: writeText, writePunctuation: writeText, @@ -244,6 +244,15 @@ namespace ts.codefix { writeParameter: writeText, writeProperty: writeText, writeSymbol: writeText, + write: writeText, + writeTextOfNode: writeText, + rawWrite: writeText, + writeLiteral: writeText, + getTextPos: () => 0, + getLine: () => 0, + getColumn: () => 0, + getIndent: () => 0, + isAtStartOfLine: () => false, writeLine: () => writeText(" "), increaseIndent: noop, decreaseIndent: noop, @@ -261,8 +270,8 @@ namespace ts.codefix { function typeToString(type: Type, enclosingDeclaration: Declaration, checker: TypeChecker): string { const writer = getTypeAccessiblityWriter(checker); - checker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration); - return writer.string(); + checker.writeType(type, enclosingDeclaration, /*flags*/ undefined, writer); + return writer.getText(); } namespace InferFromReference { diff --git a/src/services/completions.ts b/src/services/completions.ts index 11119503d36..2afac10a944 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -35,11 +35,14 @@ namespace ts.Completions { return entries && pathCompletionsInfo(entries); } - if (isInString(sourceFile, position)) { - return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log); + const contextToken = findPrecedingToken(position, sourceFile); + + if (isInString(sourceFile, position, contextToken)) { + return !contextToken || !isStringLiteral(contextToken) && !isNoSubstitutionTemplateLiteral(contextToken) + ? undefined + : getStringLiteralCompletionEntries(sourceFile, contextToken, position, typeChecker, compilerOptions, host, log); } - const contextToken = findPrecedingToken(position, sourceFile); if (contextToken && isBreakOrContinueStatement(contextToken.parent) && (contextToken.kind === SyntaxKind.BreakKeyword || contextToken.kind === SyntaxKind.ContinueKeyword || contextToken.kind === SyntaxKind.Identifier)) { return getLabelCompletionAtPosition(contextToken.parent); @@ -50,39 +53,49 @@ namespace ts.Completions { return undefined; } - const { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, request, keywordFilters, symbolToOriginInfoMap, recommendedCompletion } = completionData; + switch (completionData.kind) { + case CompletionDataKind.Data: + return completionInfoFromData(sourceFile, typeChecker, compilerOptions, log, completionData, options.includeInsertTextCompletions); + case CompletionDataKind.JsDocTagName: + // If the current position is a jsDoc tag name, only tag names should be provided for completion + return jsdocCompletionInfo(JsDoc.getJSDocTagNameCompletions()); + case CompletionDataKind.JsDocTag: + // If the current position is a jsDoc tag, only tags should be provided for completion + return jsdocCompletionInfo(JsDoc.getJSDocTagCompletions()); + case CompletionDataKind.JsDocParameterName: + return jsdocCompletionInfo(JsDoc.getJSDocParameterNameCompletions(completionData.tag)); + default: + throw Debug.assertNever(completionData); + } + } - if (sourceFile.languageVariant === LanguageVariant.JSX && - location && location.parent && location.parent.kind === SyntaxKind.JsxClosingElement) { + function jsdocCompletionInfo(entries: CompletionEntry[]): CompletionInfo { + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; + } + + function completionInfoFromData(sourceFile: SourceFile, typeChecker: TypeChecker, compilerOptions: CompilerOptions, log: Log, completionData: CompletionData, includeInsertTextCompletions: boolean): CompletionInfo { + const { symbols, completionKind, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, symbolToOriginInfoMap, recommendedCompletion } = completionData; + + if (sourceFile.languageVariant === LanguageVariant.JSX && location && location.parent && isJsxClosingElement(location.parent)) { // In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag, // instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element. // For example: - // var x =
completion list at "1" will contain "div" with type any - const tagName = (location.parent.parent).openingElement.tagName; + // var x =
+ // The completion list at "1" will contain "div" with type any + const tagName = location.parent.parent.openingElement.tagName; return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [{ - name: (tagName).getFullText(), + name: tagName.getFullText(), kind: ScriptElementKind.classElement, kindModifiers: undefined, sortText: "0", }]}; } - if (request) { - const entries = request.kind === "JsDocTagName" - // If the current position is a jsDoc tag name, only tag names should be provided for completion - ? JsDoc.getJSDocTagNameCompletions() - : request.kind === "JsDocTag" - // If the current position is a jsDoc tag, only tags should be provided for completion - ? JsDoc.getJSDocTagCompletions() - : JsDoc.getJSDocParameterNameCompletions(request.tag); - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; - } - const entries: CompletionEntry[] = []; if (isSourceFileJavaScript(sourceFile)) { - const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, recommendedCompletion, symbolToOriginInfoMap); + const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, includeInsertTextCompletions, propertyAccessToConvert, recommendedCompletion, symbolToOriginInfoMap); getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries); } else { @@ -90,7 +103,7 @@ namespace ts.Completions { return undefined; } - getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, recommendedCompletion, symbolToOriginInfoMap); + getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, includeInsertTextCompletions, propertyAccessToConvert, recommendedCompletion, symbolToOriginInfoMap); } // TODO add filter for keyword based on type/value/namespace and also location @@ -98,17 +111,29 @@ namespace ts.Completions { // Add all keywords if // - this is not a member completion list (all the keywords) // - other filters are enabled in required scenario so add those keywords + const isMemberCompletion = isMemberCompletionKind(completionKind); if (keywordFilters !== KeywordCompletionFilters.None || !isMemberCompletion) { addRange(entries, getKeywordCompletions(keywordFilters)); } - return { isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, entries }; + return { isGlobalCompletion: completionKind === CompletionKind.Global, isMemberCompletion, isNewIdentifierLocation, entries }; + } + + function isMemberCompletionKind(kind: CompletionKind): boolean { + switch (kind) { + case CompletionKind.ObjectPropertyDeclaration: + case CompletionKind.MemberLike: + case CompletionKind.PropertyAccess: + return true; + default: + return false; + } } function getJavaScriptCompletionEntries( sourceFile: SourceFile, position: number, - uniqueNames: Map<{}>, + uniqueNames: Map, target: ScriptTarget, entries: Push): void { getNameTable(sourceFile).forEach((pos, name) => { @@ -117,16 +142,9 @@ namespace ts.Completions { return; } const realName = unescapeLeadingUnderscores(name); - - if (uniqueNames.has(realName) || isStringANonContextualKeyword(realName)) { - return; - } - - uniqueNames.set(realName, true); - const displayName = getCompletionEntryDisplayName(realName, target, /*performCharacterChecks*/ true, /*allowStringLiteral*/ false); - if (displayName) { + if (addToSeen(uniqueNames, realName) && isIdentifierText(realName, target) && !isStringANonContextualKeyword(realName)) { entries.push({ - name: displayName, + name: realName, kind: ScriptElementKind.warning, kindModifiers: "", sortText: "1" @@ -138,18 +156,22 @@ namespace ts.Completions { function createCompletionEntry( symbol: Symbol, location: Node, - performCharacterChecks: boolean, + sourceFile: SourceFile, typeChecker: TypeChecker, target: ScriptTarget, - allowStringLiteral: boolean, + kind: CompletionKind, origin: SymbolOriginInfo | undefined, recommendedCompletion: Symbol | undefined, + propertyAccessToConvert: PropertyAccessExpression | undefined, + includeInsertTextCompletions: boolean, ): CompletionEntry | undefined { - // Try to get a valid display name for this symbol, if we could not find one, then ignore it. - // We would like to only show things that can be added after a dot, so for instance numeric properties can - // not be accessed with a dot (a.1 <- invalid) - const displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral, origin); - if (!displayName) { + const info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind); + if (!info) { + return undefined; + } + const { name, needsConvertPropertyAccess } = info; + Debug.assert(!(needsConvertPropertyAccess && !propertyAccessToConvert)); + if (needsConvertPropertyAccess && !includeInsertTextCompletions) { return undefined; } @@ -162,16 +184,22 @@ namespace ts.Completions { // Use a 'sortText' of 0' so that all symbol completion entries come before any other // entries (like JavaScript identifier entries). return { - name: displayName, + name, kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location), kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), sortText: "0", source: getSourceFromOrigin(origin), - hasAction: trueOrUndefined(origin !== undefined), + // TODO: GH#20619 Use configured quote style + insertText: needsConvertPropertyAccess ? `["${name}"]` : undefined, + replacementSpan: needsConvertPropertyAccess + ? createTextSpanFromBounds(findChildOfKind(propertyAccessToConvert, SyntaxKind.DotToken, sourceFile)!.getStart(sourceFile), propertyAccessToConvert.name.end) + : undefined, + hasAction: trueOrUndefined(needsConvertPropertyAccess || origin !== undefined), isRecommended: trueOrUndefined(isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker)), }; } + function isRecommendedCompletionMatch(localSymbol: Symbol, recommendedCompletion: Symbol, checker: TypeChecker): boolean { return localSymbol === recommendedCompletion || !!(localSymbol.flags & SymbolFlags.ExportValue) && checker.getExportSymbolOfSymbol(localSymbol) === recommendedCompletion; @@ -189,11 +217,13 @@ namespace ts.Completions { symbols: ReadonlyArray, entries: Push, location: Node, - performCharacterChecks: boolean, + sourceFile: SourceFile, typeChecker: TypeChecker, target: ScriptTarget, log: Log, - allowStringLiteral: boolean, + kind: CompletionKind, + includeInsertTextCompletions?: boolean, + propertyAccessToConvert?: PropertyAccessExpression | undefined, recommendedCompletion?: Symbol, symbolToOriginInfoMap?: SymbolOriginInfoMap, ): Map { @@ -203,26 +233,24 @@ namespace ts.Completions { // Based on the order we add things we will always see locals first, then globals, then module exports. // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name. const uniques = createMap(); - if (symbols) { - for (const symbol of symbols) { - const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined; - const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin, recommendedCompletion); - if (!entry) { - continue; - } - - const { name } = entry; - if (uniques.has(name)) { - continue; - } - - // Latter case tests whether this is a global variable. - if (!origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()))) { - uniques.set(name, true); - } - - entries.push(entry); + for (const symbol of symbols) { + const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined; + const entry = createCompletionEntry(symbol, location, sourceFile, typeChecker, target, kind, origin, recommendedCompletion, propertyAccessToConvert, includeInsertTextCompletions); + if (!entry) { + continue; } + + const { name } = entry; + if (uniques.has(name)) { + continue; + } + + // Latter case tests whether this is a global variable. + if (!origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()))) { + uniques.set(name, true); + } + + entries.push(entry); } log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start)); @@ -236,74 +264,90 @@ namespace ts.Completions { } } - function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined { - const node = findPrecedingToken(position, sourceFile); - if (!node || (node.kind !== SyntaxKind.StringLiteral && node.kind !== SyntaxKind.NoSubstitutionTemplateLiteral)) { - return undefined; - } + function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringLiteralLike, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined { + switch (node.parent.kind) { + case SyntaxKind.LiteralType: + switch (node.parent.parent.kind) { + case SyntaxKind.TypeReference: + // TODO: GH#21168 + return undefined; + case SyntaxKind.IndexedAccessType: + // Get all apparent property names + // i.e. interface Foo { + // foo: string; + // bar: string; + // } + // let x: Foo["/*completion position*/"] + const type = typeChecker.getTypeFromTypeNode((node.parent.parent as IndexedAccessTypeNode).objectType); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); + default: + return undefined; + } - if (node.parent.kind === SyntaxKind.PropertyAssignment && - node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && - (node.parent).name === node) { - // Get quoted name of properties of the object literal expression - // i.e. interface ConfigFiles { - // 'jspm:dev': string - // } - // let files: ConfigFiles = { - // '/*completion position*/' - // } - // - // function foo(c: ConfigFiles) {} - // foo({ - // '/*completion position*/' - // }); - return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, typeChecker, compilerOptions.target, log); - } - else if (isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) { - // Get all names of properties on the expression - // i.e. interface A { - // 'prop1': string - // } - // let a: A; - // a['/*completion position*/'] - return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log); - } - else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration - || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent) - || isExpressionOfExternalModuleImportEqualsDeclaration(node)) { - // Get all known external module names or complete a path to a module - // i.e. import * as ns from "/*completion position*/"; - // var y = import("/*completion position*/"); - // import x = require("/*completion position*/"); - // var y = require("/*completion position*/"); - // export * from "/*completion position*/"; - const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker); - return pathCompletionsInfo(entries); - } - else if (isEqualityExpression(node.parent)) { - // Get completions from the type of the other operand - // i.e. switch (a) { - // case '/*completion position*/' - // } - return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker); - } - else if (isCaseOrDefaultClause(node.parent)) { - // Get completions from the type of the switch expression - // i.e. x === '/*completion position' - return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation((node.parent.parent.parent).expression), typeChecker); - } - else { - const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); - if (argumentInfo) { - // Get string literal completions from specialized signatures of the target - // i.e. declare function f(a: 'A'); - // f("/*completion position*/") - return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker); + case SyntaxKind.PropertyAssignment: + if (node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && + (node.parent).name === node) { + // Get quoted name of properties of the object literal expression + // i.e. interface ConfigFiles { + // 'jspm:dev': string + // } + // let files: ConfigFiles = { + // '/*completion position*/' + // } + // + // function foo(c: ConfigFiles) {} + // foo({ + // '/*completion position*/' + // }); + return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, sourceFile, typeChecker, compilerOptions.target, log); + } + return fromContextualType(); + + case SyntaxKind.ElementAccessExpression: { + const { expression, argumentExpression } = node.parent as ElementAccessExpression; + if (node === argumentExpression) { + // Get all names of properties on the expression + // i.e. interface A { + // 'prop1': string + // } + // let a: A; + // a['/*completion position*/'] + const type = typeChecker.getTypeAtLocation(expression); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); + } + break; } + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + if (!isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) && !isImportCall(node.parent)) { + const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); + // Get string literal completions from specialized signatures of the target + // i.e. declare function f(a: 'A'); + // f("/*completion position*/") + return argumentInfo ? getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker) : fromContextualType(); + } + // falls through + + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ExportDeclaration: + case SyntaxKind.ExternalModuleReference: + // Get all known external module names or complete a path to a module + // i.e. import * as ns from "/*completion position*/"; + // var y = import("/*completion position*/"); + // import x = require("/*completion position*/"); + // var y = require("/*completion position*/"); + // export * from "/*completion position*/"; + return pathCompletionsInfo(PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node as StringLiteral, compilerOptions, host, typeChecker)); + + default: + return fromContextualType(); + } + + function fromContextualType(): CompletionInfo { // Get completion for string literal from string literal type // i.e. var x: "hi" | "hello" = "/*completion position*/" - return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(node), typeChecker); + return getStringLiteralCompletionEntriesFromType(getContextualTypeFromParent(node, typeChecker), typeChecker); } } @@ -319,11 +363,11 @@ namespace ts.Completions { }; } - function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { + function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement, sourceFile: SourceFile, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { const type = typeChecker.getContextualType((element.parent)); const entries: CompletionEntry[] = []; if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true); + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, sourceFile, typeChecker, target, log, CompletionKind.String); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; } @@ -348,11 +392,10 @@ namespace ts.Completions { return undefined; } - function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { - const type = typeChecker.getTypeAtLocation(node.expression); + function getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(stringLiteralNode: StringLiteral | NoSubstitutionTemplateLiteral, sourceFile: SourceFile, type: Type, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined { const entries: CompletionEntry[] = []; if (type) { - getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true); + getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, stringLiteralNode, sourceFile, typeChecker, target, log, CompletionKind.String); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries }; } @@ -423,6 +466,13 @@ namespace ts.Completions { } } + interface SymbolCompletion { + type: "symbol"; + symbol: Symbol; + location: Node; + symbolToOriginInfoMap: SymbolOriginInfoMap; + previousToken: Node; + } function getSymbolCompletionFromEntryId( typeChecker: TypeChecker, log: (message: string) => void, @@ -431,32 +481,33 @@ namespace ts.Completions { position: number, { name, source }: CompletionEntryIdentifier, allSourceFiles: ReadonlyArray, - ): { type: "symbol", symbol: Symbol, location: Node, symbolToOriginInfoMap: SymbolOriginInfoMap, previousToken: Node } | { type: "request", request: Request } | { type: "none" } { - const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true }, compilerOptions.target); + ): SymbolCompletion | { type: "request", request: Request } | { type: "none" } { + const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true, includeInsertTextCompletions: true }, compilerOptions.target); if (!completionData) { return { type: "none" }; } - - const { symbols, location, allowStringLiteral, symbolToOriginInfoMap, request, previousToken } = completionData; - if (request) { - return { type: "request", request }; + if (completionData.kind !== CompletionDataKind.Data) { + return { type: "request", request: completionData }; } + const { symbols, location, completionKind, symbolToOriginInfoMap, previousToken } = completionData; + // Find the symbol with the matching entry name. // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. - const symbol = find(symbols, s => { - const origin = symbolToOriginInfoMap[getSymbolId(s)]; - return getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral, origin) === name - && getSourceFromOrigin(origin) === source; - }); - return symbol ? { type: "symbol", symbol, location, symbolToOriginInfoMap, previousToken } : { type: "none" }; + return firstDefined(symbols, (symbol): SymbolCompletion => { // TODO: Shouldn't need return type annotation (GH#12632) + const origin = symbolToOriginInfoMap[getSymbolId(symbol)]; + const info = getCompletionEntryDisplayNameForSymbol(symbol, compilerOptions.target, origin, completionKind); + return info && info.name === name && getSourceFromOrigin(origin) === source ? { type: "symbol" as "symbol", symbol, location, symbolToOriginInfoMap, previousToken } : undefined; + }) || { type: "none" }; } function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string { return origin && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default - ? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) + // Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase. + ? firstDefined(symbol.declarations, d => isExportAssignment(d) && isIdentifier(d.expression) ? d.expression.text : undefined) + || codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) : symbol.name; } @@ -485,11 +536,11 @@ namespace ts.Completions { case "request": { const { request } = symbolCompletion; switch (request.kind) { - case "JsDocTagName": + case CompletionDataKind.JsDocTagName: return JsDoc.getJSDocTagNameCompletionDetails(name); - case "JsDocTag": + case CompletionDataKind.JsDocTag: return JsDoc.getJSDocTagCompletionDetails(name); - case "JsDocParameterName": + case CompletionDataKind.JsDocParameterName: return JsDoc.getJSDocParameterNameCompletionDetails(name); default: return Debug.assertNever(request); @@ -521,6 +572,10 @@ namespace ts.Completions { } } + interface CodeActionsAndSourceDisplay { + readonly codeActions: CodeAction[] | undefined; + readonly sourceDisplay: SymbolDisplayPart[] | undefined; + } function getCompletionEntryCodeActionsAndSourceDisplay( symbolToOriginInfoMap: SymbolOriginInfoMap, symbol: Symbol, @@ -533,12 +588,26 @@ namespace ts.Completions { formatContext: formatting.FormatContext, getCanonicalFileName: GetCanonicalFileName, allSourceFiles: ReadonlyArray, - ): { codeActions: CodeAction[] | undefined, sourceDisplay: SymbolDisplayPart[] | undefined } { + ): CodeActionsAndSourceDisplay { const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)]; - if (!symbolOriginInfo) { - return { codeActions: undefined, sourceDisplay: undefined }; - } + return symbolOriginInfo + ? getCodeActionsAndSourceDisplayForImport(symbolOriginInfo, symbol, program, checker, host, compilerOptions, sourceFile, previousToken, formatContext, getCanonicalFileName, allSourceFiles) + : { codeActions: undefined, sourceDisplay: undefined }; + } + function getCodeActionsAndSourceDisplayForImport( + symbolOriginInfo: SymbolOriginInfo, + symbol: Symbol, + program: Program, + checker: TypeChecker, + host: LanguageServiceHost, + compilerOptions: CompilerOptions, + sourceFile: SourceFile, + previousToken: Node, + formatContext: formatting.FormatContext, + getCanonicalFileName: GetCanonicalFileName, + allSourceFiles: ReadonlyArray + ): CodeActionsAndSourceDisplay { const { moduleSymbol, isDefaultExport } = symbolOriginInfo; const exportedSymbol = skipAlias(symbol.exportSymbol || symbol, checker); const moduleSymbols = getAllReExportingModules(exportedSymbol, checker, allSourceFiles); @@ -586,24 +655,33 @@ namespace ts.Completions { return completion.type === "symbol" ? completion.symbol : undefined; } + const enum CompletionDataKind { Data, JsDocTagName, JsDocTag, JsDocParameterName } interface CompletionData { - symbols: ReadonlyArray; - isGlobalCompletion: boolean; - isMemberCompletion: boolean; - allowStringLiteral: boolean; - isNewIdentifierLocation: boolean; - location: Node | undefined; - isRightOfDot: boolean; - request?: Request; - keywordFilters: KeywordCompletionFilters; - symbolToOriginInfoMap: SymbolOriginInfoMap; - recommendedCompletion: Symbol | undefined; - previousToken: Node; + readonly kind: CompletionDataKind.Data; + readonly symbols: ReadonlyArray; + readonly completionKind: CompletionKind; + /** Note that the presence of this alone doesn't mean that we need a conversion. Only do that if the completion is not an ordinary identifier. */ + readonly propertyAccessToConvert: PropertyAccessExpression | undefined; + readonly isNewIdentifierLocation: boolean; + readonly location: Node | undefined; + readonly keywordFilters: KeywordCompletionFilters; + readonly symbolToOriginInfoMap: SymbolOriginInfoMap; + readonly recommendedCompletion: Symbol | undefined; + readonly previousToken: Node | undefined; } - type Request = { kind: "JsDocTagName" } | { kind: "JsDocTag" } | { kind: "JsDocParameterName", tag: JSDocParameterTag }; + type Request = { readonly kind: CompletionDataKind.JsDocTagName | CompletionDataKind.JsDocTag } | { readonly kind: CompletionDataKind.JsDocParameterName, tag: JSDocParameterTag }; - function getRecommendedCompletion(currentToken: Node, checker: TypeChecker/*, symbolToOriginInfoMap: SymbolOriginInfoMap*/): Symbol | undefined { - const ty = checker.getContextualType(currentToken as Expression); + const enum CompletionKind { + ObjectPropertyDeclaration, + Global, + PropertyAccess, + MemberLike, + String, + None, + } + + function getRecommendedCompletion(currentToken: Node, checker: TypeChecker): Symbol | undefined { + const ty = getContextualType(currentToken, checker); const symbol = ty && ty.symbol; // Don't include make a recommended completion for an abstract class return symbol && (symbol.flags & SymbolFlags.Enum || symbol.flags & SymbolFlags.Class && !isAbstractConstructorSymbol(symbol)) @@ -611,6 +689,48 @@ namespace ts.Completions { : undefined; } + function getContextualType(currentToken: Node, checker: ts.TypeChecker): Type | undefined { + const { parent } = currentToken; + switch (currentToken.kind) { + case ts.SyntaxKind.Identifier: + return getContextualTypeFromParent(currentToken as ts.Identifier, checker); + case ts.SyntaxKind.EqualsToken: + return ts.isVariableDeclaration(parent) ? checker.getContextualType(parent.initializer) : + ts.isBinaryExpression(parent) ? checker.getTypeAtLocation(parent.left) : undefined; + case ts.SyntaxKind.NewKeyword: + return checker.getContextualType(parent as ts.Expression); + case ts.SyntaxKind.CaseKeyword: + return getSwitchedType(cast(currentToken.parent, isCaseClause), checker); + default: + return isEqualityOperatorKind(currentToken.kind) && ts.isBinaryExpression(parent) && isEqualityOperatorKind(parent.operatorToken.kind) + // completion at `x ===/**/` should be for the right side + ? checker.getTypeAtLocation(parent.left) + : checker.getContextualType(currentToken as ts.Expression); + } + } + + function getContextualTypeFromParent(node: ts.Expression, checker: ts.TypeChecker): Type | undefined { + const { parent } = node; + switch (parent.kind) { + case ts.SyntaxKind.NewExpression: + return checker.getContextualType(parent as ts.NewExpression); + case ts.SyntaxKind.BinaryExpression: { + const { left, operatorToken, right } = parent as ts.BinaryExpression; + return isEqualityOperatorKind(operatorToken.kind) + ? checker.getTypeAtLocation(node === right ? left : right) + : checker.getContextualType(node); + } + case ts.SyntaxKind.CaseClause: + return (parent as ts.CaseClause).expression === node ? getSwitchedType(parent as ts.CaseClause, checker) : undefined; + default: + return checker.getContextualType(node); + } + } + + function getSwitchedType(caseClause: ts.CaseClause, checker: ts.TypeChecker): ts.Type { + return checker.getTypeAtLocation(caseClause.parent.parent.expression); + } + function getFirstSymbolInChain(symbol: Symbol, enclosingDeclaration: Node, checker: TypeChecker): Symbol | undefined { const chain = checker.getAccessibleSymbolChain(symbol, enclosingDeclaration, /*meaning*/ SymbolFlags.All, /*useOnlyExternalAliasing*/ false); if (chain) return first(chain); @@ -629,9 +749,7 @@ namespace ts.Completions { allSourceFiles: ReadonlyArray, options: GetCompletionsAtPositionOptions, target: ScriptTarget, - ): CompletionData | undefined { - let request: Request | undefined; - + ): CompletionData | Request | undefined { let start = timestamp(); let currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853 // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.) @@ -649,7 +767,7 @@ namespace ts.Completions { if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) { // The current position is next to the '@' sign, when no tag name being provided yet. // Provide a full list of tag names - request = { kind: "JsDocTagName" }; + return { kind: CompletionDataKind.JsDocTagName }; } else { // When completion is requested without "@", we will have check to make sure that @@ -670,7 +788,7 @@ namespace ts.Completions { // */ const lineStart = getLineStartPositionForPosition(position, sourceFile); if (!(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/))) { - request = { kind: "JsDocTag" }; + return { kind: CompletionDataKind.JsDocTag }; } } } @@ -681,7 +799,7 @@ namespace ts.Completions { const tag = getJsDocTagAtPosition(currentToken, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { - request = { kind: "JsDocTagName" }; + return { kind: CompletionDataKind.JsDocTagName }; } if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === SyntaxKind.JSDocTypeExpression) { currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ true); @@ -694,27 +812,10 @@ namespace ts.Completions { } } if (isJSDocParameterTag(tag) && (nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) { - request = { kind: "JsDocParameterName", tag }; + return { kind: CompletionDataKind.JsDocParameterName, tag }; } } - if (request) { - return { - symbols: emptyArray, - isGlobalCompletion: false, - isMemberCompletion: false, - allowStringLiteral: false, - isNewIdentifierLocation: false, - location: undefined, - isRightOfDot: false, - request, - keywordFilters: KeywordCompletionFilters.None, - symbolToOriginInfoMap: undefined, - recommendedCompletion: undefined, - previousToken: undefined, - }; - } - if (!insideJsDocTagTypeExpression) { // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal // comment or the plain text part of a jsDoc comment, so no completion should be available @@ -743,6 +844,7 @@ namespace ts.Completions { // Also determine whether we are trying to complete with members of that node // or attributes of a JSX tag. let node = currentToken; + let propertyAccessToConvert: PropertyAccessExpression | undefined; let isRightOfDot = false; let isRightOfOpenTag = false; let isStartingCloseTag = false; @@ -757,18 +859,19 @@ namespace ts.Completions { let parent = contextToken.parent; if (contextToken.kind === SyntaxKind.DotToken) { - if (parent.kind === SyntaxKind.PropertyAccessExpression) { - node = (contextToken.parent).expression; - isRightOfDot = true; - } - else if (parent.kind === SyntaxKind.QualifiedName) { - node = (contextToken.parent).left; - isRightOfDot = true; - } - else { - // There is nothing that precedes the dot, so this likely just a stray character - // or leading into a '...' token. Just bail out instead. - return undefined; + isRightOfDot = true; + switch (parent.kind) { + case SyntaxKind.PropertyAccessExpression: + propertyAccessToConvert = parent as PropertyAccessExpression; + node = propertyAccessToConvert.expression; + break; + case SyntaxKind.QualifiedName: + node = (parent as QualifiedName).left; + break; + default: + // There is nothing that precedes the dot, so this likely just a stray character + // or leading into a '...' token. Just bail out instead. + return undefined; } } else if (sourceFile.languageVariant === LanguageVariant.JSX) { @@ -808,10 +911,8 @@ namespace ts.Completions { } const semanticStart = timestamp(); - let isGlobalCompletion = false; - let isMemberCompletion: boolean; - let allowStringLiteral = false; - let isNewIdentifierLocation: boolean; + let completionKind = CompletionKind.None; + let isNewIdentifierLocation = false; let keywordFilters = KeywordCompletionFilters.None; let symbols: Symbol[] = []; const symbolToOriginInfoMap: SymbolOriginInfoMap = []; @@ -827,8 +928,7 @@ namespace ts.Completions { else { symbols = tagSymbols; } - isMemberCompletion = true; - isNewIdentifierLocation = false; + completionKind = CompletionKind.MemberLike; } else if (isStartingCloseTag) { const tagName = (contextToken.parent.parent).openingElement.tagName; @@ -837,8 +937,7 @@ namespace ts.Completions { if (!typeChecker.isUnknownSymbol(tagSymbol)) { symbols = [tagSymbol]; } - isMemberCompletion = true; - isNewIdentifierLocation = false; + completionKind = CompletionKind.MemberLike; } else { // For JavaScript or TypeScript, if we're not after a dot, then just try to get the @@ -851,8 +950,8 @@ namespace ts.Completions { log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); - const recommendedCompletion = getRecommendedCompletion(previousToken, typeChecker); - return { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken }; + const recommendedCompletion = previousToken && getRecommendedCompletion(previousToken, typeChecker); + return { kind: CompletionDataKind.Data, symbols, completionKind, propertyAccessToConvert, isNewIdentifierLocation, location, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken }; type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag; @@ -869,9 +968,7 @@ namespace ts.Completions { function getTypeScriptMemberSymbols(): void { // Right of dot member completion list - isGlobalCompletion = false; - isMemberCompletion = true; - isNewIdentifierLocation = false; + completionKind = CompletionKind.PropertyAccess; // Since this is qualified name check its a type node location const isTypeLocation = insideJsDocTagTypeExpression || isPartOfTypeNode(node.parent); @@ -947,7 +1044,7 @@ namespace ts.Completions { if (tryGetConstructorLikeCompletionContainer(contextToken)) { // no members, only keywords - isMemberCompletion = false; + completionKind = CompletionKind.None; // Declaring new property/method/accessor isNewIdentifierLocation = true; // Has keywords for constructor parameter @@ -969,7 +1066,7 @@ namespace ts.Completions { if (attrsType) { symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes.properties); - isMemberCompletion = true; + completionKind = CompletionKind.MemberLike; isNewIdentifierLocation = false; return true; } @@ -977,7 +1074,7 @@ namespace ts.Completions { } // Get all entities in the current scope. - isMemberCompletion = false; + completionKind = CompletionKind.None; isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken); if (previousToken !== contextToken) { @@ -1013,13 +1110,8 @@ namespace ts.Completions { position; const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; - if (scopeNode) { - isGlobalCompletion = - scopeNode.kind === SyntaxKind.SourceFile || - scopeNode.kind === SyntaxKind.TemplateExpression || - scopeNode.kind === SyntaxKind.JsxExpression || - scopeNode.kind === SyntaxKind.Block || // Some blocks aren't statements, but all get global completions - isStatement(scopeNode); + if (isGlobalCompletionScope(scopeNode)) { + completionKind = CompletionKind.Global; } const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; @@ -1033,6 +1125,18 @@ namespace ts.Completions { return true; } + function isGlobalCompletionScope(scopeNode: Node): boolean { + switch (scopeNode.kind) { + case SyntaxKind.SourceFile: + case SyntaxKind.TemplateExpression: + case SyntaxKind.JsxExpression: + case SyntaxKind.Block: + return true; + default: + return isStatement(scopeNode); + } + } + function filterGlobalCompletion(symbols: Symbol[]): void { filterMutate(symbols, symbol => { if (!isSourceFile(location)) { @@ -1113,28 +1217,21 @@ namespace ts.Completions { codefix.forEachExternalModuleToImportFrom(typeChecker, sourceFile, allSourceFiles, moduleSymbol => { for (let symbol of typeChecker.getExportsOfModule(moduleSymbol)) { - let { name } = symbol; - // Don't add a completion for a re-export, only for the original. - // If `symbol.parent !== moduleSymbol`, this comes from an `export * from "foo"` re-export. Those don't create new symbols. + // If `symbol.parent !== ...`, this comes from an `export * from "foo"` re-export. Those don't create new symbols. // If `some(...)`, this comes from an `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check). - if (symbol.parent !== moduleSymbol || some(symbol.declarations, d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) { + if (typeChecker.getMergedSymbol(symbol.parent) !== typeChecker.resolveExternalModuleSymbol(moduleSymbol) + || some(symbol.declarations, d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) { continue; } - const isDefaultExport = name === InternalSymbolName.Default; + const isDefaultExport = symbol.name === InternalSymbolName.Default; if (isDefaultExport) { - const localSymbol = getLocalSymbolForExportDefault(symbol); - if (localSymbol) { - symbol = localSymbol; - name = localSymbol.name; - } - else { - name = codefix.moduleSymbolToValidIdentifier(moduleSymbol, target); - } + symbol = getLocalSymbolForExportDefault(symbol) || symbol; } - if (stringContainsCharactersInOrder(name.toLowerCase(), tokenTextLowerCase)) { + const origin: SymbolOriginInfo = { moduleSymbol, isDefaultExport }; + if (stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) { symbols.push(symbol); symbolToOriginInfoMap[getSymbolId(symbol)] = { moduleSymbol, isDefaultExport }; } @@ -1299,8 +1396,7 @@ namespace ts.Completions { */ function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | ObjectBindingPattern): boolean { // We're looking up possible property names from contextual/inferred/declared type. - isMemberCompletion = true; - allowStringLiteral = true; + completionKind = CompletionKind.ObjectPropertyDeclaration; let typeMembers: Symbol[]; let existingMembers: ReadonlyArray; @@ -1378,7 +1474,7 @@ namespace ts.Completions { return false; } - isMemberCompletion = true; + completionKind = CompletionKind.MemberLike; isNewIdentifierLocation = false; const moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier); @@ -1398,7 +1494,7 @@ namespace ts.Completions { */ function getGetClassLikeCompletionSymbols(classLikeDeclaration: ClassLikeDeclaration) { // We're looking up possible property names from parent type. - isMemberCompletion = true; + completionKind = CompletionKind.MemberLike; // Declaring new property/method/accessor isNewIdentifierLocation = true; // Has keywords for class elements @@ -1561,7 +1657,7 @@ namespace ts.Completions { switch (contextToken.kind) { case SyntaxKind.OpenParenToken: case SyntaxKind.CommaToken: - return isConstructorDeclaration(contextToken.parent) && contextToken.parent; + return isConstructorDeclaration(contextToken.parent) && contextToken.parent; default: if (isConstructorParameterCompletion(contextToken)) { @@ -1952,55 +2048,44 @@ namespace ts.Completions { } } - /** - * Get the name to be display in completion from a given symbol. - * - * @return undefined if the name is of external module - */ - function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean, origin: SymbolOriginInfo | undefined): string | undefined { - const name = getSymbolName(symbol, origin, target); - if (!name) return undefined; - - // First check of the displayName is not external module; if it is an external module, it is not valid entry - if (symbol.flags & SymbolFlags.Namespace) { - const firstCharCode = name.charCodeAt(0); - if (isSingleOrDoubleQuote(firstCharCode)) { - // If the symbol is external module, don't show it in the completion list - // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) - return undefined; - } - } - - // If the symbol is for a member of an object type and is the internal name of an ES - // symbol, it is not a valid entry. Internal names for ES symbols start with "__@" - if (symbol.flags & SymbolFlags.ClassMember) { - const escapedName = symbol.escapedName as string; - if (escapedName.length >= 3 && - escapedName.charCodeAt(0) === CharacterCodes._ && - escapedName.charCodeAt(1) === CharacterCodes._ && - escapedName.charCodeAt(2) === CharacterCodes.at) { - return undefined; - } - } - - return getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral); + interface CompletionEntryDisplayNameForSymbol { + readonly name: string; + readonly needsConvertPropertyAccess: boolean; } - - /** - * Get a displayName from a given for completion list, performing any necessary quotes stripping - * and checking whether the name is valid identifier name. - */ - function getCompletionEntryDisplayName(name: string, target: ScriptTarget, performCharacterChecks: boolean, allowStringLiteral: boolean): string { - // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an - // invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name. - // e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid. - // We, thus, need to check if whatever was inside the quotes is actually a valid identifier name. - if (performCharacterChecks && !isIdentifierText(name, target)) { - // TODO: GH#18169 - return allowStringLiteral ? JSON.stringify(name) : undefined; + function getCompletionEntryDisplayNameForSymbol( + symbol: Symbol, + target: ScriptTarget, + origin: SymbolOriginInfo | undefined, + kind: CompletionKind, + ): CompletionEntryDisplayNameForSymbol | undefined { + const name = getSymbolName(symbol, origin, target); + if (name === undefined + // If the symbol is external module, don't show it in the completion list + // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) + || symbol.flags & SymbolFlags.Module && startsWithQuote(name) + // If the symbol is the internal name of an ES symbol, it is not a valid entry. Internal names for ES symbols start with "__@" + || isKnownSymbol(symbol)) { + return undefined; } - return name; + const validIdentiferResult: CompletionEntryDisplayNameForSymbol = { name, needsConvertPropertyAccess: false }; + if (isIdentifierText(name, target)) return validIdentiferResult; + switch (kind) { + case CompletionKind.None: + case CompletionKind.Global: + case CompletionKind.MemberLike: + return undefined; + case CompletionKind.ObjectPropertyDeclaration: + // TODO: GH#18169 + return { name: JSON.stringify(name), needsConvertPropertyAccess: false }; + case CompletionKind.PropertyAccess: + // Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547 + return name.charCodeAt(0) === CharacterCodes.space ? undefined : { name, needsConvertPropertyAccess: true }; + case CompletionKind.String: + return validIdentiferResult; + default: + Debug.assertNever(kind); + } } // A cache of completion entries for keywords, these do not change between sessions @@ -2013,7 +2098,7 @@ namespace ts.Completions { return _keywordCompletions[keywordFilter] = generateKeywordCompletions(keywordFilter); type FilterKeywordCompletions = (entryName: string) => boolean; - function generateKeywordCompletions(keywordFilter: KeywordCompletionFilters) { + function generateKeywordCompletions(keywordFilter: KeywordCompletionFilters): CompletionEntry[] { switch (keywordFilter) { case KeywordCompletionFilters.None: return getAllKeywordCompletions(); @@ -2021,6 +2106,8 @@ namespace ts.Completions { return getFilteredKeywordCompletions(isClassMemberCompletionKeywordText); case KeywordCompletionFilters.ConstructorParameterKeywords: return getFilteredKeywordCompletions(isConstructorParameterCompletionKeywordText); + default: + Debug.assertNever(keywordFilter); } } @@ -2081,15 +2168,16 @@ namespace ts.Completions { return isConstructorParameterCompletionKeyword(stringToToken(text)); } - function isEqualityExpression(node: Node): node is BinaryExpression { - return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind); - } - - function isEqualityOperatorKind(kind: SyntaxKind) { - return kind === SyntaxKind.EqualsEqualsToken || - kind === SyntaxKind.ExclamationEqualsToken || - kind === SyntaxKind.EqualsEqualsEqualsToken || - kind === SyntaxKind.ExclamationEqualsEqualsToken; + function isEqualityOperatorKind(kind: ts.SyntaxKind): kind is EqualityOperator { + switch (kind) { + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + return true; + default: + return false; + } } /** Get the corresponding JSDocTag node if the position is in a jsDoc comment */ diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index d9a9a03c38b..5c1e7116af4 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -2,19 +2,15 @@ namespace ts.DocumentHighlights { export function getDocumentHighlights(program: Program, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] | undefined { const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true); - // Note that getTouchingWord indicates failure by returning the sourceFile node. - if (node === sourceFile) return undefined; - Debug.assert(node.parent !== undefined); - - if (isJsxOpeningElement(node.parent) && node.parent.tagName === node || isJsxClosingElement(node.parent)) { + if (node.parent && (isJsxOpeningElement(node.parent) && node.parent.tagName === node || isJsxClosingElement(node.parent))) { // For a JSX element, just highlight the matching tag, not all references. const { openingElement, closingElement } = node.parent.parent; const highlightSpans = [openingElement, closingElement].map(({ tagName }) => getHighlightSpanForNode(tagName, sourceFile)); return [{ fileName: sourceFile.fileName, highlightSpans }]; } - return getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); + return getSemanticDocumentHighlights(position, node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); } function getHighlightSpanForNode(node: Node, sourceFile: SourceFile): HighlightSpan { @@ -25,8 +21,8 @@ namespace ts.DocumentHighlights { }; } - function getSemanticDocumentHighlights(node: Node, program: Program, cancellationToken: CancellationToken, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] { - const referenceEntries = FindAllReferences.getReferenceEntriesForNode(node, program, sourceFilesToSearch, cancellationToken); + function getSemanticDocumentHighlights(position: number, node: Node, program: Program, cancellationToken: CancellationToken, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] { + const referenceEntries = FindAllReferences.getReferenceEntriesForNode(position, node, program, sourceFilesToSearch, cancellationToken); return referenceEntries && convertReferencedSymbols(referenceEntries); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index fa56326b9f0..8b7473357fe 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -43,32 +43,21 @@ namespace ts.FindAllReferences { export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined { const referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position); - - if (!referencedSymbols || !referencedSymbols.length) { - return undefined; - } - - const out: ReferencedSymbol[] = []; const checker = program.getTypeChecker(); - for (const { definition, references } of referencedSymbols) { + return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined(referencedSymbols, ({ definition, references }) => // Only include referenced symbols that have a valid definition. - if (definition) { - out.push({ definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) }); - } - } - - return out; + definition && { definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) }); } export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, sourceFile: SourceFile, position: number): ImplementationLocation[] { // A node in a JSDoc comment can't have an implementation anyway. const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ false); - const referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node); + const referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node, position); const checker = program.getTypeChecker(); return map(referenceEntries, entry => toImplementationLocation(entry, checker)); } - function getImplementationReferenceEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, node: Node): Entry[] | undefined { + function getImplementationReferenceEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, node: Node, position: number): Entry[] | undefined { if (node.kind === SyntaxKind.SourceFile) { return undefined; } @@ -89,7 +78,7 @@ namespace ts.FindAllReferences { } else { // Perform "Find all References" and retrieve only those that are implementations - return getReferenceEntriesForNode(node, program, sourceFiles, cancellationToken, { implementations: true }); + return getReferenceEntriesForNode(position, node, program, sourceFiles, cancellationToken, { implementations: true }); } } @@ -98,13 +87,13 @@ namespace ts.FindAllReferences { return map(x, toReferenceEntry); } - export function getReferenceEntriesForNode(node: Node, program: Program, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken, options: Options = {}): Entry[] | undefined { - return flattenEntries(Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options)); + export function getReferenceEntriesForNode(position: number, node: Node, program: Program, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken, options: Options = {}): Entry[] | undefined { + return flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)); } function findAllReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, sourceFile: SourceFile, position: number, options?: Options): SymbolAndEntries[] | undefined { const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); - return Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options); + return Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options); } function flattenEntries(referenceSymbols: SymbolAndEntries[]): Entry[] { @@ -253,9 +242,10 @@ namespace ts.FindAllReferences { /* @internal */ namespace ts.FindAllReferences.Core { /** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */ - export function getReferencedSymbolsForNode(node: Node, program: Program, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken, options: Options = {}): SymbolAndEntries[] | undefined { - if (node.kind === ts.SyntaxKind.SourceFile) { - return undefined; + export function getReferencedSymbolsForNode(position: number, node: Node, program: Program, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken, options: Options = {}): SymbolAndEntries[] | undefined { + if (isSourceFile(node)) { + const reference = GoToDefinition.getReferenceAtPosition(node, position, program); + return reference && getReferencedSymbolsForModule(program, program.getTypeChecker().getMergedSymbol(reference.file.symbol), sourceFiles); } if (!options.implementations) { @@ -271,11 +261,7 @@ namespace ts.FindAllReferences.Core { // Could not find a symbol e.g. unknown identifier if (!symbol) { // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial. - if (!options.implementations && node.kind === SyntaxKind.StringLiteral) { - return getReferencesForStringLiteral(node, sourceFiles, cancellationToken); - } - // Can't have references to something that we have no symbol for. - return undefined; + return !options.implementations && isStringLiteral(node) ? getReferencesForStringLiteral(node, sourceFiles, cancellationToken) : undefined; } if (symbol.flags & SymbolFlags.Module && isModuleReferenceLocation(node)) { @@ -286,7 +272,7 @@ namespace ts.FindAllReferences.Core { } function isModuleReferenceLocation(node: ts.Node): boolean { - if (node.kind !== SyntaxKind.StringLiteral) { + if (node.kind !== SyntaxKind.StringLiteral && node.kind !== SyntaxKind.NoSubstitutionTemplateLiteral) { return false; } switch (node.parent.kind) { @@ -510,6 +496,9 @@ namespace ts.FindAllReferences.Core { /** @param allSearchSymbols set of additinal symbols for use by `includes`. */ createSearch(location: Node, symbol: Symbol, comingFrom: ImportExport | undefined, searchOptions: { text?: string, allSearchSymbols?: Symbol[] } = {}): Search { // Note: if this is an external module symbol, the name doesn't include quotes. + // Note: getLocalSymbolForExportDefault handles `export default class C {}`, but not `export default C` or `export { C as default }`. + // The other two forms seem to be handled downstream (e.g. in `skipPastExportOrImportSpecifier`), so special-casing the first form + // here appears to be intentional). const { text = stripQuotes(unescapeLeadingUnderscores((getLocalSymbolForExportDefault(symbol) || symbol).escapedName)), allSearchSymbols = undefined, @@ -876,6 +865,8 @@ namespace ts.FindAllReferences.Core { case SpecialSearchKind.Class: addClassStaticThisReferences(referenceLocation, search, state); break; + default: + Debug.assertNever(state.specialSearchKind); } getImportOrExportReferences(referenceLocation, referenceSymbol, search, state); @@ -1436,7 +1427,7 @@ namespace ts.FindAllReferences.Core { // This is not needed when searching for re-exports. function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, implementations: boolean): Symbol[] { // The search set contains at least the current symbol - const result = [symbol]; + const result: Symbol[] = []; const containingObjectLiteralElement = getContainingObjectLiteralElement(location); if (containingObjectLiteralElement) { @@ -1453,9 +1444,9 @@ namespace ts.FindAllReferences.Core { // If the location is in a context sensitive location (i.e. in an object literal) try // to get a contextual type for it, and add the property symbol from the contextual // type to the search set - forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol => { - addRange(result, checker.getRootSymbols(contextualSymbol)); - }); + for (const contextualSymbol of getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker)) { + addRootSymbols(contextualSymbol); + } /* Because in short-hand property assignment, location has two meaning : property name and as value of the property * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of @@ -1496,9 +1487,7 @@ namespace ts.FindAllReferences.Core { // If this is a union property, add all the symbols from all its source symbols in all unioned types. // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list for (const rootSymbol of checker.getRootSymbols(sym)) { - if (rootSymbol !== sym) { - result.push(rootSymbol); - } + result.push(rootSymbol); // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { @@ -1522,7 +1511,7 @@ namespace ts.FindAllReferences.Core { * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. * The value of previousIterationSymbol is undefined when the function is first called. */ - function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], previousIterationSymbolsCache: SymbolTable, checker: TypeChecker): void { + function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Push, previousIterationSymbolsCache: SymbolTable, checker: TypeChecker): void { if (!symbol) { return; } @@ -1591,9 +1580,7 @@ namespace ts.FindAllReferences.Core { // compare to our searchSymbol const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation); if (containingObjectLiteralElement) { - const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol => - find(checker.getRootSymbols(contextualSymbol), search.includes)); - + const contextualSymbol = firstDefined(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), findRootSymbol); if (contextualSymbol) { return contextualSymbol; } @@ -1622,7 +1609,7 @@ namespace ts.FindAllReferences.Core { function findRootSymbol(sym: Symbol): Symbol | undefined { // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) // Or a union property, use its underlying unioned symbols - return forEach(state.checker.getRootSymbols(sym), rootSymbol => { + return firstDefined(checker.getRootSymbols(sym), rootSymbol => { // if it is in the list, then we are done if (search.includes(rootSymbol)) { return rootSymbol; @@ -1633,12 +1620,12 @@ namespace ts.FindAllReferences.Core { // parent symbol if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { // Parents will only be defined if implementations is true - if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker))) { + if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker))) { return undefined; } const result: Symbol[] = []; - getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker); + getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker); return find(result, search.includes); } @@ -1660,28 +1647,12 @@ namespace ts.FindAllReferences.Core { } /** Gets all symbols for one property. Does not get symbols for every property. */ - function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): Symbol[] | undefined { - const objectLiteral = node.parent; - const contextualType = checker.getContextualType(objectLiteral); + function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): ReadonlyArray { + const contextualType = checker.getContextualType(node.parent); const name = getNameFromObjectLiteralElement(node); - if (name && contextualType) { - const result: Symbol[] = []; - const symbol = contextualType.getProperty(name); - if (symbol) { - result.push(symbol); - } - - if (contextualType.flags & TypeFlags.Union) { - forEach((contextualType).types, t => { - const symbol = t.getProperty(name); - if (symbol) { - result.push(symbol); - } - }); - } - return result; - } - return undefined; + const symbol = contextualType && name && contextualType.getProperty(name); + return symbol ? [symbol] : + contextualType && contextualType.flags & TypeFlags.Union ? mapDefined((contextualType).types, t => t.getProperty(name)) : emptyArray; } /** diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 31f29e9ebbe..49fb1420db8 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -484,7 +484,13 @@ namespace ts.formatting { delta = Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta); } else if (indentation === Constants.Unknown) { - if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { + if (node.kind === SyntaxKind.OpenParenToken && startLine === lastIndentedLine) { + // the is used for chaining methods formatting + // - we need to get the indentation on last line and the delta of parent + indentation = indentationOnLastIndentedLine; + delta = parentDynamicIndentation.getDelta(node); + } + else if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { indentation = parentDynamicIndentation.getIndentation(); } else { @@ -622,7 +628,7 @@ namespace ts.formatting { let childContextNode = contextNode; // if there are any tokens that logically belong to node and interleave child nodes - // such tokens will be consumed in processChildNode for for the child that follows them + // such tokens will be consumed in processChildNode for the child that follows them forEachChild( node, child => { diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 91c133ca352..16270eda479 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -11,8 +11,8 @@ namespace ts.formatting { for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) { allTokens.push(token); } - function anyTokenExcept(token: SyntaxKind): TokenRange { - return { tokens: allTokens.filter(t => t !== token), isSpecific: false }; + function anyTokenExcept(...tokens: SyntaxKind[]): TokenRange { + return { tokens: allTokens.filter(t => !tokens.some(t2 => t2 === t)), isSpecific: false }; } const anyToken: TokenRange = { tokens: allTokens, isSpecific: false }; @@ -47,7 +47,7 @@ namespace ts.formatting { rule("IgnoreBeforeComment", anyToken, comments, anyContext, RuleAction.Ignore), rule("IgnoreAfterLineComment", SyntaxKind.SingleLineCommentTrivia, anyToken, anyContext, RuleAction.Ignore), - rule("NoSpaceBeforeColon", anyToken, SyntaxKind.ColonToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete), + rule("NotSpaceBeforeColon", anyToken, SyntaxKind.ColonToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext, isNotTypeAnnotationContext], RuleAction.Delete), rule("SpaceAfterColon", SyntaxKind.ColonToken, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Space), rule("NoSpaceBeforeQuestionMark", anyToken, SyntaxKind.QuestionToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], RuleAction.Delete), // insert space after '?' only when it is used in conditional operator @@ -69,10 +69,10 @@ namespace ts.formatting { rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), // More unary operator special-casing. - // DevDiv 181814: Be careful when removing leading whitespace + // DevDiv 181814: Be careful when removing leading whitespace // around unary operators. Examples: - // 1 - -2 --X--> 1--2 - // a + ++b --X--> a+++b + // 1 - -2 --X--> 1--2 + // a + ++b --X--> a+++b rule("SpaceAfterPostincrementWhenFollowedByAdd", SyntaxKind.PlusPlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), rule("SpaceAfterAddWhenFollowedByUnaryPlus", SyntaxKind.PlusToken, SyntaxKind.PlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), rule("SpaceAfterAddWhenFollowedByPreincrement", SyntaxKind.PlusToken, SyntaxKind.PlusPlusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), @@ -80,7 +80,7 @@ namespace ts.formatting { rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", SyntaxKind.MinusToken, SyntaxKind.MinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), rule("SpaceAfterSubtractWhenFollowedByPredecrement", SyntaxKind.MinusToken, SyntaxKind.MinusMinusToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], RuleAction.Space), - rule("NoSpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, [SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken, SyntaxKind.SemicolonToken], [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterCloseBrace", SyntaxKind.CloseBraceToken, [SyntaxKind.CommaToken, SyntaxKind.SemicolonToken], [isNonJsxSameLineTokenContext], RuleAction.Delete), // For functions and control block place } on a new line [multi-line rule] rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, SyntaxKind.CloseBraceToken, [isMultilineBlockContext], RuleAction.NewLine), @@ -198,7 +198,7 @@ namespace ts.formatting { RuleAction.Delete), // decorators - rule("SpaceBeforeAt", anyToken, SyntaxKind.AtToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + rule("SpaceBeforeAt", [SyntaxKind.CloseParenToken, SyntaxKind.Identifier], SyntaxKind.AtToken, [isNonJsxSameLineTokenContext], RuleAction.Space), rule("NoSpaceAfterAt", SyntaxKind.AtToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), // Insert space after @ in decorator rule("SpaceAfterDecorator", @@ -231,8 +231,8 @@ namespace ts.formatting { rule("SpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Space), rule("NoSpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Delete), - rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext, isNextTokenNotCloseBracket], RuleAction.Space), - rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext], RuleAction.Delete), + rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNextTokenNotCloseBracket], RuleAction.Space), + rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext], RuleAction.Delete), // Insert space after function keyword for anonymous functions rule("SpaceAfterAnonymousFunctionKeyword", SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.Space), @@ -300,6 +300,9 @@ namespace ts.formatting { rule("SpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.Space), rule("NoSpaceAfterTypeAssertion", SyntaxKind.GreaterThanToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], RuleAction.Delete), + + rule("SpaceBeforeTypeAnnotation", anyToken, SyntaxKind.ColonToken, [isOptionEnabled("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], RuleAction.Space), + rule("NoSpaceBeforeTypeAnnotation", anyToken, SyntaxKind.ColonToken, [isOptionDisabledOrUndefined("insertSpaceBeforeTypeAnnotation"), isNonJsxSameLineTokenContext, isTypeAnnotationContext], RuleAction.Delete), ]; // These rules are lower in priority than user-configurable. Rules earlier in this list have priority over rules later in the list. @@ -313,21 +316,21 @@ namespace ts.formatting { rule("NoSpaceBeforeComma", anyToken, SyntaxKind.CommaToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + // No space before and after indexer `x[]` + rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword, SyntaxKind.CaseKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), + rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete), + rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), + // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] rule( "SpaceBetweenStatements", [SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword], anyToken, - [isNonJsxSameLineTokenContext, isNonJsxElementContext, isNotForContext], + [isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNotForContext], RuleAction.Space), // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. rule("SpaceAfterTryFinally", [SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword], SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], RuleAction.Space), - - // No space before and after indexer `x[]` - rule("NoSpaceBeforeOpenBracket", anyTokenExcept(SyntaxKind.AsyncKeyword), SyntaxKind.OpenBracketToken, [isNonJsxSameLineTokenContext], RuleAction.Delete), - rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete), - rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space), ]; return [ @@ -441,6 +444,19 @@ namespace ts.formatting { return !isBinaryOpContext(context); } + function isNotTypeAnnotationContext(context: FormattingContext): boolean { + return !isTypeAnnotationContext(context); + } + + function isTypeAnnotationContext(context: FormattingContext): boolean { + const contextKind = context.contextNode.kind; + return contextKind === SyntaxKind.PropertyDeclaration || + contextKind === SyntaxKind.PropertySignature || + contextKind === SyntaxKind.Parameter || + contextKind === SyntaxKind.VariableDeclaration || + isFunctionLikeKind(contextKind); + } + function isConditionalOperatorContext(context: FormattingContext): boolean { return context.contextNode.kind === SyntaxKind.ConditionalExpression; } @@ -614,12 +630,12 @@ namespace ts.formatting { return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText; } - function isNonJsxElementContext(context: FormattingContext): boolean { - return context.contextNode.kind !== SyntaxKind.JsxElement; + function isNonJsxElementOrFragmentContext(context: FormattingContext): boolean { + return context.contextNode.kind !== SyntaxKind.JsxElement && context.contextNode.kind !== SyntaxKind.JsxFragment; } function isJsxExpressionContext(context: FormattingContext): boolean { - return context.contextNode.kind === SyntaxKind.JsxExpression; + return context.contextNode.kind === SyntaxKind.JsxExpression || context.contextNode.kind === SyntaxKind.JsxSpreadAttribute; } function isNextTokenParentJsxAttribute(context: FormattingContext): boolean { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 0a444a7280a..1e6323be9fa 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -367,12 +367,13 @@ namespace ts.formatting { function getActualIndentationForListItem(node: Node, sourceFile: SourceFile, options: EditorSettings): number { const containingList = getContainingList(node, sourceFile); - return containingList ? getActualIndentationFromList(containingList) : Value.Unknown; - - function getActualIndentationFromList(list: ReadonlyArray): number { - const index = indexOf(list, node); - return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : Value.Unknown; + if (containingList) { + const index = containingList.indexOf(node); + if (index !== -1) { + return deriveActualIndentationFromList(containingList, index, sourceFile, options); + } } + return Value.Unknown; } function getLineIndentationWhenExpressionIsInMultiLine(node: Node, sourceFile: SourceFile, options: EditorSettings): number { @@ -508,6 +509,7 @@ namespace ts.formatting { case SyntaxKind.ArrayBindingPattern: case SyntaxKind.ObjectBindingPattern: case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxOpeningFragment: case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxExpression: case SyntaxKind.MethodSignature: @@ -554,6 +556,8 @@ namespace ts.formatting { (!!(child).namedBindings && (child).namedBindings.kind !== SyntaxKind.NamedImports); case SyntaxKind.JsxElement: return childKind !== SyntaxKind.JsxClosingElement; + case SyntaxKind.JsxFragment: + return childKind !== SyntaxKind.JsxClosingFragment; } // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 35f4d079e29..5f17eccf9c5 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -1,22 +1,9 @@ /* @internal */ namespace ts.GoToDefinition { export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number): DefinitionInfo[] { - /// Triple slash reference comments - const comment = findReferenceInPosition(sourceFile.referencedFiles, position); - if (comment) { - const referenceFile = tryResolveScriptReference(program, sourceFile, comment); - if (referenceFile) { - return [getDefinitionInfoForFileReference(comment.fileName, referenceFile.fileName)]; - } - // Might still be on jsdoc, so keep looking. - } - - // Type reference directives - const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); - if (typeReferenceDirective) { - const referenceFile = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName); - return referenceFile && referenceFile.resolvedFileName && - [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)]; + const reference = getReferenceAtPosition(sourceFile, position, program); + if (reference) { + return [getDefinitionInfoForFileReference(reference.fileName, reference.file.fileName)]; } const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); @@ -115,6 +102,23 @@ namespace ts.GoToDefinition { return getDefinitionFromSymbol(typeChecker, symbol, node); } + export function getReferenceAtPosition(sourceFile: SourceFile, position: number, program: Program): { fileName: string, file: SourceFile } | undefined { + const referencePath = findReferenceInPosition(sourceFile.referencedFiles, position); + if (referencePath) { + const file = tryResolveScriptReference(program, sourceFile, referencePath); + return file && { fileName: referencePath.fileName, file }; + } + + const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); + if (typeReferenceDirective) { + const reference = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName); + const file = reference && program.getSourceFile(reference.resolvedFileName); + return file && { fileName: typeReferenceDirective.fileName, file }; + } + + return undefined; + } + /// Goto type export function getTypeDefinitionAtPosition(typeChecker: TypeChecker, sourceFile: SourceFile, position: number): DefinitionInfo[] { const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); @@ -301,7 +305,7 @@ namespace ts.GoToDefinition { return createDefinitionInfo(decl, symbolKind, symbolName, containerName); } - function findReferenceInPosition(refs: ReadonlyArray, pos: number): FileReference { + export function findReferenceInPosition(refs: ReadonlyArray, pos: number): FileReference { for (const ref of refs) { if (ref.pos <= pos && pos <= ref.end) { return ref; diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 0432c342c8f..d2ce802f177 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -616,7 +616,7 @@ namespace ts.FindAllReferences { /** If at an export specifier, go to the symbol it refers to. */ function skipExportSpecifierSymbol(symbol: Symbol, checker: TypeChecker): Symbol { - // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does. + // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does. if (symbol.declarations) { for (const declaration of symbol.declarations) { if (isExportSpecifier(declaration) && !(declaration as ExportSpecifier).propertyName && !(declaration as ExportSpecifier).parent.parent.moduleSpecifier) { diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 33d84763d44..91774e2290c 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -52,20 +52,30 @@ namespace ts.JsDoc { // Eg. const a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array - const documentationComment = []; + const documentationComment: SymbolDisplayPart[] = []; forEachUnique(declarations, declaration => { - forEach(getAllJSDocs(declaration), doc => { - if (doc.comment) { - if (documentationComment.length) { - documentationComment.push(lineBreakPart()); - } - documentationComment.push(textPart(doc.comment)); + for (const { comment } of getCommentHavingNodes(declaration)) { + if (comment === undefined) continue; + if (documentationComment.length) { + documentationComment.push(lineBreakPart()); } - }); + documentationComment.push(textPart(comment)); + } }); return documentationComment; } + function getCommentHavingNodes(declaration: Declaration): ReadonlyArray { + switch (declaration.kind) { + case SyntaxKind.JSDocPropertyTag: + return [declaration as JSDocPropertyTag]; + case SyntaxKind.JSDocTypedefTag: + return [(declaration as JSDocTypedefTag).parent]; + default: + return getJSDocCommentsAndTags(declaration); + } + } + export function getJsDocTagsFromDeclarations(declarations?: Declaration[]): JSDocTagInfo[] { // Only collect doc comments from duplicate declarations once. const tags: JSDocTagInfo[] = []; @@ -77,7 +87,7 @@ namespace ts.JsDoc { return tags; } - function getCommentText(tag: JSDocTag): string { + function getCommentText(tag: JSDocTag): string | undefined { const { comment } = tag; switch (tag.kind) { case SyntaxKind.JSDocAugmentsTag: @@ -96,11 +106,15 @@ namespace ts.JsDoc { } function withNode(node: Node) { - return `${node.getText()} ${comment}`; + return addComment(node.getText()); } function withList(list: NodeArray): string { - return `${list.map(x => x.getText())} ${comment}`; + return addComment(list.map(x => x.getText()).join(", ")); + } + + function addComment(s: string) { + return comment === undefined ? s : `${s} ${comment}`; } } @@ -112,7 +126,7 @@ namespace ts.JsDoc { function forEachUnique(array: T[], callback: (element: T, index: number) => U): U { if (array) { for (let i = 0; i < array.length; i++) { - if (indexOf(array, array[i]) === i) { + if (array.indexOf(array[i]) === i) { const result = callback(array[i], i); if (result) { return result; diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 762726adb77..8449805ee71 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -46,7 +46,7 @@ namespace ts.NavigateTo { continue; } - // It was a match! If the pattern has dots in it, then also see if the + // It was a match! If the pattern has dots in it, then also see if the // declaration container matches as well. let containerMatches = matches; if (patternMatcher.patternContainsDots) { diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 15c1ff99758..8840919c329 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -1,12 +1,12 @@ /* @internal */ namespace ts.Completions.PathCompletions { - export function getStringLiteralCompletionsFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] { + export function getStringLiteralCompletionsFromModuleNames(sourceFile: SourceFile, node: LiteralExpression, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] { const literalValue = normalizeSlashes(node.text); const scriptPath = node.getSourceFile().path; const scriptDirectory = getDirectoryPath(scriptPath); - const span = getDirectoryFragmentTextSpan((node).text, node.getStart() + 1); + const span = getDirectoryFragmentTextSpan((node).text, node.getStart(sourceFile) + 1); if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) { const extensions = getSupportedExtensions(compilerOptions); if (compilerOptions.rootDirs) { @@ -94,7 +94,7 @@ namespace ts.Completions.PathCompletions { * * both foo.ts and foo.tsx become foo */ - const foundFiles = createMap(); + const foundFiles = createMap(); for (let filePath of files) { filePath = normalizePath(filePath); if (exclude && comparePaths(filePath, exclude, scriptPath, ignoreCase) === Comparison.EqualTo) { @@ -103,7 +103,7 @@ namespace ts.Completions.PathCompletions { const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath)); - if (!foundFiles.get(foundFileName)) { + if (!foundFiles.has(foundFileName)) { foundFiles.set(foundFileName, true); } } @@ -147,25 +147,15 @@ namespace ts.Completions.PathCompletions { getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host, /*exclude*/ undefined, result); for (const path in paths) { - if (!paths.hasOwnProperty(path)) continue; const patterns = paths[path]; - if (!patterns) continue; - - if (path === "*") { - for (const pattern of patterns) { - for (const match of getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host)) { - // Path mappings may provide a duplicate way to get to something we've already added, so don't add again. - if (result.some(entry => entry.name === match)) continue; - result.push(createCompletionEntryForModule(match, ScriptElementKind.externalModuleName, span)); + if (paths.hasOwnProperty(path) && patterns) { + for (const pathCompletion of getCompletionsForPathMapping(path, patterns, fragment, baseUrl, fileExtensions, host)) { + // Path mappings may provide a duplicate way to get to something we've already added, so don't add again. + if (!result.some(entry => entry.name === pathCompletion)) { + result.push(createCompletionEntryForModule(pathCompletion, ScriptElementKind.externalModuleName, span)); } } } - else if (startsWith(path, fragment)) { - if (patterns.length === 1) { - if (result.some(entry => entry.name === path)) continue; - result.push(createCompletionEntryForModule(path, ScriptElementKind.externalModuleName, span)); - } - } } } @@ -187,52 +177,67 @@ namespace ts.Completions.PathCompletions { return result; } - function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: ReadonlyArray, host: LanguageServiceHost): string[] { - if (host.readDirectory) { - const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined; - if (parsed) { - // The prefix has two effective parts: the directory path and the base component after the filepath that is not a - // full directory component. For example: directory/path/of/prefix/base* - const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix); - const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix); - const normalizedPrefixBase = getBaseFileName(normalizedPrefix); - - const fragmentHasPath = stringContains(fragment, directorySeparator); - - // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call - const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory; - - const normalizedSuffix = normalizePath(parsed.suffix); - const baseDirectory = combinePaths(baseUrl, expandedPrefixDirectory); - const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; - - // If we have a suffix, then we need to read the directory all the way down. We could create a glob - // that encodes the suffix, but we would have to escape the character "?" which readDirectory - // doesn't support. For now, this is safer but slower - const includeGlob = normalizedSuffix ? "**/*" : "./*"; - - const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); - if (matches) { - const result: string[] = []; - - // Trim away prefix and suffix - for (const match of matches) { - const normalizedMatch = normalizePath(match); - if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) { - continue; - } - - const start = completePrefix.length; - const length = normalizedMatch.length - start - normalizedSuffix.length; - - result.push(removeFileExtension(normalizedMatch.substr(start, length))); - } - return result; - } - } + function getCompletionsForPathMapping( + path: string, patterns: ReadonlyArray, fragment: string, baseUrl: string, fileExtensions: ReadonlyArray, host: LanguageServiceHost, + ): string[] { + if (!endsWith(path, "*")) { + // For a path mapping "foo": ["/x/y/z.ts"], add "foo" itself as a completion. + return !stringContains(path, "*") && startsWith(path, fragment) ? [path] : emptyArray; } - return undefined; + const pathPrefix = path.slice(0, path.length - 1); + if (!startsWith(fragment, pathPrefix)) { + return emptyArray; + } + + const remainingFragment = fragment.slice(pathPrefix.length); + return flatMap(patterns, pattern => getModulesForPathsPattern(remainingFragment, baseUrl, pattern, fileExtensions, host)); + } + + function getModulesForPathsPattern(fragment: string, baseUrl: string, pattern: string, fileExtensions: ReadonlyArray, host: LanguageServiceHost): string[] | undefined { + if (!host.readDirectory) { + return undefined; + } + + const parsed = hasZeroOrOneAsteriskCharacter(pattern) ? tryParsePattern(pattern) : undefined; + if (!parsed) { + return undefined; + } + + // The prefix has two effective parts: the directory path and the base component after the filepath that is not a + // full directory component. For example: directory/path/of/prefix/base* + const normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix); + const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix); + const normalizedPrefixBase = getBaseFileName(normalizedPrefix); + + const fragmentHasPath = stringContains(fragment, directorySeparator); + + // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call + const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory; + + const normalizedSuffix = normalizePath(parsed.suffix); + // Need to normalize after combining: If we combinePaths("a", "../b"), we want "b" and not "a/../b". + const baseDirectory = normalizePath(combinePaths(baseUrl, expandedPrefixDirectory)); + const completePrefix = fragmentHasPath ? baseDirectory : ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; + + // If we have a suffix, then we need to read the directory all the way down. We could create a glob + // that encodes the suffix, but we would have to escape the character "?" which readDirectory + // doesn't support. For now, this is safer but slower + const includeGlob = normalizedSuffix ? "**/*" : "./*"; + + const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); + const directories = tryGetDirectories(host, baseDirectory); + // Trim away prefix and suffix + return mapDefined(concatenate(matches, directories), match => { + const normalizedMatch = normalizePath(match); + if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) { + return; + } + + const start = completePrefix.length; + const length = normalizedMatch.length - start - normalizedSuffix.length; + return removeFileExtension(normalizedMatch.substr(start, length)); + }); } function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions, typeChecker: TypeChecker, host: LanguageServiceHost): string[] { @@ -309,9 +314,11 @@ namespace ts.Completions.PathCompletions { function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] { // Check for typings specified in compiler options + const seen = createMap(); if (options.types) { - for (const moduleName of options.types) { - result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); + for (const typesName of options.types) { + const moduleName = getUnmangledNameForScopedPackage(typesName); + pushResult(moduleName); } } else if (host.getDirectories) { @@ -323,32 +330,40 @@ namespace ts.Completions.PathCompletions { if (typeRoots) { for (const root of typeRoots) { - getCompletionEntriesFromDirectories(host, root, span, result); + getCompletionEntriesFromDirectories(root); } } - } - if (host.getDirectories) { // Also get all @types typings installed in visible node_modules directories for (const packageJson of findPackageJsons(scriptPath, host)) { const typesDir = combinePaths(getDirectoryPath(packageJson), "node_modules/@types"); - getCompletionEntriesFromDirectories(host, typesDir, span, result); + getCompletionEntriesFromDirectories(typesDir); } } return result; - } - function getCompletionEntriesFromDirectories(host: LanguageServiceHost, directory: string, span: TextSpan, result: Push) { - if (host.getDirectories && tryDirectoryExists(host, directory)) { - const directories = tryGetDirectories(host, directory); - if (directories) { - for (let typeDirectory of directories) { - typeDirectory = normalizePath(typeDirectory); - result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span)); + function getCompletionEntriesFromDirectories(directory: string) { + Debug.assert(!!host.getDirectories); + if (tryDirectoryExists(host, directory)) { + const directories = tryGetDirectories(host, directory); + if (directories) { + for (let typeDirectory of directories) { + typeDirectory = normalizePath(typeDirectory); + const directoryName = getBaseFileName(typeDirectory); + const moduleName = getUnmangledNameForScopedPackage(directoryName); + pushResult(moduleName); + } } } } + + function pushResult(moduleName: string) { + if (!seen.has(moduleName)) { + result.push(createCompletionEntryForModule(moduleName, ScriptElementKind.externalModuleName, span)); + seen.set(moduleName, true); + } + } } function findPackageJsons(directory: string, host: LanguageServiceHost): string[] { @@ -464,7 +479,7 @@ namespace ts.Completions.PathCompletions { return tryIOAndConsumeErrors(host, host.getDirectories, directoryName); } - function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray): string[] { + function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray): string[] | undefined { return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include); } diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 8f6a468be64..a99683d45ef 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -295,7 +295,7 @@ namespace ts { // import "mod"; // import d from "mod" // import {a as A } from "mod"; - // import * as NS from "mod" + // import * as NS from "mod" // import d, {a, b as B} from "mod" // import i = require("mod"); // import("mod"); diff --git a/src/services/refactors/convertToEs6Module.ts b/src/services/refactors/convertToEs6Module.ts new file mode 100644 index 00000000000..1046bf90aa6 --- /dev/null +++ b/src/services/refactors/convertToEs6Module.ts @@ -0,0 +1,582 @@ +/* @internal */ +namespace ts.refactor { + const actionName = "Convert to ES6 module"; + + const convertToEs6Module: Refactor = { + name: actionName, + description: getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module), + getEditsForAction, + getAvailableActions, + }; + + registerRefactor(convertToEs6Module); + + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { + const { file, startPosition } = context; + if (!isSourceFileJavaScript(file) || !file.commonJsModuleIndicator) { + return undefined; + } + + const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); + return !isAtTriggerLocation(file, node) ? undefined : [ + { + name: convertToEs6Module.name, + description: convertToEs6Module.description, + actions: [ + { + description: convertToEs6Module.description, + name: actionName, + }, + ], + }, + ]; + } + + function isAtTriggerLocation(sourceFile: SourceFile, node: Node, onSecondTry = false): boolean { + switch (node.kind) { + case SyntaxKind.CallExpression: + return isAtTopLevelRequire(node as CallExpression); + case SyntaxKind.PropertyAccessExpression: + return isExportsOrModuleExportsOrAlias(sourceFile, node as PropertyAccessExpression) + || isExportsOrModuleExportsOrAlias(sourceFile, (node as PropertyAccessExpression).expression); + case SyntaxKind.VariableDeclarationList: + const decl = (node as VariableDeclarationList).declarations[0]; + return isExportsOrModuleExportsOrAlias(sourceFile, decl.initializer); + case SyntaxKind.VariableDeclaration: + return isExportsOrModuleExportsOrAlias(sourceFile, (node as VariableDeclaration).initializer); + default: + return isExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node) + || !onSecondTry && isAtTriggerLocation(sourceFile, node.parent, /*onSecondTry*/ true); + } + } + + function isAtTopLevelRequire(call: CallExpression): boolean { + if (!isRequireCall(call, /*checkArgumentIsStringLiteral*/ true)) { + return false; + } + const { parent: propAccess } = call; + const varDecl = isPropertyAccessExpression(propAccess) ? propAccess.parent : propAccess; + if (isExpressionStatement(varDecl) && isSourceFile(varDecl.parent)) { // `require("x");` as a statement + return true; + } + if (!isVariableDeclaration(varDecl)) { + return false; + } + const { parent: varDeclList } = varDecl; + if (varDeclList.kind !== SyntaxKind.VariableDeclarationList) { + return false; + } + const { parent: varStatement } = varDeclList; + return varStatement.kind === SyntaxKind.VariableStatement && varStatement.parent.kind === SyntaxKind.SourceFile; + } + + function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined { + Debug.assertEqual(actionName, _actionName); + const { file, program } = context; + Debug.assert(isSourceFileJavaScript(file)); + const edits = textChanges.ChangeTracker.with(context, changes => { + const moduleExportsChangedToDefault = convertFileToEs6Module(file, program.getTypeChecker(), changes, program.getCompilerOptions().target); + if (moduleExportsChangedToDefault) { + for (const importingFile of program.getSourceFiles()) { + fixImportOfModuleExports(importingFile, file, changes); + } + } + }); + return { edits, renameFilename: undefined, renameLocation: undefined }; + } + + function fixImportOfModuleExports(importingFile: ts.SourceFile, exportingFile: ts.SourceFile, changes: textChanges.ChangeTracker) { + for (const moduleSpecifier of importingFile.imports) { + const imported = getResolvedModule(importingFile, moduleSpecifier.text); + if (!imported || imported.resolvedFileName !== exportingFile.fileName) { + continue; + } + + const { parent } = moduleSpecifier; + switch (parent.kind) { + case SyntaxKind.ExternalModuleReference: { + const importEq = (parent as ExternalModuleReference).parent; + changes.replaceNode(importingFile, importEq, makeImport(importEq.name, /*namedImports*/ undefined, moduleSpecifier.text)); + break; + } + case SyntaxKind.CallExpression: { + const call = parent as CallExpression; + if (isRequireCall(call, /*checkArgumentIsStringLiteral*/ false)) { + changes.replaceNode(importingFile, parent, createPropertyAccess(getSynthesizedDeepClone(call), "default")); + } + break; + } + } + } + } + + /** @returns Whether we converted a `module.exports =` to a default export. */ + function convertFileToEs6Module(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget): ModuleExportsChanged { + const identifiers: Identifiers = { original: collectFreeIdentifiers(sourceFile), additional: createMap() }; + const exports = collectExportRenames(sourceFile, checker, identifiers); + convertExportsAccesses(sourceFile, exports, changes); + let moduleExportsChangedToDefault = false; + for (const statement of sourceFile.statements) { + const moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports); + moduleExportsChangedToDefault = moduleExportsChangedToDefault || moduleExportsChanged; + } + return moduleExportsChangedToDefault; + } + + /** + * Contains an entry for each renamed export. + * This is necessary because `exports.x = 0;` does not declare a local variable. + * Converting this to `export const x = 0;` would declare a local, so we must be careful to avoid shadowing. + * If there would be shadowing at either the declaration or at any reference to `exports.x` (now just `x`), we must convert to: + * const _x = 0; + * export { _x as x }; + * This conversion also must place if the exported name is not a valid identifier, e.g. `exports.class = 0;`. + */ + type ExportRenames = ReadonlyMap; + + function collectExportRenames(sourceFile: SourceFile, checker: TypeChecker, identifiers: Identifiers): ExportRenames { + const res = createMap(); + forEachExportReference(sourceFile, node => { + const { text, originalKeywordKind } = node.name; + if (!res.has(text) && (originalKeywordKind !== undefined && isNonContextualKeyword(originalKeywordKind) + || checker.resolveName(node.name.text, node, SymbolFlags.Value, /*excludeGlobals*/ true))) { + // Unconditionally add an underscore in case `text` is a keyword. + res.set(text, makeUniqueName(`_${text}`, identifiers)); + } + }); + return res; + } + + function convertExportsAccesses(sourceFile: SourceFile, exports: ExportRenames, changes: textChanges.ChangeTracker): void { + forEachExportReference(sourceFile, (node, isAssignmentLhs) => { + if (isAssignmentLhs) { + return; + } + const { text } = node.name; + changes.replaceNode(sourceFile, node, createIdentifier(exports.get(text) || text)); + }); + } + + function forEachExportReference(sourceFile: SourceFile, cb: (node: PropertyAccessExpression, isAssignmentLhs: boolean) => void): void { + sourceFile.forEachChild(function recur(node) { + if (isPropertyAccessExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node.expression)) { + const { parent } = node; + cb(node, isBinaryExpression(parent) && parent.left === node && parent.operatorToken.kind === SyntaxKind.EqualsToken); + } + node.forEachChild(recur); + }); + } + + /** Whether `module.exports =` was changed to `export default` */ + type ModuleExportsChanged = boolean; + + function convertStatement(sourceFile: SourceFile, statement: Statement, checker: TypeChecker, changes: textChanges.ChangeTracker, identifiers: Identifiers, target: ScriptTarget, exports: ExportRenames): ModuleExportsChanged { + switch (statement.kind) { + case SyntaxKind.VariableStatement: + convertVariableStatement(sourceFile, statement as VariableStatement, changes, checker, identifiers, target); + return false; + case SyntaxKind.ExpressionStatement: { + const { expression } = statement as ExpressionStatement; + switch (expression.kind) { + case SyntaxKind.CallExpression: { + if (isRequireCall(expression, /*checkArgumentIsStringLiteral*/ true)) { + // For side-effecting require() call, just make a side-effecting import. + changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0].text)); + } + return false; + } + case SyntaxKind.BinaryExpression: { + const { left, operatorToken, right } = expression as BinaryExpression; + return operatorToken.kind === SyntaxKind.EqualsToken && convertAssignment(sourceFile, checker, statement as ExpressionStatement, left, right, changes, exports); + } + } + } + // falls through + default: + return false; + } + } + + function convertVariableStatement(sourceFile: SourceFile, statement: VariableStatement, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, target: ScriptTarget): void { + const { declarationList } = statement as VariableStatement; + let foundImport = false; + const newNodes = flatMap(declarationList.declarations, decl => { + const { name, initializer } = decl; + if (isExportsOrModuleExportsOrAlias(sourceFile, initializer)) { + // `const alias = module.exports;` can be removed. + foundImport = true; + return []; + } + if (isRequireCall(initializer, /*checkArgumentIsStringLiteral*/ true)) { + foundImport = true; + return convertSingleImport(sourceFile, name, initializer.arguments[0].text, changes, checker, identifiers, target); + } + else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteral*/ true)) { + foundImport = true; + return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0].text, identifiers); + } + else { + // Move it out to its own variable statement. + return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags)); + } + }); + if (foundImport) { + // useNonAdjustedEndPosition to ensure we don't eat the newline after the statement. + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + } + } + + /** Converts `const name = require("moduleSpecifier").propertyName` */ + function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: string, identifiers: Identifiers): ReadonlyArray { + switch (name.kind) { + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: { + // `const [a, b] = require("c").d` --> `import { d } from "c"; const [a, b] = d;` + const tmp = makeUniqueName(propertyName, identifiers); + return [ + makeSingleImport(tmp, propertyName, moduleSpecifier), + makeConst(/*modifiers*/ undefined, name, createIdentifier(tmp)), + ]; + } + case SyntaxKind.Identifier: + // `const a = require("b").c` --> `import { c as a } from "./b"; + return [makeSingleImport(name.text, propertyName, moduleSpecifier)]; + default: + Debug.assertNever(name); + } + } + + function convertAssignment( + sourceFile: SourceFile, + checker: TypeChecker, + statement: ExpressionStatement, + left: Expression, + right: Expression, + changes: textChanges.ChangeTracker, + exports: ExportRenames, + ): ModuleExportsChanged { + if (!isPropertyAccessExpression(left)) { + return false; + } + + if (isExportsOrModuleExportsOrAlias(sourceFile, left)) { + if (isExportsOrModuleExportsOrAlias(sourceFile, right)) { + // `const alias = module.exports;` or `module.exports = alias;` can be removed. + changes.deleteNode(sourceFile, statement); + } + else { + let newNodes = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right) : undefined; + let changedToDefaultExport = false; + if (!newNodes) { + ([newNodes, changedToDefaultExport] = convertModuleExportsToExportDefault(right, checker)); + } + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + return changedToDefaultExport; + } + } + else if (isExportsOrModuleExportsOrAlias(sourceFile, left.expression)) { + convertNamedExport(sourceFile, statement, left.name, right, changes, exports); + } + + return false; + } + + /** + * Convert `module.exports = { ... }` to individual exports.. + * We can't always do this if the module has interesting members -- then it will be a default export instead. + */ + function tryChangeModuleExportsObject(object: ObjectLiteralExpression): ReadonlyArray | undefined { + return mapAllOrFail(object.properties, prop => { + switch (prop.kind) { + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // TODO: Maybe we should handle this? See fourslash test `refactorConvertToEs6Module_export_object_shorthand.ts`. + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.SpreadAssignment: + return undefined; + case SyntaxKind.PropertyAssignment: { + const { name, initializer } = prop as PropertyAssignment; + return !isIdentifier(name) ? undefined : convertExportsDotXEquals(name.text, initializer); + } + case SyntaxKind.MethodDeclaration: { + const m = prop as MethodDeclaration; + return !isIdentifier(m.name) ? undefined : functionExpressionToDeclaration(m.name.text, [createToken(SyntaxKind.ExportKeyword)], m); + } + default: + Debug.assertNever(prop); + } + }); + } + + function convertNamedExport( + sourceFile: SourceFile, + statement: Statement, + propertyName: Identifier, + right: Expression, + changes: textChanges.ChangeTracker, + exports: ExportRenames, + ): void { + // If "originalKeywordKind" was set, this is e.g. `exports. + const { text } = propertyName; + const rename = exports.get(text); + if (rename !== undefined) { + /* + const _class = 0; + export { _class as class }; + */ + const newNodes = [ + makeConst(/*modifiers*/ undefined, rename, right), + makeExportDeclaration([createExportSpecifier(rename, text)]), + ]; + changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + } + else { + changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right), { useNonAdjustedEndPosition: true }); + } + } + + function convertModuleExportsToExportDefault(exported: Expression, checker: TypeChecker): [ReadonlyArray, ModuleExportsChanged] { + const modifiers = [createToken(SyntaxKind.ExportKeyword), createToken(SyntaxKind.DefaultKeyword)]; + switch (exported.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: { + // `module.exports = function f() {}` --> `export default function f() {}` + const fn = exported as FunctionExpression | ArrowFunction; + return [[functionExpressionToDeclaration(fn.name && fn.name.text, modifiers, fn)], true]; + } + case SyntaxKind.ClassExpression: { + // `module.exports = class C {}` --> `export default class C {}` + const cls = exported as ClassExpression; + return [[classExpressionToDeclaration(cls.name && cls.name.text, modifiers, cls)], true]; + } + case SyntaxKind.CallExpression: + if (isRequireCall(exported, /*checkArgumentIsStringLiteral*/ true)) { + return convertReExportAll(exported.arguments[0], checker); + } + // falls through + default: + // `module.exports = 0;` --> `export default 0;` + return [[createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, exported)], true]; + } + } + + function convertReExportAll(reExported: StringLiteralLike, checker: TypeChecker): [ReadonlyArray, ModuleExportsChanged] { + // `module.exports = require("x");` ==> `export * from "x"; export { default } from "x";` + const moduleSpecifier = reExported.text; + const moduleSymbol = checker.getSymbolAtLocation(reExported); + const exports = moduleSymbol ? moduleSymbol.exports : emptyUnderscoreEscapedMap; + return exports.has("export=" as __String) + ? [[reExportDefault(moduleSpecifier)], true] + : !exports.has("default" as __String) + ? [[reExportStar(moduleSpecifier)], false] + // If there's some non-default export, must include both `export *` and `export default`. + : exports.size > 1 ? [[reExportStar(moduleSpecifier), reExportDefault(moduleSpecifier)], true] : [[reExportDefault(moduleSpecifier)], true]; + } + function reExportStar(moduleSpecifier: string): ExportDeclaration { + return makeExportDeclaration(/*exportClause*/ undefined, moduleSpecifier); + } + function reExportDefault(moduleSpecifier: string): ExportDeclaration { + return makeExportDeclaration([createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier); + } + + function convertExportsDotXEquals(name: string | undefined, exported: Expression): Statement { + const modifiers = [createToken(SyntaxKind.ExportKeyword)]; + switch (exported.kind) { + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + // `exports.f = function() {}` --> `export function f() {}` + return functionExpressionToDeclaration(name, modifiers, exported as FunctionExpression | ArrowFunction); + case SyntaxKind.ClassExpression: + // `exports.C = class {}` --> `export class C {}` + return classExpressionToDeclaration(name, modifiers, exported as ClassExpression); + default: + // `exports.x = 0;` --> `export const x = 0;` + return makeConst(modifiers, createIdentifier(name), exported); + } + } + + /** + * Converts `const <> = require("x");`. + * Returns nodes that will replace the variable declaration for the commonjs import. + * May also make use `changes` to remove qualifiers at the use sites of imports, to change `mod.x` to `x`. + */ + function convertSingleImport( + file: SourceFile, + name: BindingName, + moduleSpecifier: string, + changes: textChanges.ChangeTracker, + checker: TypeChecker, + identifiers: Identifiers, + target: ScriptTarget, + ): ReadonlyArray { + switch (name.kind) { + case SyntaxKind.ObjectBindingPattern: { + const importSpecifiers = mapAllOrFail(name.elements, e => + e.dotDotDotToken || e.initializer || e.propertyName && !isIdentifier(e.propertyName) || !isIdentifier(e.name) + ? undefined + : makeImportSpecifier(e.propertyName && (e.propertyName as Identifier).text, e.name.text)); + if (importSpecifiers) { + return [makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier)]; + } + } + // falls through -- object destructuring has an interesting pattern and must be a variable declaration + case SyntaxKind.ArrayBindingPattern: { + /* + import x from "x"; + const [a, b, c] = x; + */ + const tmp = makeUniqueName(codefix.moduleSpecifierToValidIdentifier(moduleSpecifier, target), identifiers); + return [ + makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier), + makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), createIdentifier(tmp)), + ]; + } + case SyntaxKind.Identifier: + return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers); + default: + Debug.assertNever(name); + } + } + + /** + * Convert `import x = require("x").` + * Also converts uses like `x.y()` to `y()` and uses a named import. + */ + function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: string, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers): ReadonlyArray { + const nameSymbol = checker.getSymbolAtLocation(name); + // Maps from module property name to name actually used. (The same if there isn't shadowing.) + const namedBindingsNames = createMap(); + // True if there is some non-property use like `x()` or `f(x)`. + let needDefaultImport = false; + + for (const use of identifiers.original.get(name.text)) { + if (checker.getSymbolAtLocation(use) !== nameSymbol || use === name) { + // This was a use of a different symbol with the same name, due to shadowing. Ignore. + continue; + } + + const { parent } = use; + if (isPropertyAccessExpression(parent)) { + const { expression, name: { text: propertyName } } = parent; + Debug.assert(expression === use); // Else shouldn't have been in `collectIdentifiers` + let idName = namedBindingsNames.get(propertyName); + if (idName === undefined) { + idName = makeUniqueName(propertyName, identifiers); + namedBindingsNames.set(propertyName, idName); + } + changes.replaceNode(file, parent, createIdentifier(idName)); + } + else { + needDefaultImport = true; + } + } + + const namedBindings = namedBindingsNames.size === 0 ? undefined : arrayFrom(mapIterator(namedBindingsNames.entries(), ([propertyName, idName]) => + createImportSpecifier(propertyName === idName ? undefined : createIdentifier(propertyName), createIdentifier(idName)))); + if (!namedBindings) { + // If it was unused, ensure that we at least import *something*. + needDefaultImport = true; + } + return [makeImport(needDefaultImport ? getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier)]; + } + + // Identifiers helpers + + function makeUniqueName(name: string, identifiers: Identifiers): string { + while (identifiers.original.has(name) || identifiers.additional.has(name)) { + name = `_${name}`; + } + identifiers.additional.set(name, true); + return name; + } + + /** + * Helps us create unique identifiers. + * `original` refers to the local variable names in the original source file. + * `additional` is any new unique identifiers we've generated. (e.g., we'll generate `_x`, then `__x`.) + */ + interface Identifiers { + readonly original: FreeIdentifiers; + // Additional identifiers we've added. Mutable! + readonly additional: Map; + } + + type FreeIdentifiers = ReadonlyMap>; + function collectFreeIdentifiers(file: SourceFile): FreeIdentifiers { + const map = createMultiMap(); + file.forEachChild(function recur(node) { + if (isIdentifier(node) && isFreeIdentifier(node)) { + map.add(node.text, node); + } + node.forEachChild(recur); + }); + return map; + } + + function isFreeIdentifier(node: Identifier): boolean { + const { parent } = node; + switch (parent.kind) { + case SyntaxKind.PropertyAccessExpression: + return (parent as PropertyAccessExpression).name !== node; + case SyntaxKind.BindingElement: + return (parent as BindingElement).propertyName !== node; + default: + return true; + } + } + + // Node helpers + + function functionExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray, fn: FunctionExpression | ArrowFunction | MethodDeclaration): FunctionDeclaration { + return createFunctionDeclaration( + getSynthesizedDeepClones(fn.decorators), // TODO: GH#19915 Don't think this is even legal. + concatenate(additionalModifiers, getSynthesizedDeepClones(fn.modifiers)), + getSynthesizedDeepClone(fn.asteriskToken), + name, + getSynthesizedDeepClones(fn.typeParameters), + getSynthesizedDeepClones(fn.parameters), + getSynthesizedDeepClone(fn.type), + convertToFunctionBody(getSynthesizedDeepClone(fn.body))); + } + + function classExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray, cls: ClassExpression): ClassDeclaration { + return createClassDeclaration( + getSynthesizedDeepClones(cls.decorators), // TODO: GH#19915 Don't think this is even legal. + concatenate(additionalModifiers, getSynthesizedDeepClones(cls.modifiers)), + name, + getSynthesizedDeepClones(cls.typeParameters), + getSynthesizedDeepClones(cls.heritageClauses), + getSynthesizedDeepClones(cls.members)); + } + + function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: string): ImportDeclaration { + return propertyName === "default" + ? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier) + : makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier); + } + + function makeImport(name: Identifier | undefined, namedImports: ReadonlyArray, moduleSpecifier: string): ImportDeclaration { + const importClause = (name || namedImports) && createImportClause(name, namedImports && createNamedImports(namedImports)); + return createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, importClause, createLiteral(moduleSpecifier)); + } + + function makeImportSpecifier(propertyName: string | undefined, name: string): ImportSpecifier { + return createImportSpecifier(propertyName !== undefined && propertyName !== name ? createIdentifier(propertyName) : undefined, createIdentifier(name)); + } + + function makeConst(modifiers: ReadonlyArray | undefined, name: string | BindingName, init: Expression): VariableStatement { + return createVariableStatement( + modifiers, + createVariableDeclarationList( + [createVariableDeclaration(name, /*type*/ undefined, init)], + NodeFlags.Const)); + } + + function makeExportDeclaration(exportSpecifiers: ExportSpecifier[] | undefined, moduleSpecifier?: string): ExportDeclaration { + return createExportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + exportSpecifiers && createNamedExports(exportSpecifiers), + moduleSpecifier === undefined ? undefined : createLiteral(moduleSpecifier)); + } +} diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index b7aa5ac33d1..b3110a0ca36 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1692,7 +1692,7 @@ namespace ts.refactor.extractSymbol { } for (let i = 0; i < scopes.length; i++) { const scope = scopes[i]; - const resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags); + const resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags, /*excludeGlobals*/ false); if (resolvedSymbol === symbol) { continue; } diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index 3858b198743..8b4561700d5 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -1,5 +1,6 @@ /// /// +/// /// /// /// diff --git a/src/services/refactors/useDefaultImport.ts b/src/services/refactors/useDefaultImport.ts index 56faf082a49..a103168f67b 100644 --- a/src/services/refactors/useDefaultImport.ts +++ b/src/services/refactors/useDefaultImport.ts @@ -23,7 +23,7 @@ namespace ts.refactor.installTypesForPackage { return undefined; } - const module = ts.getResolvedModule(file, importInfo.moduleSpecifier.text); + const module = getResolvedModule(file, importInfo.moduleSpecifier.text); const resolvedFile = program.getSourceFile(module.resolvedFileName); if (!(resolvedFile.externalModuleIndicator && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals)) { return undefined; @@ -52,7 +52,7 @@ namespace ts.refactor.installTypesForPackage { } const { importStatement, name, moduleSpecifier } = importInfo; const newImportClause = createImportClause(name, /*namedBindings*/ undefined); - const newImportStatement = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier); + const newImportStatement = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier); return { edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, importStatement, newImportStatement)), renameFilename: undefined, diff --git a/src/services/rename.ts b/src/services/rename.ts index cfe79679fba..ca46a93f3c9 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -38,9 +38,17 @@ namespace ts.Rename { return undefined; } - const displayName = stripQuotes(getDeclaredName(typeChecker, symbol, node)); const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node); - return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined; + if (!kind) { + return undefined; + } + + const specifierName = (isImportOrExportSpecifierName(node) || isStringOrNumericLiteral(node) && node.parent.kind === SyntaxKind.ComputedPropertyName) + ? stripQuotes(getTextOfIdentifierOrLiteral(node)) + : undefined; + const displayName = specifierName || typeChecker.symbolToString(symbol); + const fullDisplayName = specifierName || typeChecker.getFullyQualifiedName(symbol); + return getRenameInfoSuccess(displayName, fullDisplayName, kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile); } } else if (node.kind === SyntaxKind.StringLiteral) { diff --git a/src/services/services.ts b/src/services/services.ts index 1660ca10e43..4236416fbb3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -883,7 +883,8 @@ namespace ts { scriptKind: ScriptKind; } - export interface DisplayPartsSymbolWriter extends SymbolWriter { + /* @internal */ + export interface DisplayPartsSymbolWriter extends EmitTextWriter { displayParts(): SymbolDisplayPart[]; } @@ -1065,8 +1066,7 @@ namespace ts { } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean, scriptKind?: ScriptKind): SourceFile { - const text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); - const sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents, scriptKind); + const sourceFile = createSourceFile(fileName, getSnapshotText(scriptSnapshot), scriptTarget, setNodeParents, scriptKind); setSourceFileFields(sourceFile, scriptSnapshot, version); return sourceFile; } @@ -1265,7 +1265,7 @@ namespace ts { const path = toPath(fileName, currentDirectory, getCanonicalFileName); const entry = hostCache.getEntryByPath(path); if (entry) { - return isString(entry) ? undefined : entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); + return isString(entry) ? undefined : getSnapshotText(entry.scriptSnapshot); } return host.readFile && host.readFile(fileName); }, @@ -1432,7 +1432,7 @@ namespace ts { return [...program.getOptionsDiagnostics(cancellationToken), ...program.getGlobalDiagnostics(cancellationToken)]; } - function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = { includeExternalModuleExports: false }): CompletionInfo { + function getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions = { includeExternalModuleExports: false, includeInsertTextCompletions: false }): CompletionInfo { synchronizeHostData(); return Completions.getCompletionsAtPosition( host, @@ -2053,7 +2053,7 @@ namespace ts { } function getTodoCommentsRegExp(): RegExp { - // NOTE: ?: means 'non-capture group'. It allows us to have groups without having to + // NOTE: `?:` means 'non-capture group'. It allows us to have groups without having to // filter them out later in the final result array. // TODO comments can appear in one of the following forms: @@ -2251,20 +2251,6 @@ namespace ts { isLiteralComputedPropertyDeclarationName(node); } - function isObjectLiteralElement(node: Node): node is ObjectLiteralElement { - switch (node.kind) { - case SyntaxKind.JsxAttribute: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return true; - } - return false; - } - /** * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 } */ diff --git a/src/services/shims.ts b/src/services/shims.ts index 34a8bbb10d9..30a836a113f 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -141,7 +141,6 @@ namespace ts { getEncodedSemanticClassifications(fileName: string, start: number, length: number): string; getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): string; - // tslint:disable-next-line type-operator-spacing (false positive) getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: string/*Services.FormatCodeOptions*/ | undefined, source: string | undefined): string; getQuickInfoAtPosition(fileName: string, position: number): string; @@ -907,7 +906,6 @@ namespace ts { } /** Get a string based representation of a completion list entry details */ - // tslint:disable-next-line type-operator-spacing (false positive) public getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: string/*Services.FormatCodeOptions*/ | undefined, source: string | undefined) { return this.forwardJSONCall( `getCompletionEntryDetails('${fileName}', ${position}, '${entryName}')`, @@ -1085,7 +1083,7 @@ namespace ts { `getPreProcessedFileInfo('${fileName}')`, () => { // for now treat files as JavaScript - const result = preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true); + const result = preProcessFile(getSnapshotText(sourceTextSnapshot), /* readImportFiles */ true, /* detectJavaScriptImports */ true); return { referencedFiles: this.convertFileReferences(result.referencedFiles), importedFiles: this.convertFileReferences(result.importedFiles), @@ -1125,9 +1123,7 @@ namespace ts { return this.forwardJSONCall( `getTSConfigFileInfo('${fileName}')`, () => { - const text = sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()); - - const result = parseJsonText(fileName, text); + const result = parseJsonText(fileName, getSnapshotText(sourceTextSnapshot)); const normalizedFileName = normalizeSlashes(fileName); const configFile = parseJsonSourceFileConfigFileContent(result, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName); diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 36c83f5f4af..734912b3ffc 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -197,7 +197,7 @@ namespace ts.SignatureHelp { function getArgumentIndex(argumentsList: Node, node: Node) { // The list we got back can include commas. In the presence of errors it may // also just have nodes without commas. For example "Foo(a b c)" will have 3 - // args without commas. We want to find what index we're at. So we count + // args without commas. We want to find what index we're at. So we count // forward until we hit ourselves, only incrementing the index if it isn't a // comma. // @@ -224,12 +224,12 @@ namespace ts.SignatureHelp { // The argument count for a list is normally the number of non-comma children it has. // For example, if you have "Foo(a,b)" then there will be three children of the arg // list 'a' '' 'b'. So, in this case the arg count will be 2. However, there - // is a small subtlety. If you have "Foo(a,)", then the child list will just have + // is a small subtlety. If you have "Foo(a,)", then the child list will just have // 'a' ''. So, in the case where the last child is a comma, we increase the // arg count by one to compensate. // - // Note: this subtlety only applies to the last comma. If you had "Foo(a,," then - // we'll have: 'a' '' '' + // Note: this subtlety only applies to the last comma. If you had "Foo(a,," then + // we'll have: 'a' '' '' // That will give us 2 non-commas. We then add one for the last comma, giving us an // arg count of 3. const listChildren = argumentsList.getChildren(); @@ -253,9 +253,11 @@ namespace ts.SignatureHelp { // not enough to put us in the substitution expression; we should consider ourselves part of // the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1). // + // tslint:disable no-double-space // Example: f `# abcd $#{# 1 + 1# }# efghi ${ #"#hello"# } # ` // ^ ^ ^ ^ ^ ^ ^ ^ ^ // Case: 1 1 3 2 1 3 2 2 1 + // tslint:enable no-double-space Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node."); if (isTemplateLiteralKind(node.kind)) { if (isInsideTemplateLiteral(node, position)) { @@ -307,9 +309,8 @@ namespace ts.SignatureHelp { // Otherwise, we will not show signature help past the expression. // For example, // - // ` ${ 1 + 1 foo(10) - // | | - // + // ` ${ 1 + 1 foo(10) + // | | // This is because a Missing node has no width. However, what we actually want is to include trivia // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail. if (template.kind === SyntaxKind.TemplateExpression) { @@ -359,6 +360,7 @@ namespace ts.SignatureHelp { const callTarget = getInvokedExpression(invocation); const callTargetSymbol = typeChecker.getSymbolAtLocation(callTarget); const callTargetDisplayParts = callTargetSymbol && symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined); + const printer = createPrinter({ removeComments: true }); const items: SignatureHelpItem[] = map(candidates, candidateSignature => { let signatureHelpParameters: SignatureHelpParameter[]; const prefixDisplayParts: SymbolDisplayPart[] = []; @@ -375,14 +377,22 @@ namespace ts.SignatureHelp { const typeParameters = (candidateSignature.target || candidateSignature).typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray; suffixDisplayParts.push(punctuationPart(SyntaxKind.GreaterThanToken)); - const parameterParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisParameter, candidateSignature.parameters, writer, invocation)); + const parameterParts = mapToDisplayParts(writer => { + const flags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors; + const thisParameter = candidateSignature.thisParameter ? [typeChecker.symbolToParameterDeclaration(candidateSignature.thisParameter, invocation, flags)] : []; + const params = createNodeArray([...thisParameter, ...map(candidateSignature.parameters, param => typeChecker.symbolToParameterDeclaration(param, invocation, flags))]); + printer.writeList(ListFormat.CallExpressionArguments, params, getSourceFileOfNode(getParseTreeNode(invocation)), writer); + }); addRange(suffixDisplayParts, parameterParts); } else { isVariadic = candidateSignature.hasRestParameter; - const typeParameterParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation)); + const typeParameterParts = mapToDisplayParts(writer => { + if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) { + const args = createNodeArray(map(candidateSignature.typeParameters, p => typeChecker.typeParameterToDeclaration(p, invocation))); + printer.writeList(ListFormat.TypeParameters, args, getSourceFileOfNode(getParseTreeNode(invocation)), writer); + } + }); addRange(prefixDisplayParts, typeParameterParts); prefixDisplayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); @@ -390,8 +400,17 @@ namespace ts.SignatureHelp { suffixDisplayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } - const returnTypeParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation)); + const returnTypeParts = mapToDisplayParts(writer => { + writer.writePunctuation(":"); + writer.writeSpace(" "); + const predicate = typeChecker.getTypePredicateOfSignature(candidateSignature); + if (predicate) { + typeChecker.writeTypePredicate(predicate, invocation, /*flags*/ undefined, writer); + } + else { + typeChecker.writeType(typeChecker.getReturnTypeOfSignature(candidateSignature), invocation, /*flags*/ undefined, writer); + } + }); addRange(suffixDisplayParts, returnTypeParts); return { @@ -415,8 +434,10 @@ namespace ts.SignatureHelp { return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount }; function createSignatureHelpParameterForParameter(parameter: Symbol): SignatureHelpParameter { - const displayParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation)); + const displayParts = mapToDisplayParts(writer => { + const param = typeChecker.symbolToParameterDeclaration(parameter, invocation, NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors); + printer.writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(invocation)), writer); + }); return { name: parameter.name, @@ -427,8 +448,10 @@ namespace ts.SignatureHelp { } function createSignatureHelpParameterForTypeParameter(typeParameter: TypeParameter): SignatureHelpParameter { - const displayParts = mapToDisplayParts(writer => - typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation)); + const displayParts = mapToDisplayParts(writer => { + const param = typeChecker.typeParameterToDeclaration(typeParameter, invocation); + printer.writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(invocation)), writer); + }); return { name: typeParameter.symbol.name, diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index caf38306bec..9ec99f6ccaf 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -91,9 +91,14 @@ namespace ts.SymbolDisplay { } export function getSymbolModifiers(symbol: Symbol): string { - return symbol && symbol.declarations && symbol.declarations.length > 0 + const nodeModifiers = symbol && symbol.declarations && symbol.declarations.length > 0 ? getNodeModifiers(symbol.declarations[0]) : ScriptElementKindModifier.none; + + const symbolModifiers = symbol && symbol.flags & SymbolFlags.Optional ? + ScriptElementKindModifier.optionalModifier + : ScriptElementKindModifier.none; + return nodeModifiers && symbolModifiers ? nodeModifiers + "," + symbolModifiers : nodeModifiers || symbolModifiers; } interface SymbolDisplayPartsDocumentationAndSymbolKind { @@ -105,7 +110,7 @@ namespace ts.SymbolDisplay { // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node, - location: Node, semanticMeaning = getMeaningFromLocation(location)): SymbolDisplayPartsDocumentationAndSymbolKind { + location: Node, semanticMeaning = getMeaningFromLocation(location), alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind { const displayParts: SymbolDisplayPart[] = []; let documentation: SymbolDisplayPart[]; @@ -115,6 +120,8 @@ namespace ts.SymbolDisplay { let hasAddedSymbolInfo: boolean; const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isExpression(location); let type: Type; + let printer: Printer; + let documentationFromAlias: SymbolDisplayPart[]; // Class at constructor site need to be shown as constructor apart from property,method, vars if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Alias) { @@ -192,7 +199,7 @@ namespace ts.SymbolDisplay { displayParts.push(punctuationPart(SyntaxKind.ColonToken)); displayParts.push(spacePart()); if (!(type.flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous) && type.symbol) { - addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments)); + addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.AllowAnyNodeKind | SymbolFormatFlags.WriteTypeParametersOrArguments)); displayParts.push(lineBreakPart()); } if (useConstructSignatures) { @@ -243,6 +250,7 @@ namespace ts.SymbolDisplay { } } if (symbolFlags & SymbolFlags.Class && !hasAddedSymbolInfo && !isThisExpression) { + addAliasPrefixIfNecessary(); if (getDeclarationOfKind(symbol, SyntaxKind.ClassExpression)) { // Special case for class expressions because we would like to indicate that // the class name is local to the class body (similar to function expression) @@ -258,14 +266,14 @@ namespace ts.SymbolDisplay { writeTypeParametersOfSymbol(symbol, sourceFile); } if ((symbolFlags & SymbolFlags.Interface) && (semanticMeaning & SemanticMeaning.Type)) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); displayParts.push(keywordPart(SyntaxKind.InterfaceKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); writeTypeParametersOfSymbol(symbol, sourceFile); } if (symbolFlags & SymbolFlags.TypeAlias) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); displayParts.push(spacePart()); addFullSymbolName(symbol); @@ -276,7 +284,7 @@ namespace ts.SymbolDisplay { addRange(displayParts, typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, TypeFormatFlags.InTypeAlias)); } if (symbolFlags & SymbolFlags.Enum) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); if (forEach(symbol.declarations, isConstEnumDeclaration)) { displayParts.push(keywordPart(SyntaxKind.ConstKeyword)); displayParts.push(spacePart()); @@ -286,7 +294,7 @@ namespace ts.SymbolDisplay { addFullSymbolName(symbol); } if (symbolFlags & SymbolFlags.Module) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); const declaration = getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration); const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier; displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword)); @@ -294,7 +302,7 @@ namespace ts.SymbolDisplay { addFullSymbolName(symbol); } if ((symbolFlags & SymbolFlags.TypeParameter) && (semanticMeaning & SemanticMeaning.Type)) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); displayParts.push(punctuationPart(SyntaxKind.OpenParenToken)); displayParts.push(textPart("type parameter")); displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); @@ -328,7 +336,7 @@ namespace ts.SymbolDisplay { else if (declaration.kind === SyntaxKind.TypeAliasDeclaration) { // Type alias type parameter // For example - // type list = T[]; // Both T will go through same code path + // type list = T[]; // Both T will go through same code path addInPrefix(); displayParts.push(keywordPart(SyntaxKind.TypeKeyword)); displayParts.push(spacePart()); @@ -354,7 +362,32 @@ namespace ts.SymbolDisplay { } } if (symbolFlags & SymbolFlags.Alias) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); + if (!hasAddedSymbolInfo) { + const resolvedSymbol = typeChecker.getAliasedSymbol(symbol); + if (resolvedSymbol !== symbol && resolvedSymbol.declarations && resolvedSymbol.declarations.length > 0) { + const resolvedNode = resolvedSymbol.declarations[0]; + const declarationName = ts.getNameOfDeclaration(resolvedNode); + if (declarationName) { + const isExternalModuleDeclaration = + ts.isModuleWithStringLiteralName(resolvedNode) && + ts.hasModifier(resolvedNode, ModifierFlags.Ambient); + const shouldUseAliasName = symbol.name !== "default" && !isExternalModuleDeclaration; + const resolvedInfo = getSymbolDisplayPartsDocumentationAndSymbolKind( + typeChecker, + resolvedSymbol, + ts.getSourceFileOfNode(resolvedNode), + resolvedNode, + declarationName, + semanticMeaning, + shouldUseAliasName ? symbol : resolvedSymbol); + displayParts.push(...resolvedInfo.displayParts); + displayParts.push(lineBreakPart()); + documentationFromAlias = resolvedInfo.documentation; + } + } + } + switch (symbol.declarations[0].kind) { case SyntaxKind.NamespaceExportDeclaration: displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); @@ -400,7 +433,7 @@ namespace ts.SymbolDisplay { if (symbolKind !== ScriptElementKind.unknown) { if (type) { if (isThisExpression) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); displayParts.push(keywordPart(SyntaxKind.ThisKeyword)); } else { @@ -418,7 +451,8 @@ namespace ts.SymbolDisplay { // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { const typeParameterParts = mapToDisplayParts(writer => { - typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration); + const param = typeChecker.typeParameterToDeclaration(type as TypeParameter, enclosingDeclaration); + getPrinter().writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer); }); addRange(displayParts, typeParameterParts); } @@ -472,12 +506,31 @@ namespace ts.SymbolDisplay { } } + if (documentation.length === 0 && documentationFromAlias) { + documentation = documentationFromAlias; + } + return { displayParts, documentation, symbolKind, tags }; - function addNewLineIfDisplayPartsExist() { + function getPrinter() { + if (!printer) { + printer = createPrinter({ removeComments: true }); + } + return printer; + } + + function prefixNextMeaning() { if (displayParts.length) { displayParts.push(lineBreakPart()); } + addAliasPrefixIfNecessary(); + } + + function addAliasPrefixIfNecessary() { + if (alias) { + pushTypePart(ScriptElementKind.alias); + displayParts.push(spacePart()); + } } function addInPrefix() { @@ -486,14 +539,17 @@ namespace ts.SymbolDisplay { displayParts.push(spacePart()); } - function addFullSymbolName(symbol: Symbol, enclosingDeclaration?: Node) { - const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, - SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing); + function addFullSymbolName(symbolToDisplay: Symbol, enclosingDeclaration?: Node) { + if (alias && symbolToDisplay === symbol) { + symbolToDisplay = alias; + } + const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, + SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind); addRange(displayParts, fullSymbolDisplayParts); } function addPrefixForAnyFunctionOrVar(symbol: Symbol, symbolKind: string) { - addNewLineIfDisplayPartsExist(); + prefixNextMeaning(); if (symbolKind) { pushTypePart(symbolKind); if (symbol && !some(symbol.declarations, d => isArrowFunction(d) || (isFunctionExpression(d) || isClassExpression(d)) && !d.name)) { @@ -537,7 +593,8 @@ namespace ts.SymbolDisplay { function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) { const typeParameterParts = mapToDisplayParts(writer => { - typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration); + const params = typeChecker.symbolToTypeParameterDeclarations(symbol, enclosingDeclaration); + getPrinter().writeList(ListFormat.TypeParameters, params, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer); }); addRange(displayParts, typeParameterParts); } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index e73c639ba79..467ba6735ca 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -345,6 +345,11 @@ namespace ts.textChanges { return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween)); } + public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void { + const pos = before.getStart(sourceFile); + this.replaceWithSingle(sourceFile, pos, pos, createToken(modifier), { suffix: " " }); + } + public changeIdentifierToPropertyAccess(sourceFile: SourceFile, prefix: string, node: Identifier): void { const startPosition = getAdjustedStartPosition(sourceFile, node, {}, Position.Start); this.replaceWithSingle(sourceFile, startPosition, startPosition, createPropertyAccess(createIdentifier(prefix), ""), {}); @@ -805,6 +810,38 @@ namespace ts.textChanges { this.writer.write(s); this.setLastNonTriviaPosition(s, /*force*/ false); } + writeKeyword(s: string): void { + this.writer.writeKeyword(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeOperator(s: string): void { + this.writer.writeOperator(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writePunctuation(s: string): void { + this.writer.writePunctuation(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeParameter(s: string): void { + this.writer.writeParameter(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeProperty(s: string): void { + this.writer.writeProperty(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeSpace(s: string): void { + this.writer.writeSpace(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeStringLiteral(s: string): void { + this.writer.writeStringLiteral(s); + this.setLastNonTriviaPosition(s, /*force*/ false); + } + writeSymbol(s: string, sym: Symbol): void { + this.writer.writeSymbol(s, sym); + this.setLastNonTriviaPosition(s, /*force*/ false); + } writeTextOfNode(text: string, node: Node): void { this.writer.writeTextOfNode(text, node); } @@ -843,8 +880,8 @@ namespace ts.textChanges { isAtStartOfLine(): boolean { return this.writer.isAtStartOfLine(); } - reset(): void { - this.writer.reset(); + clear(): void { + this.writer.clear(); this.lastNonTriviaPosition = 0; } } diff --git a/src/services/types.ts b/src/services/types.ts index 471ae3b3459..597709a7c79 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -333,6 +333,7 @@ namespace ts { export interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; + includeInsertTextCompletions: boolean; } export interface ApplyCodeActionCommandResult { @@ -597,6 +598,7 @@ namespace ts { InsertSpaceBeforeFunctionParenthesis?: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } export interface FormatCodeSettings extends EditorSettings { @@ -615,6 +617,7 @@ namespace ts { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } export interface DefinitionInfo { @@ -746,6 +749,7 @@ namespace ts { kind: ScriptElementKind; kindModifiers: string; // see ScriptElementKindModifier, comma separated sortText: string; + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. @@ -954,6 +958,7 @@ namespace ts { ambientModifier = "declare", staticModifier = "static", abstractModifier = "abstract", + optionalModifier = "optional" } export const enum ClassificationTypeNames { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 96a1cdd55fc..abfe5a7a55d 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -833,8 +833,7 @@ namespace ts { } } - export function isInString(sourceFile: SourceFile, position: number): boolean { - const previousToken = findPrecedingToken(position, sourceFile); + export function isInString(sourceFile: SourceFile, position: number, previousToken = findPrecedingToken(position, sourceFile)): boolean { if (previousToken && isStringTextContainingNode(previousToken)) { const start = previousToken.getStart(); const end = previousToken.getEnd(); @@ -1107,6 +1106,10 @@ namespace ts { seen.set(key, true); return true; } + + export function getSnapshotText(snap: IScriptSnapshot): string { + return snap.getText(0, snap.getLength()); + } } // Display-part writer helpers @@ -1123,6 +1126,7 @@ namespace ts { let indent: number; resetWriter(); + const unknownWrite = (text: string) => writeKind(text, SymbolDisplayPartKind.text); return { displayParts: () => displayParts, writeKeyword: text => writeKind(text, SymbolDisplayPartKind.keyword), @@ -1132,8 +1136,18 @@ namespace ts { writeStringLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral), writeParameter: text => writeKind(text, SymbolDisplayPartKind.parameterName), writeProperty: text => writeKind(text, SymbolDisplayPartKind.propertyName), + writeLiteral: text => writeKind(text, SymbolDisplayPartKind.stringLiteral), writeSymbol, writeLine, + write: unknownWrite, + writeTextOfNode: unknownWrite, + getText: () => "", + getTextPos: () => 0, + getColumn: () => 0, + getLine: () => 0, + isAtStartOfLine: () => false, + rawWrite: notImplemented, + getIndent: () => indent, increaseIndent: () => { indent++; }, decreaseIndent: () => { indent--; }, clear: resetWriter, @@ -1245,6 +1259,7 @@ namespace ts { return displayPart("\n", SymbolDisplayPartKind.lineBreak); } + /* @internal */ export function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[] { try { writeDisplayParts(displayPartWriter); @@ -1257,36 +1272,23 @@ namespace ts { export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] { return mapToDisplayParts(writer => { - typechecker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); + typechecker.writeType(type, enclosingDeclaration, flags | TypeFormatFlags.MultilineObjectLiterals, writer); }); } export function symbolToDisplayParts(typeChecker: TypeChecker, symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): SymbolDisplayPart[] { return mapToDisplayParts(writer => { - typeChecker.getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags); + typeChecker.writeSymbol(symbol, enclosingDeclaration, meaning, flags, writer); }); } export function signatureToDisplayParts(typechecker: TypeChecker, signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] { - flags |= TypeFormatFlags.UseAliasDefinedOutsideCurrentScope; + flags |= TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | TypeFormatFlags.MultilineObjectLiterals | TypeFormatFlags.WriteTypeArgumentsOfSignature | TypeFormatFlags.OmitParameterModifiers; return mapToDisplayParts(writer => { - typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); + typechecker.writeSignature(signature, enclosingDeclaration, flags, /*signatureKind*/ undefined, writer); }); } - export function getDeclaredName(typeChecker: TypeChecker, symbol: Symbol, location: Node): string { - // If this is an export or import specifier it could have been renamed using the 'as' syntax. - // If so we want to search for whatever is under the cursor. - if (isImportOrExportSpecifierName(location) || isStringOrNumericLiteral(location) && location.parent.kind === SyntaxKind.ComputedPropertyName) { - return getTextOfIdentifierOrLiteral(location); - } - - // Try to get the local symbol if we're dealing with an 'export default' - // since that symbol has the "true" name. - const localExportDefaultSymbol = getLocalSymbolForExportDefault(symbol); - return typeChecker.symbolToString(localExportDefaultSymbol || symbol); - } - export function isImportOrExportSpecifierName(location: Node): location is Identifier { return location.parent && (location.parent.kind === SyntaxKind.ImportSpecifier || location.parent.kind === SyntaxKind.ExportSpecifier) && @@ -1300,12 +1302,16 @@ namespace ts { */ export function stripQuotes(name: string) { const length = name.length; - if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && isSingleOrDoubleQuote(name.charCodeAt(0))) { + if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && startsWithQuote(name)) { return name.substring(1, length - 1); } return name; } + export function startsWithQuote(name: string): boolean { + return isSingleOrDoubleQuote(name.charCodeAt(0)); + } + export function scriptKindIs(fileName: string, host: LanguageServiceHost, ...scriptKinds: ScriptKind[]): boolean { const scriptKind = getScriptKind(fileName, host); return forEach(scriptKinds, k => k === scriptKind); @@ -1363,6 +1369,10 @@ namespace ts { return visited; } + export function getSynthesizedDeepClones(nodes: NodeArray | undefined): NodeArray | undefined { + return nodes && createNodeArray(nodes.map(getSynthesizedDeepClone), nodes.hasTrailingComma); + } + /** * Sets EmitFlags to suppress leading and trailing trivia on the node. */ diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json index 934de3d8faf..a21f9f81c44 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.leadingAsterisk.json @@ -27,8 +27,7 @@ "pos": 15, "end": 21 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json index 934de3d8faf..a21f9f81c44 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noLeadingAsterisk.json @@ -27,8 +27,7 @@ "pos": 15, "end": 21 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json index 62228eac4af..079d09c6eeb 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.noReturnType.json @@ -17,8 +17,7 @@ "pos": 9, "end": 15, "escapedText": "return" - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json index 15e8b4a5cfb..4940bcf325e 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json @@ -35,8 +35,7 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json index 93f47686e8f..7a1c85b25d6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json @@ -35,8 +35,7 @@ "escapedText": "name1" }, "isNameFirst": true, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json index 926344175d7..3d511525c64 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json @@ -25,8 +25,7 @@ "escapedText": "foo" }, "isNameFirst": true, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json index 0668e7d6324..e02a0a38bb4 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnTag1.json @@ -27,8 +27,7 @@ "pos": 17, "end": 23 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json index e108287c52a..70497ee8c1b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.returnsTag1.json @@ -27,8 +27,7 @@ "pos": 18, "end": 24 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json index b39b16497e6..8a146e3cfaf 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag.json @@ -33,8 +33,7 @@ "length": 1, "pos": 18, "end": 20 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json index 5eeb97af119..5bb1df30665 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag2.json @@ -44,8 +44,7 @@ "length": 2, "pos": 18, "end": 22 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json index 96645551c5c..295b2122daa 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag3.json @@ -44,8 +44,7 @@ "length": 2, "pos": 18, "end": 23 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json index 0b2719f59ba..4aa29db3092 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag4.json @@ -44,8 +44,7 @@ "length": 2, "pos": 18, "end": 23 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json index 8b6118e9b19..5e707f6f03b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.templateTag5.json @@ -44,8 +44,7 @@ "length": 2, "pos": 18, "end": 24 - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json index 391ee1aac2f..c73009315bc 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json @@ -35,8 +35,7 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "1": { "kind": "JSDocParameterTag", @@ -70,8 +69,7 @@ "escapedText": "name2" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 2, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json index 628d54d162d..e1ef0adb926 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json @@ -35,8 +35,7 @@ "escapedText": "name1" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "1": { "kind": "JSDocParameterTag", @@ -70,8 +69,7 @@ "escapedText": "name2" }, "isNameFirst": false, - "isBracketed": false, - "comment": "" + "isBracketed": false }, "length": 2, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json index 934de3d8faf..a21f9f81c44 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typeTag.json @@ -27,8 +27,7 @@ "pos": 15, "end": 21 } - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json index 08d270286b9..a4a69fc48a6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json @@ -104,8 +104,7 @@ "isBracketed": false } ] - }, - "comment": "" + } }, "length": 1, "pos": 8, diff --git a/tests/baselines/reference/abstractPropertyNegative.errors.txt b/tests/baselines/reference/abstractPropertyNegative.errors.txt index 314ab842ded..be1c85374fb 100644 --- a/tests/baselines/reference/abstractPropertyNegative.errors.txt +++ b/tests/baselines/reference/abstractPropertyNegative.errors.txt @@ -7,15 +7,12 @@ tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstra tests/cases/compiler/abstractPropertyNegative.ts(15,5): error TS1244: Abstract methods can only appear within an abstract class. tests/cases/compiler/abstractPropertyNegative.ts(16,37): error TS1005: '{' expected. tests/cases/compiler/abstractPropertyNegative.ts(19,3): error TS2540: Cannot assign to 'ro' because it is a constant or a read-only property. -tests/cases/compiler/abstractPropertyNegative.ts(24,7): error TS2415: Class 'WrongTypePropertyImpl' incorrectly extends base class 'WrongTypeProperty'. - Types of property 'num' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/abstractPropertyNegative.ts(30,7): error TS2415: Class 'WrongTypeAccessorImpl' incorrectly extends base class 'WrongTypeAccessor'. - Types of property 'num' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/abstractPropertyNegative.ts(33,7): error TS2415: Class 'WrongTypeAccessorImpl2' incorrectly extends base class 'WrongTypeAccessor'. - Types of property 'num' are incompatible. - Type 'string' is not assignable to type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(25,5): error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'WrongTypeProperty'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(31,9): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'WrongTypeAccessor'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/abstractPropertyNegative.ts(34,5): error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'WrongTypeAccessor'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/abstractPropertyNegative.ts(38,18): error TS2676: Accessors must both be abstract or non-abstract. tests/cases/compiler/abstractPropertyNegative.ts(39,9): error TS2676: Accessors must both be abstract or non-abstract. tests/cases/compiler/abstractPropertyNegative.ts(40,9): error TS2676: Accessors must both be abstract or non-abstract. @@ -65,28 +62,25 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors abstract num: number; } class WrongTypePropertyImpl extends WrongTypeProperty { - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2415: Class 'WrongTypePropertyImpl' incorrectly extends base class 'WrongTypeProperty'. -!!! error TS2415: Types of property 'num' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. num = "nope, wrong"; + ~~~ +!!! error TS2416: Property 'num' in type 'WrongTypePropertyImpl' is not assignable to the same property in base type 'WrongTypeProperty'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. } abstract class WrongTypeAccessor { abstract get num(): number; } class WrongTypeAccessorImpl extends WrongTypeAccessor { - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2415: Class 'WrongTypeAccessorImpl' incorrectly extends base class 'WrongTypeAccessor'. -!!! error TS2415: Types of property 'num' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. get num() { return "nope, wrong"; } + ~~~ +!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl' is not assignable to the same property in base type 'WrongTypeAccessor'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. } class WrongTypeAccessorImpl2 extends WrongTypeAccessor { - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2415: Class 'WrongTypeAccessorImpl2' incorrectly extends base class 'WrongTypeAccessor'. -!!! error TS2415: Types of property 'num' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. num = "nope, wrong"; + ~~~ +!!! error TS2416: Property 'num' in type 'WrongTypeAccessorImpl2' is not assignable to the same property in base type 'WrongTypeAccessor'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. } abstract class AbstractAccessorMismatch { diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js new file mode 100644 index 00000000000..1366e242182 --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js @@ -0,0 +1,27 @@ +//// [additionOperatorWithConstrainedTypeParameter.ts] +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum, K extends string>(n: number, vs: T[], k: K) { + for (const v of vs) { + n = n + v[k]; + n += v[k]; + } +} + + +//// [additionOperatorWithConstrainedTypeParameter.js] +// test for #17069 +function sum(n, v, k) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum(n, vs, k) { + for (var _i = 0, vs_1 = vs; _i < vs_1.length; _i++) { + var v = vs_1[_i]; + n = n + v[k]; + n += v[k]; + } +} diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols new file mode 100644 index 00000000000..e7055c1e38f --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols @@ -0,0 +1,54 @@ +=== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts === +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { +>sum : Symbol(sum, Decl(additionOperatorWithConstrainedTypeParameter.ts, 0, 0)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 13)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 13)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) + + n = n + v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) + + n += v[k]; // += should work the same way +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) +} +function realSum, K extends string>(n: number, vs: T[], k: K) { +>realSum : Symbol(realSum, Decl(additionOperatorWithConstrainedTypeParameter.ts, 4, 1)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 17)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>vs : Symbol(vs, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 74)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 17)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) + + for (const v of vs) { +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>vs : Symbol(vs, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 74)) + + n = n + v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) + + n += v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) + } +} + diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types new file mode 100644 index 00000000000..d52c77a94fd --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types @@ -0,0 +1,64 @@ +=== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts === +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { +>sum : , K extends string>(n: number, v: T, k: K) => void +>T : T +>Record : Record +>K : K +>K : K +>n : number +>v : T +>T : T +>k : K +>K : K + + n = n + v[k]; +>n = n + v[k] : number +>n : number +>n + v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + + n += v[k]; // += should work the same way +>n += v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K +} +function realSum, K extends string>(n: number, vs: T[], k: K) { +>realSum : , K extends string>(n: number, vs: T[], k: K) => void +>T : T +>Record : Record +>K : K +>K : K +>n : number +>vs : T[] +>T : T +>k : K +>K : K + + for (const v of vs) { +>v : T +>vs : T[] + + n = n + v[k]; +>n = n + v[k] : number +>n : number +>n + v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + + n += v[k]; +>n += v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + } +} + diff --git a/tests/baselines/reference/allowSyntheticDefaultImports1.js b/tests/baselines/reference/allowSyntheticDefaultImports1.js index fee1d137706..8c5565a1fb7 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports1.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports1.js @@ -4,21 +4,12 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); -//// [b.ts] +//// [b.d.ts] export class Foo { member: string; } -//// [b.js] -"use strict"; -exports.__esModule = true; -var Foo = /** @class */ (function () { - function Foo() { - } - return Foo; -}()); -exports.Foo = Foo; //// [a.js] "use strict"; exports.__esModule = true; diff --git a/tests/baselines/reference/allowSyntheticDefaultImports1.symbols b/tests/baselines/reference/allowSyntheticDefaultImports1.symbols index ecbe9e4c205..5ee2812ab59 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports1.symbols +++ b/tests/baselines/reference/allowSyntheticDefaultImports1.symbols @@ -4,15 +4,15 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); >x : Symbol(x, Decl(a.ts, 1, 10)) ->Namespace.Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0)) +>Namespace.Foo : Symbol(Namespace.Foo, Decl(b.d.ts, 0, 0)) >Namespace : Symbol(Namespace, Decl(a.ts, 0, 6)) ->Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0)) +>Foo : Symbol(Namespace.Foo, Decl(b.d.ts, 0, 0)) -=== tests/cases/compiler/b.ts === +=== tests/cases/compiler/b.d.ts === export class Foo { ->Foo : Symbol(Foo, Decl(b.ts, 0, 0)) +>Foo : Symbol(Foo, Decl(b.d.ts, 0, 0)) member: string; ->member : Symbol(Foo.member, Decl(b.ts, 0, 18)) +>member : Symbol(Foo.member, Decl(b.d.ts, 0, 18)) } diff --git a/tests/baselines/reference/allowSyntheticDefaultImports1.types b/tests/baselines/reference/allowSyntheticDefaultImports1.types index c2265d7611b..c8092331a47 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports1.types +++ b/tests/baselines/reference/allowSyntheticDefaultImports1.types @@ -9,7 +9,7 @@ export var x = new Namespace.Foo(); >Namespace : typeof Namespace >Foo : typeof Namespace.Foo -=== tests/cases/compiler/b.ts === +=== tests/cases/compiler/b.d.ts === export class Foo { >Foo : Foo diff --git a/tests/baselines/reference/allowSyntheticDefaultImports2.js b/tests/baselines/reference/allowSyntheticDefaultImports2.js index 5dc8472d58b..c1e43a4fc81 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports2.js +++ b/tests/baselines/reference/allowSyntheticDefaultImports2.js @@ -4,28 +4,11 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); -//// [b.ts] +//// [b.d.ts] export class Foo { member: string; } -//// [b.js] -System.register([], function (exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var Foo; - return { - setters: [], - execute: function () { - Foo = /** @class */ (function () { - function Foo() { - } - return Foo; - }()); - exports_1("Foo", Foo); - } - }; -}); //// [a.js] System.register(["./b"], function (exports_1, context_1) { "use strict"; diff --git a/tests/baselines/reference/allowSyntheticDefaultImports2.symbols b/tests/baselines/reference/allowSyntheticDefaultImports2.symbols index 615b1095c66..a2b33c94d82 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports2.symbols +++ b/tests/baselines/reference/allowSyntheticDefaultImports2.symbols @@ -4,14 +4,14 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); >x : Symbol(x, Decl(a.ts, 1, 10)) ->Namespace.Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0)) +>Namespace.Foo : Symbol(Namespace.Foo, Decl(b.d.ts, 0, 0)) >Namespace : Symbol(Namespace, Decl(a.ts, 0, 6)) ->Foo : Symbol(Namespace.Foo, Decl(b.ts, 0, 0)) +>Foo : Symbol(Namespace.Foo, Decl(b.d.ts, 0, 0)) -=== tests/cases/compiler/b.ts === +=== tests/cases/compiler/b.d.ts === export class Foo { ->Foo : Symbol(Foo, Decl(b.ts, 0, 0)) +>Foo : Symbol(Foo, Decl(b.d.ts, 0, 0)) member: string; ->member : Symbol(Foo.member, Decl(b.ts, 0, 18)) +>member : Symbol(Foo.member, Decl(b.d.ts, 0, 18)) } diff --git a/tests/baselines/reference/allowSyntheticDefaultImports2.types b/tests/baselines/reference/allowSyntheticDefaultImports2.types index c40fbc7e988..420c19b7c1d 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports2.types +++ b/tests/baselines/reference/allowSyntheticDefaultImports2.types @@ -9,7 +9,7 @@ export var x = new Namespace.Foo(); >Namespace : typeof Namespace >Foo : typeof Namespace.Foo -=== tests/cases/compiler/b.ts === +=== tests/cases/compiler/b.d.ts === export class Foo { >Foo : Foo diff --git a/tests/baselines/reference/anyMappedTypesError.errors.txt b/tests/baselines/reference/anyMappedTypesError.errors.txt new file mode 100644 index 00000000000..e1442c15723 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/anyMappedTypesError.ts(1,12): error TS7039: Mapped object type implicitly has an 'any' template type. + + +==== tests/cases/compiler/anyMappedTypesError.ts (1 errors) ==== + type Foo = {[P in "bar"]}; + ~~~~~~~~~~~~~~ +!!! error TS7039: Mapped object type implicitly has an 'any' template type. \ No newline at end of file diff --git a/tests/baselines/reference/anyMappedTypesError.js b/tests/baselines/reference/anyMappedTypesError.js new file mode 100644 index 00000000000..8797d2cfc0e --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.js @@ -0,0 +1,4 @@ +//// [anyMappedTypesError.ts] +type Foo = {[P in "bar"]}; + +//// [anyMappedTypesError.js] diff --git a/tests/baselines/reference/anyMappedTypesError.symbols b/tests/baselines/reference/anyMappedTypesError.symbols new file mode 100644 index 00000000000..0e9a425aad3 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/anyMappedTypesError.ts === +type Foo = {[P in "bar"]}; +>Foo : Symbol(Foo, Decl(anyMappedTypesError.ts, 0, 0)) +>P : Symbol(P, Decl(anyMappedTypesError.ts, 0, 13)) + diff --git a/tests/baselines/reference/anyMappedTypesError.types b/tests/baselines/reference/anyMappedTypesError.types new file mode 100644 index 00000000000..290ea6883b1 --- /dev/null +++ b/tests/baselines/reference/anyMappedTypesError.types @@ -0,0 +1,5 @@ +=== tests/cases/compiler/anyMappedTypesError.ts === +type Foo = {[P in "bar"]}; +>Foo : Foo +>P : P + diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 56c9805b1c6..964e4a0c275 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -59,6 +59,7 @@ declare namespace ts { pos: number; end: number; } + type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.Unknown; enum SyntaxKind { Unknown = 0, EndOfFileToken = 1, @@ -639,7 +640,7 @@ declare namespace ts { body?: Block | Expression; } type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction; - type FunctionLike = FunctionLikeDeclaration | FunctionTypeNode | ConstructorTypeNode | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration; + type FunctionLike = FunctionLikeDeclaration | FunctionTypeNode | ConstructorTypeNode | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration | JSDocFunctionType; interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { kind: SyntaxKind.FunctionDeclaration; name?: Identifier; @@ -884,7 +885,7 @@ declare namespace ts { type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment; type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; type BindingOrAssignmentElementRestIndicator = DotDotDotToken | SpreadElement | SpreadAssignment; - type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; type ObjectBindingOrAssignmentPattern = ObjectBindingPattern | ObjectLiteralExpression; type ArrayBindingOrAssignmentPattern = ArrayBindingPattern | ArrayLiteralExpression; type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression; @@ -908,6 +909,7 @@ declare namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } interface LiteralLikeNode extends Node { text: string; @@ -1369,6 +1371,7 @@ declare namespace ts { interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -1623,7 +1626,7 @@ declare namespace ts { } interface ParseConfigHost { useCaseSensitiveFileNames: boolean; - readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray, includes: ReadonlyArray, depth: number): string[]; + readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray | undefined, includes: ReadonlyArray, depth?: number): string[]; /** * Gets a value indicating whether the specified path exists and is a file. * @param path The path to test. @@ -1734,6 +1737,16 @@ declare namespace ts { signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; + /** Note that the resulting nodes cannot be checked. */ + symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName; + /** Note that the resulting nodes cannot be checked. */ + symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression; + /** Note that the resulting nodes cannot be checked. */ + symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray | undefined; + /** Note that the resulting nodes cannot be checked. */ + symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration; + /** Note that the resulting nodes cannot be checked. */ + typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol | undefined; getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; @@ -1753,7 +1766,8 @@ declare namespace ts { getTypeFromTypeNode(node: TypeNode): Type; signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; - symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): string; + typePredicateToString(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; /** * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead * This will be removed in a future version. @@ -1793,33 +1807,79 @@ declare namespace ts { None = 0, NoTruncation = 1, WriteArrayAsGenericType = 2, + WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, + WriteTypeArgumentsOfSignature = 32, + UseFullyQualifiedType = 64, + UseOnlyExternalAliasing = 128, + SuppressAnyReturnType = 256, + WriteTypeParametersInQualifiedName = 512, + MultilineObjectLiterals = 1024, + WriteClassExpressionAsTypeLiteral = 2048, + UseTypeOfFunction = 4096, + OmitParameterModifiers = 8192, + UseAliasDefinedOutsideCurrentScope = 16384, + AllowThisInObjectLiteral = 32768, + AllowQualifedNameInPlaceOfIdentifier = 65536, + AllowAnonymousIdentifier = 131072, + AllowEmptyUnionOrIntersection = 262144, + AllowEmptyTuple = 524288, + AllowUniqueESSymbolType = 1048576, + AllowEmptyIndexInfoType = 2097152, + IgnoreErrors = 3112960, + InObjectTypeLiteral = 4194304, + InTypeAlias = 8388608, + } + enum TypeFormatFlags { + None = 0, + NoTruncation = 1, + WriteArrayAsGenericType = 2, + WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, SuppressAnyReturnType = 256, - WriteTypeParametersInQualifiedName = 512, - AllowThisInObjectLiteral = 1024, - AllowQualifedNameInPlaceOfIdentifier = 2048, - AllowAnonymousIdentifier = 8192, - AllowEmptyUnionOrIntersection = 16384, - AllowEmptyTuple = 32768, - IgnoreErrors = 60416, - InObjectTypeLiteral = 1048576, + MultilineObjectLiterals = 1024, + WriteClassExpressionAsTypeLiteral = 2048, + UseTypeOfFunction = 4096, + OmitParameterModifiers = 8192, + UseAliasDefinedOutsideCurrentScope = 16384, + AllowUniqueESSymbolType = 1048576, + AddUndefined = 131072, + WriteArrowStyleSignature = 262144, + InArrayType = 524288, + InElementType = 2097152, + InFirstTypeArgument = 4194304, InTypeAlias = 8388608, + /** @deprecated */ WriteOwnNameForAnyLike = 0, + NodeBuilderFlagsMask = 9469295, } + enum SymbolFormatFlags { + None = 0, + WriteTypeParametersOrArguments = 1, + UseOnlyExternalAliasing = 2, + AllowAnyNodeKind = 4, + } + /** + * @deprecated + */ interface SymbolDisplayBuilder { - buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; - buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; - buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; - buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; + /** @deprecated */ buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; + /** @deprecated */ buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; + /** @deprecated */ buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; } - interface SymbolWriter { + /** + * @deprecated Migrate to other methods of generating symbol names, ex symbolToEntityName + a printer or symbolToString + */ + interface SymbolWriter extends SymbolTracker { writeKeyword(text: string): void; writeOperator(text: string): void; writePunctuation(text: string): void; @@ -1832,34 +1892,6 @@ declare namespace ts { increaseIndent(): void; decreaseIndent(): void; clear(): void; - trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; - reportInaccessibleThisError(): void; - reportPrivateInBaseOfClassExpression(propertyName: string): void; - reportInaccessibleUniqueSymbolError(): void; - } - enum TypeFormatFlags { - None = 0, - WriteArrayAsGenericType = 1, - UseTypeOfFunction = 4, - NoTruncation = 8, - WriteArrowStyleSignature = 16, - WriteOwnNameForAnyLike = 32, - WriteTypeArgumentsOfSignature = 64, - InElementType = 128, - UseFullyQualifiedType = 256, - InFirstTypeArgument = 512, - InTypeAlias = 1024, - SuppressAnyReturnType = 4096, - AddUndefined = 8192, - WriteClassExpressionAsTypeLiteral = 16384, - InArrayType = 32768, - UseAliasDefinedOutsideCurrentScope = 65536, - AllowUniqueESSymbolType = 131072, - } - enum SymbolFormatFlags { - None = 0, - WriteTypeParametersOrArguments = 1, - UseOnlyExternalAliasing = 2, } enum TypePredicateKind { This = 0, @@ -2078,8 +2110,9 @@ declare namespace ts { EvolvingArray = 256, ObjectLiteralPatternWithComputedProperties = 512, ContainsSpread = 1024, - JsxAttributes = 2048, - MarkerType = 4096, + ReverseMapped = 2048, + JsxAttributes = 4096, + MarkerType = 8192, ClassOrInterface = 3, } interface ObjectType extends Type { @@ -2169,15 +2202,14 @@ declare namespace ts { declaration?: SignatureDeclaration; } enum InferencePriority { - Contravariant = 1, - NakedTypeVariable = 2, - MappedType = 4, - ReturnType = 8, - NeverType = 16, + NakedTypeVariable = 1, + MappedType = 2, + ReturnType = 4, } interface InferenceInfo { typeParameter: TypeParameter; candidates: Type[]; + contraCandidates: Type[]; inferredType: Type; priority: InferencePriority; topLevel: boolean; @@ -2318,6 +2350,7 @@ declare namespace ts { types?: string[]; /** Paths used to compute primary types search locations */ typeRoots?: string[]; + esModuleInterop?: boolean; [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; } interface TypeAcquisition { @@ -2491,11 +2524,11 @@ declare namespace ts { getCanonicalFileName(fileName: string): string; useCaseSensitiveFileNames(): boolean; getNewLine(): string; - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[]; /** * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files */ - resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; + resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[]; getEnvironmentVariable?(name: string): string; } interface SourceMapRange extends TextRange { @@ -2653,6 +2686,10 @@ declare namespace ts { * collisions. */ printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; + /** + * Prints a list of nodes using the given format flags + */ + printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): string; /** * Prints a source file as-is, without any emit transformations. */ @@ -2708,6 +2745,13 @@ declare namespace ts { interface PrinterOptions { removeComments?: boolean; newLine?: NewLineKind; + omitTrailingSemicolon?: boolean; + } + interface SymbolTracker { + trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; + reportInaccessibleThisError?(): void; + reportPrivateInBaseOfClassExpression?(propertyName: string): void; + reportInaccessibleUniqueSymbolError?(): void; } interface TextSpan { start: number; @@ -2720,6 +2764,71 @@ declare namespace ts { interface SyntaxList extends Node { _children: Node[]; } + enum ListFormat { + None = 0, + SingleLine = 0, + MultiLine = 1, + PreserveLines = 2, + LinesMask = 3, + NotDelimited = 0, + BarDelimited = 4, + AmpersandDelimited = 8, + CommaDelimited = 16, + DelimitersMask = 28, + AllowTrailingComma = 32, + Indented = 64, + SpaceBetweenBraces = 128, + SpaceBetweenSiblings = 256, + Braces = 512, + Parenthesis = 1024, + AngleBrackets = 2048, + SquareBrackets = 4096, + BracketsMask = 7680, + OptionalIfUndefined = 8192, + OptionalIfEmpty = 16384, + Optional = 24576, + PreferNewLine = 32768, + NoTrailingNewLine = 65536, + NoInterveningComments = 131072, + NoSpaceIfEmpty = 262144, + SingleElement = 524288, + Modifiers = 131328, + HeritageClauses = 256, + SingleLineTypeLiteralMembers = 448, + MultiLineTypeLiteralMembers = 65, + TupleTypeElements = 336, + UnionTypeConstituents = 260, + IntersectionTypeConstituents = 264, + ObjectBindingPatternElements = 262576, + ArrayBindingPatternElements = 262448, + ObjectLiteralExpressionProperties = 263122, + ArrayLiteralExpressionElements = 4466, + CommaListElements = 272, + CallExpressionArguments = 1296, + NewExpressionArguments = 9488, + TemplateExpressionSpans = 131072, + SingleLineBlockStatements = 384, + MultiLineBlockStatements = 65, + VariableDeclarationList = 272, + SingleLineFunctionBodyStatements = 384, + MultiLineFunctionBodyStatements = 1, + ClassHeritageClauses = 256, + ClassMembers = 65, + InterfaceMembers = 65, + EnumMembers = 81, + CaseBlockClauses = 65, + NamedImportsOrExportsElements = 432, + JsxElementOrFragmentChildren = 131072, + JsxElementAttributes = 131328, + CaseOrDefaultClauseStatements = 81985, + HeritageClauseTypes = 272, + SourceFileStatements = 65537, + Decorators = 24577, + TypeArguments = 26896, + TypeParameters = 26896, + Parameters = 1296, + IndexSignatureParameters = 4432, + } } declare namespace ts { const versionMajorMinor = "2.7"; @@ -2935,7 +3044,7 @@ declare namespace ts { function isStringLiteral(node: Node): node is StringLiteral; function isJsxText(node: Node): node is JsxText; function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral; - function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression; + function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral; function isTemplateHead(node: Node): node is TemplateHead; function isTemplateMiddle(node: Node): node is TemplateMiddle; function isTemplateTail(node: Node): node is TemplateTail; @@ -3128,6 +3237,7 @@ declare namespace ts { function isJSDocCommentContainingNode(node: Node): boolean; function isSetAccessor(node: Node): node is SetAccessorDeclaration; function isGetAccessor(node: Node): node is GetAccessorDeclaration; + function isObjectLiteralElement(node: Node): node is ObjectLiteralElement; } declare namespace ts { type ErrorCallback = (message: DiagnosticMessage, length: number) => void; @@ -3150,7 +3260,7 @@ declare namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): SyntaxKind; scanJsxToken(): SyntaxKind; - scanJSDocToken(): SyntaxKind; + scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; getText(): string; setText(text: string, start?: number, length?: number): void; @@ -3170,8 +3280,10 @@ declare namespace ts { function isWhiteSpaceSingleLine(ch: number): boolean; function isLineBreak(ch: number): boolean; function couldStartTrivia(text: string, pos: number): boolean; - function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; - function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined; @@ -3309,13 +3421,13 @@ declare namespace ts { declare namespace ts { function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: number): NumericLiteral; function createLiteral(value: boolean): BooleanLiteral; function createLiteral(value: string | number | boolean): PrimaryExpression; function createNumericLiteral(value: string): NumericLiteral; function createIdentifier(text: string): Identifier; - function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; + function updateIdentifier(node: Identifier): Identifier; /** Create a unique temporary variable. */ function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; /** Create a unique temporary variable for use in a loop. */ @@ -3797,7 +3909,7 @@ declare namespace ts { } } declare namespace ts { - function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string; + function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined; function resolveTripleslashReference(moduleName: string, containingFile: string): string; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; @@ -4024,6 +4136,7 @@ declare namespace ts { } interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; + includeInsertTextCompletions: boolean; } interface ApplyCodeActionCommandResult { successMessage: string; @@ -4234,6 +4347,7 @@ declare namespace ts { InsertSpaceBeforeFunctionParenthesis?: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface FormatCodeSettings extends EditorSettings { insertSpaceAfterCommaDelimiter?: boolean; @@ -4251,6 +4365,7 @@ declare namespace ts { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface DefinitionInfo { fileName: string; @@ -4366,6 +4481,7 @@ declare namespace ts { kind: ScriptElementKind; kindModifiers: string; sortText: string; + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. @@ -4532,6 +4648,7 @@ declare namespace ts { ambientModifier = "declare", staticModifier = "static", abstractModifier = "abstract", + optionalModifier = "optional", } enum ClassificationTypeNames { comment = "comment", @@ -4677,9 +4794,6 @@ declare namespace ts { declare namespace ts { /** The version of the language service API */ const servicesVersion = "0.7"; - interface DisplayPartsSymbolWriter extends SymbolWriter { - displayParts(): SymbolDisplayPart[]; - } function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings; function displayPartsToString(displayParts: SymbolDisplayPart[]): string; function getDefaultCompilerOptions(): CompilerOptions; @@ -6128,6 +6242,11 @@ declare namespace ts.server.protocol { * This affects lone identifier completions but not completions on the right hand side of `obj.`. */ includeExternalModuleExports: boolean; + /** + * If enabled, the completion list will include completions with invalid identifier names. + * For those entries, The `insertText` and `replacementSpan` properties will be set to change from `.x` property access to `["x"]`. + */ + includeInsertTextCompletions: boolean; } /** * Completions request; value of command field is "completions". @@ -6196,6 +6315,12 @@ declare namespace ts.server.protocol { * is often the same as the name but may be different in certain circumstances. */ sortText: string; + /** + * Text to insert instead of `name`. + * This is used to support bracketed completions; If `name` might be "a-b" but `insertText` would be `["a-b"]`, + * coupled with `replacementSpan` to replace a dotted access with a bracket access. + */ + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. @@ -6869,6 +6994,7 @@ declare namespace ts.server.protocol { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface CompilerOptions { allowJs?: boolean; @@ -7257,6 +7383,7 @@ declare namespace ts.server { private program; private externalFiles; private missingFilesMap; + private plugins; private cachedUnresolvedImportsPerFile; private lastCachedUnresolvedImportsList; protected languageService: LanguageService; @@ -7372,6 +7499,9 @@ declare namespace ts.server { filesToString(writeProjectFileNames: boolean): string; setCompilerOptions(compilerOptions: CompilerOptions): void; protected removeRoot(info: ScriptInfo): void; + protected enableGlobalPlugins(): void; + protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]): void; + private enableProxy(pluginModuleFactory, configEntry); } /** * If a file is opened and no tsconfig (or jsconfig) is found, @@ -7400,7 +7530,6 @@ declare namespace ts.server { private typeAcquisition; private directoriesWatchedForWildcards; readonly canonicalConfigFilePath: NormalizedPath; - private plugins; /** Ref count to the project when opened from external project */ private externalProjectRefCount; private projectErrors; @@ -7411,8 +7540,6 @@ declare namespace ts.server { updateGraph(): boolean; getConfigFilePath(): NormalizedPath; enablePlugins(): void; - private enablePlugin(pluginConfigEntry, searchPaths); - private enableProxy(pluginModuleFactory, configEntry); /** * Get the errors that dont have any file name associated */ @@ -7424,7 +7551,6 @@ declare namespace ts.server { setProjectErrors(projectErrors: Diagnostic[]): void; setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; getTypeAcquisition(): TypeAcquisition; - getExternalFiles(): SortedReadonlyArray; close(): void; getEffectiveTypeRoots(): string[]; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 0c2bdcd88ee..569ae786ddb 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -59,6 +59,7 @@ declare namespace ts { pos: number; end: number; } + type JsDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.Unknown; enum SyntaxKind { Unknown = 0, EndOfFileToken = 1, @@ -639,7 +640,7 @@ declare namespace ts { body?: Block | Expression; } type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction; - type FunctionLike = FunctionLikeDeclaration | FunctionTypeNode | ConstructorTypeNode | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration; + type FunctionLike = FunctionLikeDeclaration | FunctionTypeNode | ConstructorTypeNode | IndexSignatureDeclaration | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration | JSDocFunctionType; interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement { kind: SyntaxKind.FunctionDeclaration; name?: Identifier; @@ -884,7 +885,7 @@ declare namespace ts { type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment; type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; type BindingOrAssignmentElementRestIndicator = DotDotDotToken | SpreadElement | SpreadAssignment; - type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; type ObjectBindingOrAssignmentPattern = ObjectBindingPattern | ObjectLiteralExpression; type ArrayBindingOrAssignmentPattern = ArrayBindingPattern | ArrayLiteralExpression; type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression; @@ -908,6 +909,7 @@ declare namespace ts { kind: SyntaxKind.ArrowFunction; equalsGreaterThanToken: EqualsGreaterThanToken; body: ConciseBody; + name: never; } interface LiteralLikeNode extends Node { text: string; @@ -1369,6 +1371,7 @@ declare namespace ts { interface ExportDeclaration extends DeclarationStatement { kind: SyntaxKind.ExportDeclaration; parent?: SourceFile | ModuleBlock; + /** Will not be assigned in the case of `export * from "foo";` */ exportClause?: NamedExports; /** If this is not a StringLiteral it will be a grammar error. */ moduleSpecifier?: Expression; @@ -1623,7 +1626,7 @@ declare namespace ts { } interface ParseConfigHost { useCaseSensitiveFileNames: boolean; - readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray, includes: ReadonlyArray, depth: number): string[]; + readDirectory(rootDir: string, extensions: ReadonlyArray, excludes: ReadonlyArray | undefined, includes: ReadonlyArray, depth?: number): string[]; /** * Gets a value indicating whether the specified path exists and is a file. * @param path The path to test. @@ -1734,6 +1737,16 @@ declare namespace ts { signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration; + /** Note that the resulting nodes cannot be checked. */ + symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): EntityName; + /** Note that the resulting nodes cannot be checked. */ + symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): Expression; + /** Note that the resulting nodes cannot be checked. */ + symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): NodeArray | undefined; + /** Note that the resulting nodes cannot be checked. */ + symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): ParameterDeclaration; + /** Note that the resulting nodes cannot be checked. */ + typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeParameterDeclaration; getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol | undefined; getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; @@ -1753,7 +1766,8 @@ declare namespace ts { getTypeFromTypeNode(node: TypeNode): Type; signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; - symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): string; + typePredicateToString(predicate: TypePredicate, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; /** * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead * This will be removed in a future version. @@ -1793,33 +1807,79 @@ declare namespace ts { None = 0, NoTruncation = 1, WriteArrayAsGenericType = 2, + WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, + WriteTypeArgumentsOfSignature = 32, + UseFullyQualifiedType = 64, + UseOnlyExternalAliasing = 128, + SuppressAnyReturnType = 256, + WriteTypeParametersInQualifiedName = 512, + MultilineObjectLiterals = 1024, + WriteClassExpressionAsTypeLiteral = 2048, + UseTypeOfFunction = 4096, + OmitParameterModifiers = 8192, + UseAliasDefinedOutsideCurrentScope = 16384, + AllowThisInObjectLiteral = 32768, + AllowQualifedNameInPlaceOfIdentifier = 65536, + AllowAnonymousIdentifier = 131072, + AllowEmptyUnionOrIntersection = 262144, + AllowEmptyTuple = 524288, + AllowUniqueESSymbolType = 1048576, + AllowEmptyIndexInfoType = 2097152, + IgnoreErrors = 3112960, + InObjectTypeLiteral = 4194304, + InTypeAlias = 8388608, + } + enum TypeFormatFlags { + None = 0, + NoTruncation = 1, + WriteArrayAsGenericType = 2, + WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, SuppressAnyReturnType = 256, - WriteTypeParametersInQualifiedName = 512, - AllowThisInObjectLiteral = 1024, - AllowQualifedNameInPlaceOfIdentifier = 2048, - AllowAnonymousIdentifier = 8192, - AllowEmptyUnionOrIntersection = 16384, - AllowEmptyTuple = 32768, - IgnoreErrors = 60416, - InObjectTypeLiteral = 1048576, + MultilineObjectLiterals = 1024, + WriteClassExpressionAsTypeLiteral = 2048, + UseTypeOfFunction = 4096, + OmitParameterModifiers = 8192, + UseAliasDefinedOutsideCurrentScope = 16384, + AllowUniqueESSymbolType = 1048576, + AddUndefined = 131072, + WriteArrowStyleSignature = 262144, + InArrayType = 524288, + InElementType = 2097152, + InFirstTypeArgument = 4194304, InTypeAlias = 8388608, + /** @deprecated */ WriteOwnNameForAnyLike = 0, + NodeBuilderFlagsMask = 9469295, } + enum SymbolFormatFlags { + None = 0, + WriteTypeParametersOrArguments = 1, + UseOnlyExternalAliasing = 2, + AllowAnyNodeKind = 4, + } + /** + * @deprecated + */ interface SymbolDisplayBuilder { - buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; - buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; - buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; - buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; + /** @deprecated */ buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void; + /** @deprecated */ buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void; + /** @deprecated */ buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForParametersAndDelimiters(thisParameter: Symbol, parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; + /** @deprecated */ buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; } - interface SymbolWriter { + /** + * @deprecated Migrate to other methods of generating symbol names, ex symbolToEntityName + a printer or symbolToString + */ + interface SymbolWriter extends SymbolTracker { writeKeyword(text: string): void; writeOperator(text: string): void; writePunctuation(text: string): void; @@ -1832,34 +1892,6 @@ declare namespace ts { increaseIndent(): void; decreaseIndent(): void; clear(): void; - trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; - reportInaccessibleThisError(): void; - reportPrivateInBaseOfClassExpression(propertyName: string): void; - reportInaccessibleUniqueSymbolError(): void; - } - enum TypeFormatFlags { - None = 0, - WriteArrayAsGenericType = 1, - UseTypeOfFunction = 4, - NoTruncation = 8, - WriteArrowStyleSignature = 16, - WriteOwnNameForAnyLike = 32, - WriteTypeArgumentsOfSignature = 64, - InElementType = 128, - UseFullyQualifiedType = 256, - InFirstTypeArgument = 512, - InTypeAlias = 1024, - SuppressAnyReturnType = 4096, - AddUndefined = 8192, - WriteClassExpressionAsTypeLiteral = 16384, - InArrayType = 32768, - UseAliasDefinedOutsideCurrentScope = 65536, - AllowUniqueESSymbolType = 131072, - } - enum SymbolFormatFlags { - None = 0, - WriteTypeParametersOrArguments = 1, - UseOnlyExternalAliasing = 2, } enum TypePredicateKind { This = 0, @@ -2078,8 +2110,9 @@ declare namespace ts { EvolvingArray = 256, ObjectLiteralPatternWithComputedProperties = 512, ContainsSpread = 1024, - JsxAttributes = 2048, - MarkerType = 4096, + ReverseMapped = 2048, + JsxAttributes = 4096, + MarkerType = 8192, ClassOrInterface = 3, } interface ObjectType extends Type { @@ -2169,15 +2202,14 @@ declare namespace ts { declaration?: SignatureDeclaration; } enum InferencePriority { - Contravariant = 1, - NakedTypeVariable = 2, - MappedType = 4, - ReturnType = 8, - NeverType = 16, + NakedTypeVariable = 1, + MappedType = 2, + ReturnType = 4, } interface InferenceInfo { typeParameter: TypeParameter; candidates: Type[]; + contraCandidates: Type[]; inferredType: Type; priority: InferencePriority; topLevel: boolean; @@ -2318,6 +2350,7 @@ declare namespace ts { types?: string[]; /** Paths used to compute primary types search locations */ typeRoots?: string[]; + esModuleInterop?: boolean; [option: string]: CompilerOptionsValue | JsonSourceFile | undefined; } interface TypeAcquisition { @@ -2491,11 +2524,11 @@ declare namespace ts { getCanonicalFileName(fileName: string): string; useCaseSensitiveFileNames(): boolean; getNewLine(): string; - resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; + resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[]; /** * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files */ - resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; + resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[]; getEnvironmentVariable?(name: string): string; } interface SourceMapRange extends TextRange { @@ -2653,6 +2686,10 @@ declare namespace ts { * collisions. */ printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; + /** + * Prints a list of nodes using the given format flags + */ + printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): string; /** * Prints a source file as-is, without any emit transformations. */ @@ -2708,6 +2745,13 @@ declare namespace ts { interface PrinterOptions { removeComments?: boolean; newLine?: NewLineKind; + omitTrailingSemicolon?: boolean; + } + interface SymbolTracker { + trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; + reportInaccessibleThisError?(): void; + reportPrivateInBaseOfClassExpression?(propertyName: string): void; + reportInaccessibleUniqueSymbolError?(): void; } interface TextSpan { start: number; @@ -2720,6 +2764,71 @@ declare namespace ts { interface SyntaxList extends Node { _children: Node[]; } + enum ListFormat { + None = 0, + SingleLine = 0, + MultiLine = 1, + PreserveLines = 2, + LinesMask = 3, + NotDelimited = 0, + BarDelimited = 4, + AmpersandDelimited = 8, + CommaDelimited = 16, + DelimitersMask = 28, + AllowTrailingComma = 32, + Indented = 64, + SpaceBetweenBraces = 128, + SpaceBetweenSiblings = 256, + Braces = 512, + Parenthesis = 1024, + AngleBrackets = 2048, + SquareBrackets = 4096, + BracketsMask = 7680, + OptionalIfUndefined = 8192, + OptionalIfEmpty = 16384, + Optional = 24576, + PreferNewLine = 32768, + NoTrailingNewLine = 65536, + NoInterveningComments = 131072, + NoSpaceIfEmpty = 262144, + SingleElement = 524288, + Modifiers = 131328, + HeritageClauses = 256, + SingleLineTypeLiteralMembers = 448, + MultiLineTypeLiteralMembers = 65, + TupleTypeElements = 336, + UnionTypeConstituents = 260, + IntersectionTypeConstituents = 264, + ObjectBindingPatternElements = 262576, + ArrayBindingPatternElements = 262448, + ObjectLiteralExpressionProperties = 263122, + ArrayLiteralExpressionElements = 4466, + CommaListElements = 272, + CallExpressionArguments = 1296, + NewExpressionArguments = 9488, + TemplateExpressionSpans = 131072, + SingleLineBlockStatements = 384, + MultiLineBlockStatements = 65, + VariableDeclarationList = 272, + SingleLineFunctionBodyStatements = 384, + MultiLineFunctionBodyStatements = 1, + ClassHeritageClauses = 256, + ClassMembers = 65, + InterfaceMembers = 65, + EnumMembers = 81, + CaseBlockClauses = 65, + NamedImportsOrExportsElements = 432, + JsxElementOrFragmentChildren = 131072, + JsxElementAttributes = 131328, + CaseOrDefaultClauseStatements = 81985, + HeritageClauseTypes = 272, + SourceFileStatements = 65537, + Decorators = 24577, + TypeArguments = 26896, + TypeParameters = 26896, + Parameters = 1296, + IndexSignatureParameters = 4432, + } } declare namespace ts { const versionMajorMinor = "2.7"; @@ -2811,7 +2920,7 @@ declare namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): SyntaxKind; scanJsxToken(): SyntaxKind; - scanJSDocToken(): SyntaxKind; + scanJSDocToken(): JsDocSyntaxKind; scan(): SyntaxKind; getText(): string; setText(text: string, start?: number, length?: number): void; @@ -2831,8 +2940,10 @@ declare namespace ts { function isWhiteSpaceSingleLine(ch: number): boolean; function isLineBreak(ch: number): boolean; function couldStartTrivia(text: string, pos: number): boolean; - function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; - function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined; @@ -2988,7 +3099,7 @@ declare namespace ts { function isStringLiteral(node: Node): node is StringLiteral; function isJsxText(node: Node): node is JsxText; function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral; - function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression; + function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral; function isTemplateHead(node: Node): node is TemplateHead; function isTemplateMiddle(node: Node): node is TemplateMiddle; function isTemplateTail(node: Node): node is TemplateTail; @@ -3181,6 +3292,7 @@ declare namespace ts { function isJSDocCommentContainingNode(node: Node): boolean; function isSetAccessor(node: Node): node is SetAccessorDeclaration; function isGetAccessor(node: Node): node is GetAccessorDeclaration; + function isObjectLiteralElement(node: Node): node is ObjectLiteralElement; } declare namespace ts { function createNode(kind: SyntaxKind, pos?: number, end?: number): Node; @@ -3256,13 +3368,13 @@ declare namespace ts { declare namespace ts { function createNodeArray(elements?: ReadonlyArray, hasTrailingComma?: boolean): NodeArray; /** If a node is passed, creates a string literal whose source text is read from a source node during emit. */ - function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral; + function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral; function createLiteral(value: number): NumericLiteral; function createLiteral(value: boolean): BooleanLiteral; function createLiteral(value: string | number | boolean): PrimaryExpression; function createNumericLiteral(value: string): NumericLiteral; function createIdentifier(text: string): Identifier; - function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; + function updateIdentifier(node: Identifier): Identifier; /** Create a unique temporary variable. */ function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; /** Create a unique temporary variable for use in a loop. */ @@ -3744,7 +3856,7 @@ declare namespace ts { } } declare namespace ts { - function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string; + function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined; function resolveTripleslashReference(moduleName: string, containingFile: string): string; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; @@ -4024,6 +4136,7 @@ declare namespace ts { } interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; + includeInsertTextCompletions: boolean; } interface ApplyCodeActionCommandResult { successMessage: string; @@ -4234,6 +4347,7 @@ declare namespace ts { InsertSpaceBeforeFunctionParenthesis?: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface FormatCodeSettings extends EditorSettings { insertSpaceAfterCommaDelimiter?: boolean; @@ -4251,6 +4365,7 @@ declare namespace ts { insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; + insertSpaceBeforeTypeAnnotation?: boolean; } interface DefinitionInfo { fileName: string; @@ -4366,6 +4481,7 @@ declare namespace ts { kind: ScriptElementKind; kindModifiers: string; sortText: string; + insertText?: string; /** * An optional span that indicates the text to be replaced by this completion item. * If present, this span should be used instead of the default one. @@ -4532,6 +4648,7 @@ declare namespace ts { ambientModifier = "declare", staticModifier = "static", abstractModifier = "abstract", + optionalModifier = "optional", } enum ClassificationTypeNames { comment = "comment", @@ -4677,9 +4794,6 @@ declare namespace ts { declare namespace ts { /** The version of the language service API */ const servicesVersion = "0.7"; - interface DisplayPartsSymbolWriter extends SymbolWriter { - displayParts(): SymbolDisplayPart[]; - } function toEditorSettings(options: EditorOptions | EditorSettings): EditorSettings; function displayPartsToString(displayParts: SymbolDisplayPart[]): string; function getDefaultCompilerOptions(): CompilerOptions; diff --git a/tests/baselines/reference/apparentTypeSubtyping.errors.txt b/tests/baselines/reference/apparentTypeSubtyping.errors.txt index 01fffeb3824..ca2f0765d62 100644 --- a/tests/baselines/reference/apparentTypeSubtyping.errors.txt +++ b/tests/baselines/reference/apparentTypeSubtyping.errors.txt @@ -1,7 +1,6 @@ -tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(9,7): error TS2415: Class 'Derived' incorrectly extends base class 'Base'. - Types of property 'x' are incompatible. - Type 'String' is not assignable to type 'string'. - 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. +tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. + Type 'String' is not assignable to type 'string'. + 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. ==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts (1 errors) ==== @@ -14,12 +13,11 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtypi // is String (S) a subtype of U extends String (T)? Would only be true if we used the apparent type of U (T) class Derived extends Base { // error - ~~~~~~~ -!!! error TS2415: Class 'Derived' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type 'String' is not assignable to type 'string'. -!!! error TS2415: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. x: String; + ~ +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'String' is not assignable to type 'string'. +!!! error TS2416: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. } class Base2 { diff --git a/tests/baselines/reference/apparentTypeSupertype.errors.txt b/tests/baselines/reference/apparentTypeSupertype.errors.txt index c7610a80f2f..a4a8ccc0a8b 100644 --- a/tests/baselines/reference/apparentTypeSupertype.errors.txt +++ b/tests/baselines/reference/apparentTypeSupertype.errors.txt @@ -1,8 +1,7 @@ -tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(9,7): error TS2415: Class 'Derived' incorrectly extends base class 'Base'. - Types of property 'x' are incompatible. - Type 'U' is not assignable to type 'string'. - Type 'String' is not assignable to type 'string'. - 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. +tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(10,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. + Type 'U' is not assignable to type 'string'. + Type 'String' is not assignable to type 'string'. + 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. ==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts (1 errors) ==== @@ -15,11 +14,10 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty // is String (S) a subtype of U extends String (T)? Would only be true if we used the apparent type of U (T) class Derived extends Base { // error - ~~~~~~~ -!!! error TS2415: Class 'Derived' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'string'. -!!! error TS2415: Type 'String' is not assignable to type 'string'. -!!! error TS2415: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. x: U; + ~ +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'U' is not assignable to type 'string'. +!!! error TS2416: Type 'String' is not assignable to type 'string'. +!!! error TS2416: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible. } \ No newline at end of file diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.js b/tests/baselines/reference/asyncAwaitNestedClasses_es5.js new file mode 100644 index 00000000000..ff806b76ff1 --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.js @@ -0,0 +1,52 @@ +//// [asyncAwaitNestedClasses_es5.ts] +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { + static B = class B { + static func2(): Promise { + return new Promise((resolve) => { resolve(null); }); + } + static C = class C { + static async func() { + await B.func2(); + } + } + } +} + +A.B.C.func(); + +//// [asyncAwaitNestedClasses_es5.js] +// https://github.com/Microsoft/TypeScript/issues/20744 +var A = /** @class */ (function () { + function A() { + } + A.B = (_a = /** @class */ (function () { + function B() { + } + B.func2 = function () { + return new Promise(function (resolve) { resolve(null); }); + }; + return B; + }()), + _a.C = /** @class */ (function () { + function C() { + } + C.func = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_b) { + switch (_b.label) { + case 0: return [4 /*yield*/, _a.func2()]; + case 1: + _b.sent(); + return [2 /*return*/]; + } + }); + }); + }; + return C; + }()), + _a); + return A; + var _a; +}()); +A.B.C.func(); diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols b/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols new file mode 100644 index 00000000000..339b2617fbf --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts === +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { +>A : Symbol(A, Decl(asyncAwaitNestedClasses_es5.ts, 0, 0)) + + static B = class B { +>B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>B : Symbol(B, Decl(asyncAwaitNestedClasses_es5.ts, 2, 14)) + + static func2(): Promise { +>func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) +>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + return new Promise((resolve) => { resolve(null); }); +>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>resolve : Symbol(resolve, Decl(asyncAwaitNestedClasses_es5.ts, 4, 32)) +>resolve : Symbol(resolve, Decl(asyncAwaitNestedClasses_es5.ts, 4, 32)) + } + static C = class C { +>C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>C : Symbol(C, Decl(asyncAwaitNestedClasses_es5.ts, 6, 18)) + + static async func() { +>func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) + + await B.func2(); +>B.func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) +>B : Symbol(B, Decl(asyncAwaitNestedClasses_es5.ts, 2, 14)) +>func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) + } + } + } +} + +A.B.C.func(); +>A.B.C.func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) +>A.B.C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>A.B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>A : Symbol(A, Decl(asyncAwaitNestedClasses_es5.ts, 0, 0)) +>B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) + diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.types b/tests/baselines/reference/asyncAwaitNestedClasses_es5.types new file mode 100644 index 00000000000..fd61951d5cc --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.types @@ -0,0 +1,52 @@ +=== tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts === +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { +>A : A + + static B = class B { +>B : typeof B +>class B { static func2(): Promise { return new Promise((resolve) => { resolve(null); }); } static C = class C { static async func() { await B.func2(); } } } : typeof B +>B : typeof B + + static func2(): Promise { +>func2 : () => Promise +>Promise : Promise + + return new Promise((resolve) => { resolve(null); }); +>new Promise((resolve) => { resolve(null); }) : Promise +>Promise : PromiseConstructor +>(resolve) => { resolve(null); } : (resolve: (value?: void | PromiseLike) => void) => void +>resolve : (value?: void | PromiseLike) => void +>resolve(null) : void +>resolve : (value?: void | PromiseLike) => void +>null : null + } + static C = class C { +>C : typeof C +>class C { static async func() { await B.func2(); } } : typeof C +>C : typeof C + + static async func() { +>func : () => Promise + + await B.func2(); +>await B.func2() : void +>B.func2() : Promise +>B.func2 : () => Promise +>B : typeof B +>func2 : () => Promise + } + } + } +} + +A.B.C.func(); +>A.B.C.func() : Promise +>A.B.C.func : () => Promise +>A.B.C : typeof C +>A.B : typeof B +>A : typeof A +>B : typeof B +>C : typeof C +>func : () => Promise + diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt b/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt new file mode 100644 index 00000000000..031fe183754 --- /dev/null +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.errors.txt @@ -0,0 +1,73 @@ +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(8,5): error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'Base'. + Type 'string | Derived' is not assignable to type 'string | Base'. + Type 'Derived' is not assignable to type 'string | Base'. + Type 'Derived' is not assignable to type 'Base'. + Types of property 'n' are incompatible. + Type 'string | Derived' is not assignable to type 'string | Base'. + Type 'Derived' is not assignable to type 'string | Base'. + Type 'Derived' is not assignable to type 'Base'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(9,5): error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type 'Base'. + Type '() => string | number' is not assignable to type '() => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(14,5): error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. + Type 'string | DerivedInterface' is not assignable to type 'string | Base'. + Type 'DerivedInterface' is not assignable to type 'string | Base'. + Type 'DerivedInterface' is not assignable to type 'Base'. + Types of property 'n' are incompatible. + Type 'string | DerivedInterface' is not assignable to type 'string | Base'. + Type 'DerivedInterface' is not assignable to type 'string | Base'. + Type 'DerivedInterface' is not assignable to type 'Base'. +tests/cases/compiler/baseClassImprovedMismatchErrors.ts(15,5): error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. + Type '() => string | number' is not assignable to type '() => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. + + +==== tests/cases/compiler/baseClassImprovedMismatchErrors.ts (4 errors) ==== + class Base { + n: Base | string; + fn() { + return 10; + } + } + class Derived extends Base { + n: Derived | string; + ~ +!!! error TS2416: Property 'n' in type 'Derived' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'string | Derived' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'Derived' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'Derived' is not assignable to type 'Base'. +!!! error TS2416: Types of property 'n' are incompatible. +!!! error TS2416: Type 'string | Derived' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'Derived' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'Derived' is not assignable to type 'Base'. + fn() { + ~~ +!!! error TS2416: Property 'fn' in type 'Derived' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type '() => string | number' is not assignable to type '() => number'. +!!! error TS2416: Type 'string | number' is not assignable to type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. + return 10 as number | string; + } + } + class DerivedInterface implements Base { + n: DerivedInterface | string; + ~ +!!! error TS2416: Property 'n' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'string | DerivedInterface' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'DerivedInterface' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'DerivedInterface' is not assignable to type 'Base'. +!!! error TS2416: Types of property 'n' are incompatible. +!!! error TS2416: Type 'string | DerivedInterface' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'DerivedInterface' is not assignable to type 'string | Base'. +!!! error TS2416: Type 'DerivedInterface' is not assignable to type 'Base'. + fn() { + ~~ +!!! error TS2416: Property 'fn' in type 'DerivedInterface' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type '() => string | number' is not assignable to type '() => number'. +!!! error TS2416: Type 'string | number' is not assignable to type 'number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. + return 10 as number | string; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.js b/tests/baselines/reference/baseClassImprovedMismatchErrors.js new file mode 100644 index 00000000000..296f9e6eb1c --- /dev/null +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.js @@ -0,0 +1,57 @@ +//// [baseClassImprovedMismatchErrors.ts] +class Base { + n: Base | string; + fn() { + return 10; + } +} +class Derived extends Base { + n: Derived | string; + fn() { + return 10 as number | string; + } +} +class DerivedInterface implements Base { + n: DerivedInterface | string; + fn() { + return 10 as number | string; + } +} + +//// [baseClassImprovedMismatchErrors.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var Base = /** @class */ (function () { + function Base() { + } + Base.prototype.fn = function () { + return 10; + }; + return Base; +}()); +var Derived = /** @class */ (function (_super) { + __extends(Derived, _super); + function Derived() { + return _super !== null && _super.apply(this, arguments) || this; + } + Derived.prototype.fn = function () { + return 10; + }; + return Derived; +}(Base)); +var DerivedInterface = /** @class */ (function () { + function DerivedInterface() { + } + DerivedInterface.prototype.fn = function () { + return 10; + }; + return DerivedInterface; +}()); diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.symbols b/tests/baselines/reference/baseClassImprovedMismatchErrors.symbols new file mode 100644 index 00000000000..19ac124a2e0 --- /dev/null +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.symbols @@ -0,0 +1,42 @@ +=== tests/cases/compiler/baseClassImprovedMismatchErrors.ts === +class Base { +>Base : Symbol(Base, Decl(baseClassImprovedMismatchErrors.ts, 0, 0)) + + n: Base | string; +>n : Symbol(Base.n, Decl(baseClassImprovedMismatchErrors.ts, 0, 12)) +>Base : Symbol(Base, Decl(baseClassImprovedMismatchErrors.ts, 0, 0)) + + fn() { +>fn : Symbol(Base.fn, Decl(baseClassImprovedMismatchErrors.ts, 1, 21)) + + return 10; + } +} +class Derived extends Base { +>Derived : Symbol(Derived, Decl(baseClassImprovedMismatchErrors.ts, 5, 1)) +>Base : Symbol(Base, Decl(baseClassImprovedMismatchErrors.ts, 0, 0)) + + n: Derived | string; +>n : Symbol(Derived.n, Decl(baseClassImprovedMismatchErrors.ts, 6, 28)) +>Derived : Symbol(Derived, Decl(baseClassImprovedMismatchErrors.ts, 5, 1)) + + fn() { +>fn : Symbol(Derived.fn, Decl(baseClassImprovedMismatchErrors.ts, 7, 24)) + + return 10 as number | string; + } +} +class DerivedInterface implements Base { +>DerivedInterface : Symbol(DerivedInterface, Decl(baseClassImprovedMismatchErrors.ts, 11, 1)) +>Base : Symbol(Base, Decl(baseClassImprovedMismatchErrors.ts, 0, 0)) + + n: DerivedInterface | string; +>n : Symbol(DerivedInterface.n, Decl(baseClassImprovedMismatchErrors.ts, 12, 40)) +>DerivedInterface : Symbol(DerivedInterface, Decl(baseClassImprovedMismatchErrors.ts, 11, 1)) + + fn() { +>fn : Symbol(DerivedInterface.fn, Decl(baseClassImprovedMismatchErrors.ts, 13, 33)) + + return 10 as number | string; + } +} diff --git a/tests/baselines/reference/baseClassImprovedMismatchErrors.types b/tests/baselines/reference/baseClassImprovedMismatchErrors.types new file mode 100644 index 00000000000..0ca00a02248 --- /dev/null +++ b/tests/baselines/reference/baseClassImprovedMismatchErrors.types @@ -0,0 +1,47 @@ +=== tests/cases/compiler/baseClassImprovedMismatchErrors.ts === +class Base { +>Base : Base + + n: Base | string; +>n : string | Base +>Base : Base + + fn() { +>fn : () => number + + return 10; +>10 : 10 + } +} +class Derived extends Base { +>Derived : Derived +>Base : Base + + n: Derived | string; +>n : string | Derived +>Derived : Derived + + fn() { +>fn : () => string | number + + return 10 as number | string; +>10 as number | string : string | number +>10 : 10 + } +} +class DerivedInterface implements Base { +>DerivedInterface : DerivedInterface +>Base : Base + + n: DerivedInterface | string; +>n : string | DerivedInterface +>DerivedInterface : DerivedInterface + + fn() { +>fn : () => string | number + + return 10 as number | string; +>10 as number | string : string | number +>10 : 10 + } +} diff --git a/tests/baselines/reference/bindingPatternOmittedExpressionNesting.js b/tests/baselines/reference/bindingPatternOmittedExpressionNesting.js index e2dff308879..0a8542ee637 100644 --- a/tests/baselines/reference/bindingPatternOmittedExpressionNesting.js +++ b/tests/baselines/reference/bindingPatternOmittedExpressionNesting.js @@ -9,3 +9,4 @@ var _b, _c, _d, _e; //// [bindingPatternOmittedExpressionNesting.d.ts] +export {}; diff --git a/tests/baselines/reference/classExtensionNameOutput.js b/tests/baselines/reference/classExtensionNameOutput.js new file mode 100644 index 00000000000..8f979863426 --- /dev/null +++ b/tests/baselines/reference/classExtensionNameOutput.js @@ -0,0 +1,38 @@ +//// [classExtensionNameOutput.ts] +class A {} +if (true) { + class B extends A {} + + const foo = function () { + new B(); + } +} + +//// [classExtensionNameOutput.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +if (true) { + var B_1 = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + return B; + }(A)); + var foo = function () { + new B_1(); + }; +} diff --git a/tests/baselines/reference/classExtensionNameOutput.symbols b/tests/baselines/reference/classExtensionNameOutput.symbols new file mode 100644 index 00000000000..7c26d980295 --- /dev/null +++ b/tests/baselines/reference/classExtensionNameOutput.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/classExtensionNameOutput.ts === +class A {} +>A : Symbol(A, Decl(classExtensionNameOutput.ts, 0, 0)) + +if (true) { + class B extends A {} +>B : Symbol(B, Decl(classExtensionNameOutput.ts, 1, 11)) +>A : Symbol(A, Decl(classExtensionNameOutput.ts, 0, 0)) + + const foo = function () { +>foo : Symbol(foo, Decl(classExtensionNameOutput.ts, 4, 7)) + + new B(); +>B : Symbol(B, Decl(classExtensionNameOutput.ts, 1, 11)) + } +} diff --git a/tests/baselines/reference/classExtensionNameOutput.types b/tests/baselines/reference/classExtensionNameOutput.types new file mode 100644 index 00000000000..0bbbb9e2119 --- /dev/null +++ b/tests/baselines/reference/classExtensionNameOutput.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/classExtensionNameOutput.ts === +class A {} +>A : A + +if (true) { +>true : true + + class B extends A {} +>B : B +>A : A + + const foo = function () { +>foo : () => void +>function () { new B(); } : () => void + + new B(); +>new B() : B +>B : typeof B + } +} diff --git a/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt b/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt index 88176d95026..8b84602b807 100644 --- a/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt +++ b/tests/baselines/reference/classIsSubtypeOfBaseType.errors.txt @@ -1,7 +1,6 @@ -tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts(11,7): error TS2415: Class 'Derived2' incorrectly extends base class 'Base<{ bar: string; }>'. - Types of property 'foo' are incompatible. - Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. - Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts(12,5): error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type 'Base<{ bar: string; }>'. + Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. + Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. ==== tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts (1 errors) ==== @@ -16,12 +15,11 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla } class Derived2 extends Base<{ bar: string; }> { - ~~~~~~~~ -!!! error TS2415: Class 'Derived2' incorrectly extends base class 'Base<{ bar: string; }>'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. -!!! error TS2415: Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. foo: { + ~~~ +!!! error TS2416: Property 'foo' in type 'Derived2' is not assignable to the same property in base type 'Base<{ bar: string; }>'. +!!! error TS2416: Type '{ bar?: string; }' is not assignable to type '{ bar: string; }'. +!!! error TS2416: Property 'bar' is optional in type '{ bar?: string; }' but required in type '{ bar: string; }'. bar?: string; // error } } \ No newline at end of file diff --git a/tests/baselines/reference/commentOnParameter1.js b/tests/baselines/reference/commentOnParameter1.js index 10ae2af1264..3e7ba725017 100644 --- a/tests/baselines/reference/commentOnParameter1.js +++ b/tests/baselines/reference/commentOnParameter1.js @@ -11,10 +11,10 @@ b //// [commentOnParameter1.js] function commentedParameters( - /* Parameter a */ - a - /* End of parameter a */ - /* Parameter b */ - , b - /* End of parameter b */ +/* Parameter a */ +a +/* End of parameter a */ +/* Parameter b */ +, b +/* End of parameter b */ ) { } diff --git a/tests/baselines/reference/commentOnParameter2.js b/tests/baselines/reference/commentOnParameter2.js index d0c024a6b3b..236e660abdf 100644 --- a/tests/baselines/reference/commentOnParameter2.js +++ b/tests/baselines/reference/commentOnParameter2.js @@ -10,9 +10,9 @@ b //// [commentOnParameter2.js] function commentedParameters( - /* Parameter a */ - a /* End of parameter a */ - /* Parameter b */ - , b - /* End of parameter b */ +/* Parameter a */ +a /* End of parameter a */ +/* Parameter b */ +, b +/* End of parameter b */ ) { } diff --git a/tests/baselines/reference/commentsExternalModules.js b/tests/baselines/reference/commentsExternalModules.js index 82c6fa53b82..6271c677e65 100644 --- a/tests/baselines/reference/commentsExternalModules.js +++ b/tests/baselines/reference/commentsExternalModules.js @@ -169,3 +169,4 @@ export declare module m4 { function fooExport(): number; } //// [commentsExternalModules_1.d.ts] +export {}; diff --git a/tests/baselines/reference/commentsFunction.js b/tests/baselines/reference/commentsFunction.js index ad31aa47b91..5588a27f5ba 100644 --- a/tests/baselines/reference/commentsFunction.js +++ b/tests/baselines/reference/commentsFunction.js @@ -61,8 +61,8 @@ function foo() { foo(); /** This is comment for function signature*/ function fooWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { +/** this is comment for b*/ +b) { var d = a; } // trailing comment of function fooWithParameters("a", 10); @@ -78,7 +78,7 @@ var lambddaNoVarComment = function (/**param a*/ a, /**param b*/ b) { return a * lambdaFoo(10, 20); lambddaNoVarComment(10, 20); function blah(a /* multiline trailing comment - multiline */) { +multiline */) { } function blah2(a /* single line multiple trailing comments */ /* second */) { } diff --git a/tests/baselines/reference/commonSourceDirectory.js b/tests/baselines/reference/commonSourceDirectory.js index 5569ae6d52b..ca705a5b34e 100644 --- a/tests/baselines/reference/commonSourceDirectory.js +++ b/tests/baselines/reference/commonSourceDirectory.js @@ -28,3 +28,4 @@ foo_1.x + bar_1.y; //// [/app/bin/index.d.ts] /// +export {}; diff --git a/tests/baselines/reference/commonjsSafeImport.js b/tests/baselines/reference/commonjsSafeImport.js index 5eb560f8bb9..3bf05800aa9 100644 --- a/tests/baselines/reference/commonjsSafeImport.js +++ b/tests/baselines/reference/commonjsSafeImport.js @@ -24,3 +24,4 @@ _10_lib_1.Foo(); //// [10_lib.d.ts] export declare function Foo(): void; //// [main.d.ts] +export {}; diff --git a/tests/baselines/reference/constEnum3.js b/tests/baselines/reference/constEnum3.js new file mode 100644 index 00000000000..c219975d10f --- /dev/null +++ b/tests/baselines/reference/constEnum3.js @@ -0,0 +1,20 @@ +//// [constEnum3.ts] +const enum TestType { foo, bar } +type TestTypeStr = keyof typeof TestType; + +function f1(f: TestType) { } +function f2(f: TestTypeStr) { } + +f1(TestType.foo) +f1(TestType.bar) +f2('foo') +f2('bar') + + +//// [constEnum3.js] +function f1(f) { } +function f2(f) { } +f1(0 /* foo */); +f1(1 /* bar */); +f2('foo'); +f2('bar'); diff --git a/tests/baselines/reference/constEnum3.symbols b/tests/baselines/reference/constEnum3.symbols new file mode 100644 index 00000000000..159d866c9a6 --- /dev/null +++ b/tests/baselines/reference/constEnum3.symbols @@ -0,0 +1,38 @@ +=== tests/cases/conformance/constEnums/constEnum3.ts === +const enum TestType { foo, bar } +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) +>bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) + +type TestTypeStr = keyof typeof TestType; +>TestTypeStr : Symbol(TestTypeStr, Decl(constEnum3.ts, 0, 32)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) + +function f1(f: TestType) { } +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>f : Symbol(f, Decl(constEnum3.ts, 3, 12)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) + +function f2(f: TestTypeStr) { } +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) +>f : Symbol(f, Decl(constEnum3.ts, 4, 12)) +>TestTypeStr : Symbol(TestTypeStr, Decl(constEnum3.ts, 0, 32)) + +f1(TestType.foo) +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>TestType.foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>foo : Symbol(TestType.foo, Decl(constEnum3.ts, 0, 21)) + +f1(TestType.bar) +>f1 : Symbol(f1, Decl(constEnum3.ts, 1, 41)) +>TestType.bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) +>TestType : Symbol(TestType, Decl(constEnum3.ts, 0, 0)) +>bar : Symbol(TestType.bar, Decl(constEnum3.ts, 0, 26)) + +f2('foo') +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) + +f2('bar') +>f2 : Symbol(f2, Decl(constEnum3.ts, 3, 28)) + diff --git a/tests/baselines/reference/constEnum3.types b/tests/baselines/reference/constEnum3.types new file mode 100644 index 00000000000..fd14b87e0da --- /dev/null +++ b/tests/baselines/reference/constEnum3.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/constEnums/constEnum3.ts === +const enum TestType { foo, bar } +>TestType : TestType +>foo : TestType.foo +>bar : TestType.bar + +type TestTypeStr = keyof typeof TestType; +>TestTypeStr : "foo" | "bar" +>TestType : typeof TestType + +function f1(f: TestType) { } +>f1 : (f: TestType) => void +>f : TestType +>TestType : TestType + +function f2(f: TestTypeStr) { } +>f2 : (f: "foo" | "bar") => void +>f : "foo" | "bar" +>TestTypeStr : "foo" | "bar" + +f1(TestType.foo) +>f1(TestType.foo) : void +>f1 : (f: TestType) => void +>TestType.foo : TestType.foo +>TestType : typeof TestType +>foo : TestType.foo + +f1(TestType.bar) +>f1(TestType.bar) : void +>f1 : (f: TestType) => void +>TestType.bar : TestType.bar +>TestType : typeof TestType +>bar : TestType.bar + +f2('foo') +>f2('foo') : void +>f2 : (f: "foo" | "bar") => void +>'foo' : "foo" + +f2('bar') +>f2('bar') : void +>f2 : (f: "foo" | "bar") => void +>'bar' : "bar" + diff --git a/tests/baselines/reference/constEnumErrors.errors.txt b/tests/baselines/reference/constEnumErrors.errors.txt index 586652d41eb..c2642c9b1ac 100644 --- a/tests/baselines/reference/constEnumErrors.errors.txt +++ b/tests/baselines/reference/constEnumErrors.errors.txt @@ -5,9 +5,9 @@ tests/cases/compiler/constEnumErrors.ts(14,9): error TS2474: In 'const' enum dec 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. tests/cases/compiler/constEnumErrors.ts(24,13): error TS2476: A const enum member can only be accessed using a string literal. -tests/cases/compiler/constEnumErrors.ts(26,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. -tests/cases/compiler/constEnumErrors.ts(27,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. -tests/cases/compiler/constEnumErrors.ts(32,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +tests/cases/compiler/constEnumErrors.ts(26,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +tests/cases/compiler/constEnumErrors.ts(27,10): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. +tests/cases/compiler/constEnumErrors.ts(32,5): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. tests/cases/compiler/constEnumErrors.ts(40,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. tests/cases/compiler/constEnumErrors.ts(41,9): error TS2477: 'const' enum member initializer was evaluated to a non-finite value. tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member initializer was evaluated to disallowed value 'NaN'. @@ -55,17 +55,17 @@ tests/cases/compiler/constEnumErrors.ts(42,9): error TS2478: 'const' enum member var x = E2; ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. var y = [E2]; ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. function foo(t: any): void { } foo(E2); ~~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. const enum NaNOrInfinity { A = 9007199254740992, diff --git a/tests/baselines/reference/constEnumPropertyAccess2.errors.txt b/tests/baselines/reference/constEnumPropertyAccess2.errors.txt index aa08c11c7a2..40731d3ad54 100644 --- a/tests/baselines/reference/constEnumPropertyAccess2.errors.txt +++ b/tests/baselines/reference/constEnumPropertyAccess2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(13,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(13,9): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(14,12): error TS2476: A const enum member can only be accessed using a string literal. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(16,1): error TS2322: Type '"string"' is not assignable to type 'G'. tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(18,3): error TS2540: Cannot assign to 'B' because it is a constant or a read-only property. @@ -19,7 +19,7 @@ tests/cases/conformance/constEnums/constEnumPropertyAccess2.ts(18,3): error TS25 // Error from referring constant enum in any other context than a property access var z = G; ~ -!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment. +!!! error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. var z1 = G[G.A]; ~~~ !!! error TS2476: A const enum member can only be accessed using a string literal. diff --git a/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.js b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.js new file mode 100644 index 00000000000..1f507791802 --- /dev/null +++ b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.js @@ -0,0 +1,7 @@ +//// [contextualSignature_objectLiteralMethodMayReturnNever.ts] +interface I { m(): number; } +const o: I = { m() { throw new Error("not implemented"); } }; + + +//// [contextualSignature_objectLiteralMethodMayReturnNever.js] +var o = { m: function () { throw new Error("not implemented"); } }; diff --git a/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.symbols b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.symbols new file mode 100644 index 00000000000..dd58d4d35ed --- /dev/null +++ b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts === +interface I { m(): number; } +>I : Symbol(I, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 0, 0)) +>m : Symbol(I.m, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 0, 13)) + +const o: I = { m() { throw new Error("not implemented"); } }; +>o : Symbol(o, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 1, 5)) +>I : Symbol(I, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 0, 0)) +>m : Symbol(m, Decl(contextualSignature_objectLiteralMethodMayReturnNever.ts, 1, 14)) +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.types b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.types new file mode 100644 index 00000000000..aa1da8edcfc --- /dev/null +++ b/tests/baselines/reference/contextualSignature_objectLiteralMethodMayReturnNever.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts === +interface I { m(): number; } +>I : I +>m : () => number + +const o: I = { m() { throw new Error("not implemented"); } }; +>o : I +>I : I +>{ m() { throw new Error("not implemented"); } } : { m(): never; } +>m : () => never +>new Error("not implemented") : Error +>Error : ErrorConstructor +>"not implemented" : "not implemented" + diff --git a/tests/baselines/reference/controlFlowWithTemplateLiterals.js b/tests/baselines/reference/controlFlowWithTemplateLiterals.js new file mode 100644 index 00000000000..b640848f5ec --- /dev/null +++ b/tests/baselines/reference/controlFlowWithTemplateLiterals.js @@ -0,0 +1,19 @@ +//// [controlFlowWithTemplateLiterals.ts] +declare const envVar: string | undefined; +if (typeof envVar === `string`) { + envVar.slice(0) +} + +declare const obj: {test: string} | {} +if (`test` in obj) { + obj.test.slice(0) +} + + +//// [controlFlowWithTemplateLiterals.js] +if (typeof envVar === "string") { + envVar.slice(0); +} +if ("test" in obj) { + obj.test.slice(0); +} diff --git a/tests/baselines/reference/controlFlowWithTemplateLiterals.symbols b/tests/baselines/reference/controlFlowWithTemplateLiterals.symbols new file mode 100644 index 00000000000..978a0e507e0 --- /dev/null +++ b/tests/baselines/reference/controlFlowWithTemplateLiterals.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts === +declare const envVar: string | undefined; +>envVar : Symbol(envVar, Decl(controlFlowWithTemplateLiterals.ts, 0, 13)) + +if (typeof envVar === `string`) { +>envVar : Symbol(envVar, Decl(controlFlowWithTemplateLiterals.ts, 0, 13)) + + envVar.slice(0) +>envVar.slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +>envVar : Symbol(envVar, Decl(controlFlowWithTemplateLiterals.ts, 0, 13)) +>slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +} + +declare const obj: {test: string} | {} +>obj : Symbol(obj, Decl(controlFlowWithTemplateLiterals.ts, 5, 13)) +>test : Symbol(test, Decl(controlFlowWithTemplateLiterals.ts, 5, 20)) + +if (`test` in obj) { +>obj : Symbol(obj, Decl(controlFlowWithTemplateLiterals.ts, 5, 13)) + + obj.test.slice(0) +>obj.test.slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +>obj.test : Symbol(test, Decl(controlFlowWithTemplateLiterals.ts, 5, 20)) +>obj : Symbol(obj, Decl(controlFlowWithTemplateLiterals.ts, 5, 13)) +>test : Symbol(test, Decl(controlFlowWithTemplateLiterals.ts, 5, 20)) +>slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/controlFlowWithTemplateLiterals.types b/tests/baselines/reference/controlFlowWithTemplateLiterals.types new file mode 100644 index 00000000000..7775d26fe38 --- /dev/null +++ b/tests/baselines/reference/controlFlowWithTemplateLiterals.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts === +declare const envVar: string | undefined; +>envVar : string | undefined + +if (typeof envVar === `string`) { +>typeof envVar === `string` : boolean +>typeof envVar : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>envVar : string | undefined +>`string` : "string" + + envVar.slice(0) +>envVar.slice(0) : string +>envVar.slice : (start?: number | undefined, end?: number | undefined) => string +>envVar : string +>slice : (start?: number | undefined, end?: number | undefined) => string +>0 : 0 +} + +declare const obj: {test: string} | {} +>obj : {} | { test: string; } +>test : string + +if (`test` in obj) { +>`test` in obj : boolean +>`test` : "test" +>obj : {} | { test: string; } + + obj.test.slice(0) +>obj.test.slice(0) : string +>obj.test.slice : (start?: number | undefined, end?: number | undefined) => string +>obj.test : string +>obj : { test: string; } +>test : string +>slice : (start?: number | undefined, end?: number | undefined) => string +>0 : 0 +} + diff --git a/tests/baselines/reference/declFileConstructors.js b/tests/baselines/reference/declFileConstructors.js index 9f5fc12e002..f40ae2d5382 100644 --- a/tests/baselines/reference/declFileConstructors.js +++ b/tests/baselines/reference/declFileConstructors.js @@ -109,8 +109,8 @@ exports.SimpleConstructor = SimpleConstructor; var ConstructorWithParameters = /** @class */ (function () { /** This is comment for function signature*/ function ConstructorWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; } return ConstructorWithParameters; @@ -172,8 +172,8 @@ var GlobalSimpleConstructor = /** @class */ (function () { var GlobalConstructorWithParameters = /** @class */ (function () { /** This is comment for function signature*/ function GlobalConstructorWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; } return GlobalConstructorWithParameters; diff --git a/tests/baselines/reference/declFileFunctions.js b/tests/baselines/reference/declFileFunctions.js index 68ac66200a6..3e5c8af32ec 100644 --- a/tests/baselines/reference/declFileFunctions.js +++ b/tests/baselines/reference/declFileFunctions.js @@ -85,8 +85,8 @@ function foo() { exports.foo = foo; /** This is comment for function signature*/ function fooWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { +/** this is comment for b*/ +b) { var d = a; } exports.fooWithParameters = fooWithParameters; @@ -131,8 +131,8 @@ function nonExportedFoo() { } /** This is comment for function signature*/ function nonExportedFooWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { +/** this is comment for b*/ +b) { var d = a; } function nonExportedFooWithRestParameters(a) { @@ -151,8 +151,8 @@ function globalfoo() { } /** This is comment for function signature*/ function globalfooWithParameters(/** this is comment about a*/ a, - /** this is comment for b*/ - b) { +/** this is comment for b*/ +b) { var d = a; } function globalfooWithRestParameters(a) { diff --git a/tests/baselines/reference/declFileMethods.js b/tests/baselines/reference/declFileMethods.js index 78af9adcd98..a70dde6c3ee 100644 --- a/tests/baselines/reference/declFileMethods.js +++ b/tests/baselines/reference/declFileMethods.js @@ -200,8 +200,8 @@ var c1 = /** @class */ (function () { }; /** This is comment for function signature*/ c1.prototype.fooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c1.prototype.fooWithRestParameters = function (a) { @@ -219,8 +219,8 @@ var c1 = /** @class */ (function () { }; /** This is comment for function signature*/ c1.prototype.privateFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c1.prototype.privateFooWithRestParameters = function (a) { @@ -238,8 +238,8 @@ var c1 = /** @class */ (function () { }; /** This is comment for function signature*/ c1.staticFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c1.staticFooWithRestParameters = function (a) { @@ -257,8 +257,8 @@ var c1 = /** @class */ (function () { }; /** This is comment for function signature*/ c1.privateStaticFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c1.privateStaticFooWithRestParameters = function (a) { @@ -283,8 +283,8 @@ var c2 = /** @class */ (function () { }; /** This is comment for function signature*/ c2.prototype.fooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c2.prototype.fooWithRestParameters = function (a) { @@ -302,8 +302,8 @@ var c2 = /** @class */ (function () { }; /** This is comment for function signature*/ c2.prototype.privateFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c2.prototype.privateFooWithRestParameters = function (a) { @@ -321,8 +321,8 @@ var c2 = /** @class */ (function () { }; /** This is comment for function signature*/ c2.staticFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c2.staticFooWithRestParameters = function (a) { @@ -340,8 +340,8 @@ var c2 = /** @class */ (function () { }; /** This is comment for function signature*/ c2.privateStaticFooWithParameters = function (/** this is comment about a*/ a, - /** this is comment for b*/ - b) { + /** this is comment for b*/ + b) { var d = a; }; c2.privateStaticFooWithRestParameters = function (a) { diff --git a/tests/baselines/reference/declarationEmitBindingPatterns.js b/tests/baselines/reference/declarationEmitBindingPatterns.js index 800e30032c6..70ac7f437d3 100644 --- a/tests/baselines/reference/declarationEmitBindingPatterns.js +++ b/tests/baselines/reference/declarationEmitBindingPatterns.js @@ -18,7 +18,7 @@ function f(_a, _b, _c) { //// [declarationEmitBindingPatterns.d.ts] -declare const k: ({x: z}: { +declare const k: ({ x: z }: { x?: string; }) => void; declare var a: any; diff --git a/tests/baselines/reference/declarationEmitDestructuring2.js b/tests/baselines/reference/declarationEmitDestructuring2.js index 09980c5c9dd..c979b654960 100644 --- a/tests/baselines/reference/declarationEmitDestructuring2.js +++ b/tests/baselines/reference/declarationEmitDestructuring2.js @@ -26,18 +26,18 @@ declare function f({x, y: [a, b, c, d]}?: { }): void; declare function g([a, b, c, d]?: [number, number, number, number]): void; declare function h([a, [b], [[c]], {x, y: [a, b, c], z: {a1, b1}}]: [any, [any], [[any]], { - x?: number; - y: [any, any, any]; - z: { - a1: any; - b1: any; - }; -}]): void; + x?: number; + y: [any, any, any]; + z: { + a1: any; + b1: any; + }; + }]): void; declare function h1([a, [b], [[c]], {x, y, z: {a1, b1}}]: [any, [any], [[any]], { - x?: number; - y?: number[]; - z: { - a1: any; - b1: any; - }; -}]): void; + x?: number; + y?: number[]; + z: { + a1: any; + b1: any; + }; + }]): void; diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types index 45f76b94b51..807bb154935 100644 --- a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.types @@ -23,7 +23,7 @@ var [a11, b11, c11] = []; >a11 : any >b11 : any >c11 : any ->[] : [any, any, any] +>[] : [undefined, undefined, undefined] var [a2, [b2, { x12, y12: c2 }]=["abc", { x12: 10, y12: false }]] = [1, ["hello", { x12: 5, y12: true }]]; >a2 : number diff --git a/tests/baselines/reference/declarationEmitIndexTypeArray.js b/tests/baselines/reference/declarationEmitIndexTypeArray.js index a84080fb5c4..9fe8878a8db 100644 --- a/tests/baselines/reference/declarationEmitIndexTypeArray.js +++ b/tests/baselines/reference/declarationEmitIndexTypeArray.js @@ -21,5 +21,5 @@ var utilityFunctions = { //// [declarationEmitIndexTypeArray.d.ts] declare function doSomethingWithKeys(...keys: (keyof T)[]): void; declare const utilityFunctions: { - doSomethingWithKeys: (...keys: (keyof T)[]) => void; + doSomethingWithKeys: typeof doSomethingWithKeys; }; diff --git a/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols b/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols index 195f10a78a1..898a9883781 100644 --- a/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols +++ b/tests/baselines/reference/declarationEmitTypeofDefaultExport.symbols @@ -7,7 +7,7 @@ import * as a from "./a"; >a : Symbol(a, Decl(b.ts, 0, 6)) export default a.default; ->a.default : Symbol(a.default, Decl(a.ts, 0, 0)) +>a.default : Symbol(a.C, Decl(a.ts, 0, 0)) >a : Symbol(a, Decl(b.ts, 0, 6)) ->default : Symbol(a.default, Decl(a.ts, 0, 0)) +>default : Symbol(a.C, Decl(a.ts, 0, 0)) diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js new file mode 100644 index 00000000000..6faa0bfca60 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js @@ -0,0 +1,26 @@ +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.ts] +namespace foo { + function bar(): void {} + + export const obj = { + bar + } +} + + +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.js] +var foo; +(function (foo) { + function bar() { } + foo.obj = { + bar: bar + }; +})(foo || (foo = {})); + + +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.d.ts] +declare namespace foo { + const obj: { + bar: () => void; + }; +} diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols new file mode 100644 index 00000000000..74ce59284e0 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts === +namespace foo { +>foo : Symbol(foo, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 0, 0)) + + function bar(): void {} +>bar : Symbol(bar, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 0, 15)) + + export const obj = { +>obj : Symbol(obj, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 3, 16)) + + bar +>bar : Symbol(bar, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 3, 24)) + } +} + diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types new file mode 100644 index 00000000000..e86ead184c9 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts === +namespace foo { +>foo : typeof foo + + function bar(): void {} +>bar : () => void + + export const obj = { +>obj : { bar: () => void; } +>{ bar } : { bar: () => void; } + + bar +>bar : () => void + } +} + diff --git a/tests/baselines/reference/declarationsAndAssignments.types b/tests/baselines/reference/declarationsAndAssignments.types index b49868c4750..6bd5b8da7cb 100644 --- a/tests/baselines/reference/declarationsAndAssignments.types +++ b/tests/baselines/reference/declarationsAndAssignments.types @@ -24,7 +24,7 @@ function f0() { >x : number >y : string >z : any ->[1, "hello"] : [number, string, any] +>[1, "hello"] : [number, string, undefined] >1 : 1 >"hello" : "hello" @@ -258,13 +258,13 @@ function f8() { >a : any >b : any >c : any ->[] : [any, any, any] +>[] : [undefined, undefined, undefined] var [d, e, f] = [1]; // Error, [1] is a tuple >d : number >e : any >f : any ->[1] : [number, any, any] +>[1] : [number, undefined, undefined] >1 : 1 } diff --git a/tests/baselines/reference/decoratorOnClassMethod12.js b/tests/baselines/reference/decoratorOnClassMethod12.js index 0063e0225bc..494cb083a20 100644 --- a/tests/baselines/reference/decoratorOnClassMethod12.js +++ b/tests/baselines/reference/decoratorOnClassMethod12.js @@ -28,7 +28,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, }; var M; (function (M) { - var _this = this; var S = /** @class */ (function () { function S() { } diff --git a/tests/baselines/reference/deferredLookupTypeResolution.js b/tests/baselines/reference/deferredLookupTypeResolution.js index 5f8edd63e57..e5baa6891e8 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution.js +++ b/tests/baselines/reference/deferredLookupTypeResolution.js @@ -54,9 +54,7 @@ declare type T2 = ObjectHasKey<{ declare function f1(a: A, b: B): { [P in A | B]: any; }; -declare function f2(a: A): { - [P in A | "x"]: any; -}; +declare function f2(a: A): { [P in A | "x"]: any; }; declare function f3(x: 'a' | 'b'): { a: any; b: any; diff --git a/tests/baselines/reference/deferredLookupTypeResolution.types b/tests/baselines/reference/deferredLookupTypeResolution.types index d9486d30b07..cd123a6019e 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution.types +++ b/tests/baselines/reference/deferredLookupTypeResolution.types @@ -17,7 +17,7 @@ type StringContains = ( >L : L type ObjectHasKey = StringContains ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >O : O >L : L >StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] @@ -25,19 +25,19 @@ type ObjectHasKey = StringContains >L : L type First = ObjectHasKey; // Should be deferred ->First : ({ [K in S]: "true"; } & { [key: string]: "false"; })["0"] +>First : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] >T : T ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >T : T type T1 = ObjectHasKey<{ a: string }, 'a'>; // 'true' >T1 : "true" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >a : string type T2 = ObjectHasKey<{ a: string }, 'b'>; // 'false' >T2 : "false" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >a : string // Verify that mapped type isn't eagerly resolved in type-to-string operation @@ -55,13 +55,13 @@ declare function f1(a: A, b: B): { [P in A | >B : B function f2(a: A) { ->f2 : (a: A) => { [P in A | B]: any; } +>f2 : (a: A) => { [P in A | "x"]: any; } >A : A >a : A >A : A return f1(a, 'x'); ->f1(a, 'x') : { [P in A | B]: any; } +>f1(a, 'x') : { [P in A | "x"]: any; } >f1 : (a: A, b: B) => { [P in A | B]: any; } >a : A >'x' : "x" @@ -73,7 +73,7 @@ function f3(x: 'a' | 'b') { return f2(x); >f2(x) : { a: any; b: any; x: any; } ->f2 : (a: A) => { [P in A | B]: any; } +>f2 : (a: A) => { [P in A | "x"]: any; } >x : "a" | "b" } diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt b/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt index f6bbe72f1a6..6d1d579c0ad 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt +++ b/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/deferredLookupTypeResolution2.ts(14,13): error TS2536: Type '({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. -tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. +tests/cases/compiler/deferredLookupTypeResolution2.ts(14,13): error TS2536: Type '({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. +tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. ==== tests/cases/compiler/deferredLookupTypeResolution2.ts (2 errors) ==== @@ -18,14 +18,14 @@ tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type // Error, "false" not handled type E = { true: 'true' }[ObjectHasKey]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2536: Type '({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. +!!! error TS2536: Type '({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. type Juxtapose = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey]; // Error, "otherwise" is missing type DeepError = { true: 'true' }[Juxtapose]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. +!!! error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. type DeepOK = { true: 'true', otherwise: 'false' }[Juxtapose]; \ No newline at end of file diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.types b/tests/baselines/reference/deferredLookupTypeResolution2.types index 25b3ceff934..76354731097 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution2.types +++ b/tests/baselines/reference/deferredLookupTypeResolution2.types @@ -11,7 +11,7 @@ type StringContains = ({ [K in S]: 'true' } >L : L type ObjectHasKey = StringContains; ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >O : O >L : L >StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] @@ -19,52 +19,52 @@ type ObjectHasKey = StringContains; >L : L type A = ObjectHasKey; ->A : ({ [K in S]: "true"; } & { [key: string]: "false"; })["0"] +>A : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] >T : T ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >T : T type B = ObjectHasKey<[string, number], '1'>; // "true" >B : "true" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] type C = ObjectHasKey<[string, number], '2'>; // "false" >C : "false" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] type D = A<[string]>; // "true" >D : "true" ->A : ({ [K in S]: "true"; } & { [key: string]: "false"; })["0"] +>A : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] // Error, "false" not handled type E = { true: 'true' }[ObjectHasKey]; ->E : { true: "true"; }[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]] +>E : { true: "true"; }[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] >T : T >true : "true" ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >T : T type Juxtapose = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey]; ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] >T : T >true : "otherwise" >k : string ->ObjectHasKey : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] >T : T // Error, "otherwise" is missing type DeepError = { true: 'true' }[Juxtapose]; ->DeepError : { true: "true"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]]] +>DeepError : { true: "true"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]] >T : T >true : "true" ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] >T : T type DeepOK = { true: 'true', otherwise: 'false' }[Juxtapose]; ->DeepOK : { true: "true"; otherwise: "false"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]]] +>DeepOK : { true: "true"; otherwise: "false"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]] >T : T >true : "true" >otherwise : "false" ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in S]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] >T : T diff --git a/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt b/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt index f8e237a83ce..fa8c7f2bc7a 100644 --- a/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt +++ b/tests/baselines/reference/derivedClassFunctionOverridesBaseClassAccessor.errors.txt @@ -1,8 +1,7 @@ tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(2,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(5,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(10,7): error TS2415: Class 'Derived' incorrectly extends base class 'Base'. - Types of property 'x' are incompatible. - Type '() => number' is not assignable to type 'number'. +tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. + Type '() => number' is not assignable to type 'number'. tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFunctionOverridesBaseClassAccessor.ts(11,5): error TS2426: Class 'Base' defines instance member accessor 'x', but extended class 'Derived' defines it as instance member function. @@ -21,12 +20,11 @@ tests/cases/conformance/classes/members/inheritanceAndOverriding/derivedClassFun // error class Derived extends Base { - ~~~~~~~ -!!! error TS2415: Class 'Derived' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type '() => number' is not assignable to type 'number'. x() { ~ +!!! error TS2416: Property 'x' in type 'Derived' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type '() => number' is not assignable to type 'number'. + ~ !!! error TS2426: Class 'Base' defines instance member accessor 'x', but extended class 'Derived' defines it as instance member function. return 1; } diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types index e42d08bbebc..bddce3cc391 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.types @@ -93,18 +93,18 @@ var [c0, c1] = [...temp]; var [c2] = []; >c2 : any ->[] : [any] +>[] : [undefined] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] >c3 : any >c4 : any ->[[[]], [[[[]]]]] : [[[any]], [[[[any]]]]] ->[[]] : [[any]] ->[] : [any] ->[[[[]]]] : [[[[any]]]] ->[[[]]] : [[[any]]] ->[[]] : [[any]] ->[] : [any] +>[[[]], [[[[]]]]] : [[[undefined]], [[[[undefined]]]]] +>[[]] : [[undefined]] +>[] : [undefined] +>[[[[]]]] : [[[[undefined]]]] +>[[[]]] : [[[undefined]]] +>[[]] : [[undefined]] +>[] : [undefined] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types index 68b6565b004..e17e37f4980 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.types @@ -93,18 +93,18 @@ var [c0, c1] = [...temp]; var [c2] = []; >c2 : any ->[] : [any] +>[] : [undefined] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] >c3 : any >c4 : any ->[[[]], [[[[]]]]] : [[[any]], [[[[any]]]]] ->[[]] : [[any]] ->[] : [any] ->[[[[]]]] : [[[[any]]]] ->[[[]]] : [[[any]]] ->[[]] : [[any]] ->[] : [any] +>[[[]], [[[[]]]]] : [[[undefined]], [[[[undefined]]]]] +>[[]] : [[undefined]] +>[] : [undefined] +>[[[[]]]] : [[[[undefined]]]] +>[[[]]] : [[[undefined]]] +>[[]] : [[undefined]] +>[] : [undefined] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types index 8bde2455171..0c6b87eb46a 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.types @@ -93,18 +93,18 @@ var [c0, c1] = [...temp]; var [c2] = []; >c2 : any ->[] : [any] +>[] : [undefined] var [[[c3]], [[[[c4]]]]] = [[[]], [[[[]]]]] >c3 : any >c4 : any ->[[[]], [[[[]]]]] : [[[any]], [[[[any]]]]] ->[[]] : [[any]] ->[] : [any] ->[[[[]]]] : [[[[any]]]] ->[[[]]] : [[[any]]] ->[[]] : [[any]] ->[] : [any] +>[[[]], [[[[]]]]] : [[[undefined]], [[[[undefined]]]]] +>[[]] : [[undefined]] +>[] : [undefined] +>[[[[]]]] : [[[[undefined]]]] +>[[[]]] : [[[undefined]]] +>[[]] : [[undefined]] +>[] : [undefined] var [[c5], c6]: [[string|number], boolean] = [[1], true]; >c5 : string | number diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt index 610167a1bc0..848093e1161 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt @@ -1,4 +1,6 @@ +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2461: Type 'undefined' is not an array type. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2461: Type 'undefined' is not an array type. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(4,5): error TS2461: Type 'undefined' is not an array type. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(9,5): error TS2322: Type '[number, number, string]' is not assignable to type '[number, boolean, string]'. @@ -10,13 +12,17 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(34,5): error TS2461: Type 'F' is not an array type. -==== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts (7 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts (9 errors) ==== // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is the type Any, or var [[a0], [[a1]]] = [] // Error ~~~~ +!!! error TS2461: Type 'undefined' is not an array type. + ~~~~ !!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. ~~~~~~ +!!! error TS2461: Type 'undefined' is not an array type. + ~~~~~~ !!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value. var [[a2], [[a3]]] = undefined // Error ~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types index dc76e8a4a8a..9c29ea1a423 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.types @@ -4,7 +4,7 @@ var [[a0], [[a1]]] = [] // Error >a0 : any >a1 : any ->[] : [any, any] +>[] : [undefined, undefined] var [[a2], [[a3]]] = undefined // Error >a2 : any diff --git a/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.js b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.js new file mode 100644 index 00000000000..52bac6e2391 --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.js @@ -0,0 +1,17 @@ +//// [destructuringAssignmentWithStrictNullChecks.ts] +let bar: {}; +({ ...bar } = {}); + + +//// [destructuringAssignmentWithStrictNullChecks.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var bar; +(bar = __rest({}, [])); diff --git a/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.symbols b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.symbols new file mode 100644 index 00000000000..b241c29c9ae --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.symbols @@ -0,0 +1,7 @@ +=== tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts === +let bar: {}; +>bar : Symbol(bar, Decl(destructuringAssignmentWithStrictNullChecks.ts, 0, 3)) + +({ ...bar } = {}); +>bar : Symbol(bar, Decl(destructuringAssignmentWithStrictNullChecks.ts, 0, 3)) + diff --git a/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.types b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.types new file mode 100644 index 00000000000..375ddf82a59 --- /dev/null +++ b/tests/baselines/reference/destructuringAssignmentWithStrictNullChecks.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts === +let bar: {}; +>bar : {} + +({ ...bar } = {}); +>({ ...bar } = {}) : {} +>{ ...bar } = {} : {} +>{ ...bar } : {} +>bar : {} +>{} : {} + diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index 96b93423660..46a816af349 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -34,13 +34,12 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(46,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(47,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(55,7): error TS2420: Class 'C4' incorrectly implements interface 'F2'. - Types of property 'd4' are incompatible. - Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. - Types of parameters '__0' and '__0' are incompatible. - Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. - Property 'c' is missing in type '{ x: any; y: any; z: any; }'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(56,8): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(57,5): error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type 'F2'. + Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. + Types of parameters '__0' and '__0' are incompatible. + Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. + Property 'c' is missing in type '{ x: any; y: any; z: any; }'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,18): error TS2300: Duplicate identifier 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,26): error TS2300: Duplicate identifier 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(65,34): error TS2300: Duplicate identifier 'number'. @@ -155,17 +154,16 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( } class C4 implements F2 { - ~~ -!!! error TS2420: Class 'C4' incorrectly implements interface 'F2'. -!!! error TS2420: Types of property 'd4' are incompatible. -!!! error TS2420: Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. -!!! error TS2420: Types of parameters '__0' and '__0' are incompatible. -!!! error TS2420: Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. -!!! error TS2420: Property 'c' is missing in type '{ x: any; y: any; z: any; }'. d3([a, b, c]?) { } // Error, binding pattern can't be optional in implementation signature ~~~~~~~~~~ !!! error TS2463: A binding pattern parameter cannot be optional in an implementation signature. d4({x, y, c}) { } + ~~ +!!! error TS2416: Property 'd4' in type 'C4' is not assignable to the same property in base type 'F2'. +!!! error TS2416: Type '({ x, y, c }: { x: any; y: any; c: any; }) => void' is not assignable to type '({ x, y, z }?: { x: any; y: any; z: any; }) => any'. +!!! error TS2416: Types of parameters '__0' and '__0' are incompatible. +!!! error TS2416: Type '{ x: any; y: any; z: any; }' is not assignable to type '{ x: any; y: any; c: any; }'. +!!! error TS2416: Property 'c' is missing in type '{ x: any; y: any; z: any; }'. e0([a, b, q]) { } } diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.js b/tests/baselines/reference/destructuringReassignsRightHandSide.js new file mode 100644 index 00000000000..b893202aa1e --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.js @@ -0,0 +1,18 @@ +//// [destructuringReassignsRightHandSide.ts] +var foo: any = { foo: 1, bar: 2 }; +var bar: any; + +// reassignment in destructuring pattern +({ foo, bar } = foo); + +// reassignment in subsequent var +var { foo, baz } = foo; + +//// [destructuringReassignsRightHandSide.js] +var foo = { foo: 1, bar: 2 }; +var bar; +// reassignment in destructuring pattern +(_a = foo, foo = _a.foo, bar = _a.bar); +// reassignment in subsequent var +var _b = foo, foo = _b.foo, baz = _b.baz; +var _a; diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.symbols b/tests/baselines/reference/destructuringReassignsRightHandSide.symbols new file mode 100644 index 00000000000..a0b68b7fe53 --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts === +var foo: any = { foo: 1, bar: 2 }; +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 16)) +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 0, 24)) + +var bar: any; +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 1, 3)) + +// reassignment in destructuring pattern +({ foo, bar } = foo); +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 4, 2)) +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 4, 7)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) + +// reassignment in subsequent var +var { foo, baz } = foo; +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) +>baz : Symbol(baz, Decl(destructuringReassignsRightHandSide.ts, 7, 10)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) + diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.types b/tests/baselines/reference/destructuringReassignsRightHandSide.types new file mode 100644 index 00000000000..f5ba19820e0 --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.types @@ -0,0 +1,27 @@ +=== tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts === +var foo: any = { foo: 1, bar: 2 }; +>foo : any +>{ foo: 1, bar: 2 } : { foo: number; bar: number; } +>foo : number +>1 : 1 +>bar : number +>2 : 2 + +var bar: any; +>bar : any + +// reassignment in destructuring pattern +({ foo, bar } = foo); +>({ foo, bar } = foo) : any +>{ foo, bar } = foo : any +>{ foo, bar } : { foo: any; bar: any; } +>foo : any +>bar : any +>foo : any + +// reassignment in subsequent var +var { foo, baz } = foo; +>foo : any +>baz : any +>foo : any + diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5.types b/tests/baselines/reference/destructuringVariableDeclaration1ES5.types index 1502288895b..125fd8a2c21 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, any]; } ->f : [number, number, { f3: number; f5: number; }, any] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, any] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined]; } +>f : [number, number, { f3: number; f5: number; }, undefined] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types b/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types index 1a4b35b373b..d97bb20d24a 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5iterable.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, any]; } ->f : [number, number, { f3: number; f5: number; }, any] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, any] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined]; } +>f : [number, number, { f3: number; f5: number; }, undefined] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES6.types b/tests/baselines/reference/destructuringVariableDeclaration1ES6.types index c71e74c0594..ec42861b2fc 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES6.types +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES6.types @@ -151,9 +151,9 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; >f4 : number >f5 : number > : undefined ->{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, any]; } ->f : [number, number, { f3: number; f5: number; }, any] ->[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, any] +>{ f: [1, 2, { f3: 4, f5: 0 }] } : { f: [number, number, { f3: number; f5: number; }, undefined]; } +>f : [number, number, { f3: number; f5: number; }, undefined] +>[1, 2, { f3: 4, f5: 0 }] : [number, number, { f3: number; f5: number; }, undefined] >1 : 1 >2 : 2 >{ f3: 4, f5: 0 } : { f3: number; f5: number; } diff --git a/tests/baselines/reference/downlevelLetConst12.types b/tests/baselines/reference/downlevelLetConst12.types index 918d6c94e57..725e446e010 100644 --- a/tests/baselines/reference/downlevelLetConst12.types +++ b/tests/baselines/reference/downlevelLetConst12.types @@ -12,7 +12,7 @@ const bar = 1; let [baz] = []; >baz : any ->[] : [any] +>[] : [undefined] let {a: baz2} = { a: 1 }; >a : any @@ -23,7 +23,7 @@ let {a: baz2} = { a: 1 }; const [baz3] = [] >baz3 : any ->[] : [any] +>[] : [undefined] const {a: baz4} = { a: 1 }; >a : any diff --git a/tests/baselines/reference/downlevelLetConst16.types b/tests/baselines/reference/downlevelLetConst16.types index cc9d0f1a2ca..5655b1f8f15 100644 --- a/tests/baselines/reference/downlevelLetConst16.types +++ b/tests/baselines/reference/downlevelLetConst16.types @@ -516,7 +516,7 @@ function foo3() { } for (let [y] = []; ;) { >y : any ->[] : [any] +>[] : [undefined] use(y); >use(y) : any @@ -555,7 +555,7 @@ function foo4() { } for (const [y] = []; ;) { >y : any ->[] : [any] +>[] : [undefined] use(y); >use(y) : any diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js new file mode 100644 index 00000000000..5236a93f931 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts] //// + +//// [package.json] +{ + "name": "foo", + "version": "1.2.3" +} + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [index.d.ts] +import { C } from "foo"; +export const o: C; + +//// [use.d.ts] +import { C } from "./index"; +export function use(o: C): void; + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [package.json] +{ + "name": "foo", + "version": "1.2.3" +} + +//// [index.ts] +import { use } from "foo/use"; +import { o } from "a"; + +use(o); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var use_1 = require("foo/use"); +var a_1 = require("a"); +use_1.use(a_1.o); diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols new file mode 100644 index 00000000000..19809675af2 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols @@ -0,0 +1,44 @@ +=== /index.ts === +import { use } from "foo/use"; +>use : Symbol(use, Decl(index.ts, 0, 8)) + +import { o } from "a"; +>o : Symbol(o, Decl(index.ts, 1, 8)) + +use(o); +>use : Symbol(use, Decl(index.ts, 0, 8)) +>o : Symbol(o, Decl(index.ts, 1, 8)) + +=== /node_modules/a/node_modules/foo/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + +=== /node_modules/a/index.d.ts === +import { C } from "foo"; +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +export const o: C; +>o : Symbol(o, Decl(index.d.ts, 1, 12)) +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +=== /node_modules/foo/use.d.ts === +import { C } from "./index"; +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +export function use(o: C): void; +>use : Symbol(use, Decl(use.d.ts, 0, 28)) +>o : Symbol(o, Decl(use.d.ts, 1, 20)) +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +=== /node_modules/foo/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json new file mode 100644 index 00000000000..ae3917e931a --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json @@ -0,0 +1,45 @@ +[ + "======== Resolving module 'foo/use' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo/use' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/use@1.2.3'.", + "File '/node_modules/foo/use.ts' does not exist.", + "File '/node_modules/foo/use.tsx' does not exist.", + "File '/node_modules/foo/use.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/use.d.ts', result '/node_modules/foo/use.d.ts'.", + "======== Module name 'foo/use' was successfully resolved to '/node_modules/foo/use.d.ts'. ========", + "======== Resolving module 'a' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/a/package.json' does not exist.", + "File '/node_modules/a.ts' does not exist.", + "File '/node_modules/a.tsx' does not exist.", + "File '/node_modules/a.d.ts' does not exist.", + "File '/node_modules/a/index.ts' does not exist.", + "File '/node_modules/a/index.tsx' does not exist.", + "File '/node_modules/a/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/index.d.ts', result '/node_modules/a/index.d.ts'.", + "======== Module name 'a' was successfully resolved to '/node_modules/a/index.d.ts'. ========", + "======== Resolving module './index' from '/node_modules/foo/use.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module as file / folder, candidate module location '/node_modules/foo/index', target file type 'TypeScript'.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo@1.2.3'.", + "======== Module name './index' was successfully resolved to '/node_modules/foo/index.d.ts'. ========", + "======== Resolving module 'foo' from '/node_modules/a/index.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'. Package ID is 'foo@1.2.3'.", + "File '/node_modules/a/node_modules/foo.ts' does not exist.", + "File '/node_modules/a/node_modules/foo.tsx' does not exist.", + "File '/node_modules/a/node_modules/foo.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/a/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/a/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/a/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/node_modules/foo/index.d.ts', result '/node_modules/a/node_modules/foo/index.d.ts'.", + "======== Module name 'foo' was successfully resolved to '/node_modules/a/node_modules/foo/index.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types new file mode 100644 index 00000000000..33931774a1b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types @@ -0,0 +1,45 @@ +=== /index.ts === +import { use } from "foo/use"; +>use : (o: C) => void + +import { o } from "a"; +>o : C + +use(o); +>use(o) : void +>use : (o: C) => void +>o : C + +=== /node_modules/a/node_modules/foo/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + +=== /node_modules/a/index.d.ts === +import { C } from "foo"; +>C : typeof C + +export const o: C; +>o : C +>C : C + +=== /node_modules/foo/use.d.ts === +import { C } from "./index"; +>C : typeof C + +export function use(o: C): void; +>use : (o: C) => void +>o : C +>C : C + +=== /node_modules/foo/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js new file mode 100644 index 00000000000..822c03ca18d --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts] //// + +//// [package.json] +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [index.d.ts] +import { C } from "@foo/bar"; +export const o: C; + +//// [use.d.ts] +import { C } from "./index"; +export function use(o: C): void; + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [package.json] +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +//// [index.ts] +import { use } from "@foo/bar/use"; +import { o } from "a"; + +use(o); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var use_1 = require("@foo/bar/use"); +var a_1 = require("a"); +use_1.use(a_1.o); diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols new file mode 100644 index 00000000000..38cd37e023b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols @@ -0,0 +1,44 @@ +=== /index.ts === +import { use } from "@foo/bar/use"; +>use : Symbol(use, Decl(index.ts, 0, 8)) + +import { o } from "a"; +>o : Symbol(o, Decl(index.ts, 1, 8)) + +use(o); +>use : Symbol(use, Decl(index.ts, 0, 8)) +>o : Symbol(o, Decl(index.ts, 1, 8)) + +=== /node_modules/a/node_modules/@foo/bar/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + +=== /node_modules/a/index.d.ts === +import { C } from "@foo/bar"; +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +export const o: C; +>o : Symbol(o, Decl(index.d.ts, 1, 12)) +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +=== /node_modules/@foo/bar/use.d.ts === +import { C } from "./index"; +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +export function use(o: C): void; +>use : Symbol(use, Decl(use.d.ts, 0, 28)) +>o : Symbol(o, Decl(use.d.ts, 1, 20)) +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +=== /node_modules/@foo/bar/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json new file mode 100644 index 00000000000..a753e3dfb9a --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json @@ -0,0 +1,45 @@ +[ + "======== Resolving module '@foo/bar/use' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module '@foo/bar/use' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/use@1.2.3'.", + "File '/node_modules/@foo/bar/use.ts' does not exist.", + "File '/node_modules/@foo/bar/use.tsx' does not exist.", + "File '/node_modules/@foo/bar/use.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/@foo/bar/use.d.ts', result '/node_modules/@foo/bar/use.d.ts'.", + "======== Module name '@foo/bar/use' was successfully resolved to '/node_modules/@foo/bar/use.d.ts'. ========", + "======== Resolving module 'a' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/a/package.json' does not exist.", + "File '/node_modules/a.ts' does not exist.", + "File '/node_modules/a.tsx' does not exist.", + "File '/node_modules/a.d.ts' does not exist.", + "File '/node_modules/a/index.ts' does not exist.", + "File '/node_modules/a/index.tsx' does not exist.", + "File '/node_modules/a/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/index.d.ts', result '/node_modules/a/index.d.ts'.", + "======== Module name 'a' was successfully resolved to '/node_modules/a/index.d.ts'. ========", + "======== Resolving module './index' from '/node_modules/@foo/bar/use.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module as file / folder, candidate module location '/node_modules/@foo/bar/index', target file type 'TypeScript'.", + "File '/node_modules/@foo/bar/index.ts' does not exist.", + "File '/node_modules/@foo/bar/index.tsx' does not exist.", + "File '/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar@1.2.3'.", + "======== Module name './index' was successfully resolved to '/node_modules/@foo/bar/index.d.ts'. ========", + "======== Resolving module '@foo/bar' from '/node_modules/a/index.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar@1.2.3'.", + "File '/node_modules/a/node_modules/@foo/bar.ts' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar.tsx' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/a/node_modules/@foo/bar/index.ts' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar/index.tsx' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/node_modules/@foo/bar/index.d.ts', result '/node_modules/a/node_modules/@foo/bar/index.d.ts'.", + "======== Module name '@foo/bar' was successfully resolved to '/node_modules/a/node_modules/@foo/bar/index.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types new file mode 100644 index 00000000000..7be2442bf3b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types @@ -0,0 +1,45 @@ +=== /index.ts === +import { use } from "@foo/bar/use"; +>use : (o: C) => void + +import { o } from "a"; +>o : C + +use(o); +>use(o) : void +>use : (o: C) => void +>o : C + +=== /node_modules/a/node_modules/@foo/bar/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + +=== /node_modules/a/index.d.ts === +import { C } from "@foo/bar"; +>C : typeof C + +export const o: C; +>o : C +>C : C + +=== /node_modules/@foo/bar/use.d.ts === +import { C } from "./index"; +>C : typeof C + +export function use(o: C): void; +>use : (o: C) => void +>o : C +>C : C + +=== /node_modules/@foo/bar/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + diff --git a/tests/baselines/reference/elaboratedErrors.errors.txt b/tests/baselines/reference/elaboratedErrors.errors.txt index 7bc83a19a50..a9060282404 100644 --- a/tests/baselines/reference/elaboratedErrors.errors.txt +++ b/tests/baselines/reference/elaboratedErrors.errors.txt @@ -1,6 +1,5 @@ -tests/cases/compiler/elaboratedErrors.ts(10,7): error TS2420: Class 'WorkerFS' incorrectly implements interface 'FileSystem'. - Types of property 'read' are incompatible. - Type 'string' is not assignable to type 'number'. +tests/cases/compiler/elaboratedErrors.ts(11,3): error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'FileSystem'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/elaboratedErrors.ts(20,1): error TS2322: Type 'Beta' is not assignable to type 'Alpha'. Property 'x' is missing in type 'Beta'. tests/cases/compiler/elaboratedErrors.ts(21,1): error TS2322: Type 'Beta' is not assignable to type 'Alpha'. @@ -20,11 +19,10 @@ tests/cases/compiler/elaboratedErrors.ts(25,1): error TS2322: Type 'Alpha' is no // This should issue a large error, not a small one class WorkerFS implements FileSystem { - ~~~~~~~~ -!!! error TS2420: Class 'WorkerFS' incorrectly implements interface 'FileSystem'. -!!! error TS2420: Types of property 'read' are incompatible. -!!! error TS2420: Type 'string' is not assignable to type 'number'. read: string; + ~~~~ +!!! error TS2416: Property 'read' in type 'WorkerFS' is not assignable to the same property in base type 'FileSystem'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. } interface Alpha { x: string; } diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js index d91571f93ad..2de9f939ba1 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es2015.js @@ -120,7 +120,7 @@ class C3 { } } //// [C4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -162,7 +162,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js index 1119d6b06e3..a91120c4079 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.classMethods.es5.js @@ -256,7 +256,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -347,7 +347,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js index 4ca8322da9f..d0bf1c902c0 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es2015.js @@ -83,7 +83,7 @@ function f3() { }); } //// [F4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -123,7 +123,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js index 410a25d2e16..70cfee32542 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionDeclarations.es5.js @@ -210,7 +210,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -296,7 +296,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js index 602fd47d38b..909196952f0 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es2015.js @@ -83,7 +83,7 @@ const f3 = function () { }); }; //// [F4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -123,7 +123,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js index 45d17737cef..c9dff58c7ce 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.functionExpressions.es5.js @@ -210,7 +210,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -296,7 +296,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js index 760931a4342..99caa9d3ad3 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es2015.js @@ -103,7 +103,7 @@ const o3 = { } }; //// [O4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -145,7 +145,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js index b5069bcea2c..76d74351923 100644 --- a/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js +++ b/tests/baselines/reference/emitter.asyncGenerators.objectLiteralMethods.es5.js @@ -230,7 +230,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -318,7 +318,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.forAwait.es2015.js b/tests/baselines/reference/emitter.forAwait.es2015.js index d88ed8d1a06..323d62f0ac8 100644 --- a/tests/baselines/reference/emitter.forAwait.es2015.js +++ b/tests/baselines/reference/emitter.forAwait.es2015.js @@ -34,7 +34,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -66,7 +66,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -90,7 +90,7 @@ function f2() { }); } //// [file3.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -126,7 +126,7 @@ function f3() { }); } //// [file4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.forAwait.es2017.js b/tests/baselines/reference/emitter.forAwait.es2017.js index eb953781ab3..4b3770f02af 100644 --- a/tests/baselines/reference/emitter.forAwait.es2017.js +++ b/tests/baselines/reference/emitter.forAwait.es2017.js @@ -26,7 +26,7 @@ async function* f4() { } //// [file1.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -48,7 +48,7 @@ async function f1() { var e_1, _a; } //// [file2.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -70,7 +70,7 @@ async function f2() { var e_1, _a; } //// [file3.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -106,7 +106,7 @@ function f3() { }); } //// [file4.js] -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emitter.forAwait.es5.js b/tests/baselines/reference/emitter.forAwait.es5.js index fc8f5fd321d..2b073a3f43a 100644 --- a/tests/baselines/reference/emitter.forAwait.es5.js +++ b/tests/baselines/reference/emitter.forAwait.es5.js @@ -61,7 +61,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -141,7 +141,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -213,7 +213,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); @@ -297,7 +297,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; -var __asyncValues = (this && this.__asyncIterator) || function (o) { +var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator]; return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); diff --git a/tests/baselines/reference/emptyDeclarationEmitIsModule.js b/tests/baselines/reference/emptyDeclarationEmitIsModule.js new file mode 100644 index 00000000000..fb0cea6365e --- /dev/null +++ b/tests/baselines/reference/emptyDeclarationEmitIsModule.js @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/emptyDeclarationEmitIsModule.ts] //// + +//// [module.ts] +import * as i from "./index"; +class Foo {} +//// [index.ts] +import {} from "./module"; +export interface Bar { + x: string +} + +//// [index.js] +"use strict"; +exports.__esModule = true; +//// [module.js] +"use strict"; +exports.__esModule = true; +var Foo = /** @class */ (function () { + function Foo() { + } + return Foo; +}()); + + +//// [index.d.ts] +export interface Bar { + x: string; +} +//// [module.d.ts] +export {}; diff --git a/tests/baselines/reference/emptyDeclarationEmitIsModule.symbols b/tests/baselines/reference/emptyDeclarationEmitIsModule.symbols new file mode 100644 index 00000000000..60b0fd65204 --- /dev/null +++ b/tests/baselines/reference/emptyDeclarationEmitIsModule.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/module.ts === +import * as i from "./index"; +>i : Symbol(i, Decl(module.ts, 0, 6)) + +class Foo {} +>Foo : Symbol(Foo, Decl(module.ts, 0, 29)) + +=== tests/cases/compiler/index.ts === +import {} from "./module"; +export interface Bar { +>Bar : Symbol(Bar, Decl(index.ts, 0, 26)) + + x: string +>x : Symbol(Bar.x, Decl(index.ts, 1, 22)) +} diff --git a/tests/baselines/reference/emptyDeclarationEmitIsModule.types b/tests/baselines/reference/emptyDeclarationEmitIsModule.types new file mode 100644 index 00000000000..1a49aa948da --- /dev/null +++ b/tests/baselines/reference/emptyDeclarationEmitIsModule.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/module.ts === +import * as i from "./index"; +>i : typeof i + +class Foo {} +>Foo : Foo + +=== tests/cases/compiler/index.ts === +import {} from "./module"; +export interface Bar { +>Bar : Bar + + x: string +>x : string +} diff --git a/tests/baselines/reference/es6ImportDefaultBinding.js b/tests/baselines/reference/es6ImportDefaultBinding.js index 5629c9b8cdc..bdc9b4b8463 100644 --- a/tests/baselines/reference/es6ImportDefaultBinding.js +++ b/tests/baselines/reference/es6ImportDefaultBinding.js @@ -22,3 +22,4 @@ var x = defaultBinding; declare var a: number; export default a; //// [es6ImportDefaultBinding_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingAmd.js b/tests/baselines/reference/es6ImportDefaultBindingAmd.js index d8a13efa2d6..1f6b3c97c8f 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingAmd.js +++ b/tests/baselines/reference/es6ImportDefaultBindingAmd.js @@ -29,3 +29,4 @@ define(["require", "exports", "es6ImportDefaultBindingAmd_0"], function (require declare var a: number; export default a; //// [es6ImportDefaultBindingAmd_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js index a5b7700c36c..ff8d6538b04 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js @@ -51,3 +51,4 @@ export declare var m: number; declare const _default: {}; export default _default; //// [es6ImportDefaultBindingFollowedWithNamedImport_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.js index 54a4d434606..31194c308ba 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.js @@ -41,3 +41,4 @@ var x1 = defaultBinding6; declare var a: number; export default a; //// [es6ImportDefaultBindingFollowedWithNamedImport1_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1InEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1InEs5.js index 46e52a43135..ef9ab7215bc 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1InEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1InEs5.js @@ -45,3 +45,4 @@ var x = es6ImportDefaultBindingFollowedWithNamedImport1InEs5_0_6.default; declare var a: number; export default a; //// [es6ImportDefaultBindingFollowedWithNamedImport1InEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportInEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportInEs5.js index 90875ff5878..3c55a05f25e 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportInEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportInEs5.js @@ -47,3 +47,4 @@ export declare var a: number; export declare var x: number; export declare var m: number; //// [es6ImportDefaultBindingFollowedWithNamedImportInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding.js index 4fbac48bd36..2c86e062635 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding.js @@ -17,3 +17,4 @@ var x = nameSpaceBinding.a; //// [es6ImportDefaultBindingFollowedWithNamespaceBinding_0.d.ts] export declare var a: number; //// [es6ImportDefaultBindingFollowedWithNamespaceBinding_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1.js index eb90b4882b0..039b4a3dce8 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1.js @@ -20,3 +20,4 @@ var x = defaultBinding; declare var a: number; export default a; //// [es6ImportDefaultBindingFollowedWithNamespaceBinding_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js index a6217abb784..9183663850b 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBinding1InEs5.js @@ -24,3 +24,4 @@ var x = es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0_1.default; declare var a: number; export default a; //// [es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js index 5586054319a..9d87535274b 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5.js @@ -21,3 +21,4 @@ var x = nameSpaceBinding.a; //// [es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_0.d.ts] export declare var a: number; //// [es6ImportDefaultBindingFollowedWithNamespaceBindingInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportDefaultBindingInEs5.js b/tests/baselines/reference/es6ImportDefaultBindingInEs5.js index 165f58b9246..a6175197d8e 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingInEs5.js +++ b/tests/baselines/reference/es6ImportDefaultBindingInEs5.js @@ -20,3 +20,4 @@ Object.defineProperty(exports, "__esModule", { value: true }); declare var a: number; export = a; //// [es6ImportDefaultBindingInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNameSpaceImport.js b/tests/baselines/reference/es6ImportNameSpaceImport.js index c9013259e8e..7ab8a62bf6f 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImport.js +++ b/tests/baselines/reference/es6ImportNameSpaceImport.js @@ -23,3 +23,4 @@ var x = nameSpaceBinding.a; //// [es6ImportNameSpaceImport_0.d.ts] export declare var a: number; //// [es6ImportNameSpaceImport_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNameSpaceImportAmd.js b/tests/baselines/reference/es6ImportNameSpaceImportAmd.js index 44a0635f7a2..17a0509f093 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportAmd.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportAmd.js @@ -26,3 +26,4 @@ define(["require", "exports", "es6ImportNameSpaceImportAmd_0"], function (requir //// [es6ImportNameSpaceImportAmd_0.d.ts] export declare var a: number; //// [es6ImportNameSpaceImportAmd_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNameSpaceImportInEs5.js b/tests/baselines/reference/es6ImportNameSpaceImportInEs5.js index 1eced8142cb..4382d8f16b2 100644 --- a/tests/baselines/reference/es6ImportNameSpaceImportInEs5.js +++ b/tests/baselines/reference/es6ImportNameSpaceImportInEs5.js @@ -23,3 +23,4 @@ var x = nameSpaceBinding.a; //// [es6ImportNameSpaceImportInEs5_0.d.ts] export declare var a: number; //// [es6ImportNameSpaceImportInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNamedImport.js b/tests/baselines/reference/es6ImportNamedImport.js index 92e56660cc7..0ce1c57403e 100644 --- a/tests/baselines/reference/es6ImportNamedImport.js +++ b/tests/baselines/reference/es6ImportNamedImport.js @@ -87,3 +87,4 @@ export declare var z1: number; export declare var z2: number; export declare var aaaa: number; //// [es6ImportNamedImport_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNamedImportAmd.js b/tests/baselines/reference/es6ImportNamedImportAmd.js index 8f1a7cb013b..6b7a4bd5743 100644 --- a/tests/baselines/reference/es6ImportNamedImportAmd.js +++ b/tests/baselines/reference/es6ImportNamedImportAmd.js @@ -82,3 +82,4 @@ export declare var z1: number; export declare var z2: number; export declare var aaaa: number; //// [es6ImportNamedImportAmd_1.d.ts] +export {}; diff --git a/tests/baselines/reference/es6ImportNamedImportInEs5.js b/tests/baselines/reference/es6ImportNamedImportInEs5.js index 8cedfa664a8..9226170d84b 100644 --- a/tests/baselines/reference/es6ImportNamedImportInEs5.js +++ b/tests/baselines/reference/es6ImportNamedImportInEs5.js @@ -87,3 +87,4 @@ export declare var z1: number; export declare var z2: number; export declare var aaaa: number; //// [es6ImportNamedImportInEs5_1.d.ts] +export {}; diff --git a/tests/baselines/reference/esModuleInterop.js b/tests/baselines/reference/esModuleInterop.js new file mode 100644 index 00000000000..9a04ab01be6 --- /dev/null +++ b/tests/baselines/reference/esModuleInterop.js @@ -0,0 +1,39 @@ +//// [tests/cases/compiler/esModuleInterop.ts] //// + +//// [index.d.ts] +export function sayHello(): string; +//// [path.d.ts] +declare const anything: any; +export = anything; +//// [fs.d.ts] +declare const anything: any; +export = anything; +//// [mjts.ts] +import { sayHello } from "./hybrid"; +import path from "./path"; +import * as fs from "./fs"; + +path; +sayHello(); +fs; + + +//// [mjts.js] +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +} +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +} +exports.__esModule = true; +var hybrid_1 = require("./hybrid"); +var path_1 = __importDefault(require("./path")); +var fs = __importStar(require("./fs")); +path_1["default"]; +hybrid_1.sayHello(); +fs; diff --git a/tests/baselines/reference/esModuleInterop.symbols b/tests/baselines/reference/esModuleInterop.symbols new file mode 100644 index 00000000000..8e173220d43 --- /dev/null +++ b/tests/baselines/reference/esModuleInterop.symbols @@ -0,0 +1,37 @@ +=== tests/cases/compiler/hybrid/index.d.ts === +export function sayHello(): string; +>sayHello : Symbol(sayHello, Decl(index.d.ts, 0, 0)) + +=== tests/cases/compiler/path.d.ts === +declare const anything: any; +>anything : Symbol(anything, Decl(path.d.ts, 0, 13)) + +export = anything; +>anything : Symbol(anything, Decl(path.d.ts, 0, 13)) + +=== tests/cases/compiler/fs.d.ts === +declare const anything: any; +>anything : Symbol(anything, Decl(fs.d.ts, 0, 13)) + +export = anything; +>anything : Symbol(anything, Decl(fs.d.ts, 0, 13)) + +=== tests/cases/compiler/mjts.ts === +import { sayHello } from "./hybrid"; +>sayHello : Symbol(sayHello, Decl(mjts.ts, 0, 8)) + +import path from "./path"; +>path : Symbol(path, Decl(mjts.ts, 1, 6)) + +import * as fs from "./fs"; +>fs : Symbol(fs, Decl(mjts.ts, 2, 6)) + +path; +>path : Symbol(path, Decl(mjts.ts, 1, 6)) + +sayHello(); +>sayHello : Symbol(sayHello, Decl(mjts.ts, 0, 8)) + +fs; +>fs : Symbol(fs, Decl(mjts.ts, 2, 6)) + diff --git a/tests/baselines/reference/esModuleInterop.types b/tests/baselines/reference/esModuleInterop.types new file mode 100644 index 00000000000..98e39f596a8 --- /dev/null +++ b/tests/baselines/reference/esModuleInterop.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/hybrid/index.d.ts === +export function sayHello(): string; +>sayHello : () => string + +=== tests/cases/compiler/path.d.ts === +declare const anything: any; +>anything : any + +export = anything; +>anything : any + +=== tests/cases/compiler/fs.d.ts === +declare const anything: any; +>anything : any + +export = anything; +>anything : any + +=== tests/cases/compiler/mjts.ts === +import { sayHello } from "./hybrid"; +>sayHello : () => string + +import path from "./path"; +>path : any + +import * as fs from "./fs"; +>fs : any + +path; +>path : any + +sayHello(); +>sayHello() : string +>sayHello : () => string + +fs; +>fs : any + diff --git a/tests/baselines/reference/esModuleInteropImportCall.js b/tests/baselines/reference/esModuleInteropImportCall.js new file mode 100644 index 00000000000..2aa681ded7f --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportCall.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/esModuleInteropImportCall.ts] //// + +//// [foo.d.ts] +declare function foo(): void; +declare namespace foo {} +export = foo; + +//// [index.ts] +import("./foo").then(f => { + f.default; +}); + +//// [index.js] +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +} +Promise.resolve().then(function () { return __importStar(require("./foo")); }).then(function (f) { + f["default"]; +}); diff --git a/tests/baselines/reference/esModuleInteropImportCall.symbols b/tests/baselines/reference/esModuleInteropImportCall.symbols new file mode 100644 index 00000000000..58c5e066f86 --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportCall.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/foo.d.ts === +declare function foo(): void; +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +declare namespace foo {} +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +export = foo; +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +=== tests/cases/compiler/index.ts === +import("./foo").then(f => { +>import("./foo").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./foo" : Symbol("tests/cases/compiler/foo", Decl(foo.d.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>f : Symbol(f, Decl(index.ts, 0, 21)) + + f.default; +>f.default : Symbol(default) +>f : Symbol(f, Decl(index.ts, 0, 21)) +>default : Symbol(default) + +}); diff --git a/tests/baselines/reference/esModuleInteropImportCall.types b/tests/baselines/reference/esModuleInteropImportCall.types new file mode 100644 index 00000000000..c194af96c53 --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportCall.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/foo.d.ts === +declare function foo(): void; +>foo : () => void + +declare namespace foo {} +>foo : () => void + +export = foo; +>foo : () => void + +=== tests/cases/compiler/index.ts === +import("./foo").then(f => { +>import("./foo").then(f => { f.default;}) : Promise +>import("./foo").then : void; }, TResult2 = never>(onfulfilled?: (value: { default: () => void; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>import("./foo") : Promise<{ default: () => void; }> +>"./foo" : "./foo" +>then : void; }, TResult2 = never>(onfulfilled?: (value: { default: () => void; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>f => { f.default;} : (f: { default: () => void; }) => void +>f : { default: () => void; } + + f.default; +>f.default : () => void +>f : { default: () => void; } +>default : () => void + +}); diff --git a/tests/baselines/reference/esModuleInteropImportNamespace.js b/tests/baselines/reference/esModuleInteropImportNamespace.js new file mode 100644 index 00000000000..605976faaaa --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportNamespace.js @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/esModuleInteropImportNamespace.ts] //// + +//// [foo.d.ts] +declare function foo(): void; +declare namespace foo {} +export = foo; + +//// [index.ts] +import * as foo from "./foo"; +foo.default; + + +//// [index.js] +"use strict"; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +} +exports.__esModule = true; +var foo = __importStar(require("./foo")); +foo["default"]; diff --git a/tests/baselines/reference/esModuleInteropImportNamespace.symbols b/tests/baselines/reference/esModuleInteropImportNamespace.symbols new file mode 100644 index 00000000000..d381d553568 --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportNamespace.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/foo.d.ts === +declare function foo(): void; +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +declare namespace foo {} +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +export = foo; +>foo : Symbol(foo, Decl(foo.d.ts, 0, 0), Decl(foo.d.ts, 0, 29)) + +=== tests/cases/compiler/index.ts === +import * as foo from "./foo"; +>foo : Symbol(foo, Decl(index.ts, 0, 6)) + +foo.default; +>foo.default : Symbol(default) +>foo : Symbol(foo, Decl(index.ts, 0, 6)) +>default : Symbol(default) + diff --git a/tests/baselines/reference/esModuleInteropImportNamespace.types b/tests/baselines/reference/esModuleInteropImportNamespace.types new file mode 100644 index 00000000000..e0a49db2794 --- /dev/null +++ b/tests/baselines/reference/esModuleInteropImportNamespace.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/foo.d.ts === +declare function foo(): void; +>foo : () => void + +declare namespace foo {} +>foo : () => void + +export = foo; +>foo : () => void + +=== tests/cases/compiler/index.ts === +import * as foo from "./foo"; +>foo : { default: () => void; } + +foo.default; +>foo.default : () => void +>foo : { default: () => void; } +>default : () => void + diff --git a/tests/baselines/reference/exportClassExtendingIntersection.js b/tests/baselines/reference/exportClassExtendingIntersection.js index a6e1f52804c..9b99e90d511 100644 --- a/tests/baselines/reference/exportClassExtendingIntersection.js +++ b/tests/baselines/reference/exportClassExtendingIntersection.js @@ -119,3 +119,4 @@ export declare class MyExtendedClass extends MyExtendedClass_base { extendedClassProperty: number; } //// [Main.d.ts] +export {}; diff --git a/tests/baselines/reference/exportStarFromEmptyModule.js b/tests/baselines/reference/exportStarFromEmptyModule.js index 2730778930d..be7de642a6a 100644 --- a/tests/baselines/reference/exportStarFromEmptyModule.js +++ b/tests/baselines/reference/exportStarFromEmptyModule.js @@ -68,3 +68,4 @@ export declare class A { static q: any; } //// [exportStarFromEmptyModule_module4.d.ts] +export {}; diff --git a/tests/baselines/reference/genericImplements.errors.txt b/tests/baselines/reference/genericImplements.errors.txt index 7add57989ce..fff51884f10 100644 --- a/tests/baselines/reference/genericImplements.errors.txt +++ b/tests/baselines/reference/genericImplements.errors.txt @@ -1,7 +1,6 @@ -tests/cases/compiler/genericImplements.ts(8,7): error TS2420: Class 'X' incorrectly implements interface 'I'. - Types of property 'f' are incompatible. - Type '() => T' is not assignable to type '() => T'. - Type 'B' is not assignable to type 'T'. +tests/cases/compiler/genericImplements.ts(9,5): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. + Type '() => T' is not assignable to type '() => T'. + Type 'B' is not assignable to type 'T'. ==== tests/cases/compiler/genericImplements.ts (1 errors) ==== @@ -13,12 +12,11 @@ tests/cases/compiler/genericImplements.ts(8,7): error TS2420: Class 'X' incorrec // OK class X implements I { - ~ -!!! error TS2420: Class 'X' incorrectly implements interface 'I'. -!!! error TS2420: Types of property 'f' are incompatible. -!!! error TS2420: Type '() => T' is not assignable to type '() => T'. -!!! error TS2420: Type 'B' is not assignable to type 'T'. f(): T { return undefined; } + ~ +!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. +!!! error TS2416: Type '() => T' is not assignable to type '() => T'. +!!! error TS2416: Type 'B' is not assignable to type 'T'. } // { f: () => { b; } } // OK diff --git a/tests/baselines/reference/genericSpecializations1.errors.txt b/tests/baselines/reference/genericSpecializations1.errors.txt index dd7e540661e..83015cef259 100644 --- a/tests/baselines/reference/genericSpecializations1.errors.txt +++ b/tests/baselines/reference/genericSpecializations1.errors.txt @@ -1,13 +1,11 @@ -tests/cases/compiler/genericSpecializations1.ts(5,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. -tests/cases/compiler/genericSpecializations1.ts(9,7): error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations1.ts(6,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations1.ts(10,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. ==== tests/cases/compiler/genericSpecializations1.ts (2 errors) ==== @@ -16,23 +14,21 @@ tests/cases/compiler/genericSpecializations1.ts(9,7): error TS2420: Class 'Strin } class IntFooBad implements IFoo { - ~~~~~~~~~ -!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. } class StringFoo2 implements IFoo { - ~~~~~~~~~~ -!!! error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. } class StringFoo3 implements IFoo { diff --git a/tests/baselines/reference/genericSpecializations2.errors.txt b/tests/baselines/reference/genericSpecializations2.errors.txt index 99a6e2a6985..1088d7b8956 100644 --- a/tests/baselines/reference/genericSpecializations2.errors.txt +++ b/tests/baselines/reference/genericSpecializations2.errors.txt @@ -1,14 +1,12 @@ -tests/cases/compiler/genericSpecializations2.ts(7,7): error TS2720: Class 'IntFooBad' incorrectly implements class 'IFoo'. Did you mean to extend 'IFoo' and inherit its members as a subclass? - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations2.ts(8,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations2.ts(8,9): error TS2368: Type parameter name cannot be 'string'. -tests/cases/compiler/genericSpecializations2.ts(11,7): error TS2720: Class 'StringFoo2' incorrectly implements class 'IFoo'. Did you mean to extend 'IFoo' and inherit its members as a subclass? - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations2.ts(12,5): error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parameter name cannot be 'string'. @@ -20,25 +18,23 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame } class IntFooBad implements IFoo { - ~~~~~~~~~ -!!! error TS2720: Class 'IntFooBad' incorrectly implements class 'IFoo'. Did you mean to extend 'IFoo' and inherit its members as a subclass? -!!! error TS2720: Types of property 'foo' are incompatible. -!!! error TS2720: Type '(x: string) => string' is not assignable to type '(x: T) => T'. -!!! error TS2720: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2720: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. ~~~~~~ !!! error TS2368: Type parameter name cannot be 'string'. } class StringFoo2 implements IFoo { - ~~~~~~~~~~ -!!! error TS2720: Class 'StringFoo2' incorrectly implements class 'IFoo'. Did you mean to extend 'IFoo' and inherit its members as a subclass? -!!! error TS2720: Types of property 'foo' are incompatible. -!!! error TS2720: Type '(x: string) => string' is not assignable to type '(x: T) => T'. -!!! error TS2720: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2720: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'StringFoo2' is not assignable to the same property in base type 'IFoo'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. ~~~~~~ !!! error TS2368: Type parameter name cannot be 'string'. } diff --git a/tests/baselines/reference/genericSpecializations3.errors.txt b/tests/baselines/reference/genericSpecializations3.errors.txt index 87a7d5bcce7..eaa7f094bdb 100644 --- a/tests/baselines/reference/genericSpecializations3.errors.txt +++ b/tests/baselines/reference/genericSpecializations3.errors.txt @@ -1,8 +1,7 @@ -tests/cases/compiler/genericSpecializations3.ts(8,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => string' is not assignable to type '(x: number) => number'. - Types of parameters 'x' and 'x' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations3.ts(9,5): error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. + Type '(x: string) => string' is not assignable to type '(x: number) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations3.ts(28,1): error TS2322: Type 'StringFoo2' is not assignable to type 'IntFoo'. Types of property 'foo' are incompatible. Type '(x: string) => string' is not assignable to type '(x: number) => number'. @@ -24,13 +23,12 @@ tests/cases/compiler/genericSpecializations3.ts(29,1): error TS2322: Type 'IntFo iFoo.foo(1); class IntFooBad implements IFoo { // error - ~~~~~~~~~ -!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: number) => number'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. foo(x: string): string { return null; } + ~~~ +!!! error TS2416: Property 'foo' in type 'IntFooBad' is not assignable to the same property in base type 'IFoo'. +!!! error TS2416: Type '(x: string) => string' is not assignable to type '(x: number) => number'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'number' is not assignable to type 'string'. } var intFooBad: IntFooBad; diff --git a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt index 3ec6fa5e9f6..a7a96c2abd8 100644 --- a/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt +++ b/tests/baselines/reference/genericTypeWithNonGenericBaseMisMatch.errors.txt @@ -1,8 +1,7 @@ -tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(4,7): error TS2420: Class 'X' incorrectly implements interface 'I'. - Types of property 'f' are incompatible. - Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. - Types of parameters 'a' and 'a' are incompatible. - Type '{ a: number; }' is not assignable to type 'T'. +tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(5,2): error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. + Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. + Types of parameters 'a' and 'a' are incompatible. + Type '{ a: number; }' is not assignable to type 'T'. tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(8,5): error TS2322: Type 'X<{ a: string; }>' is not assignable to type 'I'. Types of property 'f' are incompatible. Type '(a: { a: string; }) => void' is not assignable to type '(a: { a: number; }) => void'. @@ -17,13 +16,12 @@ tests/cases/compiler/genericTypeWithNonGenericBaseMisMatch.ts(8,5): error TS2322 f: (a: { a: number }) => void } class X implements I { - ~ -!!! error TS2420: Class 'X' incorrectly implements interface 'I'. -!!! error TS2420: Types of property 'f' are incompatible. -!!! error TS2420: Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. -!!! error TS2420: Types of parameters 'a' and 'a' are incompatible. -!!! error TS2420: Type '{ a: number; }' is not assignable to type 'T'. f(a: T): void { } + ~ +!!! error TS2416: Property 'f' in type 'X' is not assignable to the same property in base type 'I'. +!!! error TS2416: Type '(a: T) => void' is not assignable to type '(a: { a: number; }) => void'. +!!! error TS2416: Types of parameters 'a' and 'a' are incompatible. +!!! error TS2416: Type '{ a: number; }' is not assignable to type 'T'. } var x = new X<{ a: string }>(); var i: I = x; // Should not be allowed -- type of 'f' is incompatible with 'I' diff --git a/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt b/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt index 4652acc8d10..576013f43c5 100644 --- a/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt +++ b/tests/baselines/reference/implementGenericWithMismatchedTypes.errors.txt @@ -1,12 +1,10 @@ -tests/cases/compiler/implementGenericWithMismatchedTypes.ts(7,7): error TS2420: Class 'C' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => number' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. -tests/cases/compiler/implementGenericWithMismatchedTypes.ts(16,7): error TS2420: Class 'C2' incorrectly implements interface 'IFoo2'. - Types of property 'foo' are incompatible. - Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. - Type 'number' is not assignable to type 'T'. +tests/cases/compiler/implementGenericWithMismatchedTypes.ts(8,5): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. + Type '(x: string) => number' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/compiler/implementGenericWithMismatchedTypes.ts(17,5): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo2'. + Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. + Type 'number' is not assignable to type 'T'. ==== tests/cases/compiler/implementGenericWithMismatchedTypes.ts (2 errors) ==== @@ -17,13 +15,12 @@ tests/cases/compiler/implementGenericWithMismatchedTypes.ts(16,7): error TS2420: foo(x: T): T; } class C implements IFoo { // error - ~ -!!! error TS2420: Class 'C' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => number' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): number { + ~~~ +!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. +!!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. return null; } } @@ -32,12 +29,11 @@ tests/cases/compiler/implementGenericWithMismatchedTypes.ts(16,7): error TS2420: foo(x: T): T; } class C2 implements IFoo2 { // error - ~~ -!!! error TS2420: Class 'C2' incorrectly implements interface 'IFoo2'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. -!!! error TS2420: Type 'number' is not assignable to type 'T'. foo(x: Tstring): number { + ~~~ +!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo2'. +!!! error TS2416: Type '(x: Tstring) => number' is not assignable to type '(x: T) => T'. +!!! error TS2416: Type 'number' is not assignable to type 'T'. return null; } } \ No newline at end of file diff --git a/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt b/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt index a1c0f21b8c4..f56da547126 100644 --- a/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt +++ b/tests/baselines/reference/implementsIncorrectlyNoAssertion.errors.txt @@ -1,7 +1,5 @@ -tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(8,7): error TS2420: Class 'Baz' incorrectly implements interface 'Foo & Bar'. - Type 'Baz' is not assignable to type 'Foo'. - Types of property 'x' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(9,5): error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'Foo & Bar'. + Type 'number' is not assignable to type 'string'. ==== tests/cases/compiler/implementsIncorrectlyNoAssertion.ts (1 errors) ==== @@ -13,12 +11,10 @@ tests/cases/compiler/implementsIncorrectlyNoAssertion.ts(8,7): error TS2420: Cla } type Wrapper = Foo & Bar; class Baz implements Wrapper { - ~~~ -!!! error TS2420: Class 'Baz' incorrectly implements interface 'Foo & Bar'. -!!! error TS2420: Type 'Baz' is not assignable to type 'Foo'. -!!! error TS2420: Types of property 'x' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. x: number; + ~ +!!! error TS2416: Property 'x' in type 'Baz' is not assignable to the same property in base type 'Foo & Bar'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. y: string; } \ No newline at end of file diff --git a/tests/baselines/reference/importCallExpressionAsyncES3System.types b/tests/baselines/reference/importCallExpressionAsyncES3System.types index 90c981c01ca..4f6a2bb31be 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES3System.types +++ b/tests/baselines/reference/importCallExpressionAsyncES3System.types @@ -3,9 +3,9 @@ export async function fn() { >fn : () => Promise const req = await import('./test') // ONE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } @@ -16,9 +16,9 @@ export class cl1 { >m : () => Promise const req = await import('./test') // TWO ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -32,9 +32,9 @@ export const obj = { >async () => { const req = await import('./test') // THREE } : () => Promise const req = await import('./test') // THREE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -51,9 +51,9 @@ export class cl2 { >async () => { const req = await import('./test') // FOUR } : () => Promise const req = await import('./test') // FOUR ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -64,9 +64,9 @@ export const l = async () => { >async () => { const req = await import('./test') // FIVE} : () => Promise const req = await import('./test') // FIVE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } diff --git a/tests/baselines/reference/importCallExpressionAsyncES5System.types b/tests/baselines/reference/importCallExpressionAsyncES5System.types index 90c981c01ca..4f6a2bb31be 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES5System.types +++ b/tests/baselines/reference/importCallExpressionAsyncES5System.types @@ -3,9 +3,9 @@ export async function fn() { >fn : () => Promise const req = await import('./test') // ONE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } @@ -16,9 +16,9 @@ export class cl1 { >m : () => Promise const req = await import('./test') // TWO ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -32,9 +32,9 @@ export const obj = { >async () => { const req = await import('./test') // THREE } : () => Promise const req = await import('./test') // THREE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -51,9 +51,9 @@ export class cl2 { >async () => { const req = await import('./test') // FOUR } : () => Promise const req = await import('./test') // FOUR ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -64,9 +64,9 @@ export const l = async () => { >async () => { const req = await import('./test') // FIVE} : () => Promise const req = await import('./test') // FIVE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } diff --git a/tests/baselines/reference/importCallExpressionAsyncES6System.types b/tests/baselines/reference/importCallExpressionAsyncES6System.types index 90c981c01ca..4f6a2bb31be 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6System.types +++ b/tests/baselines/reference/importCallExpressionAsyncES6System.types @@ -3,9 +3,9 @@ export async function fn() { >fn : () => Promise const req = await import('./test') // ONE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } @@ -16,9 +16,9 @@ export class cl1 { >m : () => Promise const req = await import('./test') // TWO ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -32,9 +32,9 @@ export const obj = { >async () => { const req = await import('./test') // THREE } : () => Promise const req = await import('./test') // THREE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -51,9 +51,9 @@ export class cl2 { >async () => { const req = await import('./test') // FOUR } : () => Promise const req = await import('./test') // FOUR ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } } @@ -64,9 +64,9 @@ export const l = async () => { >async () => { const req = await import('./test') // FIVE} : () => Promise const req = await import('./test') // FIVE ->req : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" & { default: typeof "tests/cases/conformance/dynamicImport/test"; } ->import('./test') : Promise +>req : typeof "tests/cases/conformance/dynamicImport/test" +>await import('./test') : typeof "tests/cases/conformance/dynamicImport/test" +>import('./test') : Promise >'./test' : "./test" } diff --git a/tests/baselines/reference/importCallExpressionES5System.types b/tests/baselines/reference/importCallExpressionES5System.types index 02bd64142d4..e97f722b14f 100644 --- a/tests/baselines/reference/importCallExpressionES5System.types +++ b/tests/baselines/reference/importCallExpressionES5System.types @@ -5,41 +5,41 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); ->import("./0") : Promise +>import("./0") : Promise >"./0" : "./0" var p1 = import("./0"); ->p1 : Promise ->import("./0") : Promise +>p1 : Promise +>import("./0") : Promise >"./0" : "./0" p1.then(zero => { >p1.then(zero => { return zero.foo();}) : Promise ->p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->p1 : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>p1 : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0") => string +>zero : typeof "tests/cases/conformance/dynamicImport/0" return zero.foo(); >zero.foo() : string >zero.foo : () => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }); export var p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" function foo() { >foo : () => void const p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" } @@ -50,8 +50,8 @@ class C { >method : () => void const loadAsync = import ("./0"); ->loadAsync : Promise ->import ("./0") : Promise +>loadAsync : Promise +>import ("./0") : Promise >"./0" : "./0" } } @@ -63,8 +63,8 @@ export class D { >method : () => void const loadAsync = import ("./0"); ->loadAsync : Promise ->import ("./0") : Promise +>loadAsync : Promise +>import ("./0") : Promise >"./0" : "./0" } } diff --git a/tests/baselines/reference/importCallExpressionES6System.types b/tests/baselines/reference/importCallExpressionES6System.types index 02bd64142d4..e97f722b14f 100644 --- a/tests/baselines/reference/importCallExpressionES6System.types +++ b/tests/baselines/reference/importCallExpressionES6System.types @@ -5,41 +5,41 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); ->import("./0") : Promise +>import("./0") : Promise >"./0" : "./0" var p1 = import("./0"); ->p1 : Promise ->import("./0") : Promise +>p1 : Promise +>import("./0") : Promise >"./0" : "./0" p1.then(zero => { >p1.then(zero => { return zero.foo();}) : Promise ->p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->p1 : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>p1 : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0") => string +>zero : typeof "tests/cases/conformance/dynamicImport/0" return zero.foo(); >zero.foo() : string >zero.foo : () => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }); export var p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" function foo() { >foo : () => void const p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" } @@ -50,8 +50,8 @@ class C { >method : () => void const loadAsync = import ("./0"); ->loadAsync : Promise ->import ("./0") : Promise +>loadAsync : Promise +>import ("./0") : Promise >"./0" : "./0" } } @@ -63,8 +63,8 @@ export class D { >method : () => void const loadAsync = import ("./0"); ->loadAsync : Promise ->import ("./0") : Promise +>loadAsync : Promise +>import ("./0") : Promise >"./0" : "./0" } } diff --git a/tests/baselines/reference/importCallExpressionGrammarError.errors.txt b/tests/baselines/reference/importCallExpressionGrammarError.errors.txt index 6d64808e111..b39228f100d 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.errors.txt +++ b/tests/baselines/reference/importCallExpressionGrammarError.errors.txt @@ -1,13 +1,11 @@ tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(5,8): error TS1325: Specifier of dynamic import cannot be spread element. tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(7,17): error TS1325: Specifier of dynamic import cannot be spread element. tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(8,12): error TS1324: Dynamic import must have one specifier as an argument. -tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(9,19): error TS1135: Argument expression expected. -tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(9,19): error TS7036: Dynamic import's specifier must be of type 'string', but here has type 'undefined'. -tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(10,12): error TS1324: Dynamic import must have one specifier as an argument. -tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(10,19): error TS2307: Cannot find module 'pathToModule'. +tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(9,12): error TS1324: Dynamic import must have one specifier as an argument. +tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(9,19): error TS2307: Cannot find module 'pathToModule'. -==== tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts (7 errors) ==== +==== tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts (5 errors) ==== declare function getSpecifier(): string; declare var whatToLoad: boolean; @@ -22,11 +20,6 @@ tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts(10,19) const p2 = import(); ~~~~~~~~ !!! error TS1324: Dynamic import must have one specifier as an argument. - const p3 = import(,); - -!!! error TS1135: Argument expression expected. - -!!! error TS7036: Dynamic import's specifier must be of type 'string', but here has type 'undefined'. const p4 = import("pathToModule", "secondModule"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS1324: Dynamic import must have one specifier as an argument. diff --git a/tests/baselines/reference/importCallExpressionGrammarError.js b/tests/baselines/reference/importCallExpressionGrammarError.js index 435eab35d4e..61b47759581 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.js +++ b/tests/baselines/reference/importCallExpressionGrammarError.js @@ -7,7 +7,6 @@ import(...["PathModule"]); var p1 = import(...a); const p2 = import(); -const p3 = import(,); const p4 = import("pathToModule", "secondModule"); //// [importCallExpressionGrammarError.js] @@ -15,5 +14,4 @@ var a = ["./0"]; Promise.resolve().then(() => require(...["PathModule"])); var p1 = Promise.resolve().then(() => require(...a)); const p2 = Promise.resolve().then(() => require()); -const p3 = Promise.resolve().then(() => require()); const p4 = Promise.resolve().then(() => require("pathToModule")); diff --git a/tests/baselines/reference/importCallExpressionGrammarError.symbols b/tests/baselines/reference/importCallExpressionGrammarError.symbols index 7fce3af41b5..b4a0efd052e 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.symbols +++ b/tests/baselines/reference/importCallExpressionGrammarError.symbols @@ -17,9 +17,6 @@ var p1 = import(...a); const p2 = import(); >p2 : Symbol(p2, Decl(importCallExpressionGrammarError.ts, 7, 5)) -const p3 = import(,); ->p3 : Symbol(p3, Decl(importCallExpressionGrammarError.ts, 8, 5)) - const p4 = import("pathToModule", "secondModule"); ->p4 : Symbol(p4, Decl(importCallExpressionGrammarError.ts, 9, 5)) +>p4 : Symbol(p4, Decl(importCallExpressionGrammarError.ts, 8, 5)) diff --git a/tests/baselines/reference/importCallExpressionGrammarError.types b/tests/baselines/reference/importCallExpressionGrammarError.types index c9f95fbcb6b..2e2a8221a07 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.types +++ b/tests/baselines/reference/importCallExpressionGrammarError.types @@ -26,11 +26,6 @@ const p2 = import(); >p2 : Promise >import() : Promise -const p3 = import(,); ->p3 : Promise ->import(,) : Promise -> : undefined - const p4 = import("pathToModule", "secondModule"); >p4 : Promise >import("pathToModule", "secondModule") : Promise diff --git a/tests/baselines/reference/importCallExpressionInSystem1.types b/tests/baselines/reference/importCallExpressionInSystem1.types index a82d8176753..661d27d1469 100644 --- a/tests/baselines/reference/importCallExpressionInSystem1.types +++ b/tests/baselines/reference/importCallExpressionInSystem1.types @@ -5,40 +5,40 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); ->import("./0") : Promise +>import("./0") : Promise >"./0" : "./0" var p1 = import("./0"); ->p1 : Promise ->import("./0") : Promise +>p1 : Promise +>import("./0") : Promise >"./0" : "./0" p1.then(zero => { >p1.then(zero => { return zero.foo();}) : Promise ->p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->p1 : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>p1.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>p1 : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>zero => { return zero.foo();} : (zero: typeof "tests/cases/conformance/dynamicImport/0") => string +>zero : typeof "tests/cases/conformance/dynamicImport/0" return zero.foo(); >zero.foo() : string >zero.foo : () => string ->zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }); export var p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" function foo() { >foo : () => void const p2 = import("./0"); ->p2 : Promise ->import("./0") : Promise +>p2 : Promise +>import("./0") : Promise >"./0" : "./0" } diff --git a/tests/baselines/reference/importCallExpressionInSystem2.types b/tests/baselines/reference/importCallExpressionInSystem2.types index 160da81b214..44b17eb51fd 100644 --- a/tests/baselines/reference/importCallExpressionInSystem2.types +++ b/tests/baselines/reference/importCallExpressionInSystem2.types @@ -41,6 +41,6 @@ function foo(x: Promise) { foo(import("./0")); >foo(import("./0")) : void >foo : (x: Promise) => void ->import("./0") : Promise +>import("./0") : Promise >"./0" : "./0" diff --git a/tests/baselines/reference/importCallExpressionInSystem3.types b/tests/baselines/reference/importCallExpressionInSystem3.types index 08bf03fb506..e517be6e722 100644 --- a/tests/baselines/reference/importCallExpressionInSystem3.types +++ b/tests/baselines/reference/importCallExpressionInSystem3.types @@ -14,9 +14,9 @@ async function foo() { class C extends (await import("./0")).B {} >C : C >(await import("./0")).B : B ->(await import("./0")) : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } ->await import("./0") : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } ->import("./0") : Promise +>(await import("./0")) : typeof "tests/cases/conformance/dynamicImport/0" +>await import("./0") : typeof "tests/cases/conformance/dynamicImport/0" +>import("./0") : Promise >"./0" : "./0" >B : typeof B diff --git a/tests/baselines/reference/importCallExpressionInSystem4.types b/tests/baselines/reference/importCallExpressionInSystem4.types index c9f2b2e5211..156247851c9 100644 --- a/tests/baselines/reference/importCallExpressionInSystem4.types +++ b/tests/baselines/reference/importCallExpressionInSystem4.types @@ -24,27 +24,27 @@ class C { >C : C private myModule = import("./0"); ->myModule : Promise ->import("./0") : Promise +>myModule : Promise +>import("./0") : Promise >"./0" : "./0" method() { >method : () => void const loadAsync = import("./0"); ->loadAsync : Promise ->import("./0") : Promise +>loadAsync : Promise +>import("./0") : Promise >"./0" : "./0" this.myModule.then(Zero => { >this.myModule.then(Zero => { console.log(Zero.foo()); }, async err => { console.log(err); let one = await import("./1"); console.log(one.backup()); }) : Promise ->this.myModule.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->this.myModule : Promise +>this.myModule.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>this.myModule : Promise >this : this ->myModule : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->Zero => { console.log(Zero.foo()); } : (Zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => void ->Zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>myModule : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>Zero => { console.log(Zero.foo()); } : (Zero: typeof "tests/cases/conformance/dynamicImport/0") => void +>Zero : typeof "tests/cases/conformance/dynamicImport/0" console.log(Zero.foo()); >console.log(Zero.foo()) : any @@ -53,7 +53,7 @@ class C { >log : any >Zero.foo() : string >Zero.foo : () => string ->Zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>Zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }, async err => { @@ -68,9 +68,9 @@ class C { >err : any let one = await import("./1"); ->one : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } ->await import("./1") : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } ->import("./1") : Promise +>one : typeof "tests/cases/conformance/dynamicImport/1" +>await import("./1") : typeof "tests/cases/conformance/dynamicImport/1" +>import("./1") : Promise >"./1" : "./1" console.log(one.backup()); @@ -80,7 +80,7 @@ class C { >log : any >one.backup() : string >one.backup : () => string ->one : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } +>one : typeof "tests/cases/conformance/dynamicImport/1" >backup : () => string }); @@ -91,27 +91,27 @@ export class D { >D : D private myModule = import("./0"); ->myModule : Promise ->import("./0") : Promise +>myModule : Promise +>import("./0") : Promise >"./0" : "./0" method() { >method : () => void const loadAsync = import("./0"); ->loadAsync : Promise ->import("./0") : Promise +>loadAsync : Promise +>import("./0") : Promise >"./0" : "./0" this.myModule.then(Zero => { >this.myModule.then(Zero => { console.log(Zero.foo()); }, async err => { console.log(err); let one = await import("./1"); console.log(one.backup()); }) : Promise ->this.myModule.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->this.myModule : Promise +>this.myModule.then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>this.myModule : Promise >this : this ->myModule : Promise ->then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->Zero => { console.log(Zero.foo()); } : (Zero: typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; }) => void ->Zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>myModule : Promise +>then : (onfulfilled?: (value: typeof "tests/cases/conformance/dynamicImport/0") => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>Zero => { console.log(Zero.foo()); } : (Zero: typeof "tests/cases/conformance/dynamicImport/0") => void +>Zero : typeof "tests/cases/conformance/dynamicImport/0" console.log(Zero.foo()); >console.log(Zero.foo()) : any @@ -120,7 +120,7 @@ export class D { >log : any >Zero.foo() : string >Zero.foo : () => string ->Zero : typeof "tests/cases/conformance/dynamicImport/0" & { default: typeof "tests/cases/conformance/dynamicImport/0"; } +>Zero : typeof "tests/cases/conformance/dynamicImport/0" >foo : () => string }, async err => { @@ -135,9 +135,9 @@ export class D { >err : any let one = await import("./1"); ->one : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } ->await import("./1") : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } ->import("./1") : Promise +>one : typeof "tests/cases/conformance/dynamicImport/1" +>await import("./1") : typeof "tests/cases/conformance/dynamicImport/1" +>import("./1") : Promise >"./1" : "./1" console.log(one.backup()); @@ -147,7 +147,7 @@ export class D { >log : any >one.backup() : string >one.backup : () => string ->one : typeof "tests/cases/conformance/dynamicImport/1" & { default: typeof "tests/cases/conformance/dynamicImport/1"; } +>one : typeof "tests/cases/conformance/dynamicImport/1" >backup : () => string }); diff --git a/tests/baselines/reference/incompatibleTypes.errors.txt b/tests/baselines/reference/incompatibleTypes.errors.txt index 4cd68470007..1951e363eec 100644 --- a/tests/baselines/reference/incompatibleTypes.errors.txt +++ b/tests/baselines/reference/incompatibleTypes.errors.txt @@ -1,19 +1,15 @@ -tests/cases/compiler/incompatibleTypes.ts(5,7): error TS2420: Class 'C1' incorrectly implements interface 'IFoo1'. - Types of property 'p1' are incompatible. - Type '() => string' is not assignable to type '() => number'. +tests/cases/compiler/incompatibleTypes.ts(6,12): error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type 'IFoo1'. + Type '() => string' is not assignable to type '() => number'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/incompatibleTypes.ts(16,12): error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type 'IFoo2'. + Type '(n: number) => number' is not assignable to type '(s: string) => number'. + Types of parameters 'n' and 's' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/compiler/incompatibleTypes.ts(15,7): error TS2420: Class 'C2' incorrectly implements interface 'IFoo2'. - Types of property 'p1' are incompatible. - Type '(n: number) => number' is not assignable to type '(s: string) => number'. - Types of parameters 'n' and 's' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/incompatibleTypes.ts(25,7): error TS2420: Class 'C3' incorrectly implements interface 'IFoo3'. - Types of property 'p1' are incompatible. - Type 'number' is not assignable to type 'string'. -tests/cases/compiler/incompatibleTypes.ts(33,7): error TS2420: Class 'C4' incorrectly implements interface 'IFoo4'. - Types of property 'p1' are incompatible. - Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. - Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. +tests/cases/compiler/incompatibleTypes.ts(26,12): error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'IFoo3'. + Type 'number' is not assignable to type 'string'. +tests/cases/compiler/incompatibleTypes.ts(34,12): error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type 'IFoo4'. + Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. + Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. tests/cases/compiler/incompatibleTypes.ts(42,5): error TS2345: Argument of type 'C1' is not assignable to parameter of type 'IFoo2'. Types of property 'p1' are incompatible. Type '() => string' is not assignable to type '(s: string) => number'. @@ -32,12 +28,11 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => } class C1 implements IFoo1 { // incompatible on the return type - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'IFoo1'. -!!! error TS2420: Types of property 'p1' are incompatible. -!!! error TS2420: Type '() => string' is not assignable to type '() => number'. -!!! error TS2420: Type 'string' is not assignable to type 'number'. public p1() { + ~~ +!!! error TS2416: Property 'p1' in type 'C1' is not assignable to the same property in base type 'IFoo1'. +!!! error TS2416: Type '() => string' is not assignable to type '() => number'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. return "s"; } } @@ -47,13 +42,12 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => } class C2 implements IFoo2 { // incompatible on the param type - ~~ -!!! error TS2420: Class 'C2' incorrectly implements interface 'IFoo2'. -!!! error TS2420: Types of property 'p1' are incompatible. -!!! error TS2420: Type '(n: number) => number' is not assignable to type '(s: string) => number'. -!!! error TS2420: Types of parameters 'n' and 's' are incompatible. -!!! error TS2420: Type 'string' is not assignable to type 'number'. public p1(n:number) { + ~~ +!!! error TS2416: Property 'p1' in type 'C2' is not assignable to the same property in base type 'IFoo2'. +!!! error TS2416: Type '(n: number) => number' is not assignable to type '(s: string) => number'. +!!! error TS2416: Types of parameters 'n' and 's' are incompatible. +!!! error TS2416: Type 'string' is not assignable to type 'number'. return 0; } } @@ -63,11 +57,10 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => } class C3 implements IFoo3 { // incompatible on the property type - ~~ -!!! error TS2420: Class 'C3' incorrectly implements interface 'IFoo3'. -!!! error TS2420: Types of property 'p1' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. public p1: number; + ~~ +!!! error TS2416: Property 'p1' in type 'C3' is not assignable to the same property in base type 'IFoo3'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. } interface IFoo4 { @@ -75,12 +68,11 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => } class C4 implements IFoo4 { // incompatible on the property type - ~~ -!!! error TS2420: Class 'C4' incorrectly implements interface 'IFoo4'. -!!! error TS2420: Types of property 'p1' are incompatible. -!!! error TS2420: Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. -!!! error TS2420: Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. public p1: { c: { b: string; }; d: string; }; + ~~ +!!! error TS2416: Property 'p1' in type 'C4' is not assignable to the same property in base type 'IFoo4'. +!!! error TS2416: Type '{ c: { b: string; }; d: string; }' is not assignable to type '{ a: { a: string; }; b: string; }'. +!!! error TS2416: Property 'a' is missing in type '{ c: { b: string; }; d: string; }'. } function if1(i: IFoo1): void; diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt new file mode 100644 index 00000000000..5300c97a576 --- /dev/null +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts(2,32): error TS2313: Type parameter 'P' has a circular constraint. + + +==== tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts (1 errors) ==== + // #17847 + function sum(n: number, v: T, k: K) { + ~ +!!! error TS2313: Type parameter 'P' has a circular constraint. + n += v[k]; + } + \ No newline at end of file diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.js b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.js new file mode 100644 index 00000000000..44954f5c7c2 --- /dev/null +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.js @@ -0,0 +1,12 @@ +//// [incorrectRecursiveMappedTypeConstraint.ts] +// #17847 +function sum(n: number, v: T, k: K) { + n += v[k]; +} + + +//// [incorrectRecursiveMappedTypeConstraint.js] +// #17847 +function sum(n, v, k) { + n += v[k]; +} diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.symbols b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.symbols new file mode 100644 index 00000000000..42cc7b1f4fb --- /dev/null +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts === +// #17847 +function sum(n: number, v: T, k: K) { +>sum : Symbol(sum, Decl(incorrectRecursiveMappedTypeConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 13)) +>P : Symbol(P, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 26)) +>T : Symbol(T, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 13)) +>K : Symbol(K, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 44)) +>T : Symbol(T, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 13)) +>n : Symbol(n, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 64)) +>v : Symbol(v, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 74)) +>T : Symbol(T, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 13)) +>k : Symbol(k, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 80)) +>K : Symbol(K, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 44)) + + n += v[k]; +>n : Symbol(n, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 64)) +>v : Symbol(v, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 74)) +>k : Symbol(k, Decl(incorrectRecursiveMappedTypeConstraint.ts, 1, 80)) +} + diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types new file mode 100644 index 00000000000..b6589956216 --- /dev/null +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts === +// #17847 +function sum(n: number, v: T, k: K) { +>sum : (n: number, v: T, k: K) => void +>T : T +>P : P +>T : T +>K : K +>T : T +>n : number +>v : T +>T : T +>k : K +>K : K + + n += v[k]; +>n += v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K +} + diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.js b/tests/baselines/reference/indexedAccessRetainsIndexSignature.js new file mode 100644 index 00000000000..1b77b95527b --- /dev/null +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.js @@ -0,0 +1,15 @@ +//// [indexedAccessRetainsIndexSignature.ts] +type Diff = + ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] +type Omit = Pick> +type Omit1 = Pick>; +// is in fact an equivalent of + +type Omit2 = {[P in Diff]: T[P]}; + +type O = Omit<{ a: number, b: string }, 'a'> +const o: O = { b: '' } + + +//// [indexedAccessRetainsIndexSignature.js] +var o = { b: '' }; diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols b/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols new file mode 100644 index 00000000000..9858f6fc162 --- /dev/null +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols @@ -0,0 +1,62 @@ +=== tests/cases/compiler/indexedAccessRetainsIndexSignature.ts === +type Diff = +>Diff : Symbol(Diff, Decl(indexedAccessRetainsIndexSignature.ts, 0, 0)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 0, 10)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 0, 27)) + + ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] +>P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 1, 8)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 0, 10)) +>P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 1, 8)) +>P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 1, 26)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 0, 27)) +>x : Symbol(x, Decl(indexedAccessRetainsIndexSignature.ts, 1, 48)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 0, 10)) + +type Omit = Pick> +>Omit : Symbol(Omit, Decl(indexedAccessRetainsIndexSignature.ts, 1, 71)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 2, 12)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) +>Diff : Symbol(Diff, Decl(indexedAccessRetainsIndexSignature.ts, 0, 0)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 2, 10)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 2, 12)) + +type Omit1 = Pick>; +>Omit1 : Symbol(Omit1, Decl(indexedAccessRetainsIndexSignature.ts, 2, 59)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 3, 11)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 3, 13)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 3, 11)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 3, 11)) +>Diff : Symbol(Diff, Decl(indexedAccessRetainsIndexSignature.ts, 0, 0)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 3, 11)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 3, 13)) + +// is in fact an equivalent of + +type Omit2 = {[P in Diff]: T[P]}; +>Omit2 : Symbol(Omit2, Decl(indexedAccessRetainsIndexSignature.ts, 3, 61)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 6, 11)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 6, 13)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 6, 11)) +>P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 6, 37)) +>Diff : Symbol(Diff, Decl(indexedAccessRetainsIndexSignature.ts, 0, 0)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 6, 11)) +>K : Symbol(K, Decl(indexedAccessRetainsIndexSignature.ts, 6, 13)) +>T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 6, 11)) +>P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 6, 37)) + +type O = Omit<{ a: number, b: string }, 'a'> +>O : Symbol(O, Decl(indexedAccessRetainsIndexSignature.ts, 6, 67)) +>Omit : Symbol(Omit, Decl(indexedAccessRetainsIndexSignature.ts, 1, 71)) +>a : Symbol(a, Decl(indexedAccessRetainsIndexSignature.ts, 8, 15)) +>b : Symbol(b, Decl(indexedAccessRetainsIndexSignature.ts, 8, 26)) + +const o: O = { b: '' } +>o : Symbol(o, Decl(indexedAccessRetainsIndexSignature.ts, 9, 5)) +>O : Symbol(O, Decl(indexedAccessRetainsIndexSignature.ts, 6, 67)) +>b : Symbol(b, Decl(indexedAccessRetainsIndexSignature.ts, 9, 14)) + diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.types b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types new file mode 100644 index 00000000000..8dcbe9bf218 --- /dev/null +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types @@ -0,0 +1,64 @@ +=== tests/cases/compiler/indexedAccessRetainsIndexSignature.ts === +type Diff = +>Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>T : T +>U : U + + ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] +>P : P +>T : T +>P : P +>P : P +>U : U +>x : string +>T : T + +type Omit = Pick> +>Omit : Pick +>U : U +>K : K +>U : U +>Pick : Pick +>U : U +>Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>U : U +>K : K + +type Omit1 = Pick>; +>Omit1 : Pick +>U : U +>K : K +>U : U +>Pick : Pick +>U : U +>Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>U : U +>K : K + +// is in fact an equivalent of + +type Omit2 = {[P in Diff]: T[P]}; +>Omit2 : Omit2 +>T : T +>K : K +>T : T +>P : P +>Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] +>T : T +>K : K +>T : T +>P : P + +type O = Omit<{ a: number, b: string }, 'a'> +>O : Pick<{ a: number; b: string; }, "b"> +>Omit : Pick +>a : number +>b : string + +const o: O = { b: '' } +>o : Pick<{ a: number; b: string; }, "b"> +>O : Pick<{ a: number; b: string; }, "b"> +>{ b: '' } : { b: string; } +>b : string +>'' : "" + diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index 316486e709f..7e104e77f98 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -1,9 +1,17 @@ tests/cases/compiler/indexerConstraints2.ts(9,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(17,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +tests/cases/compiler/indexerConstraints2.ts(34,6): error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[n: number]: A' instead. +tests/cases/compiler/indexerConstraints2.ts(40,6): error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[s: string]: A' instead. +tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. +tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(64,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(74,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. -==== tests/cases/compiler/indexerConstraints2.ts (3 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (11 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -37,4 +45,67 @@ tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index t ~~~~~~~~~~~~~~~ !!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. [s: string]: B; + } + + + type AliasedNumber = number; + + interface L { + [n: AliasedNumber]: A; + ~ +!!! error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[n: number]: A' instead. + } + + type AliasedString = string; + + interface M { + [s: AliasedString]: A; + ~ +!!! error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[s: string]: A' instead. + } + + type AliasedBoolean = boolean; + + interface N { + [b: AliasedBoolean]: A; + ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + type IndexableUnion = "foo" | "bar"; + + interface O { + [u: IndexableUnion]: A; + ~ +!!! error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. + } + + type NonIndexableUnion = boolean | {}; + + interface P { + [u: NonIndexableUnion]: A; + ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + type NonIndexableUnion2 = string | number; + + interface Q { + [u: NonIndexableUnion2]: A; + ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + type NonIndexableUnion3 = "foo" | 42; + + interface R { + [u: NonIndexableUnion3]: A; + ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + } + + interface S { + [u: "foo" | "bar"]: A; + ~ +!!! error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.js b/tests/baselines/reference/indexerConstraints2.js index f5bfc3c64d8..d6fb40ba22d 100644 --- a/tests/baselines/reference/indexerConstraints2.js +++ b/tests/baselines/reference/indexerConstraints2.js @@ -26,6 +26,53 @@ class J { class K extends J { [n: number]: A; [s: string]: B; +} + + +type AliasedNumber = number; + +interface L { + [n: AliasedNumber]: A; +} + +type AliasedString = string; + +interface M { + [s: AliasedString]: A; +} + +type AliasedBoolean = boolean; + +interface N { + [b: AliasedBoolean]: A; +} + +type IndexableUnion = "foo" | "bar"; + +interface O { + [u: IndexableUnion]: A; +} + +type NonIndexableUnion = boolean | {}; + +interface P { + [u: NonIndexableUnion]: A; +} + +type NonIndexableUnion2 = string | number; + +interface Q { + [u: NonIndexableUnion2]: A; +} + +type NonIndexableUnion3 = "foo" | 42; + +interface R { + [u: NonIndexableUnion3]: A; +} + +interface S { + [u: "foo" | "bar"]: A; } //// [indexerConstraints2.js] diff --git a/tests/baselines/reference/indexerConstraints2.symbols b/tests/baselines/reference/indexerConstraints2.symbols index de606a2c2e4..4cb5558a8ce 100644 --- a/tests/baselines/reference/indexerConstraints2.symbols +++ b/tests/baselines/reference/indexerConstraints2.symbols @@ -62,3 +62,96 @@ class K extends J { >s : Symbol(s, Decl(indexerConstraints2.ts, 26, 5)) >B : Symbol(B, Decl(indexerConstraints2.ts, 0, 22)) } + + +type AliasedNumber = number; +>AliasedNumber : Symbol(AliasedNumber, Decl(indexerConstraints2.ts, 27, 1)) + +interface L { +>L : Symbol(L, Decl(indexerConstraints2.ts, 30, 28)) + + [n: AliasedNumber]: A; +>n : Symbol(n, Decl(indexerConstraints2.ts, 33, 5)) +>AliasedNumber : Symbol(AliasedNumber, Decl(indexerConstraints2.ts, 27, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type AliasedString = string; +>AliasedString : Symbol(AliasedString, Decl(indexerConstraints2.ts, 34, 1)) + +interface M { +>M : Symbol(M, Decl(indexerConstraints2.ts, 36, 28)) + + [s: AliasedString]: A; +>s : Symbol(s, Decl(indexerConstraints2.ts, 39, 5)) +>AliasedString : Symbol(AliasedString, Decl(indexerConstraints2.ts, 34, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type AliasedBoolean = boolean; +>AliasedBoolean : Symbol(AliasedBoolean, Decl(indexerConstraints2.ts, 40, 1)) + +interface N { +>N : Symbol(N, Decl(indexerConstraints2.ts, 42, 30)) + + [b: AliasedBoolean]: A; +>b : Symbol(b, Decl(indexerConstraints2.ts, 45, 5)) +>AliasedBoolean : Symbol(AliasedBoolean, Decl(indexerConstraints2.ts, 40, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type IndexableUnion = "foo" | "bar"; +>IndexableUnion : Symbol(IndexableUnion, Decl(indexerConstraints2.ts, 46, 1)) + +interface O { +>O : Symbol(O, Decl(indexerConstraints2.ts, 48, 36)) + + [u: IndexableUnion]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 51, 5)) +>IndexableUnion : Symbol(IndexableUnion, Decl(indexerConstraints2.ts, 46, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type NonIndexableUnion = boolean | {}; +>NonIndexableUnion : Symbol(NonIndexableUnion, Decl(indexerConstraints2.ts, 52, 1)) + +interface P { +>P : Symbol(P, Decl(indexerConstraints2.ts, 54, 38)) + + [u: NonIndexableUnion]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 57, 5)) +>NonIndexableUnion : Symbol(NonIndexableUnion, Decl(indexerConstraints2.ts, 52, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type NonIndexableUnion2 = string | number; +>NonIndexableUnion2 : Symbol(NonIndexableUnion2, Decl(indexerConstraints2.ts, 58, 1)) + +interface Q { +>Q : Symbol(Q, Decl(indexerConstraints2.ts, 60, 42)) + + [u: NonIndexableUnion2]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 63, 5)) +>NonIndexableUnion2 : Symbol(NonIndexableUnion2, Decl(indexerConstraints2.ts, 58, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type NonIndexableUnion3 = "foo" | 42; +>NonIndexableUnion3 : Symbol(NonIndexableUnion3, Decl(indexerConstraints2.ts, 64, 1)) + +interface R { +>R : Symbol(R, Decl(indexerConstraints2.ts, 66, 37)) + + [u: NonIndexableUnion3]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 69, 5)) +>NonIndexableUnion3 : Symbol(NonIndexableUnion3, Decl(indexerConstraints2.ts, 64, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +interface S { +>S : Symbol(S, Decl(indexerConstraints2.ts, 70, 1)) + + [u: "foo" | "bar"]: A; +>u : Symbol(u, Decl(indexerConstraints2.ts, 73, 5)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index 2a52f0e41db..e2db782d788 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -62,3 +62,96 @@ class K extends J { >s : string >B : B } + + +type AliasedNumber = number; +>AliasedNumber : number + +interface L { +>L : L + + [n: AliasedNumber]: A; +>n : number +>AliasedNumber : number +>A : A +} + +type AliasedString = string; +>AliasedString : string + +interface M { +>M : M + + [s: AliasedString]: A; +>s : string +>AliasedString : string +>A : A +} + +type AliasedBoolean = boolean; +>AliasedBoolean : boolean + +interface N { +>N : N + + [b: AliasedBoolean]: A; +>b : boolean +>AliasedBoolean : boolean +>A : A +} + +type IndexableUnion = "foo" | "bar"; +>IndexableUnion : IndexableUnion + +interface O { +>O : O + + [u: IndexableUnion]: A; +>u : IndexableUnion +>IndexableUnion : IndexableUnion +>A : A +} + +type NonIndexableUnion = boolean | {}; +>NonIndexableUnion : NonIndexableUnion + +interface P { +>P : P + + [u: NonIndexableUnion]: A; +>u : NonIndexableUnion +>NonIndexableUnion : NonIndexableUnion +>A : A +} + +type NonIndexableUnion2 = string | number; +>NonIndexableUnion2 : NonIndexableUnion2 + +interface Q { +>Q : Q + + [u: NonIndexableUnion2]: A; +>u : NonIndexableUnion2 +>NonIndexableUnion2 : NonIndexableUnion2 +>A : A +} + +type NonIndexableUnion3 = "foo" | 42; +>NonIndexableUnion3 : NonIndexableUnion3 + +interface R { +>R : R + + [u: NonIndexableUnion3]: A; +>u : NonIndexableUnion3 +>NonIndexableUnion3 : NonIndexableUnion3 +>A : A +} + +interface S { +>S : S + + [u: "foo" | "bar"]: A; +>u : IndexableUnion +>A : A +} diff --git a/tests/baselines/reference/inheritance.errors.txt b/tests/baselines/reference/inheritance.errors.txt index c667e8b001e..b476f1399b4 100644 --- a/tests/baselines/reference/inheritance.errors.txt +++ b/tests/baselines/reference/inheritance.errors.txt @@ -1,7 +1,6 @@ -tests/cases/compiler/inheritance.ts(30,7): error TS2415: Class 'Baad' incorrectly extends base class 'Good'. - Types of property 'g' are incompatible. - Type '(n: number) => number' is not assignable to type '() => number'. tests/cases/compiler/inheritance.ts(31,12): error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. +tests/cases/compiler/inheritance.ts(32,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. + Type '(n: number) => number' is not assignable to type '() => number'. ==== tests/cases/compiler/inheritance.ts (2 errors) ==== @@ -35,13 +34,12 @@ tests/cases/compiler/inheritance.ts(31,12): error TS2425: Class 'Good' defines i } class Baad extends Good { - ~~~~ -!!! error TS2415: Class 'Baad' incorrectly extends base class 'Good'. -!!! error TS2415: Types of property 'g' are incompatible. -!!! error TS2415: Type '(n: number) => number' is not assignable to type '() => number'. public f(): number { return 0; } ~ !!! error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. public g(n: number) { return 0; } + ~ +!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. +!!! error TS2416: Type '(n: number) => number' is not assignable to type '() => number'. } \ No newline at end of file diff --git a/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt b/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt index 6fde83e08b0..66d955324c8 100644 --- a/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt +++ b/tests/baselines/reference/inheritanceMemberAccessorOverridingMethod.errors.txt @@ -1,12 +1,13 @@ -tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(7,7): error TS2415: Class 'b' incorrectly extends base class 'a'. - Types of property 'x' are incompatible. - Type 'string' is not assignable to type '() => string'. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. + Type 'string' is not assignable to type '() => string'. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(8,9): error TS2423: Class 'a' defines instance member function 'x', but extended class 'b' defines it as instance member accessor. tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. + Type 'string' is not assignable to type '() => string'. -==== tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts (4 errors) ==== +==== tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts (5 errors) ==== class a { x() { return "20"; @@ -14,20 +15,22 @@ tests/cases/compiler/inheritanceMemberAccessorOverridingMethod.ts(11,9): error T } class b extends a { - ~ -!!! error TS2415: Class 'b' incorrectly extends base class 'a'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type '() => string'. get x() { ~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. ~ +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. +!!! error TS2416: Type 'string' is not assignable to type '() => string'. + ~ !!! error TS2423: Class 'a' defines instance member function 'x', but extended class 'b' defines it as instance member accessor. return "20"; } set x(aValue: string) { ~ !!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + ~ +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. +!!! error TS2416: Type 'string' is not assignable to type '() => string'. } } \ No newline at end of file diff --git a/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt b/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt index 283e7ce3f18..38a390d5063 100644 --- a/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt +++ b/tests/baselines/reference/inheritanceMemberFuncOverridingAccessor.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(2,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(5,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(10,7): error TS2415: Class 'b' incorrectly extends base class 'a'. - Types of property 'x' are incompatible. - Type '() => string' is not assignable to type 'string'. +tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. + Type '() => string' is not assignable to type 'string'. tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2426: Class 'a' defines instance member accessor 'x', but extended class 'b' defines it as instance member function. @@ -21,12 +20,11 @@ tests/cases/compiler/inheritanceMemberFuncOverridingAccessor.ts(11,5): error TS2 } class b extends a { - ~ -!!! error TS2415: Class 'b' incorrectly extends base class 'a'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type '() => string' is not assignable to type 'string'. x() { ~ +!!! error TS2416: Property 'x' in type 'b' is not assignable to the same property in base type 'a'. +!!! error TS2416: Type '() => string' is not assignable to type 'string'. + ~ !!! error TS2426: Class 'a' defines instance member accessor 'x', but extended class 'b' defines it as instance member function. return "20"; } diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.errors.txt b/tests/baselines/reference/initializedDestructuringAssignmentTypes.errors.txt new file mode 100644 index 00000000000..9a8cb12b45b --- /dev/null +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.errors.txt @@ -0,0 +1,9 @@ +tests/cases/compiler/initializedDestructuringAssignmentTypes.ts(3,3): error TS2339: Property 'toFixed' does not exist on type 'string'. + + +==== tests/cases/compiler/initializedDestructuringAssignmentTypes.ts (1 errors) ==== + const [, a = ''] = ''.match('') || []; + + a.toFixed() + ~~~~~~~ +!!! error TS2339: Property 'toFixed' does not exist on type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.js b/tests/baselines/reference/initializedDestructuringAssignmentTypes.js new file mode 100644 index 00000000000..ee38f30ef5f --- /dev/null +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.js @@ -0,0 +1,8 @@ +//// [initializedDestructuringAssignmentTypes.ts] +const [, a = ''] = ''.match('') || []; + +a.toFixed() + +//// [initializedDestructuringAssignmentTypes.js] +var _a = ''.match('') || [], _b = _a[1], a = _b === void 0 ? '' : _b; +a.toFixed(); diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.symbols b/tests/baselines/reference/initializedDestructuringAssignmentTypes.symbols new file mode 100644 index 00000000000..7d9cf531f0d --- /dev/null +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/initializedDestructuringAssignmentTypes.ts === +const [, a = ''] = ''.match('') || []; +>a : Symbol(a, Decl(initializedDestructuringAssignmentTypes.ts, 0, 8)) +>''.match : Symbol(String.match, Decl(lib.d.ts, --, --)) +>match : Symbol(String.match, Decl(lib.d.ts, --, --)) + +a.toFixed() +>a : Symbol(a, Decl(initializedDestructuringAssignmentTypes.ts, 0, 8)) + diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.types b/tests/baselines/reference/initializedDestructuringAssignmentTypes.types new file mode 100644 index 00000000000..55ddfa4f56b --- /dev/null +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/initializedDestructuringAssignmentTypes.ts === +const [, a = ''] = ''.match('') || []; +> : undefined +>a : string +>'' : "" +>''.match('') || [] : RegExpMatchArray | [undefined, ""] +>''.match('') : RegExpMatchArray +>''.match : (regexp: string | RegExp) => RegExpMatchArray +>'' : "" +>match : (regexp: string | RegExp) => RegExpMatchArray +>'' : "" +>[] : [undefined, ""] + +a.toFixed() +>a.toFixed() : any +>a.toFixed : any +>a : string +>toFixed : any + diff --git a/tests/baselines/reference/instanceSubtypeCheck2.errors.txt b/tests/baselines/reference/instanceSubtypeCheck2.errors.txt index 81982ac3ec7..84b454d7ea0 100644 --- a/tests/baselines/reference/instanceSubtypeCheck2.errors.txt +++ b/tests/baselines/reference/instanceSubtypeCheck2.errors.txt @@ -1,6 +1,5 @@ -tests/cases/compiler/instanceSubtypeCheck2.ts(5,7): error TS2415: Class 'C2' incorrectly extends base class 'C1'. - Types of property 'x' are incompatible. - Type 'string' is not assignable to type 'C2'. +tests/cases/compiler/instanceSubtypeCheck2.ts(6,5): error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C1'. + Type 'string' is not assignable to type 'C2'. ==== tests/cases/compiler/instanceSubtypeCheck2.ts (1 errors) ==== @@ -9,9 +8,8 @@ tests/cases/compiler/instanceSubtypeCheck2.ts(5,7): error TS2415: Class 'C2' } class C2 extends C1 { - ~~ -!!! error TS2415: Class 'C2' incorrectly extends base class 'C1'. -!!! error TS2415: Types of property 'x' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'C2'. x: string + ~ +!!! error TS2416: Property 'x' in type 'C2' is not assignable to the same property in base type 'C1'. +!!! error TS2416: Type 'string' is not assignable to type 'C2'. } \ No newline at end of file diff --git a/tests/baselines/reference/interfaceDeclaration3.errors.txt b/tests/baselines/reference/interfaceDeclaration3.errors.txt index a9bd1d42647..2ea419aaa52 100644 --- a/tests/baselines/reference/interfaceDeclaration3.errors.txt +++ b/tests/baselines/reference/interfaceDeclaration3.errors.txt @@ -1,9 +1,7 @@ -tests/cases/compiler/interfaceDeclaration3.ts(6,11): error TS2420: Class 'C1' incorrectly implements interface 'I1'. - Types of property 'item' are incompatible. - Type 'number' is not assignable to type 'string'. -tests/cases/compiler/interfaceDeclaration3.ts(31,11): error TS2420: Class 'C1' incorrectly implements interface 'I1'. - Types of property 'item' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/compiler/interfaceDeclaration3.ts(7,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. + Type 'number' is not assignable to type 'string'. +tests/cases/compiler/interfaceDeclaration3.ts(32,16): error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. + Type 'number' is not assignable to type 'string'. tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I2' incorrectly extends interface 'I1'. Types of property 'item' are incompatible. Type 'string' is not assignable to type 'number'. @@ -16,11 +14,10 @@ tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I interface I1 { item:string; } interface I2 { item:number; } class C1 implements I1 { - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'I1'. -!!! error TS2420: Types of property 'item' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. public item:number; + ~~~~ +!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. } class C2 implements I1 { public item:string; @@ -45,11 +42,10 @@ tests/cases/compiler/interfaceDeclaration3.ts(54,11): error TS2430: Interface 'I export interface I1 { item:string; } } class C1 implements I1 { - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'I1'. -!!! error TS2420: Types of property 'item' are incompatible. -!!! error TS2420: Type 'number' is not assignable to type 'string'. public item:number; + ~~~~ +!!! error TS2416: Property 'item' in type 'C1' is not assignable to the same property in base type 'I1'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. } class C2 implements I1 { public item:string; diff --git a/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt b/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt index 035fe89cd35..d6af9ce44dd 100644 --- a/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt +++ b/tests/baselines/reference/interfaceExtendsClassWithPrivate2.errors.txt @@ -2,10 +2,10 @@ tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(10,7): error TS2415: C Types have separate declarations of a private property 'x'. tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(10,7): error TS2420: Class 'D' incorrectly implements interface 'I'. Types have separate declarations of a private property 'x'. -tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(18,7): error TS2415: Class 'D2' incorrectly extends base class 'C'. - Types have separate declarations of a private property 'x'. -tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(18,7): error TS2420: Class 'D2' incorrectly implements interface 'I'. - Types have separate declarations of a private property 'x'. +tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'C'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(20,13): error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'I'. + Type 'string' is not assignable to type 'number'. ==== tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts (4 errors) ==== @@ -33,14 +33,14 @@ tests/cases/compiler/interfaceExtendsClassWithPrivate2.ts(18,7): error TS2420: C } class D2 extends C implements I { // error - ~~ -!!! error TS2415: Class 'D2' incorrectly extends base class 'C'. -!!! error TS2415: Types have separate declarations of a private property 'x'. - ~~ -!!! error TS2420: Class 'D2' incorrectly implements interface 'I'. -!!! error TS2420: Types have separate declarations of a private property 'x'. public foo(x: any) { return x; } private x = ""; + ~ +!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'C'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2416: Property 'x' in type 'D2' is not assignable to the same property in base type 'I'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. other(x: any) { return x; } bar() { } } \ No newline at end of file diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt index 155cf4bd5ad..87faadeb4a6 100644 --- a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt @@ -14,22 +14,16 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(11,11): error TS2430: Interface 'I5' incorrectly extends interface 'T5'. Types of property 'c' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(16,7): error TS2415: Class 'C1' incorrectly extends base class 'T1'. - Types of property 'a' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,7): error TS2415: Class 'C2' incorrectly extends base class 'T2'. - Type 'C2' is not assignable to type '{ b: number; }'. - Types of property 'b' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,7): error TS2415: Class 'C3' incorrectly extends base class 'number[]'. - Types of property 'length' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,7): error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. - Types of property '0' are incompatible. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,7): error TS2415: Class 'C5' incorrectly extends base class 'T5'. - Types of property 'c' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(16,38): error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'T1'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,38): error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'T2'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,38): error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number[]'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,38): error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type '[string, number]'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,38): error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'T5'. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(30,11): error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. Types of property 'a' are incompatible. Type 'number' is not assignable to type 'string'. @@ -99,31 +93,25 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI declare function Constructor(): Constructor; class C1 extends Constructor() { a: string } - ~~ -!!! error TS2415: Class 'C1' incorrectly extends base class 'T1'. -!!! error TS2415: Types of property 'a' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2416: Property 'a' in type 'C1' is not assignable to the same property in base type 'T1'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. class C2 extends Constructor() { b: string } - ~~ -!!! error TS2415: Class 'C2' incorrectly extends base class 'T2'. -!!! error TS2415: Type 'C2' is not assignable to type '{ b: number; }'. -!!! error TS2415: Types of property 'b' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2416: Property 'b' in type 'C2' is not assignable to the same property in base type 'T2'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. class C3 extends Constructor() { length: string } - ~~ -!!! error TS2415: Class 'C3' incorrectly extends base class 'number[]'. -!!! error TS2415: Types of property 'length' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'number'. + ~~~~~~ +!!! error TS2416: Property 'length' in type 'C3' is not assignable to the same property in base type 'number[]'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. class C4 extends Constructor() { 0: number } - ~~ -!!! error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. -!!! error TS2415: Types of property '0' are incompatible. -!!! error TS2415: Type 'number' is not assignable to type 'string'. + ~ +!!! error TS2416: Property '0' in type 'C4' is not assignable to the same property in base type '[string, number]'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. class C5 extends Constructor() { c: number } - ~~ -!!! error TS2415: Class 'C5' incorrectly extends base class 'T5'. -!!! error TS2415: Types of property 'c' are incompatible. -!!! error TS2415: Type 'number' is not assignable to type 'string'. + ~ +!!! error TS2416: Property 'c' in type 'C5' is not assignable to the same property in base type 'T5'. +!!! error TS2416: Type 'number' is not assignable to type 'string'. declare class CX { static a: string } declare enum EX { A, B, C } diff --git a/tests/baselines/reference/interfaceImplementation7.errors.txt b/tests/baselines/reference/interfaceImplementation7.errors.txt index 1025a1f5296..a275090b199 100644 --- a/tests/baselines/reference/interfaceImplementation7.errors.txt +++ b/tests/baselines/reference/interfaceImplementation7.errors.txt @@ -1,9 +1,8 @@ tests/cases/compiler/interfaceImplementation7.ts(4,11): error TS2320: Interface 'i3' cannot simultaneously extend types 'i1' and 'i2'. Named property 'name' of types 'i1' and 'i2' are not identical. -tests/cases/compiler/interfaceImplementation7.ts(7,7): error TS2420: Class 'C1' incorrectly implements interface 'i4'. - Types of property 'name' are incompatible. - Type '() => string' is not assignable to type '() => { s: string; n: number; }'. - Type 'string' is not assignable to type '{ s: string; n: number; }'. +tests/cases/compiler/interfaceImplementation7.ts(8,12): error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type 'i4'. + Type '() => string' is not assignable to type '() => { s: string; n: number; }'. + Type 'string' is not assignable to type '{ s: string; n: number; }'. ==== tests/cases/compiler/interfaceImplementation7.ts (2 errors) ==== @@ -17,11 +16,10 @@ tests/cases/compiler/interfaceImplementation7.ts(7,7): error TS2420: Class 'C1' interface i4 extends i1, i2 { name(): { s: string; n: number; }; } class C1 implements i4 { - ~~ -!!! error TS2420: Class 'C1' incorrectly implements interface 'i4'. -!!! error TS2420: Types of property 'name' are incompatible. -!!! error TS2420: Type '() => string' is not assignable to type '() => { s: string; n: number; }'. -!!! error TS2420: Type 'string' is not assignable to type '{ s: string; n: number; }'. public name(): string { return ""; } + ~~~~ +!!! error TS2416: Property 'name' in type 'C1' is not assignable to the same property in base type 'i4'. +!!! error TS2416: Type '() => string' is not assignable to type '() => { s: string; n: number; }'. +!!! error TS2416: Type 'string' is not assignable to type '{ s: string; n: number; }'. } \ No newline at end of file diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.js b/tests/baselines/reference/isomorphicMappedTypeInference.js index 9c4e8c9e9f1..e7df29894f9 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.js +++ b/tests/baselines/reference/isomorphicMappedTypeInference.js @@ -275,9 +275,7 @@ declare function f3(): void; declare function f4(): void; declare function makeRecord(obj: { [P in K]: T; -}): { - [P in K]: T; -}; +}): { [P in K]: T; }; declare function f5(s: string): void; declare function makeDictionary(obj: { [x: string]: T; @@ -310,17 +308,11 @@ declare type Spec = { */ declare function applySpec(obj: Spec): (...args: any[]) => T; declare var g1: (...args: any[]) => { - sum: number; - nested: { - mul: string; - }; + sum: any; + nested: any; }; declare var g2: (...args: any[]) => { - foo: { - bar: { - baz: boolean; - }; - }; + foo: any; }; declare const foo: (object: T, partial: Partial) => T; declare let o: { diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index e60e1fb7b4c..abb1bca93fc 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -203,15 +203,15 @@ function f2() { }; let v = unboxify(b); ->v : { a: number; b: string; c: boolean; } ->unboxify(b) : { a: number; b: string; c: boolean; } +>v : { a: any; b: any; c: any; } +>unboxify(b) : { a: any; b: any; c: any; } >unboxify : (obj: Boxified) => T >b : { a: Box; b: Box; c: Box; } let x: number = v.a; >x : number >v.a : number ->v : { a: number; b: string; c: boolean; } +>v : { a: any; b: any; c: any; } >a : number } @@ -277,11 +277,11 @@ function f4() { }; b = boxify(unboxify(b)); ->b = boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }> +>b = boxify(unboxify(b)) : Boxified<{ a: any; b: any; c: any; }> >b : { a: Box; b: Box; c: Box; } ->boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }> +>boxify(unboxify(b)) : Boxified<{ a: any; b: any; c: any; }> >boxify : (obj: T) => Boxified ->unboxify(b) : { a: number; b: string; c: boolean; } +>unboxify(b) : { a: any; b: any; c: any; } >unboxify : (obj: Boxified) => T >b : { a: Box; b: Box; c: Box; } @@ -338,15 +338,15 @@ function f5(s: string) { }); let v = unboxify(b); ->v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; } ->unboxify(b) : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; } +>v : { a: any; b: any; c: any; } +>unboxify(b) : { a: any; b: any; c: any; } >unboxify : (obj: Boxified) => T >b : { a: Box | Box | Box; b: Box | Box | Box; c: Box | Box | Box; } let x: string | number | boolean = v.a; >x : string | number | boolean >v.a : string | number | boolean ->v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; } +>v : { a: any; b: any; c: any; } >a : string | number | boolean } @@ -391,15 +391,15 @@ function f6(s: string) { }); let v = unboxify(b); ->v : { [x: string]: string | number | boolean; } ->unboxify(b) : { [x: string]: string | number | boolean; } +>v : { [x: string]: any; } +>unboxify(b) : { [x: string]: any; } >unboxify : (obj: Boxified) => T >b : { [x: string]: Box | Box | Box; } let x: string | number | boolean = v[s]; >x : string | number | boolean >v[s] : string | number | boolean ->v : { [x: string]: string | number | boolean; } +>v : { [x: string]: any; } >s : string } @@ -449,20 +449,20 @@ function f10(foo: Foo) { >Foo : Foo let x = validate(foo); // { a: number, readonly b: string } ->x : { a: number; readonly b: string; } ->validate(foo) : { a: number; readonly b: string; } +>x : { a: any; readonly b: any; } +>validate(foo) : { a: any; readonly b: any; } >validate : (obj: { [P in keyof T]?: T[P] | undefined; }) => T >foo : Foo let y = clone(foo); // { a?: number, b: string } ->y : { a?: number | undefined; b: string; } ->clone(foo) : { a?: number | undefined; b: string; } +>y : { a?: any; b: any; } +>clone(foo) : { a?: any; b: any; } >clone : (obj: { readonly [P in keyof T]: T[P]; }) => T >foo : Foo let z = validateAndClone(foo); // { a: number, b: string } ->z : { a: number; b: string; } ->validateAndClone(foo) : { a: number; b: string; } +>z : { a: any; b: any; } +>validateAndClone(foo) : { a: any; b: any; } >validateAndClone : (obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T >foo : Foo } @@ -507,8 +507,8 @@ declare function applySpec(obj: Spec): (...args: any[]) => T; // Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } } var g1 = applySpec({ ->g1 : (...args: any[]) => { sum: number; nested: { mul: string; }; } ->applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: number; nested: { mul: string; }; } +>g1 : (...args: any[]) => { sum: any; nested: any; } +>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: any; nested: any; } >applySpec : (obj: Spec) => (...args: any[]) => T >{ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }} : { sum: (a: any) => number; nested: { mul: (b: any) => string; }; } @@ -532,8 +532,8 @@ var g1 = applySpec({ // Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } } var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } }); ->g2 : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; } ->applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; } +>g2 : (...args: any[]) => { foo: any; } +>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: any; } >applySpec : (obj: Spec) => (...args: any[]) => T >{ foo: { bar: { baz: (x: any) => true } } } : { foo: { bar: { baz: (x: any) => boolean; }; }; } >foo : { bar: { baz: (x: any) => boolean; }; } diff --git a/tests/baselines/reference/jsDocTags.baseline b/tests/baselines/reference/jsDocTags.baseline index 7f9e9fdce98..f316a9c4245 100644 --- a/tests/baselines/reference/jsDocTags.baseline +++ b/tests/baselines/reference/jsDocTags.baseline @@ -268,8 +268,7 @@ "documentation": [], "tags": [ { - "name": "mytag", - "text": "" + "name": "mytag" } ] } @@ -446,8 +445,7 @@ "text": "Another value" }, { - "name": "mytag", - "text": "" + "name": "mytag" } ] } @@ -580,12 +578,10 @@ "text": "here all the comments are on a new line" }, { - "name": "mytag3", - "text": "" + "name": "mytag3" }, { - "name": "mytag", - "text": "" + "name": "mytag" } ] } @@ -655,8 +651,7 @@ "documentation": [], "tags": [ { - "name": "mytag", - "text": "" + "name": "mytag" } ] } diff --git a/tests/baselines/reference/jsDocTypeTag1.js b/tests/baselines/reference/jsDocTypeTag1.js index 75333c69364..657ff5031a2 100644 --- a/tests/baselines/reference/jsDocTypeTag1.js +++ b/tests/baselines/reference/jsDocTypeTag1.js @@ -41,7 +41,7 @@ "tags": [ { "name": "type", - "text": "{String} " + "text": "{String}" } ] } @@ -88,7 +88,7 @@ "tags": [ { "name": "type", - "text": "{Number} " + "text": "{Number}" } ] } @@ -135,7 +135,7 @@ "tags": [ { "name": "type", - "text": "{Boolean} " + "text": "{Boolean}" } ] } @@ -182,7 +182,7 @@ "tags": [ { "name": "type", - "text": "{Void} " + "text": "{Void}" } ] } @@ -229,7 +229,7 @@ "tags": [ { "name": "type", - "text": "{Undefined} " + "text": "{Undefined}" } ] } @@ -276,7 +276,7 @@ "tags": [ { "name": "type", - "text": "{Null} " + "text": "{Null}" } ] } @@ -331,7 +331,7 @@ "tags": [ { "name": "type", - "text": "{Array} " + "text": "{Array}" } ] } @@ -390,7 +390,7 @@ "tags": [ { "name": "type", - "text": "{Promise} " + "text": "{Promise}" } ] } @@ -437,7 +437,7 @@ "tags": [ { "name": "type", - "text": "{Object} " + "text": "{Object}" } ] } @@ -484,7 +484,7 @@ "tags": [ { "name": "type", - "text": "{Function} " + "text": "{Function}" } ] } @@ -531,7 +531,7 @@ "tags": [ { "name": "type", - "text": "{*} " + "text": "{*}" } ] } @@ -578,7 +578,7 @@ "tags": [ { "name": "type", - "text": "{?} " + "text": "{?}" } ] } @@ -641,7 +641,7 @@ "tags": [ { "name": "type", - "text": "{String|Number} " + "text": "{String|Number}" } ] } diff --git a/tests/baselines/reference/jsDocTypeTag2.js b/tests/baselines/reference/jsDocTypeTag2.js index 01032a5cc09..9933360b009 100644 --- a/tests/baselines/reference/jsDocTypeTag2.js +++ b/tests/baselines/reference/jsDocTypeTag2.js @@ -41,7 +41,7 @@ "tags": [ { "name": "type", - "text": "{string} " + "text": "{string}" } ] } @@ -88,7 +88,7 @@ "tags": [ { "name": "type", - "text": "{number} " + "text": "{number}" } ] } @@ -135,7 +135,7 @@ "tags": [ { "name": "type", - "text": "{boolean} " + "text": "{boolean}" } ] } @@ -182,7 +182,7 @@ "tags": [ { "name": "type", - "text": "{void} " + "text": "{void}" } ] } @@ -229,7 +229,7 @@ "tags": [ { "name": "type", - "text": "{undefined} " + "text": "{undefined}" } ] } @@ -276,7 +276,7 @@ "tags": [ { "name": "type", - "text": "{null} " + "text": "{null}" } ] } @@ -331,7 +331,7 @@ "tags": [ { "name": "type", - "text": "{array} " + "text": "{array}" } ] } @@ -390,7 +390,7 @@ "tags": [ { "name": "type", - "text": "{promise} " + "text": "{promise}" } ] } @@ -437,7 +437,7 @@ "tags": [ { "name": "type", - "text": "{?number} " + "text": "{?number}" } ] } @@ -484,7 +484,7 @@ "tags": [ { "name": "type", - "text": "{function} " + "text": "{function}" } ] } @@ -567,7 +567,7 @@ "tags": [ { "name": "type", - "text": "{function (number): number} " + "text": "{function (number): number}" } ] } @@ -630,7 +630,7 @@ "tags": [ { "name": "type", - "text": "{string | number} " + "text": "{string | number}" } ] } diff --git a/tests/baselines/reference/jsDocTypedef1.js b/tests/baselines/reference/jsDocTypedef1.js index 96a86a4f7a8..e1b34f14c2b 100644 --- a/tests/baselines/reference/jsDocTypedef1.js +++ b/tests/baselines/reference/jsDocTypedef1.js @@ -181,7 +181,7 @@ "tags": [ { "name": "param", - "text": "opts " + "text": "opts" } ] } diff --git a/tests/baselines/reference/jsxAndTypeAssertion.errors.txt b/tests/baselines/reference/jsxAndTypeAssertion.errors.txt index d5df3915bf6..5aa92086c37 100644 --- a/tests/baselines/reference/jsxAndTypeAssertion.errors.txt +++ b/tests/baselines/reference/jsxAndTypeAssertion.errors.txt @@ -10,13 +10,11 @@ tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(14,45): error TS1005: '}' ex tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,2): error TS17008: JSX element 'foo' has no corresponding closing tag. tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,8): error TS17008: JSX element 'foo' has no corresponding closing tag. tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,13): error TS17008: JSX element 'foo' has no corresponding closing tag. -tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(18,83): error TS1109: Expression expected. tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: ':' expected. tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(21,1): error TS1005: ' extends React.Component {} +const m = + + +//// [jsxHasLiteralType.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var React = require("react"); +var MyComponent = /** @class */ (function (_super) { + __extends(MyComponent, _super); + function MyComponent() { + return _super !== null && _super.apply(this, arguments) || this; + } + return MyComponent; +}(React.Component)); +var m = React.createElement(MyComponent, { x: "a" }); diff --git a/tests/baselines/reference/jsxHasLiteralType.symbols b/tests/baselines/reference/jsxHasLiteralType.symbols new file mode 100644 index 00000000000..a7106f2699e --- /dev/null +++ b/tests/baselines/reference/jsxHasLiteralType.symbols @@ -0,0 +1,25 @@ +=== tests/cases/compiler/jsxHasLiteralType.tsx === +import * as React from "react"; +>React : Symbol(React, Decl(jsxHasLiteralType.tsx, 0, 6)) + +interface Props { +>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31)) + + x?: "a" | "b"; +>x : Symbol(Props.x, Decl(jsxHasLiteralType.tsx, 2, 17)) +} +class MyComponent

extends React.Component {} +>MyComponent : Symbol(MyComponent, Decl(jsxHasLiteralType.tsx, 4, 1)) +>P : Symbol(P, Decl(jsxHasLiteralType.tsx, 5, 18)) +>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31)) +>Props : Symbol(Props, Decl(jsxHasLiteralType.tsx, 0, 31)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66)) +>React : Symbol(React, Decl(jsxHasLiteralType.tsx, 0, 6)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55), Decl(react.d.ts, 161, 66)) +>P : Symbol(P, Decl(jsxHasLiteralType.tsx, 5, 18)) + +const m = +>m : Symbol(m, Decl(jsxHasLiteralType.tsx, 6, 5)) +>MyComponent : Symbol(MyComponent, Decl(jsxHasLiteralType.tsx, 4, 1)) +>x : Symbol(x, Decl(jsxHasLiteralType.tsx, 6, 22)) + diff --git a/tests/baselines/reference/jsxHasLiteralType.types b/tests/baselines/reference/jsxHasLiteralType.types new file mode 100644 index 00000000000..61120edcea6 --- /dev/null +++ b/tests/baselines/reference/jsxHasLiteralType.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/jsxHasLiteralType.tsx === +import * as React from "react"; +>React : typeof React + +interface Props { +>Props : Props + + x?: "a" | "b"; +>x : "a" | "b" | undefined +} +class MyComponent

extends React.Component {} +>MyComponent : MyComponent

; - } - } - class B extends React.Component { - render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object - return ; - ~~~~~~ -!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType4.js b/tests/baselines/reference/tsxGenericAttributesType4.js index 1f8c9a631c0..3fad8aaccde 100644 --- a/tests/baselines/reference/tsxGenericAttributesType4.js +++ b/tests/baselines/reference/tsxGenericAttributesType4.js @@ -8,7 +8,6 @@ class B1 extends React.Component { } class B extends React.Component { render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; } } @@ -43,7 +42,6 @@ var B = /** @class */ (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } B.prototype.render = function () { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; }; return B; diff --git a/tests/baselines/reference/tsxGenericAttributesType4.symbols b/tests/baselines/reference/tsxGenericAttributesType4.symbols index ab64844e0fd..0d01dec93ca 100644 --- a/tests/baselines/reference/tsxGenericAttributesType4.symbols +++ b/tests/baselines/reference/tsxGenericAttributesType4.symbols @@ -30,12 +30,11 @@ class B extends React.Component { render() { >render : Symbol(B.render, Decl(file.tsx, 7, 43)) - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; >B1 : Symbol(B1, Decl(file.tsx, 0, 32)) >this.props : Symbol(React.Component.props, Decl(react.d.ts, 167, 37)) >this : Symbol(B, Decl(file.tsx, 6, 1)) >props : Symbol(React.Component.props, Decl(react.d.ts, 167, 37)) ->x : Symbol(x, Decl(file.tsx, 10, 34)) +>x : Symbol(x, Decl(file.tsx, 9, 34)) } } diff --git a/tests/baselines/reference/tsxGenericAttributesType4.types b/tests/baselines/reference/tsxGenericAttributesType4.types index ede5a874a42..874d77d8325 100644 --- a/tests/baselines/reference/tsxGenericAttributesType4.types +++ b/tests/baselines/reference/tsxGenericAttributesType4.types @@ -31,7 +31,6 @@ class B extends React.Component { render() { >render : () => JSX.Element - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; > : JSX.Element >B1 : typeof B1 diff --git a/tests/baselines/reference/tsxGenericAttributesType5.errors.txt b/tests/baselines/reference/tsxGenericAttributesType5.errors.txt deleted file mode 100644 index 83f07326f92..00000000000 --- a/tests/baselines/reference/tsxGenericAttributesType5.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/conformance/jsx/file.tsx(12,36): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - - -==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== - import React = require('react'); - - class B1 extends React.Component { - render() { - return
hi
; - } - } - class B extends React.Component { - props: U; - render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object - return ; - ~~~~~~ -!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - } - } \ No newline at end of file diff --git a/tests/baselines/reference/tsxGenericAttributesType5.js b/tests/baselines/reference/tsxGenericAttributesType5.js index 402ed461a4f..240f2bf95c2 100644 --- a/tests/baselines/reference/tsxGenericAttributesType5.js +++ b/tests/baselines/reference/tsxGenericAttributesType5.js @@ -9,7 +9,6 @@ class B1 extends React.Component { class B extends React.Component { props: U; render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; } } @@ -44,7 +43,6 @@ var B = /** @class */ (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } B.prototype.render = function () { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; }; return B; diff --git a/tests/baselines/reference/tsxGenericAttributesType5.symbols b/tests/baselines/reference/tsxGenericAttributesType5.symbols index 972e19f2e3c..18252ea5d1b 100644 --- a/tests/baselines/reference/tsxGenericAttributesType5.symbols +++ b/tests/baselines/reference/tsxGenericAttributesType5.symbols @@ -34,12 +34,11 @@ class B extends React.Component { render() { >render : Symbol(B.render, Decl(file.tsx, 8, 13)) - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; >B1 : Symbol(B1, Decl(file.tsx, 0, 32)) >this.props : Symbol(B.props, Decl(file.tsx, 7, 43)) >this : Symbol(B, Decl(file.tsx, 6, 1)) >props : Symbol(B.props, Decl(file.tsx, 7, 43)) ->x : Symbol(x, Decl(file.tsx, 11, 34)) +>x : Symbol(x, Decl(file.tsx, 10, 34)) } } diff --git a/tests/baselines/reference/tsxGenericAttributesType5.types b/tests/baselines/reference/tsxGenericAttributesType5.types index c5320a5a8c4..11b10ae6a88 100644 --- a/tests/baselines/reference/tsxGenericAttributesType5.types +++ b/tests/baselines/reference/tsxGenericAttributesType5.types @@ -35,7 +35,6 @@ class B extends React.Component { render() { >render : () => JSX.Element - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; > : JSX.Element >B1 : typeof B1 diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.errors.txt b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.errors.txt deleted file mode 100644 index 95749802ced..00000000000 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.errors.txt +++ /dev/null @@ -1,31 +0,0 @@ -tests/cases/conformance/jsx/file.tsx(13,9): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. - Type '{}' is not assignable to type 'Prop'. - Property 'a' is missing in type '{}'. -tests/cases/conformance/jsx/file.tsx(14,18): error TS2322: Type '{ a: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. - Type '{ a: string; }' is not assignable to type 'Prop'. - Property 'b' is missing in type '{ a: string; }'. - - -==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== - import React = require('react'); - - interface Prop { - a: number, - b: string - } - - declare class MyComp

extends React.Component { - internalProp: P; - } - - // Error - let x = - ~~~~~~~~~~ -!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. -!!! error TS2322: Type '{}' is not assignable to type 'Prop'. -!!! error TS2322: Property 'a' is missing in type '{}'. - let x1 = - ~~~~~~ -!!! error TS2322: Type '{ a: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. -!!! error TS2322: Type '{ a: string; }' is not assignable to type 'Prop'. -!!! error TS2322: Property 'b' is missing in type '{ a: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.js b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.js index 469adbee4b7..5959f527539 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.js +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.js @@ -10,7 +10,6 @@ declare class MyComp

extends React.Component { internalProp: P; } -// Error let x = let x1 = @@ -18,6 +17,5 @@ let x1 = "use strict"; exports.__esModule = true; var React = require("react"); -// Error var x = ; var x1 = ; diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.symbols b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.symbols index 9c9ca8c419f..6c4e407fc61 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.symbols +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.symbols @@ -26,13 +26,12 @@ declare class MyComp

extends React.Component { >P : Symbol(P, Decl(file.tsx, 7, 21)) } -// Error let x = ->x : Symbol(x, Decl(file.tsx, 12, 3)) +>x : Symbol(x, Decl(file.tsx, 11, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) let x1 = ->x1 : Symbol(x1, Decl(file.tsx, 13, 3)) +>x1 : Symbol(x1, Decl(file.tsx, 12, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) ->a : Symbol(a, Decl(file.tsx, 13, 16)) +>a : Symbol(a, Decl(file.tsx, 12, 16)) diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.types b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.types index 0dc264c2720..a5d9212ce83 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.types +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter2.types @@ -26,7 +26,6 @@ declare class MyComp

extends React.Component { >P : P } -// Error let x = >x : JSX.Element > : JSX.Element diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt index 2fc79a30ade..dd38d89662f 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt @@ -1,5 +1,9 @@ -tests/cases/conformance/jsx/file.tsx(16,17): error TS2559: Type '{ a: number; b: string; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. -tests/cases/conformance/jsx/file.tsx(17,18): error TS2559: Type '{ a: string; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(13,10): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. + Type '{}' is not assignable to type 'Prop'. + Property 'a' is missing in type '{}'. +tests/cases/conformance/jsx/file.tsx(19,18): error TS2322: Type '{ a: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. + Type '{ a: string; }' is not assignable to type 'Prop'. + Property 'b' is missing in type '{ a: string; }'. ==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== @@ -14,13 +18,19 @@ tests/cases/conformance/jsx/file.tsx(17,18): error TS2559: Type '{ a: string; }' internalProp: P; } - // OK: we fille in missing type argument with empty object + // Error let x1 = + ~~~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. +!!! error TS2322: Type '{}' is not assignable to type 'Prop'. +!!! error TS2322: Property 'a' is missing in type '{}'. + + // OK + let x = // Error - let x = - ~~~~~~~~~~~~~ -!!! error TS2559: Type '{ a: number; b: string; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. let x2 = ~~~~~~ -!!! error TS2559: Type '{ a: string; }' has no properties in common with type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. \ No newline at end of file +!!! error TS2322: Type '{ a: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Prop & { children?: ReactNode; }'. +!!! error TS2322: Type '{ a: string; }' is not assignable to type 'Prop'. +!!! error TS2322: Property 'b' is missing in type '{ a: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.js b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.js index 3eed9e5fb17..8e4dae1b2e9 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.js +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.js @@ -10,19 +10,22 @@ declare class MyComp

extends React.Component { internalProp: P; } -// OK: we fille in missing type argument with empty object +// Error let x1 = -// Error +// OK let x = + +// Error let x2 = //// [file.jsx] "use strict"; exports.__esModule = true; var React = require("react"); -// OK: we fille in missing type argument with empty object -var x1 = ; // Error +var x1 = ; +// OK var x = ; +// Error var x2 = ; diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.symbols b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.symbols index 8d0ea3cb8e2..9305e503cc7 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.symbols +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.symbols @@ -26,20 +26,21 @@ declare class MyComp

extends React.Component { >P : Symbol(P, Decl(file.tsx, 7, 21)) } -// OK: we fille in missing type argument with empty object +// Error let x1 = >x1 : Symbol(x1, Decl(file.tsx, 12, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) -// Error +// OK let x = >x : Symbol(x, Decl(file.tsx, 15, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) >a : Symbol(a, Decl(file.tsx, 15, 15)) >b : Symbol(b, Decl(file.tsx, 15, 22)) +// Error let x2 = ->x2 : Symbol(x2, Decl(file.tsx, 16, 3)) +>x2 : Symbol(x2, Decl(file.tsx, 18, 3)) >MyComp : Symbol(MyComp, Decl(file.tsx, 5, 1)) ->a : Symbol(a, Decl(file.tsx, 16, 16)) +>a : Symbol(a, Decl(file.tsx, 18, 16)) diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.types b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.types index 5463e2fe4b0..03301a17710 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.types +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.types @@ -26,13 +26,13 @@ declare class MyComp

extends React.Component { >P : P } -// OK: we fille in missing type argument with empty object +// Error let x1 = >x1 : JSX.Element > : JSX.Element >MyComp : typeof MyComp -// Error +// OK let x = >x : JSX.Element > : JSX.Element @@ -41,6 +41,7 @@ let x = >10 : 10 >b : string +// Error let x2 = >x2 : JSX.Element > : JSX.Element diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types index aa38d2ccf8a..32f483227d3 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments3.types @@ -130,8 +130,8 @@ function createLink(func: (a: number)=>void) { >o1 : JSX.Element >{}} /> : JSX.Element >Link : { (l: { func: (arg: U) => void; }): JSX.Element; (l: { func: (arg1: U, arg2: string) => void; }): JSX.Element; } ->func : (a: number, b: string) => any ->(a:number, b:string)=>{} : (a: number, b: string) => any +>func : (a: number, b: string) => void +>(a:number, b:string)=>{} : (a: number, b: string) => void >a : number >b : string } diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt index 71d6f73d864..21a35e0553b 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt @@ -4,9 +4,11 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(14,15): error TS2428: All declarations of 'B' must have identical type parameters. tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(32,22): error TS2428: All declarations of 'A' must have identical type parameters. tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(38,22): error TS2428: All declarations of 'A' must have identical type parameters. +tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(53,11): error TS2428: All declarations of 'C' must have identical type parameters. +tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(57,11): error TS2428: All declarations of 'C' must have identical type parameters. -==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (6 errors) ==== +==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (8 errors) ==== interface A { ~ !!! error TS2428: All declarations of 'A' must have identical type parameters. @@ -59,4 +61,29 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi !!! error TS2428: All declarations of 'A' must have identical type parameters. y: T; } - } \ No newline at end of file + } + + interface B { + u: T; + v: Constraint; // ok + } + + interface B { // ok + x: T; + y: Constraint; // ok + } + + interface C { + ~ +!!! error TS2428: All declarations of 'C' must have identical type parameters. + x: T; + } + + interface C { // error + ~ +!!! error TS2428: All declarations of 'C' must have identical type parameters. + y: T; + } + + interface Constraint {} + \ No newline at end of file diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js index 245da303d73..5b1964b2891 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js @@ -39,6 +39,27 @@ module M3 { export interface A { // error y: T; } -} +} + +interface B { + u: T; + v: Constraint; // ok +} + +interface B { // ok + x: T; + y: Constraint; // ok +} + +interface C { + x: T; +} + +interface C { // error + y: T; +} + +interface Constraint {} + //// [twoGenericInterfacesWithDifferentConstraints.js] diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols index 46b0d397e09..6d802b9ff2c 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols @@ -99,3 +99,54 @@ module M3 { >T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 31, 23), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 37, 23)) } } + +interface B { +>B : Symbol(B, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 40, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 45, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + u: T; +>u : Symbol(B.u, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 31)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + v: Constraint; // ok +>v : Symbol(B.v, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 43, 7)) +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) +} + +interface B { // ok +>B : Symbol(B, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 40, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 45, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + x: T; +>x : Symbol(B.x, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 16)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + y: Constraint; // ok +>y : Symbol(B.y, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 48, 7)) +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) +} + +interface C { +>C : Symbol(C, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 50, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 54, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) + + x: T; +>x : Symbol(C.x, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 16)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) +} + +interface C { // error +>C : Symbol(C, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 50, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 54, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) + + y: T; +>y : Symbol(C.y, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 31)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) +} + +interface Constraint {} +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 60, 21)) + diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types index ca56778032b..8f7899549fc 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types @@ -99,3 +99,54 @@ module M3 { >T : T } } + +interface B { +>B : B +>T : T + + u: T; +>u : T +>T : T + + v: Constraint; // ok +>v : Constraint +>Constraint : Constraint +>T : T +} + +interface B { // ok +>B : B +>T : T + + x: T; +>x : T +>T : T + + y: Constraint; // ok +>y : Constraint +>Constraint : Constraint +>T : T +} + +interface C { +>C : C +>T : T + + x: T; +>x : T +>T : T +} + +interface C { // error +>C : C +>T : T + + y: T; +>y : T +>T : T +} + +interface Constraint {} +>Constraint : Constraint +>T : T + diff --git a/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.js b/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.js index df12050eaf6..558650a2a31 100644 --- a/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.js +++ b/tests/baselines/reference/typeCheckObjectCreationExpressionWithUndefinedCallResolutionData.js @@ -29,3 +29,4 @@ f.foo(); //// [file1.d.ts] export declare function foo(): any; //// [file2.d.ts] +export {}; diff --git a/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.js b/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.js index 84db5d4a4a9..5f8a850c589 100644 --- a/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.js +++ b/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.js @@ -152,6 +152,6 @@ declare let b: GuardInterface; declare function invalidGuard(c: any): this is number; declare let c: number | number[]; declare let holder: { - invalidGuard: (c: any) => this is number; + invalidGuard: typeof invalidGuard; }; declare let detached: () => this is FollowerGuard; diff --git a/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt b/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt deleted file mode 100644 index ac20e826969..00000000000 --- a/tests/baselines/reference/typeParameterListWithTrailingComma1.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/compiler/typeParameterListWithTrailingComma1.ts(1,10): error TS1009: Trailing comma not allowed. - - -==== tests/cases/compiler/typeParameterListWithTrailingComma1.ts (1 errors) ==== - class C { - ~ -!!! error TS1009: Trailing comma not allowed. - } \ No newline at end of file diff --git a/tests/baselines/reference/types.asyncGenerators.esnext.1.symbols b/tests/baselines/reference/types.asyncGenerators.esnext.1.symbols index b5707649fda..59b93d7ab1a 100644 --- a/tests/baselines/reference/types.asyncGenerators.esnext.1.symbols +++ b/tests/baselines/reference/types.asyncGenerators.esnext.1.symbols @@ -17,7 +17,7 @@ async function * inferReturnType4() { yield Promise.resolve(1); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * inferReturnType5() { @@ -26,7 +26,7 @@ async function * inferReturnType5() { yield 1; yield Promise.resolve(2); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * inferReturnType6() { @@ -39,7 +39,7 @@ async function * inferReturnType7() { yield* [Promise.resolve(1)]; >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * inferReturnType8() { @@ -59,7 +59,7 @@ const assignability2: () => AsyncIterableIterator = async function * () yield Promise.resolve(1); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) }; @@ -75,7 +75,7 @@ const assignability4: () => AsyncIterableIterator = async function * () yield* [Promise.resolve(1)]; >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) }; @@ -97,7 +97,7 @@ const assignability7: () => AsyncIterable = async function * () { yield Promise.resolve(1); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) }; @@ -113,7 +113,7 @@ const assignability9: () => AsyncIterable = async function * () { yield* [Promise.resolve(1)]; >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) }; @@ -135,7 +135,7 @@ const assignability12: () => AsyncIterator = async function * () { yield Promise.resolve(1); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) }; @@ -151,7 +151,7 @@ const assignability14: () => AsyncIterator = async function * () { yield* [Promise.resolve(1)]; >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) }; @@ -173,7 +173,7 @@ async function * explicitReturnType2(): AsyncIterableIterator { yield Promise.resolve(1); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * explicitReturnType3(): AsyncIterableIterator { @@ -188,7 +188,7 @@ async function * explicitReturnType4(): AsyncIterableIterator { yield* [Promise.resolve(1)]; >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * explicitReturnType5(): AsyncIterableIterator { @@ -209,7 +209,7 @@ async function * explicitReturnType7(): AsyncIterable { yield Promise.resolve(1); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * explicitReturnType8(): AsyncIterable { @@ -224,7 +224,7 @@ async function * explicitReturnType9(): AsyncIterable { yield* [Promise.resolve(1)]; >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * explicitReturnType10(): AsyncIterable { @@ -245,7 +245,7 @@ async function * explicitReturnType12(): AsyncIterator { yield Promise.resolve(1); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * explicitReturnType13(): AsyncIterator { @@ -260,7 +260,7 @@ async function * explicitReturnType14(): AsyncIterator { yield* [Promise.resolve(1)]; >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } async function * explicitReturnType15(): AsyncIterator { @@ -286,6 +286,6 @@ async function * awaitedType2() { const x = await Promise.resolve(1); >x : Symbol(x, Decl(types.asyncGenerators.esnext.1.ts, 121, 9)) >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } diff --git a/tests/baselines/reference/types.asyncGenerators.esnext.2.symbols b/tests/baselines/reference/types.asyncGenerators.esnext.2.symbols index bb6ec27150c..9d4bcc17b13 100644 --- a/tests/baselines/reference/types.asyncGenerators.esnext.2.symbols +++ b/tests/baselines/reference/types.asyncGenerators.esnext.2.symbols @@ -15,7 +15,7 @@ async function * inferReturnType3() { yield* Promise.resolve([1, 2]); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } const assignability1: () => AsyncIterableIterator = async function * () { diff --git a/tests/baselines/reference/uniqueSymbols.symbols b/tests/baselines/reference/uniqueSymbols.symbols index e798011683a..42324fa6e4d 100644 --- a/tests/baselines/reference/uniqueSymbols.symbols +++ b/tests/baselines/reference/uniqueSymbols.symbols @@ -388,7 +388,7 @@ const constInitToLReadonlyNestedTypeWithIndexedAccess: L["nested"]["readonlyNest const promiseForConstCall = Promise.resolve(constCall); >promiseForConstCall : Symbol(promiseForConstCall, Decl(uniqueSymbols.ts, 111, 5)) >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >constCall : Symbol(constCall, Decl(uniqueSymbols.ts, 1, 5)) @@ -725,7 +725,7 @@ interface Context { method2(): Promise; >method2 : Symbol(Context.method2, Decl(uniqueSymbols.ts, 214, 24)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >s : Symbol(s, Decl(uniqueSymbols.ts, 115, 13)) method3(): AsyncIterableIterator; diff --git a/tests/baselines/reference/uniqueSymbolsDeclarations.symbols b/tests/baselines/reference/uniqueSymbolsDeclarations.symbols index ff433aa19d0..beff6685aa7 100644 --- a/tests/baselines/reference/uniqueSymbolsDeclarations.symbols +++ b/tests/baselines/reference/uniqueSymbolsDeclarations.symbols @@ -388,7 +388,7 @@ const constInitToLReadonlyNestedTypeWithIndexedAccess: L["nested"]["readonlyNest const promiseForConstCall = Promise.resolve(constCall); >promiseForConstCall : Symbol(promiseForConstCall, Decl(uniqueSymbolsDeclarations.ts, 111, 5)) >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >constCall : Symbol(constCall, Decl(uniqueSymbolsDeclarations.ts, 1, 5)) @@ -725,7 +725,7 @@ interface Context { method2(): Promise; >method2 : Symbol(Context.method2, Decl(uniqueSymbolsDeclarations.ts, 214, 24)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.esnext.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >s : Symbol(s, Decl(uniqueSymbolsDeclarations.ts, 115, 13)) method3(): AsyncIterableIterator; diff --git a/tests/baselines/reference/unusedGetterInClass.errors.txt b/tests/baselines/reference/unusedGetterInClass.errors.txt new file mode 100644 index 00000000000..7ab8d33fd95 --- /dev/null +++ b/tests/baselines/reference/unusedGetterInClass.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/unusedGetterInClass.ts(4,17): error TS6133: 'fullName' is declared but its value is never read. + + +==== tests/cases/compiler/unusedGetterInClass.ts (1 errors) ==== + class Employee { + private _fullName: string; + + private get fullName(): string { + ~~~~~~~~ +!!! error TS6133: 'fullName' is declared but its value is never read. + return this._fullName; + } + // Will not also error on the setter + private set fullName(_: string) {} + } \ No newline at end of file diff --git a/tests/baselines/reference/unusedGetterInClass.js b/tests/baselines/reference/unusedGetterInClass.js index 0bdbf006608..3cdac7b63df 100644 --- a/tests/baselines/reference/unusedGetterInClass.js +++ b/tests/baselines/reference/unusedGetterInClass.js @@ -2,9 +2,11 @@ class Employee { private _fullName: string; - get fullName(): string { + private get fullName(): string { return this._fullName; } + // Will not also error on the setter + private set fullName(_: string) {} } //// [unusedGetterInClass.js] @@ -15,6 +17,8 @@ var Employee = /** @class */ (function () { get: function () { return this._fullName; }, + // Will not also error on the setter + set: function (_) { }, enumerable: true, configurable: true }); diff --git a/tests/baselines/reference/unusedGetterInClass.symbols b/tests/baselines/reference/unusedGetterInClass.symbols index 7bab42f6743..f80229b1972 100644 --- a/tests/baselines/reference/unusedGetterInClass.symbols +++ b/tests/baselines/reference/unusedGetterInClass.symbols @@ -5,12 +5,16 @@ class Employee { private _fullName: string; >_fullName : Symbol(Employee._fullName, Decl(unusedGetterInClass.ts, 0, 16)) - get fullName(): string { ->fullName : Symbol(Employee.fullName, Decl(unusedGetterInClass.ts, 1, 30)) + private get fullName(): string { +>fullName : Symbol(Employee.fullName, Decl(unusedGetterInClass.ts, 1, 30), Decl(unusedGetterInClass.ts, 5, 5)) return this._fullName; >this._fullName : Symbol(Employee._fullName, Decl(unusedGetterInClass.ts, 0, 16)) >this : Symbol(Employee, Decl(unusedGetterInClass.ts, 0, 0)) >_fullName : Symbol(Employee._fullName, Decl(unusedGetterInClass.ts, 0, 16)) } + // Will not also error on the setter + private set fullName(_: string) {} +>fullName : Symbol(Employee.fullName, Decl(unusedGetterInClass.ts, 1, 30), Decl(unusedGetterInClass.ts, 5, 5)) +>_ : Symbol(_, Decl(unusedGetterInClass.ts, 7, 25)) } diff --git a/tests/baselines/reference/unusedGetterInClass.types b/tests/baselines/reference/unusedGetterInClass.types index 648bed6ac5d..822d47e6952 100644 --- a/tests/baselines/reference/unusedGetterInClass.types +++ b/tests/baselines/reference/unusedGetterInClass.types @@ -5,7 +5,7 @@ class Employee { private _fullName: string; >_fullName : string - get fullName(): string { + private get fullName(): string { >fullName : string return this._fullName; @@ -13,4 +13,8 @@ class Employee { >this : this >_fullName : string } + // Will not also error on the setter + private set fullName(_: string) {} +>fullName : string +>_ : string } diff --git a/tests/baselines/reference/unusedImportDeclaration.js b/tests/baselines/reference/unusedImportDeclaration.js index df84d925cd1..2bfcb7c2e5f 100644 --- a/tests/baselines/reference/unusedImportDeclaration.js +++ b/tests/baselines/reference/unusedImportDeclaration.js @@ -38,3 +38,4 @@ declare class TesterB { } export = TesterB; //// [unusedImportDeclaration_testerA.d.ts] +export {}; diff --git a/tests/baselines/reference/unusedSetterInClass.errors.txt b/tests/baselines/reference/unusedSetterInClass.errors.txt index d7cd764b293..d5380cdc1dd 100644 --- a/tests/baselines/reference/unusedSetterInClass.errors.txt +++ b/tests/baselines/reference/unusedSetterInClass.errors.txt @@ -1,13 +1,16 @@ tests/cases/compiler/unusedSetterInClass.ts(2,13): error TS6133: '_fullName' is declared but its value is never read. +tests/cases/compiler/unusedSetterInClass.ts(4,17): error TS6133: 'fullName' is declared but its value is never read. -==== tests/cases/compiler/unusedSetterInClass.ts (1 errors) ==== +==== tests/cases/compiler/unusedSetterInClass.ts (2 errors) ==== class Employee { private _fullName: string; ~~~~~~~~~ !!! error TS6133: '_fullName' is declared but its value is never read. - set fullName(newName: string) { + private set fullName(newName: string) { + ~~~~~~~~ +!!! error TS6133: 'fullName' is declared but its value is never read. this._fullName = newName; } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedSetterInClass.js b/tests/baselines/reference/unusedSetterInClass.js index 30911d8ef2a..9b7a65eb449 100644 --- a/tests/baselines/reference/unusedSetterInClass.js +++ b/tests/baselines/reference/unusedSetterInClass.js @@ -2,7 +2,7 @@ class Employee { private _fullName: string; - set fullName(newName: string) { + private set fullName(newName: string) { this._fullName = newName; } } diff --git a/tests/baselines/reference/unusedSetterInClass.symbols b/tests/baselines/reference/unusedSetterInClass.symbols index cf04d2da65f..da5d62bdc85 100644 --- a/tests/baselines/reference/unusedSetterInClass.symbols +++ b/tests/baselines/reference/unusedSetterInClass.symbols @@ -5,14 +5,14 @@ class Employee { private _fullName: string; >_fullName : Symbol(Employee._fullName, Decl(unusedSetterInClass.ts, 0, 16)) - set fullName(newName: string) { + private set fullName(newName: string) { >fullName : Symbol(Employee.fullName, Decl(unusedSetterInClass.ts, 1, 30)) ->newName : Symbol(newName, Decl(unusedSetterInClass.ts, 3, 17)) +>newName : Symbol(newName, Decl(unusedSetterInClass.ts, 3, 25)) this._fullName = newName; >this._fullName : Symbol(Employee._fullName, Decl(unusedSetterInClass.ts, 0, 16)) >this : Symbol(Employee, Decl(unusedSetterInClass.ts, 0, 0)) >_fullName : Symbol(Employee._fullName, Decl(unusedSetterInClass.ts, 0, 16)) ->newName : Symbol(newName, Decl(unusedSetterInClass.ts, 3, 17)) +>newName : Symbol(newName, Decl(unusedSetterInClass.ts, 3, 25)) } } diff --git a/tests/baselines/reference/unusedSetterInClass.types b/tests/baselines/reference/unusedSetterInClass.types index 1f6cf0d25a0..1a4c5c8a76c 100644 --- a/tests/baselines/reference/unusedSetterInClass.types +++ b/tests/baselines/reference/unusedSetterInClass.types @@ -5,7 +5,7 @@ class Employee { private _fullName: string; >_fullName : string - set fullName(newName: string) { + private set fullName(newName: string) { >fullName : string >newName : string diff --git a/tests/baselines/reference/unusedSetterInClass2.errors.txt b/tests/baselines/reference/unusedSetterInClass2.errors.txt new file mode 100644 index 00000000000..c3be0fc0302 --- /dev/null +++ b/tests/baselines/reference/unusedSetterInClass2.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/unusedSetterInClass2.ts(3,17): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + + +==== tests/cases/compiler/unusedSetterInClass2.ts (1 errors) ==== + // Unlike everything else, a setter without a getter is used by a write access. + class Employee { + private set p(_: number) {} + ~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + + m() { + this.p = 0; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/unusedSetterInClass2.js b/tests/baselines/reference/unusedSetterInClass2.js new file mode 100644 index 00000000000..9c3111982a9 --- /dev/null +++ b/tests/baselines/reference/unusedSetterInClass2.js @@ -0,0 +1,25 @@ +//// [unusedSetterInClass2.ts] +// Unlike everything else, a setter without a getter is used by a write access. +class Employee { + private set p(_: number) {} + + m() { + this.p = 0; + } +} + +//// [unusedSetterInClass2.js] +// Unlike everything else, a setter without a getter is used by a write access. +var Employee = /** @class */ (function () { + function Employee() { + } + Object.defineProperty(Employee.prototype, "p", { + set: function (_) { }, + enumerable: true, + configurable: true + }); + Employee.prototype.m = function () { + this.p = 0; + }; + return Employee; +}()); diff --git a/tests/baselines/reference/unusedSetterInClass2.symbols b/tests/baselines/reference/unusedSetterInClass2.symbols new file mode 100644 index 00000000000..1092f85ff9e --- /dev/null +++ b/tests/baselines/reference/unusedSetterInClass2.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/unusedSetterInClass2.ts === +// Unlike everything else, a setter without a getter is used by a write access. +class Employee { +>Employee : Symbol(Employee, Decl(unusedSetterInClass2.ts, 0, 0)) + + private set p(_: number) {} +>p : Symbol(Employee.p, Decl(unusedSetterInClass2.ts, 1, 16)) +>_ : Symbol(_, Decl(unusedSetterInClass2.ts, 2, 18)) + + m() { +>m : Symbol(Employee.m, Decl(unusedSetterInClass2.ts, 2, 31)) + + this.p = 0; +>this.p : Symbol(Employee.p, Decl(unusedSetterInClass2.ts, 1, 16)) +>this : Symbol(Employee, Decl(unusedSetterInClass2.ts, 0, 0)) +>p : Symbol(Employee.p, Decl(unusedSetterInClass2.ts, 1, 16)) + } +} diff --git a/tests/baselines/reference/unusedSetterInClass2.types b/tests/baselines/reference/unusedSetterInClass2.types new file mode 100644 index 00000000000..0237db7ce8c --- /dev/null +++ b/tests/baselines/reference/unusedSetterInClass2.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/unusedSetterInClass2.ts === +// Unlike everything else, a setter without a getter is used by a write access. +class Employee { +>Employee : Employee + + private set p(_: number) {} +>p : number +>_ : number + + m() { +>m : () => void + + this.p = 0; +>this.p = 0 : 0 +>this.p : number +>this : this +>p : number +>0 : 0 + } +} diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.js b/tests/baselines/reference/useObjectValuesAndEntries1.js index c269e4f4c8e..a10fb9a2d32 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.js +++ b/tests/baselines/reference/useObjectValuesAndEntries1.js @@ -5,10 +5,10 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] -var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}) // [never, any][] +var entries = Object.entries(o); +var entries1 = Object.entries(1); +var entries2 = Object.entries({a: true, b: 2}) +var entries3 = Object.entries({}) //// [useObjectValuesAndEntries1.js] @@ -17,7 +17,7 @@ for (var _i = 0, _a = Object.values(o); _i < _a.length; _i++) { var x = _a[_i]; var y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] -var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({ a: true, b: 2 }); // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}); // [never, any][] +var entries = Object.entries(o); +var entries1 = Object.entries(1); +var entries2 = Object.entries({ a: true, b: 2 }); +var entries3 = Object.entries({}); diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.symbols b/tests/baselines/reference/useObjectValuesAndEntries1.symbols index 2c412b7a8ff..538e3f69d78 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.symbols +++ b/tests/baselines/reference/useObjectValuesAndEntries1.symbols @@ -16,20 +16,20 @@ for (var x of Object.values(o)) { >x : Symbol(x, Decl(useObjectValuesAndEntries1.ts, 2, 8)) } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +var entries = Object.entries(o); >entries : Symbol(entries, Decl(useObjectValuesAndEntries1.ts, 6, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries1.ts, 0, 3)) -var entries1 = Object.entries(1); // <-- entries: [string, any][] +var entries1 = Object.entries(1); >entries1 : Symbol(entries1, Decl(useObjectValuesAndEntries1.ts, 7, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] +var entries2 = Object.entries({a: true, b: 2}) >entries2 : Symbol(entries2, Decl(useObjectValuesAndEntries1.ts, 8, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) @@ -37,7 +37,7 @@ var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][ >a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 8, 31)) >b : Symbol(b, Decl(useObjectValuesAndEntries1.ts, 8, 39)) -var entries3 = Object.entries({}) // [never, any][] +var entries3 = Object.entries({}) >entries3 : Symbol(entries3, Decl(useObjectValuesAndEntries1.ts, 9, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.types b/tests/baselines/reference/useObjectValuesAndEntries1.types index 0cb080c6477..c52d0ce872e 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.types +++ b/tests/baselines/reference/useObjectValuesAndEntries1.types @@ -10,9 +10,9 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : number >Object.values(o) : number[] ->Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } +>Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } >Object : ObjectConstructor ->values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } +>values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } >o : { a: number; b: number; } let y = x; @@ -20,39 +20,39 @@ for (var x of Object.values(o)) { >x : number } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +var entries = Object.entries(o); >entries : [string, number][] >Object.entries(o) : [string, number][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >o : { a: number; b: number; } -var entries1 = Object.entries(1); // <-- entries: [string, any][] +var entries1 = Object.entries(1); >entries1 : [string, any][] >Object.entries(1) : [string, any][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >1 : 1 -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] +var entries2 = Object.entries({a: true, b: 2}) >entries2 : [string, number | boolean][] >Object.entries({a: true, b: 2}) : [string, number | boolean][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >{a: true, b: 2} : { a: boolean; b: number; } >a : boolean >true : true >b : number >2 : 2 -var entries3 = Object.entries({}) // [never, any][] +var entries3 = Object.entries({}) >entries3 : [string, {}][] >Object.entries({}) : [string, {}][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >{} : {} diff --git a/tests/baselines/reference/useObjectValuesAndEntries4.types b/tests/baselines/reference/useObjectValuesAndEntries4.types index 245803a24d4..33a427760a8 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries4.types +++ b/tests/baselines/reference/useObjectValuesAndEntries4.types @@ -10,9 +10,9 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : number >Object.values(o) : number[] ->Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } +>Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } >Object : ObjectConstructor ->values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } +>values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } >o : { a: number; b: number; } let y = x; @@ -23,8 +23,8 @@ for (var x of Object.values(o)) { var entries = Object.entries(o); >entries : [string, number][] >Object.entries(o) : [string, number][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } >o : { a: number; b: number; } diff --git a/tests/baselines/reference/withImportDecl.js b/tests/baselines/reference/withImportDecl.js index 5c9d693c006..2bf5879ec9b 100644 --- a/tests/baselines/reference/withImportDecl.js +++ b/tests/baselines/reference/withImportDecl.js @@ -91,3 +91,4 @@ export declare class A { } //// [withImportDecl_1.d.ts] /// +export {}; diff --git a/tests/cases/compiler/allowSyntheticDefaultImports1.ts b/tests/cases/compiler/allowSyntheticDefaultImports1.ts index 4793da79136..a2aadfa0b6e 100644 --- a/tests/cases/compiler/allowSyntheticDefaultImports1.ts +++ b/tests/cases/compiler/allowSyntheticDefaultImports1.ts @@ -4,7 +4,7 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); -// @Filename: b.ts +// @Filename: b.d.ts export class Foo { member: string; } diff --git a/tests/cases/compiler/allowSyntheticDefaultImports2.ts b/tests/cases/compiler/allowSyntheticDefaultImports2.ts index 8fa004be387..efdee90e817 100644 --- a/tests/cases/compiler/allowSyntheticDefaultImports2.ts +++ b/tests/cases/compiler/allowSyntheticDefaultImports2.ts @@ -3,7 +3,7 @@ import Namespace from "./b"; export var x = new Namespace.Foo(); -// @Filename: b.ts +// @Filename: b.d.ts export class Foo { member: string; } \ No newline at end of file diff --git a/tests/cases/compiler/anyMappedTypesError.ts b/tests/cases/compiler/anyMappedTypesError.ts new file mode 100644 index 00000000000..6b37b286046 --- /dev/null +++ b/tests/cases/compiler/anyMappedTypesError.ts @@ -0,0 +1,3 @@ +// @noImplicitAny: true + +type Foo = {[P in "bar"]}; \ No newline at end of file diff --git a/tests/cases/compiler/baseClassImprovedMismatchErrors.ts b/tests/cases/compiler/baseClassImprovedMismatchErrors.ts new file mode 100644 index 00000000000..5b59d2bc96a --- /dev/null +++ b/tests/cases/compiler/baseClassImprovedMismatchErrors.ts @@ -0,0 +1,18 @@ +class Base { + n: Base | string; + fn() { + return 10; + } +} +class Derived extends Base { + n: Derived | string; + fn() { + return 10 as number | string; + } +} +class DerivedInterface implements Base { + n: DerivedInterface | string; + fn() { + return 10 as number | string; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/classExtensionNameOutput.ts b/tests/cases/compiler/classExtensionNameOutput.ts new file mode 100644 index 00000000000..3992780b0fb --- /dev/null +++ b/tests/cases/compiler/classExtensionNameOutput.ts @@ -0,0 +1,8 @@ +class A {} +if (true) { + class B extends A {} + + const foo = function () { + new B(); + } +} \ No newline at end of file diff --git a/tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts b/tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts new file mode 100644 index 00000000000..2536f67f6c4 --- /dev/null +++ b/tests/cases/compiler/contextualSignature_objectLiteralMethodMayReturnNever.ts @@ -0,0 +1,2 @@ +interface I { m(): number; } +const o: I = { m() { throw new Error("not implemented"); } }; diff --git a/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts b/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts new file mode 100644 index 00000000000..8d70a435e4d --- /dev/null +++ b/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts @@ -0,0 +1,8 @@ +// @declaration: true +namespace foo { + function bar(): void {} + + export const obj = { + bar + } +} diff --git a/tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts b/tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts new file mode 100644 index 00000000000..b3565a38e10 --- /dev/null +++ b/tests/cases/compiler/destructuringAssignmentWithStrictNullChecks.ts @@ -0,0 +1,3 @@ +// @strictNullChecks: true +let bar: {}; +({ ...bar } = {}); diff --git a/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts new file mode 100644 index 00000000000..02ae0c58d02 --- /dev/null +++ b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts @@ -0,0 +1,38 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/a/node_modules/foo/package.json +{ + "name": "foo", + "version": "1.2.3" +} + +// @Filename: /node_modules/a/node_modules/foo/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/a/index.d.ts +import { C } from "foo"; +export const o: C; + +// @Filename: /node_modules/foo/use.d.ts +import { C } from "./index"; +export function use(o: C): void; + +// @Filename: /node_modules/foo/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/foo/package.json +{ + "name": "foo", + "version": "1.2.3" +} + +// @Filename: /index.ts +import { use } from "foo/use"; +import { o } from "a"; + +use(o); diff --git a/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts new file mode 100644 index 00000000000..5ccf69a5a8d --- /dev/null +++ b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts @@ -0,0 +1,38 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/a/node_modules/@foo/bar/package.json +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +// @Filename: /node_modules/a/node_modules/@foo/bar/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/a/index.d.ts +import { C } from "@foo/bar"; +export const o: C; + +// @Filename: /node_modules/@foo/bar/use.d.ts +import { C } from "./index"; +export function use(o: C): void; + +// @Filename: /node_modules/@foo/bar/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/@foo/bar/package.json +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +// @Filename: /index.ts +import { use } from "@foo/bar/use"; +import { o } from "a"; + +use(o); diff --git a/tests/cases/compiler/emptyDeclarationEmitIsModule.ts b/tests/cases/compiler/emptyDeclarationEmitIsModule.ts new file mode 100644 index 00000000000..a96b6d75763 --- /dev/null +++ b/tests/cases/compiler/emptyDeclarationEmitIsModule.ts @@ -0,0 +1,9 @@ +// @declaration: true +// @filename: module.ts +import * as i from "./index"; +class Foo {} +// @filename: index.ts +import {} from "./module"; +export interface Bar { + x: string +} \ No newline at end of file diff --git a/tests/cases/compiler/esModuleInterop.ts b/tests/cases/compiler/esModuleInterop.ts new file mode 100644 index 00000000000..7dfd8ff8611 --- /dev/null +++ b/tests/cases/compiler/esModuleInterop.ts @@ -0,0 +1,17 @@ +// @esModuleInterop: true +// @filename: hybrid/index.d.ts +export function sayHello(): string; +// @filename: path.d.ts +declare const anything: any; +export = anything; +// @filename: fs.d.ts +declare const anything: any; +export = anything; +// @filename: mjts.ts +import { sayHello } from "./hybrid"; +import path from "./path"; +import * as fs from "./fs"; + +path; +sayHello(); +fs; diff --git a/tests/cases/compiler/esModuleInteropImportCall.ts b/tests/cases/compiler/esModuleInteropImportCall.ts new file mode 100644 index 00000000000..759d4f3f936 --- /dev/null +++ b/tests/cases/compiler/esModuleInteropImportCall.ts @@ -0,0 +1,11 @@ +// @esModuleInterop: true +// @lib: es6 +// @Filename: foo.d.ts +declare function foo(): void; +declare namespace foo {} +export = foo; + +// @Filename: index.ts +import("./foo").then(f => { + f.default; +}); \ No newline at end of file diff --git a/tests/cases/compiler/esModuleInteropImportNamespace.ts b/tests/cases/compiler/esModuleInteropImportNamespace.ts new file mode 100644 index 00000000000..0b3c92577ef --- /dev/null +++ b/tests/cases/compiler/esModuleInteropImportNamespace.ts @@ -0,0 +1,9 @@ +// @esModuleInterop: true +// @Filename: foo.d.ts +declare function foo(): void; +declare namespace foo {} +export = foo; + +// @Filename: index.ts +import * as foo from "./foo"; +foo.default; diff --git a/tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts b/tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts new file mode 100644 index 00000000000..67e996c975b --- /dev/null +++ b/tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts @@ -0,0 +1,4 @@ +// #17847 +function sum(n: number, v: T, k: K) { + n += v[k]; +} diff --git a/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts b/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts new file mode 100644 index 00000000000..d23cbe87ddf --- /dev/null +++ b/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts @@ -0,0 +1,10 @@ +type Diff = + ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] +type Omit = Pick> +type Omit1 = Pick>; +// is in fact an equivalent of + +type Omit2 = {[P in Diff]: T[P]}; + +type O = Omit<{ a: number, b: string }, 'a'> +const o: O = { b: '' } diff --git a/tests/cases/compiler/indexerConstraints2.ts b/tests/cases/compiler/indexerConstraints2.ts index a7439b018e7..38b4ddec41a 100644 --- a/tests/cases/compiler/indexerConstraints2.ts +++ b/tests/cases/compiler/indexerConstraints2.ts @@ -25,4 +25,51 @@ class J { class K extends J { [n: number]: A; [s: string]: B; +} + + +type AliasedNumber = number; + +interface L { + [n: AliasedNumber]: A; +} + +type AliasedString = string; + +interface M { + [s: AliasedString]: A; +} + +type AliasedBoolean = boolean; + +interface N { + [b: AliasedBoolean]: A; +} + +type IndexableUnion = "foo" | "bar"; + +interface O { + [u: IndexableUnion]: A; +} + +type NonIndexableUnion = boolean | {}; + +interface P { + [u: NonIndexableUnion]: A; +} + +type NonIndexableUnion2 = string | number; + +interface Q { + [u: NonIndexableUnion2]: A; +} + +type NonIndexableUnion3 = "foo" | 42; + +interface R { + [u: NonIndexableUnion3]: A; +} + +interface S { + [u: "foo" | "bar"]: A; } \ No newline at end of file diff --git a/tests/cases/compiler/initializedDestructuringAssignmentTypes.ts b/tests/cases/compiler/initializedDestructuringAssignmentTypes.ts new file mode 100644 index 00000000000..bc3ec4ca407 --- /dev/null +++ b/tests/cases/compiler/initializedDestructuringAssignmentTypes.ts @@ -0,0 +1,3 @@ +const [, a = ''] = ''.match('') || []; + +a.toFixed() \ No newline at end of file diff --git a/tests/cases/compiler/jsxHasLiteralType.tsx b/tests/cases/compiler/jsxHasLiteralType.tsx new file mode 100644 index 00000000000..17132fdad40 --- /dev/null +++ b/tests/cases/compiler/jsxHasLiteralType.tsx @@ -0,0 +1,11 @@ +// @strictNullChecks: true +// @jsx: react +// @skipLibCheck: true +// @libFiles: lib.d.ts,react.d.ts +import * as React from "react"; + +interface Props { + x?: "a" | "b"; +} +class MyComponent

extends React.Component {} +const m = diff --git a/tests/cases/compiler/mappedTypeRecursiveInference.ts b/tests/cases/compiler/mappedTypeRecursiveInference.ts index d7a9cf3a0be..1b2e34837f6 100644 --- a/tests/cases/compiler/mappedTypeRecursiveInference.ts +++ b/tests/cases/compiler/mappedTypeRecursiveInference.ts @@ -1,5 +1,22 @@ +// @lib: es6, dom interface A { a: A } declare let a: A; type Deep = { [K in keyof T]: Deep } declare function foo(deep: Deep): T; const out = foo(a); +out.a +out.a.a +out.a.a.a.a.a.a.a + + +interface B { [s: string]: B } +declare let b: B; +const oub = foo(b); +oub.b +oub.b.b +oub.b.a.n.a.n.a + +let xhr: XMLHttpRequest; +const out2 = foo(xhr); +out2.responseXML +out2.responseXML.activeElement.className.length diff --git a/tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts b/tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts new file mode 100644 index 00000000000..bcaa9010715 --- /dev/null +++ b/tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts @@ -0,0 +1,18 @@ +// @noUnusedLocals: true + +namespace n { + function f() { + f; + } + + switch (0) { + case 0: + function g() { + g; + } + default: + function h() { + h; + } + } +} diff --git a/tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts b/tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts new file mode 100644 index 00000000000..065c6f89e7a --- /dev/null +++ b/tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts @@ -0,0 +1,13 @@ +// @noUnusedLocals: true +// @lib: es6 + +const x = Symbol("x"); +const y = Symbol("y"); +class C { + private [x]: number; + private [y]: number; + m() { + this[x] = 0; // write-only + this[y]; + } +} diff --git a/tests/cases/compiler/nullableFunctionError.ts b/tests/cases/compiler/nullableFunctionError.ts new file mode 100644 index 00000000000..5477d7fa29a --- /dev/null +++ b/tests/cases/compiler/nullableFunctionError.ts @@ -0,0 +1,6 @@ +// @strictNullChecks: true + +null(); +undefined(); +let f: null | undefined; +f(); diff --git a/tests/cases/compiler/parseErrorDoubleCommaInCall.ts b/tests/cases/compiler/parseErrorDoubleCommaInCall.ts new file mode 100644 index 00000000000..2171e9262a9 --- /dev/null +++ b/tests/cases/compiler/parseErrorDoubleCommaInCall.ts @@ -0,0 +1,3 @@ +Boolean({ + x: 0,, +}); diff --git a/tests/cases/compiler/strictFunctionTypes1.ts b/tests/cases/compiler/strictFunctionTypes1.ts index 6c07bc51ffe..ad8836fcf05 100644 --- a/tests/cases/compiler/strictFunctionTypes1.ts +++ b/tests/cases/compiler/strictFunctionTypes1.ts @@ -17,3 +17,13 @@ const x1 = f1(fo, fs); // (x: string) => void const x2 = f2("abc", fo, fs); // "abc" const x3 = f3("abc", fo, fx); // "abc" | "def" const x4 = f4(fo, fs); // Func + +declare const never: never; + +const x10 = f2(never, fo, fs); // string +const x11 = f3(never, fo, fx); // "def" + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +let x = foo([]); // never diff --git a/tests/cases/compiler/superAccessCastedCall.ts b/tests/cases/compiler/superAccessCastedCall.ts new file mode 100644 index 00000000000..98f154834e1 --- /dev/null +++ b/tests/cases/compiler/superAccessCastedCall.ts @@ -0,0 +1,20 @@ +class Foo { + bar(): void {} +} + +class Bar extends Foo { + x: Number; + + constructor() { + super(); + this.x = 2; + } + + bar() { + super.bar(); + (super.bar as any)(); + } +} + +let b = new Bar(); +b.bar() \ No newline at end of file diff --git a/tests/cases/compiler/superElementAccess.ts b/tests/cases/compiler/superElementAccess.ts new file mode 100644 index 00000000000..1b7e3f45683 --- /dev/null +++ b/tests/cases/compiler/superElementAccess.ts @@ -0,0 +1,36 @@ + +class MyBase { + m1(a: string) { return a; } + private p1() { } + m2: () => void = function () { } + d1: number = 42; + private d2: number = 42; + get value() {return 0 } + set value(v: number) { } +} + + +class MyDerived extends MyBase { + + foo() { + super["m1"]("hi"); // Should be allowed, method on base prototype + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature + + super["m2"].bind(this); // Should error, instance property, not a public instance member function + + super["p1"](); // Should error, private not public instance member function + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment + + super["value"] = 0; // Should error, instance data property not a public instance member function + + var z = super["value"]; // Should error, instance data property not a public instance member function + } +} \ No newline at end of file diff --git a/tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts b/tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts new file mode 100644 index 00000000000..b5e40b7ceff --- /dev/null +++ b/tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts @@ -0,0 +1,17 @@ +class A { x() {} } + +class B extends A { + constructor() { + super(); + } + foo() { + return () => { + super.x; + } + } + bar() { + return () => { + super["x"]; + } + } +} \ No newline at end of file diff --git a/tests/cases/compiler/systemObjectShorthandRename.ts b/tests/cases/compiler/systemObjectShorthandRename.ts new file mode 100644 index 00000000000..7bc6ce56649 --- /dev/null +++ b/tests/cases/compiler/systemObjectShorthandRename.ts @@ -0,0 +1,12 @@ +// @module: system +// @target: es2015 +// @filename: x.ts +export const x = 'X' +// @filename: index.ts +import {x} from './x.js' + +const x2 = {x} +const a = {x2} + +const x3 = x +const b = {x3} \ No newline at end of file diff --git a/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts b/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts new file mode 100644 index 00000000000..d844a910279 --- /dev/null +++ b/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts @@ -0,0 +1,4 @@ +// @target: es5 +var K = 'k' +var a = { p : (true ? { [K] : 'v'} : null) } +var b = { p : (true ? { [K] : 'v'} as any : null) } \ No newline at end of file diff --git a/tests/cases/compiler/unusedGetterInClass.ts b/tests/cases/compiler/unusedGetterInClass.ts index e5259f91cdc..cc08954eb75 100644 --- a/tests/cases/compiler/unusedGetterInClass.ts +++ b/tests/cases/compiler/unusedGetterInClass.ts @@ -5,7 +5,9 @@ class Employee { private _fullName: string; - get fullName(): string { + private get fullName(): string { return this._fullName; } + // Will not also error on the setter + private set fullName(_: string) {} } \ No newline at end of file diff --git a/tests/cases/compiler/unusedSetterInClass.ts b/tests/cases/compiler/unusedSetterInClass.ts index a8e45bab434..634f2b2b08e 100644 --- a/tests/cases/compiler/unusedSetterInClass.ts +++ b/tests/cases/compiler/unusedSetterInClass.ts @@ -5,7 +5,7 @@ class Employee { private _fullName: string; - set fullName(newName: string) { + private set fullName(newName: string) { this._fullName = newName; } } \ No newline at end of file diff --git a/tests/cases/compiler/unusedSetterInClass2.ts b/tests/cases/compiler/unusedSetterInClass2.ts new file mode 100644 index 00000000000..2e6ee32e0e6 --- /dev/null +++ b/tests/cases/compiler/unusedSetterInClass2.ts @@ -0,0 +1,10 @@ +// @noUnusedLocals:true + +// Unlike everything else, a setter without a getter is used by a write access. +class Employee { + private set p(_: number) {} + + m() { + this.p = 0; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts b/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts new file mode 100644 index 00000000000..222718122ef --- /dev/null +++ b/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts @@ -0,0 +1,18 @@ +// @target: ES5 +// @lib: es5,es2015.promise +// @noEmitHelpers: true +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { + static B = class B { + static func2(): Promise { + return new Promise((resolve) => { resolve(null); }); + } + static C = class C { + static async func() { + await B.func2(); + } + } + } +} + +A.B.C.func(); \ No newline at end of file diff --git a/tests/cases/conformance/constEnums/constEnum3.ts b/tests/cases/conformance/constEnums/constEnum3.ts new file mode 100644 index 00000000000..ffc6bb1c5f5 --- /dev/null +++ b/tests/cases/conformance/constEnums/constEnum3.ts @@ -0,0 +1,10 @@ +const enum TestType { foo, bar } +type TestTypeStr = keyof typeof TestType; + +function f1(f: TestType) { } +function f2(f: TestTypeStr) { } + +f1(TestType.foo) +f1(TestType.bar) +f2('foo') +f2('bar') diff --git a/tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts b/tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts new file mode 100644 index 00000000000..18777844558 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowWithTemplateLiterals.ts @@ -0,0 +1,10 @@ +// @strictNullChecks: true +declare const envVar: string | undefined; +if (typeof envVar === `string`) { + envVar.slice(0) +} + +declare const obj: {test: string} | {} +if (`test` in obj) { + obj.test.slice(0) +} diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts b/tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts index 38dc47f3207..609a70a2013 100644 --- a/tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts +++ b/tests/cases/conformance/dynamicImport/importCallExpressionGrammarError.ts @@ -10,5 +10,4 @@ import(...["PathModule"]); var p1 = import(...a); const p2 = import(); -const p3 = import(,); const p4 = import("pathToModule", "secondModule"); \ No newline at end of file diff --git a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts index 60099bb1c0f..719f10bbbcc 100644 --- a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts +++ b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts @@ -7,7 +7,7 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] -var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}) // [never, any][] +var entries = Object.entries(o); +var entries1 = Object.entries(1); +var entries2 = Object.entries({a: true, b: 2}) +var entries3 = Object.entries({}) diff --git a/tests/cases/conformance/es6/Symbols/symbolProperty60.ts b/tests/cases/conformance/es6/Symbols/symbolProperty60.ts new file mode 100644 index 00000000000..4086223f69c --- /dev/null +++ b/tests/cases/conformance/es6/Symbols/symbolProperty60.ts @@ -0,0 +1,23 @@ +// @target: es2015 +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { + [Symbol.toStringTag]: string; + [key: string]: number; +} + +interface I2 { + [Symbol.toStringTag]: string; + [key: number]: boolean; +} + +declare const mySymbol: unique symbol; + +interface I3 { + [mySymbol]: string; + [key: string]: number; +} + +interface I4 { + [mySymbol]: string; + [key: number]: boolean; +} \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts b/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts new file mode 100644 index 00000000000..042ed5d5248 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts @@ -0,0 +1,9 @@ +// @target: es5 +var foo: any = { foo: 1, bar: 2 }; +var bar: any; + +// reassignment in destructuring pattern +({ foo, bar } = foo); + +// reassignment in subsequent var +var { foo, baz } = foo; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts b/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts new file mode 100644 index 00000000000..2303bb33944 --- /dev/null +++ b/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts @@ -0,0 +1,11 @@ +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum, K extends string>(n: number, vs: T[], k: K) { + for (const v of vs) { + n = n + v[k]; + n += v[k]; + } +} diff --git a/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts b/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts index 181252c0721..4c698626eb0 100644 --- a/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts +++ b/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts @@ -38,4 +38,24 @@ module M3 { export interface A { // error y: T; } -} \ No newline at end of file +} + +interface B { + u: T; + v: Constraint; // ok +} + +interface B { // ok + x: T; + y: Constraint; // ok +} + +interface C { + x: T; +} + +interface C { // error + y: T; +} + +interface Constraint {} diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx index 2c134d4e20e..de918e6bb77 100644 --- a/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType4.tsx @@ -13,7 +13,6 @@ class B1 extends React.Component { } class B extends React.Component { render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; } } \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx b/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx index ba8d9a284ca..5e4da2e46f7 100644 --- a/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx +++ b/tests/cases/conformance/jsx/tsxGenericAttributesType5.tsx @@ -14,7 +14,6 @@ class B1 extends React.Component { class B extends React.Component { props: U; render() { - // Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object return ; } } \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx b/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx index 84c4ffcef45..7b96a88a382 100644 --- a/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx +++ b/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx @@ -15,6 +15,5 @@ declare class MyComp

extends React.Component { internalProp: P; } -// Error let x = let x1 = \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter3.tsx b/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter3.tsx index abae7e36853..57b9a9e0a8e 100644 --- a/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter3.tsx +++ b/tests/cases/conformance/jsx/tsxReactComponentWithDefaultTypeParameter3.tsx @@ -15,9 +15,11 @@ declare class MyComp

extends React.Component { internalProp: P; } -// OK: we fille in missing type argument with empty object +// Error let x1 = -// Error +// OK let x = + +// Error let x2 = \ No newline at end of file diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts index cbbc9a52200..ffc5076831a 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts @@ -76,4 +76,13 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { o2 = o1; // Error k1 = k2; // Error k2 = k1; -} \ No newline at end of file +} + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} + diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts new file mode 100644 index 00000000000..1e852f12f92 --- /dev/null +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts @@ -0,0 +1,32 @@ +// @strict: true +// test for #15371 +function f(s: string, tp: T[P]): void { + tp = s; +} +function g(s: string, tp: T[P]): void { + tp = s; +} +function h(s: string, tp: T[P]): void { + tp = s; +} +function i(s: string, tp: T[P]): void { + tp = s; +} +function j(s: string, tp: T[P]): void { + tp = s; +} +function k(s: string, tp: T[P]): void { + tp = s; +} +function o(s: string, tp: T[P]): void { + tp = s; +} +function l(s: string, tp: T[P]): void { + tp = s; +} +function m(s: string, tp: T[P]): void { + tp = s; +} +function n(s: string, tp: T[P]): void { + tp = s; +} diff --git a/tests/cases/fourslash/ambientShorthandFindAllRefs.ts b/tests/cases/fourslash/ambientShorthandFindAllRefs.ts index 3f325a546c2..14918f4a449 100644 --- a/tests/cases/fourslash/ambientShorthandFindAllRefs.ts +++ b/tests/cases/fourslash/ambientShorthandFindAllRefs.ts @@ -12,5 +12,5 @@ const ranges = test.ranges(); const [r0, r1] = ranges; // TODO: Want these to be in the same group, but that would require creating a symbol for `x`. -verify.singleReferenceGroup("import x", [r0]); -verify.singleReferenceGroup("import x", [r1]); \ No newline at end of file +verify.singleReferenceGroup("(alias) module \"jquery\"\nimport x", [r0]); +verify.singleReferenceGroup("(alias) module \"jquery\"\nimport x", [r1]); \ No newline at end of file diff --git a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts index f0e717999cf..6530a0e0c99 100644 --- a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts +++ b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts @@ -10,22 +10,22 @@ ////import [|/*importBang*/bang|] = require("jquery"); ////[|foo/*useFoo*/|]([|bar/*useBar*/|], [|baz/*useBaz*/|], [|bang/*useBang*/|]); -verify.quickInfoAt("useFoo", "import foo"); +verify.quickInfoAt("useFoo", "(alias) module \"jquery\"\nimport foo"); verify.goToDefinition({ useFoo: "module", importFoo: "module" }); -verify.quickInfoAt("useBar", "import bar"); +verify.quickInfoAt("useBar", "(alias) module \"jquery\"\nimport bar"); verify.goToDefinition("useBar", "module"); -verify.quickInfoAt("useBaz", "import baz"); +verify.quickInfoAt("useBaz", "(alias) module \"jquery\"\nimport baz"); verify.goToDefinition({ useBaz: "importBaz", importBaz: "module" }); -verify.quickInfoAt("useBang", "import bang = require(\"jquery\")"); +verify.quickInfoAt("useBang", "(alias) module \"jquery\"\nimport bang = require(\"jquery\")"); verify.goToDefinition({ useBang: "module", importBang: "module" diff --git a/tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts b/tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts index 8f80c871eb3..13927f9d2dd 100644 --- a/tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts +++ b/tests/cases/fourslash/cancellationWhenfindingAllRefsOnDefinition.ts @@ -36,8 +36,5 @@ function checkRefs() { const ranges = test.ranges(); const [r0, r1] = ranges; verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]); - verify.referenceGroups(r1, [ - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] }, - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] } - ]); + verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]); } diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts new file mode 100644 index 00000000000..e64d4072757 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction1.ts @@ -0,0 +1,13 @@ +/// + +////function f() { +//// await Promise.resolve(); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f() { + await Promise.resolve(); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts new file mode 100644 index 00000000000..42e0bc5be78 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction10.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => number | string = () => { +//// await Promise.resolve('foo'); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts new file mode 100644 index 00000000000..bc7b17f8db5 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction11.ts @@ -0,0 +1,14 @@ +/// + +////const f: string = () => { +//// await Promise.resolve('foo'); +////} + +// should not change type if it's incorrectly set +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: string = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts new file mode 100644 index 00000000000..ee694a80e9f --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction12.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => Array = function() { +//// await Promise.resolve([]); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise> = async function() { + await Promise.resolve([]); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts new file mode 100644 index 00000000000..06f54d29eeb --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction13.ts @@ -0,0 +1,13 @@ +/// + +////const f: () => Promise = () => { +//// await Promise.resolve('foo'); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f: () => Promise = async () => { + await Promise.resolve('foo'); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts new file mode 100644 index 00000000000..c798af5f5ab --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction14.ts @@ -0,0 +1,13 @@ +/// + +////const f = function(): number { +//// await Promise.resolve(1); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async function(): Promise { + await Promise.resolve(1); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts new file mode 100644 index 00000000000..a2c6f7dcb1a --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction15.ts @@ -0,0 +1,13 @@ +/// + +////const f = (): number[] => { +//// await Promise.resolve([1]); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async (): Promise => { + await Promise.resolve([1]); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts new file mode 100644 index 00000000000..e8da351af5d --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction2.ts @@ -0,0 +1,13 @@ +/// + +////const f = function() { +//// await Promise.resolve(); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async function() { + await Promise.resolve(); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts new file mode 100644 index 00000000000..54d0aba103b --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction3.ts @@ -0,0 +1,12 @@ +/// + +////const f = { +//// get a() { +//// return await Promise.resolve(); +//// }, +//// get a() { +//// await Promise.resolve(); +//// }, +////} + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts new file mode 100644 index 00000000000..dd123e25d0b --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction4.ts @@ -0,0 +1,9 @@ +/// + +////class Foo { +//// constructor { +//// await Promise.resolve(); +//// } +////} + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts new file mode 100644 index 00000000000..a1c58b53831 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction5.ts @@ -0,0 +1,17 @@ +/// + +////class Foo { +//// bar() { +//// await Promise.resolve(); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`class Foo { + async bar() { + await Promise.resolve(); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts new file mode 100644 index 00000000000..c1b06811113 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.5.ts @@ -0,0 +1,13 @@ +/// + +////const f = promise => { +//// await promise; +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async promise => { + await promise; +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts new file mode 100644 index 00000000000..0b0aa098164 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction6.ts @@ -0,0 +1,13 @@ +/// + +////const f = (promise) => { +//// await promise; +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`const f = async (promise) => { + await promise; +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts new file mode 100644 index 00000000000..a467e9ee0ce --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction7.ts @@ -0,0 +1,17 @@ +/// + +////function f() { +//// for await (const x of g()) { +//// console.log(x); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f() { + for await (const x of g()) { + console.log(x); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts new file mode 100644 index 00000000000..7c43add3edd --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction8.ts @@ -0,0 +1,13 @@ +/// + +////function f(): number | string { +//// await Promise.resolve(8); +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`async function f(): Promise { + await Promise.resolve(8); +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts new file mode 100644 index 00000000000..f93603e69c4 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction9.ts @@ -0,0 +1,17 @@ +/// + +////class Foo { +//// bar(): string { +//// await Promise.resolve('baz'); +//// } +////} + +verify.codeFix({ + description: "Add async modifier to containing function", + newFileContent: +`class Foo { + async bar(): Promise { + await Promise.resolve('baz'); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts new file mode 100644 index 00000000000..e6314a3a5f0 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts @@ -0,0 +1,21 @@ +/// + +////function f() { +//// await Promise.resolve(); +////} +//// +////const g = () => { +//// await f(); +////} + +verify.codeFixAll({ + fixId: "fixAwaitInSyncFunction", + newFileContent: +`async function f() { + await Promise.resolve(); +} + +const g = async () => { + await f(); +}`, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import1.ts b/tests/cases/fourslash/codeFixCalledES2015Import1.ts new file mode 100644 index 00000000000..45e88c19047 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import1.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////function invoke(f: () => void) { f(); } +////invoke(foo); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo = require("./foo");'.`, + newRangeContent: `import foo = require("./foo");`, + index: 1, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import10.ts b/tests/cases/fourslash/codeFixCalledES2015Import10.ts new file mode 100644 index 00000000000..d82e345c56c --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import10.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////import * as foo from "./foo"; +////[|foo()|]; + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo = require("./foo");'.`, + newFileContent: `import foo = require("./foo"); +foo();`, + index: 1, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import11.ts b/tests/cases/fourslash/codeFixCalledES2015Import11.ts new file mode 100644 index 00000000000..14b02fa38bc --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import11.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////import * as foo from "./foo"; +////[|foo()|]; + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newFileContent: `import foo from "./foo"; +foo();`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import12.ts b/tests/cases/fourslash/codeFixCalledES2015Import12.ts new file mode 100644 index 00000000000..6c31531d572 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import12.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////import * as foo from "./foo"; +////[|foo()|]; + +goTo.file(1); +verify.codeFix({ + description: `Use synthetic 'default' member.`, + newFileContent: `import * as foo from "./foo"; +foo.default();`, + index: 4, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import13.ts b/tests/cases/fourslash/codeFixCalledES2015Import13.ts new file mode 100644 index 00000000000..a67371bd46a --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import13.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////import * as Foo from "./foo"; +////[|new Foo()|]; + +goTo.file(1); +verify.codeFix({ + description: `Use synthetic 'default' member.`, + newFileContent: `import * as Foo from "./foo"; +new Foo.default();`, + index: 2, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import2.ts b/tests/cases/fourslash/codeFixCalledES2015Import2.ts new file mode 100644 index 00000000000..80040cb4192 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import2.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////function invoke(f: () => void) { f(); } +////invoke(foo); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import3.ts b/tests/cases/fourslash/codeFixCalledES2015Import3.ts new file mode 100644 index 00000000000..82f08fbc22f --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import3.ts @@ -0,0 +1,19 @@ +/// +// @esModuleInterop: true +// @module: amd +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////function invoke(f: () => void) { f(); } +////invoke(foo); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import4.ts b/tests/cases/fourslash/codeFixCalledES2015Import4.ts new file mode 100644 index 00000000000..ba6d90d6d41 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import4.ts @@ -0,0 +1,17 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo = require("./foo");'.`, + newRangeContent: `import foo = require("./foo");`, + index: 1, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import5.ts b/tests/cases/fourslash/codeFixCalledES2015Import5.ts new file mode 100644 index 00000000000..63b2137b6ef --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import5.ts @@ -0,0 +1,17 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import6.ts b/tests/cases/fourslash/codeFixCalledES2015Import6.ts new file mode 100644 index 00000000000..b741831bce9 --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import6.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @module: amd +// @Filename: foo.d.ts +////declare function foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import7.ts b/tests/cases/fourslash/codeFixCalledES2015Import7.ts new file mode 100644 index 00000000000..070a25254cb --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import7.ts @@ -0,0 +1,17 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare class foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////new foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo = require("./foo");'.`, + newRangeContent: `import foo = require("./foo");`, + index: 1, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import8.ts b/tests/cases/fourslash/codeFixCalledES2015Import8.ts new file mode 100644 index 00000000000..41e547c8abb --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import8.ts @@ -0,0 +1,17 @@ +/// +// @esModuleInterop: true +// @Filename: foo.d.ts +////declare class foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////new foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixCalledES2015Import9.ts b/tests/cases/fourslash/codeFixCalledES2015Import9.ts new file mode 100644 index 00000000000..1ce110f056a --- /dev/null +++ b/tests/cases/fourslash/codeFixCalledES2015Import9.ts @@ -0,0 +1,18 @@ +/// +// @esModuleInterop: true +// @module: amd +// @Filename: foo.d.ts +////declare class foo(): void; +////declare namespace foo {} +////export = foo; + +// @Filename: index.ts +////[|import * as foo from "./foo";|] +////new foo(); + +goTo.file(1); +verify.codeFix({ + description: `Replace import with 'import foo from "./foo";'.`, + newRangeContent: `import foo from "./foo";`, + index: 0, +}); diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts index 9bec3df4f41..0a7ae3e0e68 100644 --- a/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts @@ -8,5 +8,5 @@ verify.codeFix({ description: "Change 'extends' to 'implements'", // TODO: GH#18794 - newRangeContent: "abstract class A implements I1 , I2", + newRangeContent: "abstract class A implements I1, I2", }); diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts index 6940cd27830..e183677a31f 100644 --- a/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts @@ -13,5 +13,5 @@ verify.codeFix({ description: "Change 'extends' to 'implements'", // TODO: GH#18794 - newRangeContent: "class A implements I1 , I2 { }", + newRangeContent: "class A implements I1, I2 { }", }); diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithTrivia.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithTrivia.ts new file mode 100644 index 00000000000..ed7fa4c3b1d --- /dev/null +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithTrivia.ts @@ -0,0 +1,19 @@ +/// + +//// interface I1 { } +//// interface I2 { } +//// interface I3 { } + +//// [|class MyClass /*A !*/ //B ! +//// /*C !*/ extends /*D !*/ I1 /*E !*/ //F ! +//// /*G !*/ implements /*H !*/ I2 /*I !*/, /*J !*/ I3 /*K !*/ //L !|] +//// { +//// } + +verify.codeFix({ + description: "Change 'extends' to 'implements'", + // TODO: GH#18794 + newRangeContent: `class MyClass /*A !*/ //B ! + /*C !*/ implements /*D !*/ I1, /*E !*/ //F ! + /*G !*/ /*H !*/ I2 /*I !*/, /*J !*/ I3 /*K !*/ //L !`, +}); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts index b787d0c271e..5fff622f2db 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMappedType.ts @@ -13,6 +13,6 @@ verify.codeFix({ x: { readonly [K in keyof X]: X[K] }; } class C implements I {\r - x: { readonly [K in keyof X]: Y[K]; };\r + x: { readonly [K in keyof Y]: Y[K]; };\r }`, }); diff --git a/tests/cases/fourslash/codeFixInPropertyAccess_js.ts b/tests/cases/fourslash/codeFixInPropertyAccess_js.ts new file mode 100644 index 00000000000..2afde9b5ee1 --- /dev/null +++ b/tests/cases/fourslash/codeFixInPropertyAccess_js.ts @@ -0,0 +1,45 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: /a.js +//// /** +//// * @typedef Foo +//// * @property foo +//// */ + +//// /** +//// * @param {Foo.foo} inst +//// */ +//// function blah(inst) { +//// return false; +//// } + +verify.codeFixAll({ + fixId: "correctQualifiedNameToIndexedAccessType", + newFileContent: +`/** + * @typedef Foo + * @property foo + */ +/** + * @param {Foo["foo"]} inst + */ +function blah(inst) { + return false; +}`, +}); + + +/** + * @typedef Foo + * @property foo + */ + +/** + * @param {Foo.foo} inst + */ +function blah(inst) { + return false; +} \ No newline at end of file diff --git a/tests/cases/fourslash/completionEntryForDeferredMappedTypeMembers.ts b/tests/cases/fourslash/completionEntryForDeferredMappedTypeMembers.ts new file mode 100644 index 00000000000..785ac32ee39 --- /dev/null +++ b/tests/cases/fourslash/completionEntryForDeferredMappedTypeMembers.ts @@ -0,0 +1,17 @@ +/// +// @Filename: test.ts +//// interface A { a: A } +//// declare let a: A; +//// type Deep = { [K in keyof T]: Deep } +//// declare function foo(deep: Deep): T; +//// const out = foo(a); +//// out./*1*/a +//// out.a./*2*/a +//// out.a.a./*3*/a + +goTo.marker('1'); +verify.completionListCount(1); +goTo.marker('2'); +verify.completionListCount(1); +goTo.marker('3'); +verify.completionListCount(1); diff --git a/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts b/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts new file mode 100644 index 00000000000..0a86f5396c4 --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteralInIndexedAccess01.ts @@ -0,0 +1,13 @@ +/// + +////interface Foo { +//// foo: string; +//// bar: string; +////} +//// +////let x: Foo["/*1*/"] + +goTo.marker("1"); +verify.completionListContains("foo"); +verify.completionListContains("bar"); +verify.completionListCount(2); diff --git a/tests/cases/fourslash/completionListInImportClause05.ts b/tests/cases/fourslash/completionListInImportClause05.ts new file mode 100644 index 00000000000..f7b5244d5a4 --- /dev/null +++ b/tests/cases/fourslash/completionListInImportClause05.ts @@ -0,0 +1,20 @@ +/// + +// @Filename: app.ts +////import * as A from "[|/*1*/|]"; + +// @Filename: /node_modules/@types/a__b/index.d.ts +////declare module "@e/f" { function fun(): string; } + +// @Filename: /node_modules/@types/c__d/index.d.ts +////export declare let x: number; + +// NOTE: The node_modules folder is in "/", rather than ".", because it requires +// less scaffolding to mock. In particular, "/" is where we look for type roots. + +const [replacementSpan] = test.ranges(); +verify.completionsAt("1", [ + { name: "@a/b", replacementSpan }, + { name: "@c/d", replacementSpan }, + { name: "@e/f", replacementSpan }, +]); diff --git a/tests/cases/fourslash/completionListInImportClause06.ts b/tests/cases/fourslash/completionListInImportClause06.ts new file mode 100644 index 00000000000..f6cfefa437f --- /dev/null +++ b/tests/cases/fourslash/completionListInImportClause06.ts @@ -0,0 +1,17 @@ +/// + +// @typeRoots: T1,T2 + +// @Filename: app.ts +////import * as A from "[|/*1*/|]"; + +// @Filename: T1/a__b/index.d.ts +////export declare let x: number; + +// @Filename: T2/a__b/index.d.ts +////export declare let x: number; + +// Confirm that entries are de-dup'd. +verify.completionsAt("1", [ + { name: "@a/b", replacementSpan: test.ranges()[0] }, +]); diff --git a/tests/cases/fourslash/completionListInvalidMemberNames.ts b/tests/cases/fourslash/completionListInvalidMemberNames.ts index 8e62ba2fb67..3dc54274e83 100644 --- a/tests/cases/fourslash/completionListInvalidMemberNames.ts +++ b/tests/cases/fourslash/completionListInvalidMemberNames.ts @@ -11,8 +11,21 @@ //// "\u0031\u0062": "invalid unicode identifer name (1b)" ////}; //// -////x./*a*/; +////x[|./*a*/|]; ////x["/*b*/"]; -verify.completionsAt("a", ["bar", "break", "any", "$", "b"]); -verify.completionsAt("b", ["foo ", "bar", "break", "any", "#", "$", "b", "\u0031\u0062"]); +verify.completionsAt("b", ["foo ", "bar", "break", "any", "#", "$", "b", "1b"]); + +const replacementSpan = test.ranges()[0]; +verify.completionsAt("a", [ + { name: "foo ", insertText: '["foo "]', replacementSpan }, + "bar", + "break", + "any", + { name: "#", insertText: '["#"]', replacementSpan }, + "$", + "b", + { name: "1b", insertText: '["1b"]', replacementSpan }, +], { + includeInsertTextCompletions: true, +}); diff --git a/tests/cases/fourslash/completionListInvalidMemberNames2.ts b/tests/cases/fourslash/completionListInvalidMemberNames2.ts index 753f9bbcb30..153ed3bdb5e 100644 --- a/tests/cases/fourslash/completionListInvalidMemberNames2.ts +++ b/tests/cases/fourslash/completionListInvalidMemberNames2.ts @@ -1,10 +1,19 @@ /// -////enum Foo { -//// X, Y, '☆' -////} -////Foo./*a*/; -////Foo["/*b*/"]; +// TODO: we should probably support this like we do in completionListInvalidMemberNames.ts -verify.completionsAt("a", ["X", "Y"]); -verify.completionsAt("b", ["X", "Y", "☆"]); +////declare var Symbol: SymbolConstructor; +////interface SymbolConstructor { +//// readonly hasInstance: symbol; +////} +////interface Function { +//// [Symbol.hasInstance](value: any): boolean; +////} +////interface SomeInterface { +//// (value: number): any; +////} +////var _ : SomeInterface; +////_./**/ + +goTo.marker(); +verify.not.completionListContains("[Symbol.hasInstance]"); diff --git a/tests/cases/fourslash/completionListInvalidMemberNames3.ts b/tests/cases/fourslash/completionListInvalidMemberNames3.ts deleted file mode 100644 index cf1141b4094..00000000000 --- a/tests/cases/fourslash/completionListInvalidMemberNames3.ts +++ /dev/null @@ -1,71 +0,0 @@ -/// - -// @allowjs: true - -// @Filename: test.js -////interface Symbol { -//// /** Returns a string representation of an object. */ -//// toString(): string; - -//// /** Returns the primitive value of the specified object. */ -//// valueOf(): Object; -////} - -////interface SymbolConstructor { -//// /** -//// * A reference to the prototype. -//// */ -//// readonly prototype: Symbol; - -//// /** -//// * Returns a new unique Symbol value. -//// * @param description Description of the new Symbol object. -//// */ -//// (description?: string | number): symbol; - -//// /** -//// * Returns a Symbol object from the global symbol registry matching the given key if found. -//// * Otherwise, returns a new symbol with this key. -//// * @param key key to search for. -//// */ -//// for(key: string): symbol; - -//// /** -//// * Returns a key from the global symbol registry matching the given Symbol if found. -//// * Otherwise, returns a undefined. -//// * @param sym Symbol to find the key for. -//// */ -//// keyFor(sym: symbol): string | undefined; -////} - -////declare var Symbol: SymbolConstructor;/// - -////interface SymbolConstructor { -//// /** -//// * A method that determines if a constructor object recognizes an object as one of the -//// * constructors instances. Called by the semantics of the instanceof operator. -//// */ -//// readonly hasInstance: symbol; -////} - -////interface Function { -//// /** -//// * Determines whether the given value inherits from this function if this function was used -//// * as a constructor function. -//// * -//// * A constructor function can control which objects are recognized as its instances by -//// * 'instanceof' by overriding this method. -//// */ -//// [Symbol.hasInstance](value: any): boolean; -////} - -////interface SomeInterface { -//// (value: number): any; -////} - -////var _ : SomeInterface; -////_./**/ - -goTo.marker(); - -verify.not.completionListContains("[Symbol.hasInstance]"); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInvalidMemberNames_startWithSpace.ts b/tests/cases/fourslash/completionListInvalidMemberNames_startWithSpace.ts new file mode 100644 index 00000000000..f86c8a5a813 --- /dev/null +++ b/tests/cases/fourslash/completionListInvalidMemberNames_startWithSpace.ts @@ -0,0 +1,8 @@ +/// + +////declare const x: { " foo": 0, "foo ": 1 }; +////x[|./**/|]; + +const replacementSpan = test.ranges()[0]; +// No completion for " foo" because it starts with a space. See https://github.com/Microsoft/TypeScript/pull/20547 +verify.completionsAt("", [{ name: "foo ", insertText: '["foo "]', replacementSpan }], { includeInsertTextCompletions: true }); diff --git a/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts b/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts new file mode 100644 index 00000000000..8463a710b01 --- /dev/null +++ b/tests/cases/fourslash/completionListInvalidMemberNames_withExistingIdentifier.ts @@ -0,0 +1,7 @@ +/// + +////declare const x: { "foo ": "space in the name", }; +////x[|.fo/**/|]; + +const replacementSpan = test.ranges()[0]; +verify.completionsAt("", [{ name: "foo ", insertText: '["foo "]', replacementSpan }], { includeInsertTextCompletions: true }); diff --git a/tests/cases/fourslash/completionListOnAliases.ts b/tests/cases/fourslash/completionListOnAliases.ts index c15e5284c06..0c5b7adcd50 100644 --- a/tests/cases/fourslash/completionListOnAliases.ts +++ b/tests/cases/fourslash/completionListOnAliases.ts @@ -9,7 +9,7 @@ ////} goTo.marker("1"); -verify.completionListContains("x", "import x = M", undefined); +verify.completionListContains("x", "(alias) namespace x\nimport x = M", undefined); goTo.marker("2"); verify.completionListContains("value"); diff --git a/tests/cases/fourslash/completionWithConditionalOperatorMissingColon.ts b/tests/cases/fourslash/completionWithConditionalOperatorMissingColon.ts new file mode 100644 index 00000000000..9ec879d5022 --- /dev/null +++ b/tests/cases/fourslash/completionWithConditionalOperatorMissingColon.ts @@ -0,0 +1,6 @@ +/// +////1 ? fun/*1*/ +////function func () {} + +goTo.marker("1"); +verify.completionListContains("func"); diff --git a/tests/cases/fourslash/completion_enum-members-with-invalid-identifiers-should-not-show-in-completion.ts b/tests/cases/fourslash/completion_enum-members-with-invalid-identifiers-should-not-show-in-completion.ts deleted file mode 100644 index 6d5b3167198..00000000000 --- a/tests/cases/fourslash/completion_enum-members-with-invalid-identifiers-should-not-show-in-completion.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// - -//// enum e { -//// "1", -//// 2 = 3, -//// 3, -//// a, -//// b -//// } -//// -//// e./**/ - -verify.completionsAt("", ["a", "b"]); diff --git a/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts b/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts new file mode 100644 index 00000000000..7549c2e001b --- /dev/null +++ b/tests/cases/fourslash/completionsImport_default_exportDefaultIdentifier.ts @@ -0,0 +1,26 @@ +/// + +// Tests that we use the name "foo". + +// @Filename: /a.ts +////const foo = 0; +////export default foo; + +// @Filename: /b.ts +////f/**/; + +goTo.marker(""); +verify.completionListContains({ name: "foo", source: "/a" }, "(alias) const foo: 0\nexport default foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, { + includeExternalModuleExports: true, + sourceDisplay: "./a", +}); + +verify.applyCodeActionFromCompletion("", { + name: "foo", + source: "/a", + description: `Import 'foo' from module "./a"`, + // TODO: GH#18445 + newFileContent: `import foo from "./a";\r +\r +f;`, +}); diff --git a/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts b/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts index c793a5f06ad..a69c0ab19ca 100644 --- a/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts +++ b/tests/cases/fourslash/completionsImport_named_didNotExistBefore.ts @@ -11,7 +11,7 @@ goTo.marker(""); const options = { includeExternalModuleExports: true, sourceDisplay: undefined }; verify.completionListContains({ name: "Test1", source: "/a" }, "function Test1(): void", "", "function", /*spanIndex*/ undefined, /*hasAction*/ true, { ...options, sourceDisplay: "./a" }); -verify.completionListContains("Test2", "import Test2", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ undefined, options); +verify.completionListContains("Test2", "(alias) function Test2(): void\nimport Test2", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ undefined, options); verify.not.completionListContains({ name: "Test2", source: "/a" }, undefined, undefined, undefined, undefined, undefined, options); verify.applyCodeActionFromCompletion("", { diff --git a/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace.ts b/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace.ts new file mode 100644 index 00000000000..b88ce9cae0d --- /dev/null +++ b/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace.ts @@ -0,0 +1,26 @@ +/// + +// @Filename: /a.d.ts +////declare namespace N { +//// export const foo = 0; +////} +////export = N; + +// @Filename: /b.ts +////f/**/; + +goTo.marker(""); +verify.completionListContains({ name: "foo", source: "/a" }, "const N.foo: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, { + includeExternalModuleExports: true, + sourceDisplay: "./a", +}); + +verify.applyCodeActionFromCompletion("", { + name: "foo", + source: "/a", + description: `Import 'foo' from module "./a"`, + // TODO: GH#18445 + newFileContent: `import { foo } from "./a";\r +\r +f;`, +}); diff --git a/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace_merged.ts b/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace_merged.ts new file mode 100644 index 00000000000..55b33c22114 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_named_exportEqualsNamespace_merged.ts @@ -0,0 +1,21 @@ +/// + +// @Filename: /b.d.ts +////declare namespace N { +//// export const foo: number; +////} +////declare module "n" { +//// export = N; +////} + +// @Filename: /c.d.ts +////declare namespace N {} + +// @Filename: /a.ts +////fo/**/ + +goTo.marker(""); +verify.completionListContains({ name: "foo", source: "n" }, "const N.foo: number", "", "const", undefined, /*hasAction*/ true, { + includeExternalModuleExports: true, + sourceDisplay: "n", +}); diff --git a/tests/cases/fourslash/completionsImport_ofAlias.ts b/tests/cases/fourslash/completionsImport_ofAlias.ts index a693065b93c..5808e6c9f1a 100644 --- a/tests/cases/fourslash/completionsImport_ofAlias.ts +++ b/tests/cases/fourslash/completionsImport_ofAlias.ts @@ -21,7 +21,7 @@ goTo.marker(""); const options = { includeExternalModuleExports: true, sourceDisplay: "./a" }; // TODO: https://github.com/Microsoft/TypeScript/issues/14003 //TODO: verify that there's only one! -verify.completionListContains({ name: "foo", source: "/a" }, "import foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, options); +verify.completionListContains({ name: "foo", source: "/a" }, "(alias) const foo: 0\nimport foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, options); verify.not.completionListContains({ name: "foo", source: "/a_reexport" }, undefined, undefined, undefined, undefined, undefined, options); verify.not.completionListContains({ name: "foo", source: "/a_reexport_2" }, undefined, undefined, undefined, undefined, undefined, options); diff --git a/tests/cases/fourslash/completionsOptionalKindModifier.ts b/tests/cases/fourslash/completionsOptionalKindModifier.ts new file mode 100644 index 00000000000..39ace2342d3 --- /dev/null +++ b/tests/cases/fourslash/completionsOptionalKindModifier.ts @@ -0,0 +1,10 @@ +/// + +////interface A { a?: number; method?(): number; }; +////function f(x: A) { +////x./*a*/; +////} + +goTo.marker("a"); +verify.completionListContains("a", /* text */ undefined, /* documentation */ undefined, { kindModifiers: "optional" }); +verify.completionListContains("method", /* text */ undefined, /* documentation */ undefined, { kindModifiers: "optional" }); diff --git a/tests/cases/fourslash/completionsOptionalMethod.ts b/tests/cases/fourslash/completionsOptionalMethod.ts new file mode 100644 index 00000000000..72399f177f2 --- /dev/null +++ b/tests/cases/fourslash/completionsOptionalMethod.ts @@ -0,0 +1,8 @@ +/// + +// @strictNullChecks: true + +////declare const x: { m?(): void }; +////x./**/ + +verify.completionsAt("", ["m"]); diff --git a/tests/cases/fourslash/completionsPaths.ts b/tests/cases/fourslash/completionsPaths.ts index 9473ae54b25..6bb2fb38706 100644 --- a/tests/cases/fourslash/completionsPaths.ts +++ b/tests/cases/fourslash/completionsPaths.ts @@ -12,10 +12,19 @@ ////not read // @Filename: /src/a.ts -////import {} from "/*1*/"; +////import {} from "[|/*1*/|]"; // @Filename: /src/folder/b.ts -////import {} from "x//*2*/"; +////import {} from "x/[|/*2*/|]"; -verify.completionsAt("1", ["y", "x"]); -verify.completionsAt("2", ["bar", "foo"]); +// @Filename: /src/folder/c.ts +////const foo = require("x/[|/*3*/|]"); + +// @Filename: /src/folder/4.ts +////const foo = require(`x/[|/*4*/|]`); + +const [r0, r1, r2, r3] = test.ranges(); +verify.completionsAt("1", [{ name: "y", replacementSpan: r0 }, { name: "x", replacementSpan: r0 }]); +verify.completionsAt("2", [{ name: "bar", replacementSpan: r1 }, { name: "foo", replacementSpan: r1 }]); +verify.completionsAt("3", [{ name: "bar", replacementSpan: r2 }, { name: "foo", replacementSpan: r2 }]); +verify.completionsAt("4", [{ name: "bar", replacementSpan: r3 }, { name: "foo", replacementSpan: r3 }]); diff --git a/tests/cases/fourslash/completionsPaths_pathMapping.ts b/tests/cases/fourslash/completionsPaths_pathMapping.ts new file mode 100644 index 00000000000..7a6283bce3a --- /dev/null +++ b/tests/cases/fourslash/completionsPaths_pathMapping.ts @@ -0,0 +1,27 @@ +/// + +// @Filename: /src/b.ts +////export const x = 0; + +// @Filename: /src/dir/x.ts +/////export const x = 0; + +// @Filename: /src/a.ts +////import {} from "foo/[|/**/|]"; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": ".", +//// "paths": { +//// "foo/*": ["src/*"] +//// } +//// } +////} + +const [replacementSpan] = test.ranges(); +verify.completionsAt("", [ + { name: "a", replacementSpan }, + { name: "b", replacementSpan }, + { name: "dir", replacementSpan }, +]); diff --git a/tests/cases/fourslash/completionsPaths_pathMapping_parentDirectory.ts b/tests/cases/fourslash/completionsPaths_pathMapping_parentDirectory.ts new file mode 100644 index 00000000000..7dcd6e3adb1 --- /dev/null +++ b/tests/cases/fourslash/completionsPaths_pathMapping_parentDirectory.ts @@ -0,0 +1,20 @@ +/// + +// @Filename: /src/a.ts +////import { } from "foo/[|/**/|]"; + +// @Filename: /oof/x.ts +////export const x = 0; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": "src", +//// "paths": { +//// "foo/*": ["../oof/*"] +//// } +//// } +////} + +const [replacementSpan] = test.ranges(); +verify.completionsAt("", [{ name: "x", replacementSpan }]); diff --git a/tests/cases/fourslash/completionsRecommended_equals.ts b/tests/cases/fourslash/completionsRecommended_equals.ts index 21b17677ccc..37e4c931359 100644 --- a/tests/cases/fourslash/completionsRecommended_equals.ts +++ b/tests/cases/fourslash/completionsRecommended_equals.ts @@ -1,8 +1,10 @@ /// -////enum E {} -////declare const e: E; -////e === /**/ +////enum Enu {} +////declare const e: Enu; +////e === /*a*/; +////e === E/*b*/ -goTo.marker(); -verify.completionListContains("E", "enum E", "", "enum", undefined, undefined, { isRecommended: true }); +goTo.eachMarker(["a", "b"], () => { + verify.completionListContains("Enu", "enum Enu", "", "enum", undefined, undefined, { isRecommended: true }); +}); diff --git a/tests/cases/fourslash/completionsRecommended_import.ts b/tests/cases/fourslash/completionsRecommended_import.ts index dc8066d246e..158221f03a8 100644 --- a/tests/cases/fourslash/completionsRecommended_import.ts +++ b/tests/cases/fourslash/completionsRecommended_import.ts @@ -3,25 +3,36 @@ // @noLib: true // @Filename: /a.ts -////export class C {} -////export function f(c: C) {} +////export class Cls {} +////export function f(c: Cls) {} // @Filename: /b.ts ////import { f } from "./a"; -// Here we will recommend a new import of 'C' -////f(new /*b*/); +// Here we will recommend a new import of 'Cls' +////f(new C/*b0*/); +////f(new /*b1*/); // @Filename: /c.ts -////import * as a from "./a"; -// Here we will recommend 'a' because it contains 'C'. -////a.f(new /*c*/); +////import * as alpha from "./a"; +// Here we will recommend 'alpha' because it contains 'Cls'. +////alpha.f(new al/*c0*/); +////alpha.f(new /*c1*/); -goTo.marker("b"); -verify.completionListContains({ name: "C", source: "/a" }, "class C", "", "class", undefined, /*hasAction*/ true, { - includeExternalModuleExports: true, - isRecommended: true, - sourceDisplay: "./a", +goTo.eachMarker(["b0", "b1"], (_, idx) => { + verify.completionListContains( + { name: "Cls", source: "/a" }, + idx === 0 ? "constructor Cls(): Cls" : "class Cls", + "", + "class", + undefined, + /*hasAction*/ true, { + includeExternalModuleExports: true, + isRecommended: true, + sourceDisplay: "./a", + }); +}); + +goTo.eachMarker(["c0", "c1"], (_, idx) => { + verify.completionListContains("alpha", "import alpha", "", "alias", undefined, undefined, { isRecommended: true }) }); -goTo.marker("c"); -verify.completionListContains("a", "import a", "", "alias", undefined, undefined, { isRecommended: true }); diff --git a/tests/cases/fourslash/completionsRecommended_local.ts b/tests/cases/fourslash/completionsRecommended_local.ts index fad660761fa..768db8c0c91 100644 --- a/tests/cases/fourslash/completionsRecommended_local.ts +++ b/tests/cases/fourslash/completionsRecommended_local.ts @@ -1,18 +1,37 @@ /// -////enum E {} -////class C {} -////abstract class A {} -////const e: E = /*e*/ -////const c: C = new /*c*/ -////const a: A = new /*a*/ +////enum Enu {} +////class Cls {} +////abstract class Abs {} +////const e: Enu = E/*e0*/; +////const e: Enu = /*e1*/; +////const c: Cls = new C/*c0*/; +////const c: Cls = new /*c1*/; +////const a: Abs = new A/*a0*/; +////const a: Abs = new /*a1*/; -goTo.marker("e"); -verify.completionListContains("E", "enum E", "", "enum", undefined, undefined, { isRecommended: true }); +// Also works on mutations +////let enu: Enu; +////enu = E/*let0*/; +////enu = E/*let1*/; -goTo.marker("c"); -verify.completionListContains("C", "class C", "", "class", undefined, undefined, { isRecommended: true }); +goTo.eachMarker(["e0"], () => {//, "e1", "let0", "let1" + verify.completionListContains("Enu", "enum Enu", "", "enum", undefined, undefined, { isRecommended: true }); +}); -goTo.marker("a"); -// Not recommended, because it's an abstract class -verify.completionListContains("A", "class A", "", "class"); +goTo.eachMarker(["c0", "c1"], (_, idx) => { + verify.completionListContains( + "Cls", + idx === 0 ? "constructor Cls(): Cls" : "class Cls", + "", + "class", + undefined, + undefined, { + isRecommended: true, + }); +}); + +goTo.eachMarker(["a0", "a1"], (_, idx) => { + // Not recommended, because it's an abstract class + verify.completionListContains("Abs", idx == 0 ? "constructor Abs(): Abs" : "class Abs", "", "class"); +}); diff --git a/tests/cases/fourslash/completionsRecommended_namespace.ts b/tests/cases/fourslash/completionsRecommended_namespace.ts index 3ea8d597210..d3fe9c2a54b 100644 --- a/tests/cases/fourslash/completionsRecommended_namespace.ts +++ b/tests/cases/fourslash/completionsRecommended_namespace.ts @@ -3,31 +3,37 @@ // @noLib: true // @Filename: /a.ts -////export namespace N { +////export namespace Name { //// export class C {} ////} -////export function f(c: N.C) {} -////f(new /*a*/); +////export function f(c: Name.C) {} +////f(new N/*a0*/); +////f(new /*a1*/); // @Filename: /b.ts ////import { f } from "./a"; -// Here we will recommend a new import of 'N' -////f(new /*b*/); +// Here we will recommend a new import of 'Name' +////f(new N/*b0*/); +////f(new /*b1*/); // @Filename: /c.ts -////import * as a from "./a"; -// Here we will recommend 'a' because it contains 'N' which contains 'C'. -////a.f(new /*c*/); +////import * as alpha from "./a"; +// Here we will recommend 'a' because it contains 'Name' which contains 'C'. +////alpha.f(new a/*c0*/); +////alpha.f(new /*c1*/); -goTo.marker("a"); -verify.completionListContains("N", "namespace N", "", "module", undefined, undefined, { isRecommended: true }); - -goTo.marker("b"); -verify.completionListContains({ name: "N", source: "/a" }, "namespace N", "", "module", undefined, /*hasAction*/ true, { - includeExternalModuleExports: true, - isRecommended: true, - sourceDisplay: "./a", +goTo.eachMarker(["a0", "a1"], () => { + verify.completionListContains("Name", "namespace Name", "", "module", undefined, undefined, { isRecommended: true }); }); -goTo.marker("c"); -verify.completionListContains("a", "import a", "", "alias", undefined, undefined, { isRecommended: true }); +goTo.eachMarker(["b0", "b1"], () => { + verify.completionListContains({ name: "Name", source: "/a" }, "namespace Name", "", "module", undefined, /*hasAction*/ true, { + includeExternalModuleExports: true, + isRecommended: true, + sourceDisplay: "./a", + }); +}); + +goTo.eachMarker(["c0", "c1"], () => { + verify.completionListContains("alpha", "import alpha", "", "alias", undefined, undefined, { isRecommended: true }); +}); diff --git a/tests/cases/fourslash/completionsRecommended_switch.ts b/tests/cases/fourslash/completionsRecommended_switch.ts index b73d0be632b..a8941ac53ea 100644 --- a/tests/cases/fourslash/completionsRecommended_switch.ts +++ b/tests/cases/fourslash/completionsRecommended_switch.ts @@ -1,10 +1,12 @@ /// -////enum E {} -////declare const e: E; +////enum Enu {} +////declare const e: Enu; ////switch (e) { -//// case /**/ +//// case E/*0*/: +//// case /*1*/: ////} -goTo.marker(); -verify.completionListContains("E", "enum E", "", "enum", undefined, undefined, { isRecommended: true }); +goTo.eachMarker((_, idx) => { + verify.completionListContains("Enu", "enum Enu", "", "enum", undefined, undefined, { isRecommended: true }); +}); diff --git a/tests/cases/fourslash/duplicatePackageServices.ts b/tests/cases/fourslash/duplicatePackageServices.ts index c84c43cdd9e..48dfdf8aa83 100644 --- a/tests/cases/fourslash/duplicatePackageServices.ts +++ b/tests/cases/fourslash/duplicatePackageServices.ts @@ -36,9 +36,9 @@ verify.goToDefinition("useAX", "defAX"); verify.goToDefinition("useBX", "defAX"); const [r0, r1, r2, r3, r4, r5] = test.ranges(); -const aImport = { definition: "import X", ranges: [r0, r1] }; +const aImport = { definition: "(alias) class X\nimport X", ranges: [r0, r1] }; const def = { definition: "class X", ranges: [r2] }; -const bImport = { definition: "import X", ranges: [r3, r4] }; +const bImport = { definition: "(alias) class X\nimport X", ranges: [r3, r4] }; verify.referenceGroups([r0, r1], [aImport, def, bImport]); verify.referenceGroups([r2], [def, aImport, bImport]); verify.referenceGroups([r3, r4], [bImport, def, aImport]); diff --git a/tests/cases/fourslash/editClearsJsDocCache.ts b/tests/cases/fourslash/editClearsJsDocCache.ts new file mode 100644 index 00000000000..0ffc351300f --- /dev/null +++ b/tests/cases/fourslash/editClearsJsDocCache.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////** @type {/*type*/number} */ +////let /*x*/x; + +verify.quickInfoAt("x", "let x: number"); + +goTo.marker("type"); +edit.replace(test.markers()[0].position, "number".length, "string"); + +verify.quickInfoAt("x", "let x: string"); diff --git a/tests/cases/fourslash/exportEqualTypes.ts b/tests/cases/fourslash/exportEqualTypes.ts index f130d211031..cb1e2ec90a1 100644 --- a/tests/cases/fourslash/exportEqualTypes.ts +++ b/tests/cases/fourslash/exportEqualTypes.ts @@ -15,7 +15,7 @@ ////var /*3*/r2 = t./*4*/foo; // t should have 'foo' in dropdown list and be of type 'string' verify.quickInfos({ - 1: "import test = require('./exportEqualTypes_file0')", + 1: "(alias) interface test\nimport test = require('./exportEqualTypes_file0')", 2: "var r1: Date", 3: "var r2: string" }); diff --git a/tests/cases/fourslash/externalModuleWithExportAssignment.ts b/tests/cases/fourslash/externalModuleWithExportAssignment.ts index 5b392623690..e35a89f1d7e 100644 --- a/tests/cases/fourslash/externalModuleWithExportAssignment.ts +++ b/tests/cases/fourslash/externalModuleWithExportAssignment.ts @@ -29,8 +29,22 @@ ////var v1: a1./*15*/connectExport; goTo.file("externalModuleWithExportAssignment_file1.ts"); -verify.quickInfoAt("1", 'import a1 = require("./externalModuleWithExportAssignment_file0")'); -verify.quickInfoAt("2", "var a: {\n (): a1.connectExport;\n test1: a1.connectModule;\n test2(): a1.connectModule;\n}", undefined); +verify.quickInfoAt("1", [ + "(alias) namespace a1", + "(alias) var a1: {", + " (): connectExport;", + " test1: connectModule;", + " test2(): connectModule;", + "}", + 'import a1 = require("./externalModuleWithExportAssignment_file0")' +].join("\n")); +verify.quickInfoAt("2", [ + "var a: {", + " (): a1.connectExport;", + " test1: a1.connectModule;", + " test2(): a1.connectModule;", + "}" +].join("\n"), undefined); goTo.marker('3'); verify.quickInfoIs("(property) test1: a1.connectModule\n(res: any, req: any, next: any) => void", undefined); diff --git a/tests/cases/fourslash/extractMethod_forAwait.ts b/tests/cases/fourslash/extractMethod_forAwait.ts new file mode 100644 index 00000000000..238c5875a0d --- /dev/null +++ b/tests/cases/fourslash/extractMethod_forAwait.ts @@ -0,0 +1,25 @@ +/// + +////async function f(xs: AsyncIterable) { +//// /*a*/for await (const x of xs) { +//// x * 2; +//// }/*b*/ +////} + +goTo.select('a', 'b') +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in global scope", + newContent: +`async function f(xs: AsyncIterable) { + /*RENAME*/newFunction(xs); +} + +function newFunction(xs: any) { + for await (const x of xs) { + x * 2; + } +} +` +}); diff --git a/tests/cases/fourslash/findAllReferencesOfConstructor.ts b/tests/cases/fourslash/findAllReferencesOfConstructor.ts index 37f0264c816..d177907b974 100644 --- a/tests/cases/fourslash/findAllReferencesOfConstructor.ts +++ b/tests/cases/fourslash/findAllReferencesOfConstructor.ts @@ -48,7 +48,7 @@ verify.referenceGroups(a1, defs("constructor C(): C (+1 overload)")); function defs(definition: string) { return [ { definition, ranges: [a0, a1, a2, a3, d0, d1, a4] }, - { definition: "import C", ranges: [b0] }, - { definition: "import C", ranges: [c0] } + { definition: "(alias) class C\nimport C", ranges: [b0] }, + { definition: "(alias) class C\nimport C", ranges: [c0] } ] } diff --git a/tests/cases/fourslash/findAllRefsClassExpression2.ts b/tests/cases/fourslash/findAllRefsClassExpression2.ts index ce2fc8bbf3d..b9d2267c516 100644 --- a/tests/cases/fourslash/findAllRefsClassExpression2.ts +++ b/tests/cases/fourslash/findAllRefsClassExpression2.ts @@ -11,6 +11,6 @@ const [r0, r1, r2] = test.ranges(); const defs = { definition: "(property) A: typeof (Anonymous class)", ranges: [r0] }; -const imports = { definition: "import A", ranges: [r1, r2] }; +const imports = { definition: "(alias) (property) A: typeof (Anonymous class)\nimport A", ranges: [r1, r2] }; verify.referenceGroups([r0], [defs, imports]); verify.referenceGroups([r1, r2], [imports, defs]); diff --git a/tests/cases/fourslash/findAllRefsExportAsNamespace.ts b/tests/cases/fourslash/findAllRefsExportAsNamespace.ts index e6b29fce47f..f6149f17d90 100644 --- a/tests/cases/fourslash/findAllRefsExportAsNamespace.ts +++ b/tests/cases/fourslash/findAllRefsExportAsNamespace.ts @@ -18,7 +18,7 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; const globals = { definition: "function f(): void", ranges: [r0, r2] }; -const imports = { definition: "import f", ranges: [r1] }; +const imports = { definition: "(alias) function f(): void\nimport f", ranges: [r1] }; verify.referenceGroups([r0, r2], [globals, imports]); verify.referenceGroups(r1, [imports, globals]); diff --git a/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts b/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts index a5e9bd1cd7d..6be7ea0bdba 100644 --- a/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts +++ b/tests/cases/fourslash/findAllRefsExportConstEqualToClass.ts @@ -12,6 +12,6 @@ const [C0, D0, C1, D1] = test.ranges(); verify.singleReferenceGroup("class C", [C0, C1]); const d0Group = { definition: "const D: typeof C", ranges: [D0] }; -const d1Group = { definition: "import D", ranges: [D1] }; +const d1Group = { definition: "(alias) const D: typeof C\nimport D", ranges: [D1] }; verify.referenceGroups(D0, [d0Group, d1Group]); verify.referenceGroups(D1, [d1Group, d0Group]); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport.ts index 414b2503391..1fe48cd78ae 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport.ts @@ -14,9 +14,9 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; verify.referenceGroups(r0, [ { definition: "function f(): void", ranges: [r0] }, - { definition: "import g", ranges: [r1, r2] } + { definition: "(alias) function g(): void\nimport g", ranges: [r1, r2] } ]); -verify.referenceGroups(r1, [{ definition: "import g", ranges: [r1, r2] }]); +verify.referenceGroups(r1, [{ definition: "(alias) function g(): void\nimport g", ranges: [r1, r2] }]); verify.referenceGroups(r2, [{ definition: "(alias) g(): void\nimport g", ranges: [r1, r2] }]); verify.goToDefinition("ref", "def"); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport04.ts b/tests/cases/fourslash/findAllRefsForDefaultExport04.ts index 093910d1cb5..279f2bd1e81 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport04.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport04.ts @@ -11,13 +11,13 @@ const [r0, r1, r2, r3, r4] = test.ranges(); verify.referenceGroups([r0, r2], [ { definition: "const a: 0", ranges: [r0, r2] }, - { definition: "import a", ranges: [r3, r4] } + { definition: "(alias) const a: 0\nimport a", ranges: [r3, r4] } ]); verify.referenceGroups(r1, [ - { definition: "export default a", ranges: [r1] }, - { definition: "import a", ranges: [r3, r4] }, + { definition: "(alias) const a: 0\nexport default a", ranges: [r1] }, + { definition: "(alias) const a: 0\nimport a", ranges: [r3, r4] }, ]); verify.referenceGroups([r3, r4], [ - { definition: "import a", ranges: [r3, r4] }, - { definition: "export default a", ranges: [r1] }, + { definition: "(alias) const a: 0\nimport a", ranges: [r3, r4] }, + { definition: "(alias) const a: 0\nexport default a", ranges: [r1] }, ]); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts index 4c2427639f8..2154087d81a 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts @@ -13,16 +13,16 @@ const [r0, r1, r2, r3] = test.ranges(); verify.referenceGroups([r0, r1], [ { definition: "const foo: 1", ranges: [r0, r1] }, - { definition: "import default", ranges: [r2], }, - { definition: "import fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2], }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, ]); verify.referenceGroups(r2, [ - { definition: "import default", ranges: [r2] }, - { definition: "import fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); verify.referenceGroups(r3, [ - { definition: "import fooDefault", ranges: [r3] }, - { definition: "import default", ranges: [r2] }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.ts b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.ts index 26a05f2e12e..41377a41aca 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.ts @@ -17,16 +17,16 @@ verify.noErrors(); const [r0, r1, r2, r3] = test.ranges(); verify.referenceGroups([r0, r1], [ { definition: "const foo: 1", ranges: [r0, r1] }, - { definition: "import default", ranges: [r2], }, - { definition: "import fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2], }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, ]); verify.referenceGroups(r2, [ - { definition: "import default", ranges: [r2] }, - { definition: "import fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); verify.referenceGroups(r3, [ - { definition: "import fooDefault", ranges: [r3] }, - { definition: "import default", ranges: [r2] }, + { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, + { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); diff --git a/tests/cases/fourslash/findAllRefsForModule.ts b/tests/cases/fourslash/findAllRefsForModule.ts index ae6b216463f..bff3aa17785 100644 --- a/tests/cases/fourslash/findAllRefsForModule.ts +++ b/tests/cases/fourslash/findAllRefsForModule.ts @@ -12,12 +12,12 @@ ////const a = require("[|../a|]"); // @Filename: /d.ts -//// /// +//// /// verify.noErrors(); const ranges = test.ranges(); const [r0, r1, r2] = ranges; -verify.referenceGroups([r0, r1], [{ definition: 'module "/a"', ranges: [r0, r2, r1] }]); -// TODO:GH#15736 -verify.referenceGroups(r2, undefined); +verify.referenceGroups(ranges, [{ definition: 'module "/a"', ranges: [r0, r2, r1] }]); +// Testing that it works with documentHighlights too +verify.rangesAreDocumentHighlights(); diff --git a/tests/cases/fourslash/findAllRefsForModuleGlobal.ts b/tests/cases/fourslash/findAllRefsForModuleGlobal.ts index 4c1b39cdb0f..ce3c36c7966 100644 --- a/tests/cases/fourslash/findAllRefsForModuleGlobal.ts +++ b/tests/cases/fourslash/findAllRefsForModuleGlobal.ts @@ -12,6 +12,4 @@ verify.noErrors(); const ranges = test.ranges(); const [r0, r1, r2] = ranges; -verify.referenceGroups([r1, r2], [{ definition: 'module "/node_modules/foo/index"', ranges: [r0, r1, r2] }]); -// TODO:GH#15736 -verify.referenceGroups(r0, undefined); +verify.singleReferenceGroup('module "/node_modules/foo/index"'); diff --git a/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts b/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts index 125a11f19c4..2d9d9e267c5 100644 --- a/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts +++ b/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts @@ -8,10 +8,4 @@ //// ////let {[|property|]: pVar} = x; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) property: {}", ranges }]); -verify.referenceGroups([r1, r2], [ - { definition: "(property) property: {}", ranges: [r0] }, - { definition: "(property) property: {}", ranges: [r1, r2] } -]); +verify.singleReferenceGroup("(property) property: {}"); diff --git a/tests/cases/fourslash/findAllRefsForObjectSpread.ts b/tests/cases/fourslash/findAllRefsForObjectSpread.ts index c9c70edffd2..970806922ed 100644 --- a/tests/cases/fourslash/findAllRefsForObjectSpread.ts +++ b/tests/cases/fourslash/findAllRefsForObjectSpread.ts @@ -16,9 +16,8 @@ verify.referenceGroups(r1, [{ definition: "(property) A2.a: number", ranges: [r1 // but the resulting property refers to everything verify.referenceGroups(r2, [ - { definition: "(property) A1.a: string", ranges: [r0, r3] }, + { definition: "(property) A1.a: string", ranges: [r0, r2, r3] }, { definition: "(property) A2.a: number", ranges: [r1] }, - { definition: "(property) a: string | number", ranges: [r2] } ]); verify.referenceGroups(r3, [{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] }]); diff --git a/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts b/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts index c57f4a67fda..033532a18ad 100644 --- a/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts +++ b/tests/cases/fourslash/findAllRefsImportStarOfExportEquals.ts @@ -1,5 +1,6 @@ /// +// @allowSyntheticDefaultimports: true // @Filename: /node_modules/a/index.d.ts ////declare function [|{| "isWriteAccess": true, "isDefinition": true |}a|](): void; ////declare namespace [|{| "isWriteAccess": true, "isDefinition": true |}a|] { @@ -9,13 +10,13 @@ // Import with different name and we find local refs // @Filename: /b.ts -////import * as [|{| "isWriteAccess": true, "isDefinition": true |}b|] from "a"; +////import [|{| "isWriteAccess": true, "isDefinition": true |}b|] from "a"; ////[|b|](); ////[|b|].x; // Import with same name and we find all refs // @Filename: /c.ts -////import * as [|{| "isWriteAccess": true, "isDefinition": true |}a|] from "a"; +////import [|{| "isWriteAccess": true, "isDefinition": true |}a|] from "a"; ////[|a|](); ////[|a|].x; @@ -28,31 +29,31 @@ const cRanges = [c0, c1, c2]; verify.referenceGroups(a0, [ { definition: "function a(): void\nnamespace a", ranges: aRanges }, - { definition: "import b", ranges: bRanges }, - { definition: "import a", ranges: cRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges }, + { definition: "(alias) function a(): void\n(alias) namespace a\nimport a", ranges: cRanges } ]); verify.referenceGroups([a1, a2], [ { definition: "namespace a\nfunction a(): void", ranges: aRanges }, - { definition: "import b", ranges: bRanges }, - { definition: "import a", ranges: cRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges }, + { definition: "(alias) function a(): void\n(alias) namespace a\nimport a", ranges: cRanges } ]); verify.referenceGroups([b0, b0], [ - { definition: "import b", ranges: bRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges } ]); verify.referenceGroups(b1, [ { definition: "(alias) b(): void\nimport b", ranges: bRanges } ]); verify.referenceGroups([c0, c2], [ - { definition: "import a", ranges: cRanges }, + { definition: "(alias) function a(): void\n(alias) namespace a\nimport a", ranges: cRanges }, { definition: "namespace a\nfunction a(): void", ranges: aRanges }, - { definition: "import b", ranges: bRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges } ]); verify.referenceGroups(c1, [ { definition: "(alias) a(): void\nimport a", ranges: cRanges }, { definition: "namespace a\nfunction a(): void", ranges: aRanges }, - { definition: "import b", ranges: bRanges } + { definition: "(alias) function b(): void\n(alias) namespace b\nimport b", ranges: bRanges } ]); verify.renameLocations(aRanges, aRanges.concat(cRanges)); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts index 41acc117f9e..3b14e686cc6 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts @@ -10,9 +10,5 @@ //// v.[|propName|]; const [r0, r1, r2, r3] = test.ranges(); -verify.referenceGroups(r0, [{ definition: "(method) class1.doStuff(): void", ranges: [r0, r2] }]); -verify.referenceGroups(r2, [ - { definition: "(method) class1.doStuff(): void", ranges: [r0] }, - { definition: "(method) class1.doStuff(): void", ranges: [r2] } -]); +verify.singleReferenceGroup("(method) class1.doStuff(): void", [r0, r2]); verify.singleReferenceGroup("(property) class1.propName: string", [r1, r3]); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts index cc82e4a4e44..a88943a7f54 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts @@ -22,7 +22,7 @@ verify.referenceGroups(r0, [{ definition: "(method) class1.doStuff(): void", ran verify.referenceGroups(r1, [{ definition: "(property) class1.propName: string", ranges: [r1, r5, r7] }]); verify.referenceGroups(r2, [{ definition: "(method) interface1.doStuff(): void", ranges: [r2, r4, r6] }]); verify.referenceGroups(r3, [{ definition: "(property) interface1.propName: string", ranges: [r3, r5, r7] }]); -verify.referenceGroups(r4, [ +verify.referenceGroups([r4, r6], [ { definition: "(method) class1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface1.doStuff(): void", ranges: [r2] }, { definition: "(method) class2.doStuff(): void", ranges: [r4, r6] } @@ -32,9 +32,3 @@ verify.referenceGroups([r5, r7], [ { definition: "(property) interface1.propName: string", ranges: [r3] }, { definition: "(property) class2.propName: string", ranges: [r5, r7] } ]); -verify.referenceGroups(r6, [ - { definition: "(method) class1.doStuff(): void", ranges: [r0] }, - { definition: "(method) interface1.doStuff(): void", ranges: [r2] }, - { definition: "(method) class2.doStuff(): void", ranges: [r4] }, - { definition: "(method) class2.doStuff(): void", ranges: [r6] } -]); diff --git a/tests/cases/fourslash/findAllRefsMappedType.ts b/tests/cases/fourslash/findAllRefsMappedType.ts index 7daf0296d94..97658da08c1 100644 --- a/tests/cases/fourslash/findAllRefsMappedType.ts +++ b/tests/cases/fourslash/findAllRefsMappedType.ts @@ -7,9 +7,4 @@ ////declare const u: U; ////u.[|a|]; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups([r0, r1], [{ definition: "(property) T.a: number", ranges }]); -verify.referenceGroups(r2, [ - { definition: "(property) T.a: number", ranges: [r0, r1] }, - { definition: "(property) a: string", ranges: [r2] }]); +verify.singleReferenceGroup("(property) T.a: number"); diff --git a/tests/cases/fourslash/findAllRefsOnDefinition.ts b/tests/cases/fourslash/findAllRefsOnDefinition.ts index 7d136efc42a..99b402aba8c 100644 --- a/tests/cases/fourslash/findAllRefsOnDefinition.ts +++ b/tests/cases/fourslash/findAllRefsOnDefinition.ts @@ -26,7 +26,4 @@ const ranges = test.ranges(); const [r0, r1] = ranges; verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] }, - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] }, -]); +verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]); diff --git a/tests/cases/fourslash/findAllRefsOnImportAliases.ts b/tests/cases/fourslash/findAllRefsOnImportAliases.ts index 98509ad6938..cb5dc082157 100644 --- a/tests/cases/fourslash/findAllRefsOnImportAliases.ts +++ b/tests/cases/fourslash/findAllRefsOnImportAliases.ts @@ -15,8 +15,8 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; const classes = { definition: "class Class", ranges: [r0] }; -const imports = { definition: "import Class", ranges: [r1, r2] }; -const reExports = { definition: "import Class", ranges: [r3] }; +const imports = { definition: "(alias) class Class\nimport Class", ranges: [r1, r2] }; +const reExports = { definition: "(alias) class Class\nimport Class", ranges: [r3] }; verify.referenceGroups(r0, [classes, imports, reExports]); verify.referenceGroups(r1, [imports, classes, reExports]); verify.referenceGroups(r2, [ diff --git a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts index 64f44018d07..74b099ea767 100644 --- a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts +++ b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts @@ -17,8 +17,8 @@ const c2Ranges = ranges.get("C2"); const [c2_0, c2_1] = c2Ranges; const c3Ranges = ranges.get("C3"); const classes = { definition: "class Class", ranges: classRanges }; -const c2s = { definition: "import C2", ranges: c2Ranges }; -const c3s = { definition: "import C3", ranges: c3Ranges }; +const c2s = { definition: "(alias) class C2\nimport C2", ranges: c2Ranges }; +const c3s = { definition: "(alias) class C3\nimport C3", ranges: c3Ranges }; verify.referenceGroups(classRanges, [classes, c2s, c3s]); diff --git a/tests/cases/fourslash/findAllRefsReExportLocal.ts b/tests/cases/fourslash/findAllRefsReExportLocal.ts index 3e5890e6317..f57cc8480f0 100644 --- a/tests/cases/fourslash/findAllRefsReExportLocal.ts +++ b/tests/cases/fourslash/findAllRefsReExportLocal.ts @@ -18,9 +18,9 @@ const axRanges = [ax0, ax1, ax2]; const bxRanges = [bx0, bx1]; const byRanges = [by0, by1]; const axGroup = { definition: "var x: any", ranges: axRanges }; -const bxGroup = { definition: "import x", ranges: bxRanges }; -const ayGroup = { definition: "import y", ranges: [ay] } -const byGroup = { definition: "import y", ranges: byRanges } +const bxGroup = { definition: "(alias) var x: any\nimport x", ranges: bxRanges }; +const ayGroup = { definition: "(alias) var y: any\nimport y", ranges: [ay] } +const byGroup = { definition: "(alias) var y: any\nimport y", ranges: byRanges } verify.referenceGroups(axRanges, [axGroup, bxGroup, ayGroup, byGroup]); verify.referenceGroups(bxRanges, [bxGroup, axGroup, ayGroup, byGroup]); diff --git a/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts b/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts index c9d42e53d4e..12305381fe8 100644 --- a/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts +++ b/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts @@ -19,13 +19,13 @@ const [a, b, cFromB, cFromA, cUse, d] = test.ranges(); const cFromARanges = [cFromA, cUse]; const aGroup = { definition: "const x: 0", ranges: [a] }; -const cFromAGroup = { definition: "import x", ranges: cFromARanges }; +const cFromAGroup = { definition: "(alias) const x: 0\nimport x", ranges: cFromARanges }; verify.referenceGroups(a, [aGroup, cFromAGroup]); const bGroup = { definition: "const x: 0", ranges: [b] }; -const cFromBGroup = { definition: "import x", ranges: [cFromB] }; -const dGroup = { definition: "import x", ranges: [d] }; +const cFromBGroup = { definition: "(alias) const x: 0\nimport x", ranges: [cFromB] }; +const dGroup = { definition: "(alias) const x: 0\nimport x", ranges: [d] }; verify.referenceGroups(b, [bGroup, cFromBGroup, dGroup]); verify.referenceGroups(cFromB, [cFromBGroup, dGroup, bGroup]); diff --git a/tests/cases/fourslash/findAllRefsReExportStar.ts b/tests/cases/fourslash/findAllRefsReExportStar.ts index 86901cfadf2..a82f91cc5b0 100644 --- a/tests/cases/fourslash/findAllRefsReExportStar.ts +++ b/tests/cases/fourslash/findAllRefsReExportStar.ts @@ -13,6 +13,6 @@ verify.noErrors(); const ranges = test.ranges(); const [r0, r1] = ranges; const a = { definition: "function foo(): void", ranges: [r0] }; -const c = { definition: "import foo", ranges: [r1] }; +const c = { definition: "(alias) function foo(): void\nimport foo", ranges: [r1] }; verify.referenceGroups(r0, [a, c]); verify.referenceGroups(r1, [c, a]); diff --git a/tests/cases/fourslash/findAllRefsReExports.ts b/tests/cases/fourslash/findAllRefsReExports.ts index e9936867604..9c0e3b26bfc 100644 --- a/tests/cases/fourslash/findAllRefsReExports.ts +++ b/tests/cases/fourslash/findAllRefsReExports.ts @@ -22,13 +22,13 @@ verify.noErrors(); const [foo0, foo1, bar0, foo2, defaultC, defaultD, bar1, baz0, defaultE, bang0, boom0, bar2, baz1, bang1, boom1] = test.ranges(); const a = { definition: "function foo(): void", ranges: [foo0, foo1, foo2] }; -const b = { definition: "import bar", ranges: [bar0] }; -const c = { definition: "import default", ranges: [defaultC, defaultE] }; -const d = { definition: "import default", ranges: [defaultD] }; -const eBar = { definition: "import bar", ranges: [bar1, bar2] }; -const eBaz = { definition: "import baz", ranges: [baz0, baz1] }; -const eBang = { definition: "import bang", ranges: [bang0, bang1] }; -const eBoom = { definition: "import boom", ranges: [boom0, boom1] }; +const b = { definition: "(alias) function bar(): void\nimport bar", ranges: [bar0] }; +const c = { definition: "(alias) function foo(): void\nimport default", ranges: [defaultC, defaultE] }; +const d = { definition: "(alias) function foo(): void\nimport default", ranges: [defaultD] }; +const eBar = { definition: "(alias) function bar(): void\nimport bar", ranges: [bar1, bar2] }; +const eBaz = { definition: "(alias) function baz(): void\nimport baz", ranges: [baz0, baz1] }; +const eBang = { definition: "(alias) function bang(): void\nimport bang", ranges: [bang0, bang1] }; +const eBoom = { definition: "(alias) function boom(): void\nimport boom", ranges: [boom0, boom1] }; verify.referenceGroups([foo0, foo1, foo2], [a, b, eBar, c, d, eBoom, eBaz, eBang]); diff --git a/tests/cases/fourslash/findAllRefsReExports2.ts b/tests/cases/fourslash/findAllRefsReExports2.ts index 5dfdc8aebbf..31aa07fa29e 100644 --- a/tests/cases/fourslash/findAllRefsReExports2.ts +++ b/tests/cases/fourslash/findAllRefsReExports2.ts @@ -10,5 +10,5 @@ verify.noErrors(); const [r0, r1, r2] = test.ranges(); verify.referenceGroups(r0, [ { definition: "function foo(): void", ranges: [r0, r1] }, - { definition: "import oof", ranges: [r2] } + { definition: "(alias) function oof(): void\nimport oof", ranges: [r2] } ]); diff --git a/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts b/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts new file mode 100644 index 00000000000..4447c5a4641 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts @@ -0,0 +1,30 @@ +/// + +// @noLib: true + +////interface A { +//// readonly [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number | string; +////} +////interface B extends A { +//// readonly [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number; +////} +////const a: A = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 }; +////const b: B = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 }; + +const [r0, r1, r2, r3] = test.ranges(); +verify.referenceGroups(r0, [ + { definition: "(property) A.x: string | number", ranges: [r0, r1, r2, r3] }, +]); +verify.referenceGroups(r1, [ + { definition: "(property) A.x: string | number", ranges: [r0, r2] }, + { definition: "(property) B.x: number", ranges: [r1, r3] }, +]); +verify.referenceGroups(r2, [ + { definition: "(property) A.x: string | number", ranges: [r0, r1, r3] }, + { definition: "(property) x: number", ranges: [r2] }, +]); +verify.referenceGroups(r3, [ + { definition: "(property) A.x: string | number", ranges: [r0, r2] }, + { definition: "(property) B.x: number", ranges: [r1] }, + { definition: "(property) x: number", ranges: [r3] }, +]); diff --git a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts index 5a5db1496a7..62b1c19c5ed 100644 --- a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts +++ b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts @@ -12,7 +12,7 @@ const [r0, r1, r2, r3] = test.ranges(); const aRanges = [r0, r1]; const bRanges = [r2, r3]; const aGroup = { definition: "const x: 0", ranges: aRanges }; -const bGroup = { definition: "import x", ranges: bRanges }; +const bGroup = { definition: "(alias) const x: 0\nimport x", ranges: bRanges }; verify.referenceGroups(aRanges, [aGroup, bGroup]); verify.referenceGroups(bRanges, [bGroup]); diff --git a/tests/cases/fourslash/findAllRefsRootSymbols.ts b/tests/cases/fourslash/findAllRefsRootSymbols.ts index f72dcb54aef..05407b6a2e3 100644 --- a/tests/cases/fourslash/findAllRefsRootSymbols.ts +++ b/tests/cases/fourslash/findAllRefsRootSymbols.ts @@ -10,8 +10,7 @@ verify.referenceGroups(r0, [{ definition: "(property) I.x: {}", ranges: [r0, r3] verify.referenceGroups(r1, [{ definition: "(property) J.x: {}", ranges: [r1, r3] }]); verify.referenceGroups(r2, [{ definition: "(property) x: string", ranges: [r2, r3] }]); verify.referenceGroups(r3, [ - { definition: "(property) I.x: {}", ranges: [r0] }, + { definition: "(property) I.x: {}", ranges: [r0, r3] }, { definition: "(property) J.x: {}", ranges: [r1] }, { definition: "(property) x: string", ranges: [r2] }, - { definition: "(property) x: string & {}", ranges: [r3] }, ]); diff --git a/tests/cases/fourslash/findAllRefsThisKeyword.ts b/tests/cases/fourslash/findAllRefsThisKeyword.ts index 6f5374f902a..61dd687fd64 100644 --- a/tests/cases/fourslash/findAllRefsThisKeyword.ts +++ b/tests/cases/fourslash/findAllRefsThisKeyword.ts @@ -32,8 +32,4 @@ verify.referenceGroups(g0, [{ definition: "(parameter) this: any", ranges: [g0, verify.referenceGroups(g1, [{ definition: "this: any", ranges: [g0, g1] }]); verify.singleReferenceGroup("this: typeof C", [x, y]); verify.singleReferenceGroup("this: this", [constructor, method]); -verify.referenceGroups(propDef, [{ definition: "(property) this: number", ranges: [propDef, propUse] }]); -verify.referenceGroups(propUse, [ - { definition: "(property) this: number", ranges: [propDef] }, - { definition: "(property) this: number", ranges: [propUse] }, -]); +verify.singleReferenceGroup("(property) this: number", [propDef, propUse]); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts index d2baf7c96b3..4a1bf374c05 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts @@ -7,10 +7,4 @@ ////var x: Foo; ////x.[|_bar|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(method) Foo._bar(): number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Foo._bar(): number", ranges: [r0] }, - { definition: "(method) Foo._bar(): number", ranges: [r1] } -]); +verify.singleReferenceGroup("(method) Foo._bar(): number"); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts index 3f5cd9ddbed..ec120254fde 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts @@ -7,10 +7,4 @@ ////var x: Foo; ////x.[|__bar|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(method) Foo.__bar(): number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Foo.__bar(): number", ranges: [r0] }, - { definition: "(method) Foo.__bar(): number", ranges: [r1] } -]); +verify.singleReferenceGroup("(method) Foo.__bar(): number"); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts index e1870065325..e6f46b128e7 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts @@ -7,10 +7,4 @@ ////var x: Foo; ////x.[|___bar|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(method) Foo.___bar(): number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Foo.___bar(): number", ranges: [r0] }, - { definition: "(method) Foo.___bar(): number", ranges: [r1] } -]); +verify.singleReferenceGroup("(method) Foo.___bar(): number"); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts index 74eef0ae989..593d61f3fbe 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts @@ -7,10 +7,4 @@ ////var x: Foo; ////x.[|____bar|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(method) Foo.____bar(): number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Foo.____bar(): number", ranges: [r0] }, - { definition: "(method) Foo.____bar(): number", ranges: [r1] } -]); +verify.singleReferenceGroup("(method) Foo.____bar(): number"); diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts index 0c6f088d06b..897bf9f562a 100644 --- a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment.ts @@ -13,7 +13,4 @@ verify.referenceGroups(r1, [ { definition: "(property) name: string", ranges: [r1, r4] } ]); verify.singleReferenceGroup("(property) name: string", [r2]); -verify.referenceGroups(r4, [ - { definition: "(property) name: string", ranges: [r1] }, - { definition: "(property) name: string", ranges: [r4] }, -]); +verify.referenceGroups(r4, [{ definition: "(property) name: string", ranges: [r1, r4] }]); diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts index d4f758696fe..0f9b95c75ed 100644 --- a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts @@ -16,7 +16,4 @@ verify.referenceGroups(r2, [ { definition: "var M.dx: any", ranges: [r1] }, { definition: "(property) dx: any", ranges: [r2, r3] } ]); -verify.referenceGroups(r3, [ - { definition: "(property) dx: any", ranges: [r2] }, - { definition: "(property) dx: any", ranges: [r3] } -]); +verify.referenceGroups(r3, [{ definition: "(property) dx: any", ranges: [r2, r3] }]); diff --git a/tests/cases/fourslash/findReferencesJSXTagName.ts b/tests/cases/fourslash/findReferencesJSXTagName.ts index 39031051f1b..8547ad8b330 100644 --- a/tests/cases/fourslash/findReferencesJSXTagName.ts +++ b/tests/cases/fourslash/findReferencesJSXTagName.ts @@ -12,7 +12,7 @@ ////

; const [r0, r1, r2] = test.ranges(); -const imports = { definition: "import SubmissionComp", ranges: [r0, r1] }; +const imports = { definition: "(alias) const SubmissionComp: (submission: any) => any\nimport SubmissionComp", ranges: [r0, r1] }; const def = { definition: "const SubmissionComp: (submission: any) => any", ranges: [r2] }; verify.referenceGroups([r0, r1], [imports, def]); verify.referenceGroups(r2, [def, imports]); diff --git a/tests/cases/fourslash/formatInsertSpaceAfterCloseBraceBeforeCloseBracket.ts b/tests/cases/fourslash/formatInsertSpaceAfterCloseBraceBeforeCloseBracket.ts new file mode 100644 index 00000000000..c7df70734b0 --- /dev/null +++ b/tests/cases/fourslash/formatInsertSpaceAfterCloseBraceBeforeCloseBracket.ts @@ -0,0 +1,7 @@ +/// + +////[{}] + +format.setOption("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", true); +format.document(); +verify.currentFileContentIs("[ {} ]"); diff --git a/tests/cases/fourslash/formattingChainingMethods.ts b/tests/cases/fourslash/formattingChainingMethods.ts new file mode 100644 index 00000000000..8e8cafb14cd --- /dev/null +++ b/tests/cases/fourslash/formattingChainingMethods.ts @@ -0,0 +1,37 @@ +/// + +//// z$ = this.store.select(this.fake()) +//// .ofType( +//// 'ACTION', +//// 'ACTION-2' +//// ) +//// .pipe( +//// filter(x => !!x), +//// switchMap(() => +//// this.store.select(this.menuSelector.getAll('x')) +//// .pipe( +//// tap(x => { +//// this.x = !x; +//// }) +//// ) +//// ) +//// ); + +format.document(); +verify.currentFileContentIs(`z$ = this.store.select(this.fake()) + .ofType( + 'ACTION', + 'ACTION-2' + ) + .pipe( + filter(x => !!x), + switchMap(() => + this.store.select(this.menuSelector.getAll('x')) + .pipe( + tap(x => { + this.x = !x; + }) + ) + ) + );` +); diff --git a/tests/cases/fourslash/formattingDecorators.ts b/tests/cases/fourslash/formattingDecorators.ts index 366b9cb7729..9ff6de3cf18 100644 --- a/tests/cases/fourslash/formattingDecorators.ts +++ b/tests/cases/fourslash/formattingDecorators.ts @@ -41,6 +41,8 @@ /////*29*/ property1; //// /////*30*/ @ decorator33 @ decorator34 @decorator35 property2; +/////*31*/function test(@decorator36@decorator37 param) {}; +/////*32*/function test2(@decorator38()@decorator39()param) {}; ////} format.document(); @@ -103,4 +105,8 @@ verify.currentLineContentIs(" @decorator32"); goTo.marker("29"); verify.currentLineContentIs(" property1;"); goTo.marker("30"); -verify.currentLineContentIs(" @decorator33 @decorator34 @decorator35 property2;"); \ No newline at end of file +verify.currentLineContentIs(" @decorator33 @decorator34 @decorator35 property2;"); +goTo.marker("31"); +verify.currentLineContentIs("function test(@decorator36 @decorator37 param) { };"); +goTo.marker("32"); +verify.currentLineContentIs("function test2(@decorator38() @decorator39() param) { };"); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingJsxElements.ts b/tests/cases/fourslash/formattingJsxElements.ts index a27bc809456..58326c5a9e9 100644 --- a/tests/cases/fourslash/formattingJsxElements.ts +++ b/tests/cases/fourslash/formattingJsxElements.ts @@ -47,6 +47,16 @@ //// ) ////} //// +////const bar = ( +//// <> +//// /*fragmentChildIndent*/

text

+//// +////); +//// +////const bar2 = <> +////

text

+//// /*fragmentClosingTagIndent*/; +//// ////(function () { //// return
,{integer}
;/*commaInJsxElement*/ ////
, {integer}
;/*commaInJsxElement2*/ +////<>,{integer};/*commaInJsxFragment*/ +////<>, {integer};/*commaInJsxFragment2*/ ////);/*closingParenInJsxElement*/ ////) ;/*closingParenInJsxElement2*/ +////<>);/*closingParenInJsxFragment*/ +////<>) ;/*closingParenInJsxFragment2*/ ////;/*jsxExpressionSpaces*/ ////;/*jsxExpressionSpaces2*/ //// {}}/*jsxExpressionSpaces3*/ @@ -111,6 +125,10 @@ verify.currentLineContentIs(' class3={'); goTo.marker("6"); verify.currentLineContentIs(' } />'); +goTo.marker("fragmentChildIndent"); +verify.currentLineContentIs("

text

"); +goTo.marker("fragmentClosingTagIndent"); +verify.currentLineContentIs(";"); goTo.marker("attrAutoformat"); verify.currentLineContentIs(' className=""'); @@ -139,10 +157,18 @@ goTo.marker("commaInJsxElement"); verify.currentLineContentIs("
,{integer}
;"); goTo.marker("commaInJsxElement2"); verify.currentLineContentIs("
, {integer}
;"); +goTo.marker("commaInJsxFragment"); +verify.currentLineContentIs("<>,{integer};"); +goTo.marker("commaInJsxFragment2"); +verify.currentLineContentIs("<>, {integer};"); goTo.marker("closingParenInJsxElement"); verify.currentLineContentIs(");"); goTo.marker("closingParenInJsxElement2"); verify.currentLineContentIs(") ;"); +goTo.marker("closingParenInJsxFragment"); +verify.currentLineContentIs("<>);"); +goTo.marker("closingParenInJsxFragment2"); +verify.currentLineContentIs("<>) ;"); goTo.marker("jsxExpressionSpaces"); verify.currentLineContentIs(";"); goTo.marker("jsxExpressionSpaces2"); diff --git a/tests/cases/fourslash/formattingOptionsChange.ts b/tests/cases/fourslash/formattingOptionsChange.ts index 0e731412ede..390ed426aa9 100644 --- a/tests/cases/fourslash/formattingOptionsChange.ts +++ b/tests/cases/fourslash/formattingOptionsChange.ts @@ -9,6 +9,7 @@ /////*insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,]; /////*insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces*/`${1}`;`${ 1 }` /////*insertSpaceAfterTypeAssertion*/const bar = Thing.getFoo(); +/////*insertSpaceBeforeTypeAnnotation*/const bar : number = 1; /////*placeOpenBraceOnNewLineForFunctions*/class foo { ////} /////*placeOpenBraceOnNewLineForControlBlocks*/if (true) { @@ -26,6 +27,7 @@ runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis", " ( 1 ) runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ];", "[1];[];[];[,];"); runTest("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", "`${ 1 }`; `${ 1 }`", "`${1}`; `${1}`"); runTest("insertSpaceAfterTypeAssertion", "const bar = Thing.getFoo();", "const bar = Thing.getFoo();"); +runTest("insertSpaceBeforeTypeAnnotation", "const bar : number = 1;", "const bar: number = 1;"); runTest("placeOpenBraceOnNewLineForFunctions", "class foo", "class foo {"); runTest("placeOpenBraceOnNewLineForControlBlocks", "if (true)", "if (true) {"); runTest("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces", "{ var t = 1 }; var { a, b } = { a: 'sw', b: 'r' }; function f({ a, b }) { }", "{var t = 1}; var {a, b} = {a: 'sw', b: 'r'}; function f({a, b}) {}"); diff --git a/tests/cases/fourslash/formattingOptionsChangeJsx.ts b/tests/cases/fourslash/formattingOptionsChangeJsx.ts index a3c7e28a1ef..363b53fe81c 100644 --- a/tests/cases/fourslash/formattingOptionsChangeJsx.ts +++ b/tests/cases/fourslash/formattingOptionsChangeJsx.ts @@ -1,14 +1,21 @@ /// //@Filename: file.tsx -/////*InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces*/; +/////*1*/; +//// +//// -runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces", ";", ";"); +runTest("1", ";", ";"); +runTest("2", " { ...this._getButtonProps() }", " {...this._getButtonProps()}"); -function runTest(propertyName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) { +function runTest(markerName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) { + const propertyName = "InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"; + // Go to the correct file - goTo.marker(propertyName); + goTo.marker(markerName); // Set the option to false first format.setOption(propertyName, false); @@ -17,7 +24,7 @@ function runTest(propertyName: string, expectedStringWhenTrue: string, expectedS format.document(); // Verify - goTo.marker(propertyName); + goTo.marker(markerName); verify.currentLineContentIs(expectedStringWhenFalse); // Set the option to true @@ -27,6 +34,6 @@ function runTest(propertyName: string, expectedStringWhenTrue: string, expectedS format.document(); // Verify - goTo.marker(propertyName); + goTo.marker(markerName); verify.currentLineContentIs(expectedStringWhenTrue); } \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index acebb9dfc05..97379957cbf 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -97,6 +97,7 @@ declare namespace FourSlashInterface { InsertSpaceAfterTypeAssertion: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; + insertSpaceBeforeTypeAnnotation: boolean; [s: string]: boolean | number | string | undefined; } interface Range { @@ -122,7 +123,8 @@ declare namespace FourSlashInterface { } class goTo { marker(name?: string | Marker): void; - eachMarker(action: () => void): void; + eachMarker(markers: ReadonlyArray, action: (marker: Marker, index: number) => void): void; + eachMarker(action: (marker: Marker, index: number) => void): void; rangeStart(range: Range): void; eachRange(action: () => void): void; bof(): void; @@ -133,6 +135,7 @@ declare namespace FourSlashInterface { file(index: number, content?: string, scriptKindName?: string): any; file(name: string, content?: string, scriptKindName?: string): any; select(startMarker: string, endMarker: string): void; + selectRange(range: Range): void; } class verifyNegatable { private negative; @@ -145,7 +148,7 @@ declare namespace FourSlashInterface { entryId: string | { name: string, source?: string }, text?: string, documentation?: string, - kind?: string, + kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: { includeExternalModuleExports?: boolean, sourceDisplay?: string, isRecommended?: true }, @@ -186,7 +189,10 @@ declare namespace FourSlashInterface { class verify extends verifyNegatable { assertHasRanges(ranges: Range[]): void; caretAtMarker(markerName?: string): void; - completionsAt(markerName: string, completions: string[], options?: { isNewIdentifierLocation?: boolean }): void; + completionsAt(markerName: string, completions: ReadonlyArray, options?: { + isNewIdentifierLocation?: boolean; + includeInsertTextCompletions?: boolean; + }): void; completionsAndDetailsAt( markerName: string, completions: { diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts index 329a72c30fd..e4c3c93d0e1 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts @@ -3,11 +3,4 @@ ////let y = o.[|foo|]; ////let z = o['[|foo|]']; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups(r0, [{ definition: '(property) ["foo"]: number', ranges }]); -verify.referenceGroups([r1, r2], [ - // TODO: these are the same thing, should be in the same group. - { definition: "(property) [\"foo\"]: number", ranges: [r0] }, - { definition: "(property) [\"foo\"]: number", ranges: [r1, r2] }, -]); +verify.singleReferenceGroup('(property) ["foo"]: number'); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts index 4268e5d180d..e31bc46eae6 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts @@ -8,6 +8,6 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; const defs = { definition: "var x: number", ranges: [r0] }; -const imports = { definition: "import x", ranges: [r1, r2] }; +const imports = { definition: "(alias) var x: number\nimport x", ranges: [r1, r2] }; verify.referenceGroups(r0, [defs, imports]); verify.referenceGroups([r1, r2], [imports, defs]); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts index b391deec9cc..33bdad09e1a 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts @@ -2,10 +2,4 @@ ////let o = { [|{| "isWriteAccess": true, "isDefinition": true |}1|]: 12 }; ////let y = o[[|1|]]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) 1: number", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(property) 1: number", ranges: [r0] }, - { definition: "(property) 1: number", ranges: [r1] } -]); +verify.singleReferenceGroup("(property) 1: number"); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts index 4b842da6f59..cf88d476fef 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts @@ -2,10 +2,4 @@ ////let o = { "[|{| "isWriteAccess": true, "isDefinition": true |}x|]": 12 }; ////let y = o.[|x|]; -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: '(property) "x": number', ranges }]); -verify.referenceGroups(r1, [ - { definition: '(property) "x": number', ranges: [r0] }, - { definition: '(property) "x": number', ranges: [r1] }, -]); +verify.singleReferenceGroup('(property) "x": number'); diff --git a/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts b/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts new file mode 100644 index 00000000000..f6c12044dd9 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixDefaultExport2.ts @@ -0,0 +1,14 @@ +/// + +// @Filename: /lib.ts +////class Base { } +////export default Base; + +// @Filename: /test.ts +////[|class Derived extends Base { }|] + +goTo.file("/test.ts"); +verify.importFixAtPosition([ +`import Base from "./lib"; + +class Derived extends Base { }`,]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts new file mode 100644 index 00000000000..c383b09862e --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /src/a.ts +////[|foo|] + +// @Filename: /src/thisHasPathMapping.ts +////export function foo() {}; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": ".", +//// "paths": { +//// "foo": ["src/thisHasPathMapping.ts"] +//// } +//// } +////} + +verify.importFixAtPosition([ +`import { foo } from "foo"; + +foo` +]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts new file mode 100644 index 00000000000..f29932eed73 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /a.ts +////[|foo|] + +// @Filename: /thisHasPathMapping.ts +////export function foo() {}; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": ".", +//// "paths": { +//// "foo": ["././thisHasPathMapping"] +//// } +//// } +////} + +verify.importFixAtPosition([ +`import { foo } from "foo"; + +foo` +]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts new file mode 100644 index 00000000000..4bd938ae0b9 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /src/a.ts +////[|foo|] + +// @Filename: /thisHasPathMapping.ts +////export function foo() {}; + +// @Filename: /tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": "src", +//// "paths": { +//// "foo": ["..\\thisHasPathMapping"] +//// } +//// } +////} + +verify.importFixAtPosition([ +`import { foo } from "foo"; + +foo` +]); diff --git a/tests/cases/fourslash/incompatibleOverride.ts b/tests/cases/fourslash/incompatibleOverride.ts index f33e7f226b6..0b3dd323015 100644 --- a/tests/cases/fourslash/incompatibleOverride.ts +++ b/tests/cases/fourslash/incompatibleOverride.ts @@ -3,8 +3,8 @@ // Squiggle for implementing a derived class with an incompatible override is too large //// class Foo { xyz: string; } -//// class /*1*/Bar/*2*/ extends Foo { xyz: number; } -//// class /*3*/Baz/*4*/ extends Foo { public xyz: number; } +//// class Bar extends Foo { /*1*/xyz/*2*/: number; } +//// class Baz extends Foo { public /*3*/xyz/*4*/: number; } //// class /*5*/Baf/*6*/ extends Foo { //// constructor(public xyz: number) { //// super(); diff --git a/tests/cases/fourslash/jsDocTags.ts b/tests/cases/fourslash/jsDocTags.ts index 368939ecbfc..14ac14e6331 100644 --- a/tests/cases/fourslash/jsDocTags.ts +++ b/tests/cases/fourslash/jsDocTags.ts @@ -67,7 +67,7 @@ verify.currentSignatureHelpTagsAre([{name: "myjsdoctag", text:"this is a comment goTo.marker("11"); verify.currentSignatureHelpTagsAre([{name: "mytag", text:"comment1 comment2"}]) goTo.marker("12"); -verify.currentSignatureHelpTagsAre([{name: "mytag", text:""}]) +verify.currentSignatureHelpTagsAre([{name: "mytag"}]) goTo.marker("13"); verify.currentSignatureHelpTagsAre([{ name: "returns", text: "a value" }]) diff --git a/tests/cases/fourslash/jsconfig.ts b/tests/cases/fourslash/jsconfig.ts new file mode 100644 index 00000000000..ce09c46b857 --- /dev/null +++ b/tests/cases/fourslash/jsconfig.ts @@ -0,0 +1,16 @@ +/// + +// @Filename: /a.js +////function f(/**/x) { +////} + +// @Filename: /jsconfig.json +////{ +//// "compilerOptions": { +//// "checkJs": true, +//// "noImplicitAny": true +//// } +////} + +goTo.file("/a.js"); +verify.errorExistsAfterMarker(""); diff --git a/tests/cases/fourslash/jsdocTypedefTagTypeExpressionCompletion.ts b/tests/cases/fourslash/jsdocTypedefTagTypeExpressionCompletion.ts index 379cc60e058..b7a2b7d8993 100644 --- a/tests/cases/fourslash/jsdocTypedefTagTypeExpressionCompletion.ts +++ b/tests/cases/fourslash/jsdocTypedefTagTypeExpressionCompletion.ts @@ -11,7 +11,7 @@ //// /** //// * @param {string} foo A value. //// * @returns {number} Another value -//// * @mytag +//// * @mytag //// */ //// method4(foo: string) { return 3; } //// } diff --git a/tests/cases/fourslash/mergedDeclarationsWithExportAssignment1.ts b/tests/cases/fourslash/mergedDeclarationsWithExportAssignment1.ts index fd9a2e34b4b..f6a159f7eee 100644 --- a/tests/cases/fourslash/mergedDeclarationsWithExportAssignment1.ts +++ b/tests/cases/fourslash/mergedDeclarationsWithExportAssignment1.ts @@ -15,7 +15,11 @@ ////var /*3*/z = new /*2*/Foo(); ////var /*5*/r2 = Foo./*4*/x; -verify.quickInfoAt("1", "import Foo = require('./mergedDeclarationsWithExportAssignment1_file0')"); +verify.quickInfoAt("1", [ + "(alias) class Foo", + "(alias) namespace Foo", + "import Foo = require('./mergedDeclarationsWithExportAssignment1_file0')" +].join("\n")); goTo.marker('2'); verify.completionListContains('Foo'); diff --git a/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts b/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts index 78c22b09dac..9fcedc94103 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts @@ -15,33 +15,4 @@ //// new /*8*/a4.c(); ////} -var marker = 0; -function goToMarker() { - marker++; - goTo.marker(marker.toString()); -} - -function verifyImport(name: string, assigningDisplay:ts.SymbolDisplayPart[], optionalParentName?: string) { - goToMarker(); - var moduleNameDisplay = [{ text: name, kind: "aliasName" }]; - if (optionalParentName) { - moduleNameDisplay = [{ text: optionalParentName, kind: "moduleName" }, { text: ".", kind: "punctuation" }].concat(moduleNameDisplay); - } - verify.verifyQuickInfoDisplayParts("alias", optionalParentName ? "export" : "", { start: test.markerByName(marker.toString()).position, length: name.length }, - [{ text: "import", kind: "keyword" }, { text: " ", kind: "space" }].concat(moduleNameDisplay).concat( - { text: " ", kind: "space" }, { text: "=", kind: "operator" }, { text: " ", kind: "space" }).concat(assigningDisplay), - [], []); -} - -var moduleMDisplay = [{ text: "m", kind: "moduleName" }]; -var moduleMDotM1Display = moduleMDisplay.concat({ text: ".", kind: "punctuation" }, { text: "m1", kind: "moduleName" }); - -verifyImport("a1", moduleMDisplay); -verifyImport("a1", moduleMDisplay); -verifyImport("a2", moduleMDotM1Display); -verifyImport("a2", moduleMDotM1Display); - -verifyImport("a3", moduleMDisplay, "m2"); -verifyImport("a3", moduleMDisplay, "m2"); -verifyImport("a4", moduleMDotM1Display, "m2"); -verifyImport("a4", moduleMDotM1Display, "m2"); \ No newline at end of file +verify.baselineQuickInfo(); diff --git a/tests/cases/fourslash/quickInfoForRequire.ts b/tests/cases/fourslash/quickInfoForRequire.ts index fe923945429..231dd8603b2 100644 --- a/tests/cases/fourslash/quickInfoForRequire.ts +++ b/tests/cases/fourslash/quickInfoForRequire.ts @@ -5,6 +5,11 @@ //@Filename: quickInfoForRequire_input.ts ////import a = require("./AA/B/*1*/B"); +////import b = require(`./AA/B/*2*/B`); + goTo.marker("1"); verify.quickInfoIs("module a"); + +goTo.marker("2"); +verify.quickInfoIs("module a"); diff --git a/tests/cases/fourslash/quickInfoImportedTypes.ts b/tests/cases/fourslash/quickInfoImportedTypes.ts new file mode 100644 index 00000000000..52da97ada91 --- /dev/null +++ b/tests/cases/fourslash/quickInfoImportedTypes.ts @@ -0,0 +1,34 @@ +/// + +// @Filename: quickInfoImportedTypes.ts +//// /** This is an interface */ +//// export interface Foo { +//// a?: number; +//// } +//// /** One or two */ +//// export type Bar = 1 | 2 +//// /** This is a class */ +//// export class Baz { +//// public x: T = {} as T +//// } + +// @Filename: two.ts +//// import { Foo, Bar, Baz } from './quickInfoImportedTypes'; +//// let x: Foo/*1*/; +//// let y: Bar/*2*/; +//// let z: Baz/*3*/; + +verify.quickInfoAt("1", [ + "(alias) interface Foo", + "import Foo", +].join("\n"), "This is an interface "); + +verify.quickInfoAt("2", [ + "(alias) type Bar = 1 | 2", + "import Bar", +].join("\n"), "One or two "); + +verify.quickInfoAt("3", [ + "(alias) class Baz", + "import Baz", +].join("\n"), "This is a class "); diff --git a/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts b/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts new file mode 100644 index 00000000000..9e7efc52761 --- /dev/null +++ b/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts @@ -0,0 +1,28 @@ +/// + +// @Filename: quickInfoImportedTypesWithMergedMeanings.ts +//// export namespace Original { } +//// export type Original = () => T; +//// /** some docs */ +//// export function Original() { } + +// @Filename: transient.ts +//// export { Original/*1*/ } from './quickInfoImportedTypesWithMergedMeanings'; + +// @Filename: importer.ts +//// import { Original as Alias } from './quickInfoImportedTypesWithMergedMeanings'; +//// Alias/*2*/; + +verify.quickInfoAt("1", [ + "(alias) type Original = () => T", + "(alias) namespace Original", + "(alias) function Original(): void", + "import Original", +].join("\n"), "some docs "); + +verify.quickInfoAt("2", [ + "(alias) type Alias = () => T", + "(alias) namespace Alias", + "(alias) function Alias(): void", + "import Alias", +].join("\n"), "some docs "); diff --git a/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts b/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts new file mode 100644 index 00000000000..1b46eba1f6b --- /dev/null +++ b/tests/cases/fourslash/quickInfoMappedTypeRecursiveInference.ts @@ -0,0 +1,56 @@ +/// +// @Filename: test.ts +//// interface A { a: A } +//// declare let a: A; +//// type Deep = { [K in keyof T]: Deep } +//// declare function foo(deep: Deep): T; +//// const out/*1*/ = foo/*2*/(a); +//// out.a/*3*/ +//// out.a.a/*4*/ +//// out.a.a.a.a.a.a.a/*5*/ +//// +//// interface B { [s: string]: B } +//// declare let b: B; +//// const oub/*6*/ = foo/*7*/(b); +//// oub.b/*8*/ +//// oub.b.b/*9*/ +//// oub.b.a.n.a.n.a/*10*/ + +verify.quickInfoAt('1', `const out: { + a: any; +}`); +verify.quickInfoAt('2', `function foo<{ + a: any; +}>(deep: Deep<{ + a: any; +}>): { + a: any; +}`); +verify.quickInfoAt('3', `(property) a: { + a: any; +}`); +verify.quickInfoAt('4', `(property) a: { + a: any; +}`); +verify.quickInfoAt('5', `(property) a: { + a: any; +}`); +verify.quickInfoAt('6', `const oub: { + [x: string]: any; +}`); +verify.quickInfoAt('7', `function foo<{ + [x: string]: any; +}>(deep: Deep<{ + [x: string]: any; +}>): { + [x: string]: any; +}`); +verify.quickInfoAt('8', `{ + [x: string]: any; +}`); +verify.quickInfoAt('9', `{ + [x: string]: any; +}`); +verify.quickInfoAt('10', `{ + [x: string]: any; +}`); diff --git a/tests/cases/fourslash/quickInfoMeaning.ts b/tests/cases/fourslash/quickInfoMeaning.ts index 2c7aa5a0ccd..f50675ba393 100644 --- a/tests/cases/fourslash/quickInfoMeaning.ts +++ b/tests/cases/fourslash/quickInfoMeaning.ts @@ -29,7 +29,7 @@ verify.quickInfoIs("const foo: number"); verify.goToDefinitionIs("foo_value_declaration"); goTo.marker("foo_type"); -verify.quickInfoIs("import foo = require(\"foo_module\")"); +verify.quickInfoIs("(alias) interface foo\nimport foo = require(\"foo_module\")"); verify.goToDefinitionIs("foo_type_declaration"); @@ -54,7 +54,7 @@ verify.navigationItemsListContains("bar", "alias", "bar", "exact"); verify.navigationItemsListContains("bar", "interface", "bar", "exact"); goTo.marker("bar_value"); -verify.quickInfoIs("import bar = require(\"bar_module\")"); +verify.quickInfoIs("(alias) const bar: number\nimport bar = require(\"bar_module\")"); verify.goToDefinitionIs("bar_value_declaration"); goTo.marker("bar_type"); diff --git a/tests/cases/fourslash/quickInfoOnInternalAliases.ts b/tests/cases/fourslash/quickInfoOnInternalAliases.ts index 8d334ef4a6c..f22b61ae86d 100644 --- a/tests/cases/fourslash/quickInfoOnInternalAliases.ts +++ b/tests/cases/fourslash/quickInfoOnInternalAliases.ts @@ -21,16 +21,16 @@ verify.quickInfos({ 1: ["class m1.m2.c", "class comment;"], - 2: ["import internalAlias = m1.m2.c", "This is on import declaration"], + 2: ["(alias) class internalAlias\nimport internalAlias = m1.m2.c", "This is on import declaration"], 3: ["class m1.m2.c", "class comment;"], 4: "var newVar: internalAlias", 5: "(alias) new internalAlias(): internalAlias\nimport internalAlias = m1.m2.c", 6: "var anotherAliasVar: typeof internalAlias", - 7: ["import internalAlias = m1.m2.c", "This is on import declaration"], - 8: "import internalFoo = m1.foo", + 7: ["(alias) class internalAlias\nimport internalAlias = m1.m2.c", "This is on import declaration"], + 8: "(alias) function internalFoo(): void\nimport internalFoo = m1.foo", 9: "function m1.foo(): void", 10: "var callVar: void", 11: "(alias) internalFoo(): void\nimport internalFoo = m1.foo", 12: "var anotherAliasFoo: () => void", - 13: "import internalFoo = m1.foo" + 13: "(alias) function internalFoo(): void\nimport internalFoo = m1.foo" }); diff --git a/tests/cases/fourslash/quickInfoPropertyTag.ts b/tests/cases/fourslash/quickInfoPropertyTag.ts new file mode 100644 index 00000000000..b413a7610e1 --- /dev/null +++ b/tests/cases/fourslash/quickInfoPropertyTag.ts @@ -0,0 +1,16 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////** +//// * @typedef I +//// * @property {number} x Doc +//// * More doc +//// */ +//// +/////** @type {I} */ +////const obj = { /**/x: 10 }; + +// TODO: GH#21123 There shouldn't be a " " before "More doc" +verify.quickInfoAt("", "(property) x: number", "Doc\n More doc"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts new file mode 100644 index 00000000000..6529bb64af0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const exportsAlias = exports; +////exportsAlias.f = function() {}; +/////*a*/module/*b*/.exports = exportsAlias; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: ` +export function f() { } +`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts new file mode 100644 index 00000000000..1c8633eb4eb --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts @@ -0,0 +1,19 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.default = 0; +////exports.default; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `const _default = 0; +export { _default as default }; +_default;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts new file mode 100644 index 00000000000..16b48fcd204 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts @@ -0,0 +1,19 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.class = 0; +////exports.async = 1; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `const _class = 0; +export { _class as class }; +export const async = 1;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts new file mode 100644 index 00000000000..ddcf79d0114 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts @@ -0,0 +1,26 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = function() {} +////module.exports = function f() {} +////module.exports = class {} +////module.exports = class C {} +////module.exports = 0; + +// See also `refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts` + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export default function() { } +export default function f() { } +export default class { +} +export default class C { +} +export default 0;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts new file mode 100644 index 00000000000..8d22ea77c2b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts @@ -0,0 +1,43 @@ +/// + +// @allowJs: true + +// @Filename: /a.d.ts +////export const x: number; + +// @Filename: /b.d.ts +////export default function f() {} + +// @Filename: /c.d.ts +////export default function f(): void; +////export function g(): void; + +// @Filename: /d.ts +////declare const x: number; +////export = x; + +// @Filename: /z.js +// Normally -- just `export *` +/////*a*/module/*b*/.exports = require("./a"); +// If just a default is exported, just `export { default }` +////module.exports = require("./b"); +// May need both +////module.exports = require("./c"); +// For `export =` re-export the "default" since that's what it will be converted to. +////module.exports = require("./d"); +// In untyped case just go with `export *` +////module.exports = require("./unknown"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: +`export * from "./a"; +export { default } from "./b"; +export * from "./c"; +export { default } from "./c"; +export { default } from "./d"; +export * from "./unknown";`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts new file mode 100644 index 00000000000..7b48bd5f91e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts @@ -0,0 +1,26 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = 0; + +// @Filename: /b.ts +////import a = require("./a"); + +// @Filename: /c.js +////const a = require("./a"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export default 0;`, +}); + +goTo.file("/b.ts"); +verify.currentFileContentIs('import a from "./a";'); + +goTo.file("/c.js"); +verify.currentFileContentIs('const a = require("./a").default;'); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts new file mode 100644 index 00000000000..8251f90fc0d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts @@ -0,0 +1,19 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.f = function() {} +////exports.C = class {} +////exports.x = 0; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export function f() { } +export class C { +} +export const x = 0;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts new file mode 100644 index 00000000000..b18bc94579d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts @@ -0,0 +1,25 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/module/*b*/.exports = { +//// x: 0, +//// f: function() {}, +//// g: () => {}, +//// h() {}, +//// C: class {}, +////}; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export const x = 0; +export function f() { } +export function g() { } +export function h() { } +export class C { +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts new file mode 100644 index 00000000000..05b4903eda3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts @@ -0,0 +1,18 @@ +/// + +// TODO: Maybe we could transform this to `export function f() {}`. + +// @allowJs: true + +// @Filename: /a.js +////function f() {} +/////*a*/module/*b*/.exports = { f }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `function f() {} +export default { f };`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts new file mode 100644 index 00000000000..da9976fa7d0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts @@ -0,0 +1,36 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////exports.x = 0; +////exports.x; +//// +////const y = 1; +/////*a*/exports/*b*/.y = y; +////exports.y; +//// +////exports.z = 2; +////function f(z) { +//// exports.z; +////} + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export const x = 0; +x; + +const y = 1; +const _y = y; +export { _y as y }; +_y; + +const _z = 2; +export { _z as z }; +function f(z) { + _z; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts new file mode 100644 index 00000000000..b3b7fbf94c6 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////*a*/exports/*b*/.f = async function* f(p) {} +////exports.C = class C extends D { m() {} } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `export async function* f(p) { } +export class C extends D { + m() { } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts new file mode 100644 index 00000000000..b33b0a1a160 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const [x, y] = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import _x from "x"; +const [x, y] = _x;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts new file mode 100644 index 00000000000..7c5415c1451 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"); +////x(); +////x.y; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x, { y } from "x"; +x(); +y;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts new file mode 100644 index 00000000000..321a9cccf8b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts @@ -0,0 +1,20 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = require("x"); +////const [a, b] = /*a*/require/*b*/("x"); +////const {c, ...d} = require("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +import _x from "x"; +const [a, b] = _x; +import __x from "x"; +const { c, ...d } = __x;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts new file mode 100644 index 00000000000..37d65ddc622 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts @@ -0,0 +1,18 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"), y = 0, { z } = require("z"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +const y = 0; +import { z } from "z";`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts new file mode 100644 index 00000000000..0c953b2e7e6 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts @@ -0,0 +1,21 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const [] = /*a0*/require/*b0*/("a-b"); +////const [] = /*a1*/require/*b1*/("0a"); +////const [] = /*a2*/require/*b2*/("1a"); + +goTo.select("a0", "b0"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import aB from "a-b"; +const [] = aB; +import A from "0a"; +const [] = A; +import _A from "1a"; +const [] = _A;` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts new file mode 100644 index 00000000000..f757db2164a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts @@ -0,0 +1,15 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const { x: { a, b } } = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +const { x: { a, b } } = x;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts new file mode 100644 index 00000000000..474fd4b0f0f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const { x, y: z } = /*a*/require/*b*/("x"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: 'import { x, y as z } from "x";', +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts new file mode 100644 index 00000000000..bf7e207550e --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts @@ -0,0 +1,16 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x"); +////x.y; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import { y } from "x"; +y;`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts new file mode 100644 index 00000000000..57efd5370f2 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts @@ -0,0 +1,24 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const x = /*a*/require/*b*/("x").default; +////const a = require("b").c; +////const a = require("a").a; +////const [a, b] = require("c").d; +////const [a, b] = require("c").a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'. + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import x from "x"; +import { c as a } from "b"; +import { a } from "a"; +import { d } from "c"; +const [a, b] = d; +import { a as _a } from "c"; +const [a, b] = _a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'.`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts new file mode 100644 index 00000000000..c389280d75c --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////const mod = /*a*/require/*b*/("mod"); +////const x = 0; +////mod.x(x); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: `import { x as _x } from "mod"; +const x = 0; +_x(x);` +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts new file mode 100644 index 00000000000..2b81c816e20 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts @@ -0,0 +1,16 @@ +/// + +// Test that we leave it alone if the name is a keyword. + +// @allowJs: true + +// @Filename: /a.js +/////*a*/require/*b*/("foo"); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Convert to ES6 module", + actionName: "Convert to ES6 module", + actionDescription: "Convert to ES6 module", + newContent: 'import "foo";', +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts new file mode 100644 index 00000000000..8d441f47dc3 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts @@ -0,0 +1,13 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////c[|o|]nst [|a|]lias [|=|] [|m|]odule[|.|]export[|s|]; +////[|a|]lias[|.|][|x|] = 0; +////[|module.exports|]; +////[|require("x")|]; +////[|require("x").y;|]; + +goTo.eachRange(() => verify.refactorAvailable("Convert to ES6 module")); + diff --git a/tests/cases/fourslash/referencesBloomFilters.ts b/tests/cases/fourslash/referencesBloomFilters.ts index 2745f6144ca..2f3fd02a827 100644 --- a/tests/cases/fourslash/referencesBloomFilters.ts +++ b/tests/cases/fourslash/referencesBloomFilters.ts @@ -17,10 +17,7 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; verify.referenceGroups(r0, [{ definition: "(property) searchProp: number", ranges }]); -verify.referenceGroups([r1, r2], [ - { definition: "(property) searchProp: number", ranges: [r0, r3] }, - { definition: "(property) searchProp: number", ranges: [r1, r2] } -]); +verify.referenceGroups([r1, r2], [{ definition: "(property) searchProp: number", ranges }]); verify.referenceGroups(r3, [ { definition: "(property) searchProp: number", ranges: [r0, r1, r2] }, { definition: '(property) "searchProp": number', ranges: [r3] } diff --git a/tests/cases/fourslash/referencesBloomFilters2.ts b/tests/cases/fourslash/referencesBloomFilters2.ts index 26690e437ee..3dea66b593d 100644 --- a/tests/cases/fourslash/referencesBloomFilters2.ts +++ b/tests/cases/fourslash/referencesBloomFilters2.ts @@ -16,11 +16,7 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) 42: number", ranges }]); -verify.referenceGroups([r1, r2], [ - { definition: "(property) 42: number", ranges: [r0, r3] }, - { definition: "(property) 42: number", ranges: [r1, r2] } -]); +verify.referenceGroups([r0, r1, r2], [{ definition: "(property) 42: number", ranges }]); verify.referenceGroups(r3, [ { definition: "(property) 42: number", ranges: [r0, r1, r2] }, { definition: '(property) "42": number', ranges: [r3] } diff --git a/tests/cases/fourslash/referencesForAmbients.ts b/tests/cases/fourslash/referencesForAmbients.ts index 2397738581e..02001d2ffdf 100644 --- a/tests/cases/fourslash/referencesForAmbients.ts +++ b/tests/cases/fourslash/referencesForAmbients.ts @@ -17,5 +17,5 @@ const [moduleFoo0, f0, moduleBar0, foo0, moduleFoo1, foo1, f1, moduleBar1, foo2] = test.ranges(); verify.singleReferenceGroup('module "foo"', [moduleFoo1, moduleFoo0]); verify.singleReferenceGroup('module "bar"', [moduleBar1, moduleBar0]); -verify.singleReferenceGroup('import foo = require("foo")', [foo0, foo1, foo2]); +verify.singleReferenceGroup('(alias) module "foo"\nimport foo = require("foo")', [foo0, foo1, foo2]); verify.singleReferenceGroup("var f: number", [f0, f1]); diff --git a/tests/cases/fourslash/referencesForClassMembers.ts b/tests/cases/fourslash/referencesForClassMembers.ts index 0db4ebb0873..847ebcb84b6 100644 --- a/tests/cases/fourslash/referencesForClassMembers.ts +++ b/tests/cases/fourslash/referencesForClassMembers.ts @@ -25,12 +25,7 @@ verify.referenceGroups([a1, a2], [ const methods = ranges.get("method"); const [m0, m1, m2] = methods; verify.referenceGroups(m0, [{ definition: "(method) Base.method(): void", ranges: methods }]); -verify.referenceGroups(m1, [ +verify.referenceGroups([m1, m2], [ { definition: "(method) Base.method(): void", ranges: [m0] }, { definition: "(method) MyClass.method(): void", ranges: [m1, m2] } ]); -verify.referenceGroups(m2, [ - { definition: "(method) Base.method(): void", ranges: [m0] }, - { definition: "(method) MyClass.method(): void", ranges: [m1] }, - { definition: "(method) MyClass.method(): void", ranges: [m2] } -]); diff --git a/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts b/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts index b5be77a73bb..d42c0331469 100644 --- a/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts +++ b/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts @@ -25,12 +25,7 @@ verify.referenceGroups([a1, a2], [ const methods = ranges.get("method"); const [m0, m1, m2] = methods; verify.referenceGroups(m0, [{ definition: "(method) Base.method(): void", ranges: methods }]); -verify.referenceGroups(m1, [ +verify.referenceGroups([m1, m2], [ { definition: "(method) Base.method(): void", ranges: [m0] }, { definition: "(method) MyClass.method(): void", ranges: [m1, m2] } ]); -verify.referenceGroups(m2, [ - { definition: "(method) Base.method(): void", ranges: [m0] }, - { definition: "(method) MyClass.method(): void", ranges: [m1] }, - { definition: "(method) MyClass.method(): void", ranges: [m2] } -]); diff --git a/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts b/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts index 448c2627531..e995294a94d 100644 --- a/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts +++ b/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts @@ -25,12 +25,7 @@ verify.referenceGroups([a1, a2], [ const methods = ranges.get("method"); const [m0, m1, m2] = methods; verify.referenceGroups(m0, [{ definition: "(method) Base.method(a?: T, b?: U): this", ranges: methods }]); -verify.referenceGroups(m1, [ +verify.referenceGroups([m1, m2], [ { definition: "(method) Base.method(a?: T, b?: U): this", ranges: [m0] }, { definition: "(method) MyClass.method(): void", ranges: [m1, m2] } ]); -verify.referenceGroups(m2, [ - { definition: "(method) Base.method(a?: T, b?: U): this", ranges: [m0] }, - { definition: "(method) MyClass.method(): void", ranges: [m1] }, - { definition: "(method) MyClass.method(): void", ranges: [m2] } -]); diff --git a/tests/cases/fourslash/referencesForClassParameter.ts b/tests/cases/fourslash/referencesForClassParameter.ts index 24eb9e5496e..ec1e1bb2f0e 100644 --- a/tests/cases/fourslash/referencesForClassParameter.ts +++ b/tests/cases/fourslash/referencesForClassParameter.ts @@ -19,10 +19,4 @@ ////var n = new foo(undefined); ////n.[|{| "isWriteAccess": true |}p|] = null; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups([r0, r1], [{ definition: "(property) foo.p: any", ranges }]); -verify.referenceGroups(r2, [ - { definition: "(property) foo.p: any", ranges: [r0, r1] }, - { definition: "(property) foo.p: any", ranges: [r2] } -]); +verify.singleReferenceGroup("(property) foo.p: any"); diff --git a/tests/cases/fourslash/referencesForGlobals5.ts b/tests/cases/fourslash/referencesForGlobals5.ts index d7dd9304746..0d205b4b9b2 100644 --- a/tests/cases/fourslash/referencesForGlobals5.ts +++ b/tests/cases/fourslash/referencesForGlobals5.ts @@ -12,4 +12,4 @@ // @Filename: referencesForGlobals_2.ts ////var m = [|globalAlias|]; -verify.singleReferenceGroup("import globalAlias = globalModule"); +verify.singleReferenceGroup("(alias) namespace globalAlias\nimport globalAlias = globalModule"); diff --git a/tests/cases/fourslash/referencesForInheritedProperties.ts b/tests/cases/fourslash/referencesForInheritedProperties.ts index c2674fe1fe1..100fda73f89 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties.ts @@ -28,14 +28,8 @@ verify.referenceGroups(r1, [ { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface2.doStuff(): void", ranges: [r1, r2, r3] } ]); -verify.referenceGroups(r2, [ +verify.referenceGroups([r2, r3], [ { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface2.doStuff(): void", ranges: [r1] }, { definition: "(method) class1.doStuff(): void", ranges: [r2, r3] } ]); -verify.referenceGroups(r3, [ - { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, - { definition: "(method) interface2.doStuff(): void", ranges: [r1] }, - { definition: "(method) class1.doStuff(): void", ranges: [r2] }, - { definition: "(method) class1.doStuff(): void", ranges: [r3] } -]); diff --git a/tests/cases/fourslash/referencesForInheritedProperties2.ts b/tests/cases/fourslash/referencesForInheritedProperties2.ts index 0f89a9aa744..39bc01e5eb6 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties2.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties2.ts @@ -33,14 +33,8 @@ verify.referenceGroups(r1, [ { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface2.doStuff(): void", ranges: [r1, r2, r3] } ]); -verify.referenceGroups(r2, [ +verify.referenceGroups([r2, r3], [ { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface2.doStuff(): void", ranges: [r1] }, { definition: "(method) class1.doStuff(): void", ranges: [r2, r3] } ]); -verify.referenceGroups(r3, [ - { definition: "(method) interface1.doStuff(): void", ranges: [r0] }, - { definition: "(method) interface2.doStuff(): void", ranges: [r1] }, - { definition: "(method) class1.doStuff(): void", ranges: [r2] }, - { definition: "(method) class1.doStuff(): void", ranges: [r3] } -]); diff --git a/tests/cases/fourslash/referencesForInheritedProperties4.ts b/tests/cases/fourslash/referencesForInheritedProperties4.ts index 8a822ec5238..adf8240ea31 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties4.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties4.ts @@ -11,11 +11,5 @@ const ranges = test.rangesByText(); const [r0, r1] = ranges.get("doStuff"); -verify.referenceGroups(r0, [ - { definition: "(method) class1.doStuff(): void", ranges: [r0, r1] }, -]); -verify.referenceGroups(r1, [ - { definition: "(method) class1.doStuff(): void", ranges: [r0] }, - { definition: "(method) class1.doStuff(): void", ranges: [r1] }, -]); +verify.singleReferenceGroup("(method) class1.doStuff(): void", ranges.get("doStuff")); verify.singleReferenceGroup("(property) class1.propName: string", ranges.get("propName")); diff --git a/tests/cases/fourslash/referencesForInheritedProperties6.ts b/tests/cases/fourslash/referencesForInheritedProperties6.ts index a39dc085c71..df1f0810018 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties6.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties6.ts @@ -16,12 +16,7 @@ const ranges = test.rangesByText(); const [m0, m1, m2] = ranges.get("doStuff"); verify.referenceGroups(m0, [{ definition: "(method) class1.doStuff(): void", ranges: [m0, m1, m2] }]); -verify.referenceGroups(m1, [ +verify.referenceGroups([m1, m2], [ { definition: "(method) class1.doStuff(): void", ranges: [m0] }, { definition: "(method) class2.doStuff(): void", ranges: [m1, m2] } ]); -verify.referenceGroups(m2, [ - { definition: "(method) class1.doStuff(): void", ranges: [m0] }, - { definition: "(method) class2.doStuff(): void", ranges: [m1] }, - { definition: "(method) class2.doStuff(): void", ranges: [m2] } -]); diff --git a/tests/cases/fourslash/referencesForInheritedProperties7.ts b/tests/cases/fourslash/referencesForInheritedProperties7.ts index 4911cbefd57..be92ced55aa 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties7.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties7.ts @@ -35,6 +35,5 @@ verify.referenceGroups([r5, r7], [ verify.referenceGroups(r6, [ { definition: "(method) class1.doStuff(): void", ranges: [r0] }, { definition: "(method) interface1.doStuff(): void", ranges: [r2] }, - { definition: "(method) class2.doStuff(): void", ranges: [r4] }, - { definition: "(method) class2.doStuff(): void", ranges: [r6] } + { definition: "(method) class2.doStuff(): void", ranges: [r4, r6] }, ]); diff --git a/tests/cases/fourslash/referencesForMergedDeclarations2.ts b/tests/cases/fourslash/referencesForMergedDeclarations2.ts index 5cf9234511a..ba61d4c9061 100644 --- a/tests/cases/fourslash/referencesForMergedDeclarations2.ts +++ b/tests/cases/fourslash/referencesForMergedDeclarations2.ts @@ -11,4 +11,8 @@ ////var a: [|alias|].Bar; // namespace ////[|alias|].call(this); // value -verify.singleReferenceGroup("import alias = ATest"); +verify.singleReferenceGroup([ + "(alias) namespace alias", + "(alias) function alias(): void", + "import alias = ATest" +].join("\n")); diff --git a/tests/cases/fourslash/referencesForObjectLiteralProperties.ts b/tests/cases/fourslash/referencesForObjectLiteralProperties.ts index ea7c20829ae..804faaebe6e 100644 --- a/tests/cases/fourslash/referencesForObjectLiteralProperties.ts +++ b/tests/cases/fourslash/referencesForObjectLiteralProperties.ts @@ -8,10 +8,4 @@ ////var y = x; ////y.[|add|]; -const ranges = test.ranges(); -const [r0, r1, r2, r3] = ranges; -verify.referenceGroups(r0, [{ definition: "(property) add: number", ranges }]); -verify.referenceGroups([r1, r2, r3], [ - { definition: "(property) add: number", ranges: [r0] }, - { definition: "(property) add: number", ranges: [r1, r2, r3] } -]); +verify.singleReferenceGroup("(property) add: number"); diff --git a/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts b/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts index a92ac909782..34c84dba5ca 100644 --- a/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts +++ b/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts @@ -13,11 +13,5 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; verify.referenceGroups(r0, [{ definition: "(method) IFoo.doSomething(v: T): T", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) IFoo.doSomething(v: string): string", ranges: [r0, r2] }, - { definition: "(method) IFoo.doSomething(v: string): string", ranges: [r1] } -]); -verify.referenceGroups(r2, [ - { definition: "(method) IFoo.doSomething(v: number): number", ranges: [r0, r1] }, - { definition: "(method) IFoo.doSomething(v: number): number", ranges: [r2] } -]); +verify.referenceGroups(r1, [{ definition: "(method) IFoo.doSomething(v: string): string", ranges }]); +verify.referenceGroups(r2, [{ definition: "(method) IFoo.doSomething(v: number): number", ranges }]); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts index 89b6c7c755e..ce5d474b9dc 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts @@ -7,11 +7,4 @@ ////var x: Foo; ////x.[|blah|]; -//verify.singleReferenceGroup('(method) Foo["blah"](): number'); -const ranges = test.ranges(); -const [r0, r1] = ranges; -verify.referenceGroups(r0, [{ definition: '(method) Foo["blah"](): number', ranges }]); -verify.referenceGroups(r1, [ - { definition: '(method) Foo["blah"](): number', ranges: [r0] }, - { definition: '(method) Foo["blah"](): number', ranges: [r1] } -]); +verify.singleReferenceGroup('(method) Foo["blah"](): number'); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts index aae15afd0c7..22fa6b30cbc 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts @@ -8,10 +8,4 @@ ////var y: Foo2; ////y[[|42|]]; -const ranges = test.ranges(); -const [r0, r1, r2] = ranges; -verify.referenceGroups([r0, r1], [{ definition: '(property) Foo2["42"]: number', ranges }]); -verify.referenceGroups(r2, [ - { definition: '(property) Foo2["42"]: number', ranges: [r0, r1] }, - { definition: '(property) Foo2["42"]: number', ranges: [r2] }, -]); +verify.singleReferenceGroup('(property) Foo2["42"]: number'); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts index c289a17c91c..a7589ba29a0 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts @@ -8,6 +8,5 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; verify.referenceGroups(r0, [{ definition: '(property) "someProperty": number', ranges }]); verify.referenceGroups([r1, r2], [ - { definition: '(property) "someProperty": number', ranges: [r0] }, - { definition: '(property) "someProperty": number', ranges: [r1, r2] }, + { definition: '(property) "someProperty": number', ranges: [r0, r1, r2] }, ]); diff --git a/tests/cases/fourslash/referencesForUnionProperties.ts b/tests/cases/fourslash/referencesForUnionProperties.ts index 97570077346..2df9ce96844 100644 --- a/tests/cases/fourslash/referencesForUnionProperties.ts +++ b/tests/cases/fourslash/referencesForUnionProperties.ts @@ -30,8 +30,7 @@ verify.referenceGroups(hasAOrB, [ { definition: "(property) HasAOrB.a: string", ranges: [hasAOrB, x] } ]); verify.referenceGroups(x, [ - { definition: "(property) a: number", ranges: [one] }, + { definition: "(property) a: number", ranges: [one, x] }, { definition: "(property) Base.a: string", ranges: [base] }, { definition: "(property) HasAOrB.a: string", ranges: [hasAOrB] }, - { definition: "(property) a: string | number", ranges: [x] } ]); diff --git a/tests/cases/fourslash/renameDefaultImport.ts b/tests/cases/fourslash/renameDefaultImport.ts index 086a05f6b99..3cf0c8b0880 100644 --- a/tests/cases/fourslash/renameDefaultImport.ts +++ b/tests/cases/fourslash/renameDefaultImport.ts @@ -18,7 +18,7 @@ const ranges = test.ranges(); const [C, B0, B1] = ranges; const classes = { definition: "class B", ranges: [C] }; -const imports = { definition: "import B", ranges: [B0, B1] }; +const imports = { definition: "(alias) class B\nimport B", ranges: [B0, B1] }; verify.referenceGroups(C, [classes, imports]); verify.referenceGroups(B0, [imports, classes]); verify.referenceGroups(B1, [ diff --git a/tests/cases/fourslash/renameDefaultImportDifferentName.ts b/tests/cases/fourslash/renameDefaultImportDifferentName.ts index ac44c26c443..75f80257e0b 100644 --- a/tests/cases/fourslash/renameDefaultImportDifferentName.ts +++ b/tests/cases/fourslash/renameDefaultImportDifferentName.ts @@ -18,7 +18,7 @@ const ranges = test.ranges(); const [C, B0, B1] = ranges; const bRanges = [B0, B1]; const classes = { definition: "class C", ranges: [C] }; -const imports = { definition: "import B", ranges: [B0, B1] }; +const imports = { definition: "(alias) class B\nimport B", ranges: [B0, B1] }; verify.referenceGroups(C, [classes, imports]); verify.referenceGroups(B0, [imports]); verify.referenceGroups(B1, [{ definition: "(alias) new B(): B\nimport B", ranges: bRanges }]); diff --git a/tests/cases/fourslash/renameForAliasingExport01.ts b/tests/cases/fourslash/renameForAliasingExport01.ts new file mode 100644 index 00000000000..a46d1806933 --- /dev/null +++ b/tests/cases/fourslash/renameForAliasingExport01.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: foo.ts +////let x = 1; +//// +////export { /**/[|x|] as y }; + +goTo.marker(); +verify.renameInfoSucceeded(/*displayName*/"x", /*fullDisplayName*/"x"); \ No newline at end of file diff --git a/tests/cases/fourslash/renameForAliasingExport02.ts b/tests/cases/fourslash/renameForAliasingExport02.ts new file mode 100644 index 00000000000..ece969ca504 --- /dev/null +++ b/tests/cases/fourslash/renameForAliasingExport02.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: foo.ts +////let x = 1; +//// +////export { x as /**/[|y|] }; + +goTo.marker(); +verify.renameInfoSucceeded(/*displayName*/"y", /*fullDisplayName*/'"/tests/cases/fourslash/foo".y'); \ No newline at end of file diff --git a/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts b/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts index 30feb0760e9..a961ebf2411 100644 --- a/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts +++ b/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts @@ -10,7 +10,7 @@ const ranges = test.ranges(); const [r0, r1, r2] = ranges; const vars = { definition: "var a: any", ranges: [r0] }; -const imports = { definition: "import a", ranges: [r1, r2] }; +const imports = { definition: "(alias) var a: any\nimport a", ranges: [r1, r2] }; verify.referenceGroups(r0, [vars, imports]); verify.referenceGroups(r1, [imports, vars]); verify.referenceGroups(r2, [imports, vars]); diff --git a/tests/cases/fourslash/renameImportOfExportEquals.ts b/tests/cases/fourslash/renameImportOfExportEquals.ts index 12cd86df647..65c65a62400 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals.ts @@ -22,8 +22,8 @@ const bRanges = [b0, b1]; const xRanges = [x0, x1]; const nGroup = { definition: "namespace N", ranges: nRanges }; -const aGroup = { definition: "import N", ranges: aRanges }; -const bGroup = { definition: "import N", ranges: [b0, b1] }; +const aGroup = { definition: "(alias) namespace N\nimport N", ranges: aRanges }; +const bGroup = { definition: "(alias) namespace N\nimport N", ranges: [b0, b1] }; verify.referenceGroups(nRanges, [nGroup, aGroup, bGroup]); verify.referenceGroups([a0, a1], [aGroup, nGroup, bGroup]); diff --git a/tests/cases/fourslash/renameImportOfExportEquals2.ts b/tests/cases/fourslash/renameImportOfExportEquals2.ts index 8ac00b8c012..83ff1794bde 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals2.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals2.ts @@ -24,9 +24,9 @@ const pRanges = [P0, P1]; const qRanges = [Q0, Q1]; const ns = { definition: "namespace N", ranges: nRanges }; -const os = { definition: "import O", ranges: oRanges }; -const ps = { definition: "import P", ranges: pRanges }; -const qs = { definition: "import Q", ranges: qRanges }; +const os = { definition: "(alias) namespace O\nimport O", ranges: oRanges }; +const ps = { definition: "(alias) namespace P\nimport P", ranges: pRanges }; +const qs = { definition: "(alias) namespace Q\nimport Q", ranges: qRanges }; verify.referenceGroups(nRanges, [ns, os, ps, qs]); verify.referenceGroups(oRanges, [os, ps, qs]); diff --git a/tests/cases/fourslash/renameImportOfReExport.ts b/tests/cases/fourslash/renameImportOfReExport.ts index 3f8250b4d77..6afb953ad53 100644 --- a/tests/cases/fourslash/renameImportOfReExport.ts +++ b/tests/cases/fourslash/renameImportOfReExport.ts @@ -20,8 +20,8 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; const importRanges = [r2, r3]; const classes = { definition: "class C", ranges: [r0] }; -const bs = { definition: "import C", ranges: [r1] }; -const imports = { definition: "import C", ranges: importRanges }; +const bs = { definition: "(alias) class C\nimport C", ranges: [r1] }; +const imports = { definition: "(alias) class C\nimport C", ranges: importRanges }; verify.referenceGroups(r0, [classes, bs, imports]); verify.referenceGroups(r1, [bs, imports, classes]); verify.referenceGroups(importRanges, [imports, bs, classes]); diff --git a/tests/cases/fourslash/renameImportOfReExport2.ts b/tests/cases/fourslash/renameImportOfReExport2.ts index ac61200b2f0..bcaa0e41c8a 100644 --- a/tests/cases/fourslash/renameImportOfReExport2.ts +++ b/tests/cases/fourslash/renameImportOfReExport2.ts @@ -18,8 +18,8 @@ const cRanges = ranges.get("C"); const [d0, d1, d2] = ranges.get("D"); const classes = { definition: "class C", ranges: cRanges }; -const bImports = { definition: "import D", ranges: [d0] }; -const cImports = { definition: "import D", ranges: [d1, d2] }; +const bImports = { definition: "(alias) class D\nimport D", ranges: [d0] }; +const cImports = { definition: "(alias) class D\nimport D", ranges: [d1, d2] }; verify.referenceGroups(cRanges, [classes, bImports, cImports]); verify.referenceGroups(d0, [bImports, cImports]); diff --git a/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts b/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts new file mode 100644 index 00000000000..7f2cbb8148f --- /dev/null +++ b/tests/cases/fourslash/server/formatSpaceBetweenFunctionAndArrayIndex.ts @@ -0,0 +1,19 @@ +/// + +//// +////function test() { +//// return []; +////} +//// +////test() [0] +//// + +format.document(); +verify.currentFileContentIs( +` +function test() { + return []; +} + +test()[0] +`); diff --git a/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts b/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts index fa9a510d5ac..0b333721914 100644 --- a/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts +++ b/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts @@ -26,7 +26,4 @@ const ranges = test.ranges(); const [r0, r1] = ranges; verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] }, - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] } -]); +verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]); diff --git a/tests/cases/fourslash/shims/getReferencesAtPosition.ts b/tests/cases/fourslash/shims/getReferencesAtPosition.ts index fa9a510d5ac..0b333721914 100644 --- a/tests/cases/fourslash/shims/getReferencesAtPosition.ts +++ b/tests/cases/fourslash/shims/getReferencesAtPosition.ts @@ -26,7 +26,4 @@ const ranges = test.ranges(); const [r0, r1] = ranges; verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]); -verify.referenceGroups(r1, [ - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] }, - { definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] } -]); +verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]); diff --git a/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts b/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts index b98cfe6bbfe..d445997338b 100644 --- a/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts +++ b/tests/cases/fourslash/signatureHelpOnOverloadsDifferentArity3.ts @@ -13,14 +13,14 @@ verify.currentSignatureHelpIs("f(): any"); verify.currentSignatureParameterCountIs(0); verify.signatureHelpArgumentCountIs(0); -edit.insert(", "); +edit.insert("x, "); verify.signatureHelpCountIs(4); verify.currentSignatureHelpIs("f(s: string, b: boolean): any"); verify.currentSignatureParameterCountIs(2); verify.currentParameterHelpArgumentNameIs("b"); verify.currentParameterSpanIs("b: boolean"); -edit.insert(", "); +edit.insert("x, "); verify.signatureHelpCountIs(4); verify.currentSignatureHelpIs("f(s: string, b: boolean): any"); verify.currentSignatureParameterCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/squiggleIllegalSubclassOverride.ts b/tests/cases/fourslash/squiggleIllegalSubclassOverride.ts index bb7b40fd259..955d461b9f1 100644 --- a/tests/cases/fourslash/squiggleIllegalSubclassOverride.ts +++ b/tests/cases/fourslash/squiggleIllegalSubclassOverride.ts @@ -4,8 +4,8 @@ //// public x: number; ////} //// -////class /*1*/Bar/*2*/ extends Foo { -//// public x: string; +////class Bar extends Foo { +//// public /*1*/x/*2*/: string; ////} verify.errorExistsBetweenMarkers("1", "2"); diff --git a/tests/cases/fourslash/transitiveExportImports.ts b/tests/cases/fourslash/transitiveExportImports.ts index 093121c1d9e..68cca0c407b 100644 --- a/tests/cases/fourslash/transitiveExportImports.ts +++ b/tests/cases/fourslash/transitiveExportImports.ts @@ -21,7 +21,7 @@ const aRanges = [a0, a1]; const bRanges = [b0, c2]; const cRanges = [c0, c1]; -const bGroup = { definition: "import b = require('./a')", ranges: bRanges } +const bGroup = { definition: "(alias) class b\nimport b = require('./a')", ranges: bRanges } verify.referenceGroups(aRanges, [ { definition: "class A", ranges: aRanges }, diff --git a/tests/cases/fourslash/transitiveExportImports2.ts b/tests/cases/fourslash/transitiveExportImports2.ts index 397bbf44a37..73e1e828b0c 100644 --- a/tests/cases/fourslash/transitiveExportImports2.ts +++ b/tests/cases/fourslash/transitiveExportImports2.ts @@ -20,8 +20,8 @@ const bRanges = [B0, B1]; const cRanges = [B2]; const aGroup = { definition: "namespace A", ranges: aRanges }; -const bGroup = { definition: "import B = A", ranges: bRanges }; -const cGroup = { definition: "import B", ranges: cRanges }; +const bGroup = { definition: "(alias) namespace B\nimport B = A", ranges: bRanges }; +const cGroup = { definition: "(alias) namespace B\nimport B", ranges: cRanges }; verify.referenceGroups(aRanges, [aGroup, bGroup, cGroup]); verify.referenceGroups(bRanges, [bGroup, cGroup]); diff --git a/tests/cases/fourslash/transitiveExportImports3.ts b/tests/cases/fourslash/transitiveExportImports3.ts index 638fa85df83..abb7b2a2983 100644 --- a/tests/cases/fourslash/transitiveExportImports3.ts +++ b/tests/cases/fourslash/transitiveExportImports3.ts @@ -13,9 +13,9 @@ verify.noErrors(); const [f0, f1, g0, f2, g1] = test.ranges(); const af = { definition: "function f(): void", ranges: [f0, f1] }; -const g0Group = { definition: "import g", ranges: [g0] }; -const g1Group = { definition: "import g", ranges: [g1] }; -const bf = { definition: "import f", ranges: [f2] }; +const g0Group = { definition: "(alias) function g(): void\nimport g", ranges: [g0] }; +const g1Group = { definition: "(alias) function g(): void\nimport g", ranges: [g1] }; +const bf = { definition: "(alias) function f(): void\nimport f", ranges: [f2] }; verify.referenceGroups([f0, f1], [af, g0Group, g1Group, bf]); verify.referenceGroups(g0, [g0Group, g1Group]); diff --git a/tslint.json b/tslint.json index 737a0ab8318..b801df720f2 100644 --- a/tslint.json +++ b/tslint.json @@ -31,6 +31,7 @@ "check-else" ], "no-bom": true, + "no-double-space": true, "no-in-operator": true, "no-increment-decrement": true, "no-inferrable-types": true,

+>P : P +>Props : Props +>Props : Props +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>P : P + +const m = +>m : JSX.Element +> : JSX.Element +>MyComponent : typeof MyComponent +>x : "a" + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 530a2b8bbf3..8ea17554b35 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -1102,10 +1102,10 @@ declare type Handlers = { }; declare function on(handlerHash: Handlers): T; declare var hashOfEmpty1: { - test: {}; + test: any; }; declare var hashOfEmpty2: { - test: boolean; + test: any; }; interface Options1 { data?: Data; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index bf95972be76..0e7da19c3e2 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -1793,16 +1793,16 @@ declare function on(handlerHash: Handlers): T >T : T var hashOfEmpty1 = on({ test: () => {} }); // {} ->hashOfEmpty1 : { test: {}; } ->on({ test: () => {} }) : { test: {}; } +>hashOfEmpty1 : { test: any; } +>on({ test: () => {} }) : { test: any; } >on : (handlerHash: Handlers) => T >{ test: () => {} } : { test: () => void; } >test : () => void >() => {} : () => void var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean } ->hashOfEmpty2 : { test: boolean; } ->on({ test: (x: boolean) => {} }) : { test: boolean; } +>hashOfEmpty2 : { test: any; } +>on({ test: (x: boolean) => {} }) : { test: any; } >on : (handlerHash: Handlers) => T >{ test: (x: boolean) => {} } : { test: (x: boolean) => void; } >test : (x: boolean) => void diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 0634c3419e0..2981cb0366d 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -27,9 +27,11 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error Type 'T' is not assignable to type 'T & U'. Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(84,9): error TS2322: Type 'keyof T' is not assignable to type 'K'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(85,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. -==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (25 errors) ==== +==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (27 errors) ==== class Shape { name: string; width: number; @@ -162,4 +164,18 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error ~~ !!! error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'. k2 = k1; - } \ No newline at end of file + } + + // Repro from #17166 + function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + ~ +!!! error TS2322: Type 'keyof T' is not assignable to type 'K'. + value = obj[key]; // error, T[keyof T] =/=> T[K] + ~~~~~ +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. + } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.js b/tests/baselines/reference/keyofAndIndexedAccessErrors.js index 838a3a6a86b..2a1042cf4ee 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.js +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.js @@ -77,7 +77,17 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { o2 = o1; // Error k1 = k2; // Error k2 = k1; -} +} + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} + + //// [keyofAndIndexedAccessErrors.js] var Shape = /** @class */ (function () { @@ -109,3 +119,10 @@ function f20(k1, k2, o1, o2) { k1 = k2; // Error k2 = k1; } +// Repro from #17166 +function f3(obj, k, value) { + for (var key in obj) { + k = key; // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols index 36fb8d2989b..0e97ef793fb 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols @@ -268,3 +268,34 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37)) >k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) } + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { +>f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 78, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) + + for (let key in obj) { +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) + + k = key // error, keyof T =/=> K +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) + + value = obj[key]; // error, T[keyof T] =/=> T[K] +>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) + } +} + + diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 4d2e25641d3..f5cc7c093d9 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -299,3 +299,37 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >k2 : keyof (T & U) >k1 : keyof (T | U) } + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { +>f3 : (obj: T, k: K, value: T[K]) => void +>T : T +>K : K +>T : T +>obj : T +>T : T +>k : K +>K : K +>value : T[K] +>T : T +>K : K + + for (let key in obj) { +>key : keyof T +>obj : T + + k = key // error, keyof T =/=> K +>k = key : keyof T +>k : K +>key : keyof T + + value = obj[key]; // error, T[keyof T] =/=> T[K] +>value = obj[key] : T[keyof T] +>value : T[K] +>obj[key] : T[keyof T] +>obj : T +>key : keyof T + } +} + + diff --git a/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt b/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt index 28bc188f7b6..9b7efb94850 100644 --- a/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: number; baz: {}; }>'. - Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; }'. +tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; } & ThisType<{ x: number; y: number; } & { bar: any; baz: any; }>'. + Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; }'. Types of property 'computed' are incompatible. - Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: number; baz: {}; }>'. + Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: any; baz: any; }>'. Types of property 'baz' are incompatible. Type 'number' is not assignable to type '() => {}'. @@ -35,10 +35,10 @@ tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS ~~~~~ }); ~ -!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: number; baz: {}; }>'. -!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; }'. +!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; } & ThisType<{ x: number; y: number; } & { bar: any; baz: any; }>'. +!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; }'. !!! error TS2345: Types of property 'computed' are incompatible. -!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: number; baz: {}; }>'. +!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: any; baz: any; }>'. !!! error TS2345: Types of property 'baz' are incompatible. !!! error TS2345: Type 'number' is not assignable to type '() => {}'. \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.js b/tests/baselines/reference/mappedTypeRecursiveInference.js index 5b7631818bc..914eb2f16b6 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.js +++ b/tests/baselines/reference/mappedTypeRecursiveInference.js @@ -4,7 +4,34 @@ declare let a: A; type Deep = { [K in keyof T]: Deep } declare function foo(deep: Deep): T; const out = foo(a); +out.a +out.a.a +out.a.a.a.a.a.a.a + + +interface B { [s: string]: B } +declare let b: B; +const oub = foo(b); +oub.b +oub.b.b +oub.b.a.n.a.n.a + +let xhr: XMLHttpRequest; +const out2 = foo(xhr); +out2.responseXML +out2.responseXML.activeElement.className.length //// [mappedTypeRecursiveInference.js] var out = foo(a); +out.a; +out.a.a; +out.a.a.a.a.a.a.a; +var oub = foo(b); +oub.b; +oub.b.b; +oub.b.a.n.a.n.a; +var xhr; +var out2 = foo(xhr); +out2.responseXML; +out2.responseXML.activeElement.className.length; diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.symbols b/tests/baselines/reference/mappedTypeRecursiveInference.symbols index a3fa3722551..59109f15f91 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.symbols +++ b/tests/baselines/reference/mappedTypeRecursiveInference.symbols @@ -30,3 +30,81 @@ const out = foo(a); >foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) >a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 1, 11)) +out.a +>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) + +out.a.a +>out.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) + +out.a.a.a.a.a.a.a +>out.a.a.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) +>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13)) + + +interface B { [s: string]: B } +>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17)) +>s : Symbol(s, Decl(mappedTypeRecursiveInference.ts, 10, 15)) +>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17)) + +declare let b: B; +>b : Symbol(b, Decl(mappedTypeRecursiveInference.ts, 11, 11)) +>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17)) + +const oub = foo(b); +>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5)) +>foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) +>b : Symbol(b, Decl(mappedTypeRecursiveInference.ts, 11, 11)) + +oub.b +>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5)) + +oub.b.b +>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5)) + +oub.b.a.n.a.n.a +>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5)) + +let xhr: XMLHttpRequest; +>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 17, 3)) +>XMLHttpRequest : Symbol(XMLHttpRequest, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +const out2 = foo(xhr); +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5)) +>foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45)) +>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 17, 3)) + +out2.responseXML +>out2.responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5)) +>responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) + +out2.responseXML.activeElement.className.length +>out2.responseXML.activeElement.className.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>out2.responseXML.activeElement.className : Symbol(className, Decl(lib.dom.d.ts, --, --)) +>out2.responseXML.activeElement : Symbol(activeElement, Decl(lib.dom.d.ts, --, --)) +>out2.responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) +>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5)) +>responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --)) +>activeElement : Symbol(activeElement, Decl(lib.dom.d.ts, --, --)) +>className : Symbol(className, Decl(lib.dom.d.ts, --, --)) +>length : Symbol(length, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/mappedTypeRecursiveInference.types b/tests/baselines/reference/mappedTypeRecursiveInference.types index 382135591d5..04995464f67 100644 --- a/tests/baselines/reference/mappedTypeRecursiveInference.types +++ b/tests/baselines/reference/mappedTypeRecursiveInference.types @@ -26,8 +26,106 @@ declare function foo(deep: Deep): T; >T : T const out = foo(a); ->out : { a: {}; } ->foo(a) : { a: {}; } +>out : { a: any; } +>foo(a) : { a: any; } >foo : (deep: Deep) => T >a : A +out.a +>out.a : { a: any; } +>out : { a: any; } +>a : { a: any; } + +out.a.a +>out.a.a : { a: any; } +>out.a : { a: any; } +>out : { a: any; } +>a : { a: any; } +>a : { a: any; } + +out.a.a.a.a.a.a.a +>out.a.a.a.a.a.a.a : { a: any; } +>out.a.a.a.a.a.a : { a: any; } +>out.a.a.a.a.a : { a: any; } +>out.a.a.a.a : { a: any; } +>out.a.a.a : { a: any; } +>out.a.a : { a: any; } +>out.a : { a: any; } +>out : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } +>a : { a: any; } + + +interface B { [s: string]: B } +>B : B +>s : string +>B : B + +declare let b: B; +>b : B +>B : B + +const oub = foo(b); +>oub : { [x: string]: any; } +>foo(b) : { [x: string]: any; } +>foo : (deep: Deep) => T +>b : B + +oub.b +>oub.b : { [x: string]: any; } +>oub : { [x: string]: any; } +>b : { [x: string]: any; } + +oub.b.b +>oub.b.b : { [x: string]: any; } +>oub.b : { [x: string]: any; } +>oub : { [x: string]: any; } +>b : { [x: string]: any; } +>b : { [x: string]: any; } + +oub.b.a.n.a.n.a +>oub.b.a.n.a.n.a : { [x: string]: any; } +>oub.b.a.n.a.n : { [x: string]: any; } +>oub.b.a.n.a : { [x: string]: any; } +>oub.b.a.n : { [x: string]: any; } +>oub.b.a : { [x: string]: any; } +>oub.b : { [x: string]: any; } +>oub : { [x: string]: any; } +>b : { [x: string]: any; } +>a : { [x: string]: any; } +>n : { [x: string]: any; } +>a : { [x: string]: any; } +>n : { [x: string]: any; } +>a : { [x: string]: any; } + +let xhr: XMLHttpRequest; +>xhr : XMLHttpRequest +>XMLHttpRequest : XMLHttpRequest + +const out2 = foo(xhr); +>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; } +>foo(xhr) : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; } +>foo : (deep: Deep) => T +>xhr : XMLHttpRequest + +out2.responseXML +>out2.responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; querySelector: any; querySelectorAll: any; createEvent: any; readonly children: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly childElementCount: any; readonly stylesheets: any; elementsFromPoint: any; } +>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; } +>responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; querySelector: any; querySelectorAll: any; createEvent: any; readonly children: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly childElementCount: any; readonly stylesheets: any; elementsFromPoint: any; } + +out2.responseXML.activeElement.className.length +>out2.responseXML.activeElement.className.length : { toString: any; toFixed: any; toExponential: any; toPrecision: any; valueOf: any; toLocaleString: any; } +>out2.responseXML.activeElement.className : { toString: any; charAt: any; charCodeAt: any; concat: any; indexOf: any; lastIndexOf: any; localeCompare: any; match: any; replace: any; search: any; slice: any; split: any; substring: any; toLowerCase: any; toLocaleLowerCase: any; toUpperCase: any; toLocaleUpperCase: any; trim: any; readonly length: any; substr: any; valueOf: any; [Symbol.iterator]: any; codePointAt: any; includes: any; endsWith: any; normalize: any; repeat: any; startsWith: any; anchor: any; big: any; blink: any; bold: any; fixed: any; fontcolor: any; fontsize: any; italics: any; link: any; small: any; strike: any; sub: any; sup: any; } +>out2.responseXML.activeElement : { readonly classList: any; className: any; readonly clientHeight: any; readonly clientLeft: any; readonly clientTop: any; readonly clientWidth: any; id: any; innerHTML: any; msContentZoomFactor: any; readonly msRegionOverflow: any; onariarequest: any; oncommand: any; ongotpointercapture: any; onlostpointercapture: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsgotpointercapture: any; onmsinertiastart: any; onmslostpointercapture: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; outerHTML: any; readonly prefix: any; readonly scrollHeight: any; scrollLeft: any; scrollTop: any; readonly scrollWidth: any; readonly tagName: any; readonly assignedSlot: any; slot: any; readonly shadowRoot: any; getAttribute: any; getAttributeNode: any; getAttributeNodeNS: any; getAttributeNS: any; getBoundingClientRect: any; getClientRects: any; getElementsByTagName: any; getElementsByTagNameNS: any; hasAttribute: any; hasAttributeNS: any; msGetRegionContent: any; msGetUntransformedBounds: any; msMatchesSelector: any; msReleasePointerCapture: any; msSetPointerCapture: any; msZoomTo: any; releasePointerCapture: any; removeAttribute: any; removeAttributeNode: any; removeAttributeNS: any; requestFullscreen: any; requestPointerLock: any; setAttribute: any; setAttributeNode: any; setAttributeNodeNS: any; setAttributeNS: any; setPointerCapture: any; webkitMatchesSelector: any; webkitRequestFullscreen: any; webkitRequestFullScreen: any; getElementsByClassName: any; matches: any; closest: any; scrollIntoView: any; scroll: any; scrollTo: any; scrollBy: any; insertAdjacentElement: any; insertAdjacentHTML: any; insertAdjacentText: any; attachShadow: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; readonly childElementCount: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly nextElementSibling: any; readonly previousElementSibling: any; querySelector: any; querySelectorAll: any; remove: any; readonly children: any; } +>out2.responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; querySelector: any; querySelectorAll: any; createEvent: any; readonly children: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly childElementCount: any; readonly stylesheets: any; elementsFromPoint: any; } +>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; } +>responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; querySelector: any; querySelectorAll: any; createEvent: any; readonly children: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly childElementCount: any; readonly stylesheets: any; elementsFromPoint: any; } +>activeElement : { readonly classList: any; className: any; readonly clientHeight: any; readonly clientLeft: any; readonly clientTop: any; readonly clientWidth: any; id: any; innerHTML: any; msContentZoomFactor: any; readonly msRegionOverflow: any; onariarequest: any; oncommand: any; ongotpointercapture: any; onlostpointercapture: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsgotpointercapture: any; onmsinertiastart: any; onmslostpointercapture: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; outerHTML: any; readonly prefix: any; readonly scrollHeight: any; scrollLeft: any; scrollTop: any; readonly scrollWidth: any; readonly tagName: any; readonly assignedSlot: any; slot: any; readonly shadowRoot: any; getAttribute: any; getAttributeNode: any; getAttributeNodeNS: any; getAttributeNS: any; getBoundingClientRect: any; getClientRects: any; getElementsByTagName: any; getElementsByTagNameNS: any; hasAttribute: any; hasAttributeNS: any; msGetRegionContent: any; msGetUntransformedBounds: any; msMatchesSelector: any; msReleasePointerCapture: any; msSetPointerCapture: any; msZoomTo: any; releasePointerCapture: any; removeAttribute: any; removeAttributeNode: any; removeAttributeNS: any; requestFullscreen: any; requestPointerLock: any; setAttribute: any; setAttributeNode: any; setAttributeNodeNS: any; setAttributeNS: any; setPointerCapture: any; webkitMatchesSelector: any; webkitRequestFullscreen: any; webkitRequestFullScreen: any; getElementsByClassName: any; matches: any; closest: any; scrollIntoView: any; scroll: any; scrollTo: any; scrollBy: any; insertAdjacentElement: any; insertAdjacentHTML: any; insertAdjacentText: any; attachShadow: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; readonly childElementCount: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly nextElementSibling: any; readonly previousElementSibling: any; querySelector: any; querySelectorAll: any; remove: any; readonly children: any; } +>className : { toString: any; charAt: any; charCodeAt: any; concat: any; indexOf: any; lastIndexOf: any; localeCompare: any; match: any; replace: any; search: any; slice: any; split: any; substring: any; toLowerCase: any; toLocaleLowerCase: any; toUpperCase: any; toLocaleUpperCase: any; trim: any; readonly length: any; substr: any; valueOf: any; [Symbol.iterator]: any; codePointAt: any; includes: any; endsWith: any; normalize: any; repeat: any; startsWith: any; anchor: any; big: any; blink: any; bold: any; fixed: any; fontcolor: any; fontsize: any; italics: any; link: any; small: any; strike: any; sub: any; sup: any; } +>length : { toString: any; toFixed: any; toExponential: any; toPrecision: any; valueOf: any; toLocaleString: any; } + diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index 2e51f73179d..f5d0e66ff3f 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -1,106 +1,38 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(11,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[keyof T]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(16,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[K]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(20,5): error TS2536: Type 'keyof U' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,5): error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'. - Type 'T[string]' is not assignable to type 'U[keyof U]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[keyof U]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,12): error TS2536: Type 'keyof U' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(25,5): error TS2536: Type 'K' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[K]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,12): error TS2536: Type 'K' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(30,5): error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'. - Type 'undefined' is not assignable to type 'T[string]'. - Type 'Partial[keyof T]' is not assignable to type 'T[string]'. - Type 'T[keyof T] | undefined' is not assignable to type 'T[string]'. - Type 'undefined' is not assignable to type 'T[string]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(35,5): error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. Type 'T[K] | undefined' is not assignable to type 'T[K]'. Type 'undefined' is not assignable to type 'T[K]'. - Type 'undefined' is not assignable to type 'T[string]'. - Type 'Partial[K]' is not assignable to type 'T[string]'. - Type 'T[K] | undefined' is not assignable to type 'T[string]'. - Type 'undefined' is not assignable to type 'T[string]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'. - Type 'undefined' is not assignable to type 'T[string]'. - Type 'Partial[keyof T]' is not assignable to type 'T[string]'. - Type 'U[keyof T] | undefined' is not assignable to type 'T[string]'. - Type 'undefined' is not assignable to type 'T[string]'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'Partial[keyof T]'. - Type 'T[string]' is not assignable to type 'Partial[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. - Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[keyof T]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. Type 'U[K] | undefined' is not assignable to type 'T[K]'. Type 'undefined' is not assignable to type 'T[K]'. - Type 'undefined' is not assignable to type 'T[string]'. - Type 'Partial[K]' is not assignable to type 'T[string]'. - Type 'U[K] | undefined' is not assignable to type 'T[string]'. - Type 'undefined' is not assignable to type 'T[string]'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'T[K]' is not assignable to type 'Partial[K]'. - Type 'T[string]' is not assignable to type 'Partial[K]'. - Type 'T[string]' is not assignable to type 'U[K] | undefined'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[K]' is not assignable to type 'U[K] | undefined'. - Type 'T[string]' is not assignable to type 'U[K] | undefined'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[K]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(51,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'Readonly[keyof T]'. - Type 'T[string]' is not assignable to type 'Readonly[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[keyof T]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'Readonly'. + Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2322: Type 'T[K]' is not assignable to type 'Readonly[K]'. - Type 'T[string]' is not assignable to type 'Readonly[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[K]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'Readonly'. + Type 'T[K]' is not assignable to type 'U[K]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(72,5): error TS2322: Type 'Partial' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(78,5): error TS2322: Type 'Partial' is not assignable to type 'Partial'. @@ -108,11 +40,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(88,5): error TS2 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(127,5): error TS2322: Type 'Partial' is not assignable to type 'Identity'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(143,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. - Type 'T[string]' is not assignable to type 'U[P]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[P]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(148,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. Type 'keyof U' is not assignable to type 'keyof T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(153,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: T[P]; }'. @@ -123,14 +51,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(163,5): error TS Type 'keyof T' is not assignable to type 'K'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. - Type 'T[string]' is not assignable to type 'U[P]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[P]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. -==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (30 errors) ==== +==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (28 errors) ==== function f1(x: T, k: keyof T) { return x[k]; } @@ -144,11 +68,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f4(x: T, y: U, k: K) { @@ -156,11 +76,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f5(x: T, y: U, k: keyof U) { @@ -170,11 +86,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof U]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2536: Type 'keyof U' cannot be used to index type 'T'. } @@ -186,11 +98,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2536: Type 'K' cannot be used to index type 'T'. } @@ -201,10 +109,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; } @@ -214,10 +118,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. !!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; } @@ -227,25 +127,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; // Error - ~~~~ -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'Partial[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'Partial[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f13(x: T, y: Partial, k: K) { @@ -254,25 +136,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. !!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; // Error - ~~~~ -!!! error TS2322: Type 'T[K]' is not assignable to type 'Partial[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'Partial[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f20(x: T, y: Readonly, k: keyof T) { @@ -294,14 +158,9 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'Readonly[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'Readonly[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'Readonly'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2542: Index signature in type 'Readonly' only permits reading. } @@ -311,14 +170,9 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'Readonly[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'Readonly[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'Readonly'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2542: Index signature in type 'Readonly' only permits reading. } @@ -409,11 +263,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. !!! error TS2322: Type 'T[P]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[P]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f72(x: { [P in keyof T]: T[P] }, y: { [P in keyof U]: U[P] }) { @@ -454,11 +304,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'. !!! error TS2322: Type 'T[P]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[P]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f80(t: T): Partial { diff --git a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt index 13618c926ef..8c95aa78fb7 100644 --- a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt +++ b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt @@ -1,13 +1,11 @@ -tests/cases/compiler/mismatchedGenericArguments1.ts(4,7): error TS2420: Class 'C' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => number' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. -tests/cases/compiler/mismatchedGenericArguments1.ts(10,7): error TS2420: Class 'C2' incorrectly implements interface 'IFoo'. - Types of property 'foo' are incompatible. - Type '(x: string) => number' is not assignable to type '(x: T) => T'. - Types of parameters 'x' and 'x' are incompatible. - Type 'T' is not assignable to type 'string'. +tests/cases/compiler/mismatchedGenericArguments1.ts(5,4): error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. + Type '(x: string) => number' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/compiler/mismatchedGenericArguments1.ts(11,4): error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo'. + Type '(x: string) => number' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. ==== tests/cases/compiler/mismatchedGenericArguments1.ts (2 errors) ==== @@ -15,25 +13,23 @@ tests/cases/compiler/mismatchedGenericArguments1.ts(10,7): error TS2420: Class ' foo(x: T): T; } class C implements IFoo { - ~ -!!! error TS2420: Class 'C' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => number' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): number { + ~~~ +!!! error TS2416: Property 'foo' in type 'C' is not assignable to the same property in base type 'IFoo'. +!!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. return null; } } class C2 implements IFoo { - ~~ -!!! error TS2420: Class 'C2' incorrectly implements interface 'IFoo'. -!!! error TS2420: Types of property 'foo' are incompatible. -!!! error TS2420: Type '(x: string) => number' is not assignable to type '(x: T) => T'. -!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): number { + ~~~ +!!! error TS2416: Property 'foo' in type 'C2' is not assignable to the same property in base type 'IFoo'. +!!! error TS2416: Type '(x: string) => number' is not assignable to type '(x: T) => T'. +!!! error TS2416: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2416: Type 'T' is not assignable to type 'string'. return null; } } diff --git a/tests/baselines/reference/missingArgument1.errors.txt b/tests/baselines/reference/missingArgument1.errors.txt index ba2bb0892f2..7530da802c8 100644 --- a/tests/baselines/reference/missingArgument1.errors.txt +++ b/tests/baselines/reference/missingArgument1.errors.txt @@ -10,7 +10,7 @@ tests/cases/compiler/missingArgument1.ts(1,8): error TS2304: Cannot find name 'b !!! error TS2304: Cannot find name 'foo'. ~ !!! error TS2304: Cannot find name 'a'. - + ~ !!! error TS1135: Argument expression expected. ~ !!! error TS2304: Cannot find name 'b'. \ No newline at end of file diff --git a/tests/baselines/reference/missingArgument1.js b/tests/baselines/reference/missingArgument1.js index eed0d9b11d6..94f78377e40 100644 --- a/tests/baselines/reference/missingArgument1.js +++ b/tests/baselines/reference/missingArgument1.js @@ -2,4 +2,4 @@ foo(a,,b); //// [missingArgument1.js] -foo(a, , b); +foo(a, b); diff --git a/tests/baselines/reference/missingArgument1.types b/tests/baselines/reference/missingArgument1.types index 4b362a76145..b4468f4b3f6 100644 --- a/tests/baselines/reference/missingArgument1.types +++ b/tests/baselines/reference/missingArgument1.types @@ -3,6 +3,5 @@ foo(a,,b); >foo(a,,b) : any >foo : any >a : any -> : undefined >b : any diff --git a/tests/baselines/reference/moduleAugmentationGlobal4.js b/tests/baselines/reference/moduleAugmentationGlobal4.js index a47e4c6673a..dd1c589e43b 100644 --- a/tests/baselines/reference/moduleAugmentationGlobal4.js +++ b/tests/baselines/reference/moduleAugmentationGlobal4.js @@ -36,7 +36,6 @@ declare global { } } export { }; -export {}; //// [f2.d.ts] declare global { interface Something { @@ -44,7 +43,6 @@ declare global { } } export { }; -export {}; //// [f3.d.ts] import "./f1"; import "./f2"; diff --git a/tests/baselines/reference/moduleAugmentationInAmbientModule1.js b/tests/baselines/reference/moduleAugmentationInAmbientModule1.js index 7bd3c93496c..fe6aabc0a5e 100644 --- a/tests/baselines/reference/moduleAugmentationInAmbientModule1.js +++ b/tests/baselines/reference/moduleAugmentationInAmbientModule1.js @@ -36,3 +36,4 @@ x.foo().x; //// [main.d.ts] /// +export {}; diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json index 3a87769891b..e852d58f2b3 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json @@ -3,7 +3,7 @@ "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", "File '/node_modules/foo/bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar@1.2.3'.", "File '/node_modules/foo/bar.ts' does not exist.", "File '/node_modules/foo/bar.tsx' does not exist.", "File '/node_modules/foo/bar.d.ts' does not exist.", @@ -13,7 +13,7 @@ "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'JavaScript'.", "File '/node_modules/foo/bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar@1.2.3'.", "File '/node_modules/foo/bar.js' does not exist.", "File '/node_modules/foo/bar.jsx' does not exist.", "File '/node_modules/foo/bar/index.js' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json index c28189a1f7d..19fe1f125bc 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json @@ -3,7 +3,7 @@ "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.", "File '/node_modules/foo/@bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar@1.2.3'.", "File '/node_modules/foo/@bar.ts' does not exist.", "File '/node_modules/foo/@bar.tsx' does not exist.", "File '/node_modules/foo/@bar.d.ts' does not exist.", @@ -13,7 +13,7 @@ "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'JavaScript'.", "File '/node_modules/foo/@bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar@1.2.3'.", "File '/node_modules/foo/@bar.js' does not exist.", "File '/node_modules/foo/@bar.jsx' does not exist.", "File '/node_modules/foo/@bar/index.js' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/multiImportExport.js b/tests/baselines/reference/multiImportExport.js index 01dc798bf1d..69276cbac9b 100644 --- a/tests/baselines/reference/multiImportExport.js +++ b/tests/baselines/reference/multiImportExport.js @@ -67,3 +67,4 @@ export = Math; //// [Drawing.d.ts] export import Math = require('./Math/Math'); //// [consumer.d.ts] +export {}; diff --git a/tests/baselines/reference/multipleInheritance.errors.txt b/tests/baselines/reference/multipleInheritance.errors.txt index 19ef1e755e3..c4a440d9a0e 100644 --- a/tests/baselines/reference/multipleInheritance.errors.txt +++ b/tests/baselines/reference/multipleInheritance.errors.txt @@ -1,9 +1,8 @@ tests/cases/compiler/multipleInheritance.ts(9,21): error TS1174: Classes can only extend a single class. tests/cases/compiler/multipleInheritance.ts(18,21): error TS1174: Classes can only extend a single class. -tests/cases/compiler/multipleInheritance.ts(34,7): error TS2415: Class 'Baad' incorrectly extends base class 'Good'. - Types of property 'g' are incompatible. - Type '(n: number) => number' is not assignable to type '() => number'. tests/cases/compiler/multipleInheritance.ts(35,12): error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. +tests/cases/compiler/multipleInheritance.ts(36,12): error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. + Type '(n: number) => number' is not assignable to type '() => number'. ==== tests/cases/compiler/multipleInheritance.ts (4 errors) ==== @@ -45,13 +44,12 @@ tests/cases/compiler/multipleInheritance.ts(35,12): error TS2425: Class 'Good' d } class Baad extends Good { - ~~~~ -!!! error TS2415: Class 'Baad' incorrectly extends base class 'Good'. -!!! error TS2415: Types of property 'g' are incompatible. -!!! error TS2415: Type '(n: number) => number' is not assignable to type '() => number'. public f(): number { return 0; } ~ !!! error TS2425: Class 'Good' defines instance member property 'f', but extended class 'Baad' defines it as instance member function. public g(n:number) { return 0; } + ~ +!!! error TS2416: Property 'g' in type 'Baad' is not assignable to the same property in base type 'Good'. +!!! error TS2416: Type '(n: number) => number' is not assignable to type '() => number'. } \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt new file mode 100644 index 00000000000..9ea0147978a --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(2,14): error TS6133: 'f' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(8,22): error TS6133: 'g' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(12,22): error TS6133: 'h' is declared but its value is never read. + + +==== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts (3 errors) ==== + namespace n { + function f() { + ~ +!!! error TS6133: 'f' is declared but its value is never read. + f; + } + + switch (0) { + case 0: + function g() { + ~ +!!! error TS6133: 'g' is declared but its value is never read. + g; + } + default: + function h() { + ~ +!!! error TS6133: 'h' is declared but its value is never read. + h; + } + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.js b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.js new file mode 100644 index 00000000000..2b33ed8c31d --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.js @@ -0,0 +1,36 @@ +//// [noUnusedLocals_selfReference_skipsBlockLocations.ts] +namespace n { + function f() { + f; + } + + switch (0) { + case 0: + function g() { + g; + } + default: + function h() { + h; + } + } +} + + +//// [noUnusedLocals_selfReference_skipsBlockLocations.js] +var n; +(function (n) { + function f() { + f; + } + switch (0) { + case 0: + function g() { + g; + } + default: + function h() { + h; + } + } +})(n || (n = {})); diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.symbols b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.symbols new file mode 100644 index 00000000000..7607caf3d7e --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts === +namespace n { +>n : Symbol(n, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 0)) + + function f() { +>f : Symbol(f, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 13)) + + f; +>f : Symbol(f, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 0, 13)) + } + + switch (0) { + case 0: + function g() { +>g : Symbol(g, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 6, 15)) + + g; +>g : Symbol(g, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 6, 15)) + } + default: + function h() { +>h : Symbol(h, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 10, 16)) + + h; +>h : Symbol(h, Decl(noUnusedLocals_selfReference_skipsBlockLocations.ts, 10, 16)) + } + } +} + diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.types b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.types new file mode 100644 index 00000000000..6675db4f1c3 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts === +namespace n { +>n : typeof n + + function f() { +>f : () => void + + f; +>f : () => void + } + + switch (0) { +>0 : 0 + + case 0: +>0 : 0 + + function g() { +>g : () => void + + g; +>g : () => void + } + default: + function h() { +>h : () => void + + h; +>h : () => void + } + } +} + diff --git a/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.errors.txt b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.errors.txt new file mode 100644 index 00000000000..9f95f4cfd2f --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts(4,13): error TS6133: '[x]' is declared but its value is never read. + + +==== tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts (1 errors) ==== + const x = Symbol("x"); + const y = Symbol("y"); + class C { + private [x]: number; + ~~~ +!!! error TS6133: '[x]' is declared but its value is never read. + private [y]: number; + m() { + this[x] = 0; // write-only + this[y]; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.js b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.js new file mode 100644 index 00000000000..6c5bf109b57 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.js @@ -0,0 +1,25 @@ +//// [noUnusedLocals_writeOnlyProperty_dynamicNames.ts] +const x = Symbol("x"); +const y = Symbol("y"); +class C { + private [x]: number; + private [y]: number; + m() { + this[x] = 0; // write-only + this[y]; + } +} + + +//// [noUnusedLocals_writeOnlyProperty_dynamicNames.js] +var x = Symbol("x"); +var y = Symbol("y"); +var C = /** @class */ (function () { + function C() { + } + C.prototype.m = function () { + this[x] = 0; // write-only + this[y]; + }; + return C; +}()); diff --git a/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.symbols b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.symbols new file mode 100644 index 00000000000..6a30e2a9fa9 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts === +const x = Symbol("x"); +>x : Symbol(x, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 0, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) + +const y = Symbol("y"); +>y : Symbol(y, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) + +class C { +>C : Symbol(C, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 22)) + + private [x]: number; +>x : Symbol(x, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 0, 5)) + + private [y]: number; +>y : Symbol(y, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 5)) + + m() { +>m : Symbol(C.m, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 4, 24)) + + this[x] = 0; // write-only +>this : Symbol(C, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 22)) +>x : Symbol(x, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 0, 5)) + + this[y]; +>this : Symbol(C, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 22)) +>y : Symbol(y, Decl(noUnusedLocals_writeOnlyProperty_dynamicNames.ts, 1, 5)) + } +} + diff --git a/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.types b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.types new file mode 100644 index 00000000000..7b173395a99 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_writeOnlyProperty_dynamicNames.types @@ -0,0 +1,39 @@ +=== tests/cases/compiler/noUnusedLocals_writeOnlyProperty_dynamicNames.ts === +const x = Symbol("x"); +>x : unique symbol +>Symbol("x") : unique symbol +>Symbol : SymbolConstructor +>"x" : "x" + +const y = Symbol("y"); +>y : unique symbol +>Symbol("y") : unique symbol +>Symbol : SymbolConstructor +>"y" : "y" + +class C { +>C : C + + private [x]: number; +>x : unique symbol + + private [y]: number; +>y : unique symbol + + m() { +>m : () => void + + this[x] = 0; // write-only +>this[x] = 0 : 0 +>this[x] : number +>this : this +>x : unique symbol +>0 : 0 + + this[y]; +>this[y] : number +>this : this +>y : unique symbol + } +} + diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt new file mode 100644 index 00000000000..56781157131 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt @@ -0,0 +1,67 @@ +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(3,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(6,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(9,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(12,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(15,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(18,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(21,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(24,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(27,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(30,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. + Type 'string' is not assignable to type 'number'. + + +==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts (10 errors) ==== + // test for #15371 + function f(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function g(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function h(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function i(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function j(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function k(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function o(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function l(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function m(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function n(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js new file mode 100644 index 00000000000..7a24345a94b --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js @@ -0,0 +1,67 @@ +//// [nonPrimitiveConstraintOfIndexAccessType.ts] +// test for #15371 +function f(s: string, tp: T[P]): void { + tp = s; +} +function g(s: string, tp: T[P]): void { + tp = s; +} +function h(s: string, tp: T[P]): void { + tp = s; +} +function i(s: string, tp: T[P]): void { + tp = s; +} +function j(s: string, tp: T[P]): void { + tp = s; +} +function k(s: string, tp: T[P]): void { + tp = s; +} +function o(s: string, tp: T[P]): void { + tp = s; +} +function l(s: string, tp: T[P]): void { + tp = s; +} +function m(s: string, tp: T[P]): void { + tp = s; +} +function n(s: string, tp: T[P]): void { + tp = s; +} + + +//// [nonPrimitiveConstraintOfIndexAccessType.js] +"use strict"; +// test for #15371 +function f(s, tp) { + tp = s; +} +function g(s, tp) { + tp = s; +} +function h(s, tp) { + tp = s; +} +function i(s, tp) { + tp = s; +} +function j(s, tp) { + tp = s; +} +function k(s, tp) { + tp = s; +} +function o(s, tp) { + tp = s; +} +function l(s, tp) { + tp = s; +} +function m(s, tp) { + tp = s; +} +function n(s, tp) { + tp = s; +} diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols new file mode 100644 index 00000000000..3ada1e3f3d1 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols @@ -0,0 +1,145 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts === +// test for #15371 +function f(s: string, tp: T[P]): void { +>f : Symbol(f, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 0, 0)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 48)) +} +function g(s: string, tp: T[P]): void { +>g : Symbol(g, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 3, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 26)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 46)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 56)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 26)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 56)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 46)) +} +function h(s: string, tp: T[P]): void { +>h : Symbol(h, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 6, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 31)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 51)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 61)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 31)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 61)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 51)) +} +function i(s: string, tp: T[P]): void { +>i : Symbol(i, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 9, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 26)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 46)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 56)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 26)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 56)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 46)) +} +function j(s: string, tp: T[P]): void { +>j : Symbol(j, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 12, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 27)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 47)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 57)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 27)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 57)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 47)) +} +function k(s: string, tp: T[P]): void { +>k : Symbol(k, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 15, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 48)) +} +function o(s: string, tp: T[P]): void { +>o : Symbol(o, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 18, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 48)) +} +function l(s: string, tp: T[P]): void { +>l : Symbol(l, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 21, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 24)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 44)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 54)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 24)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 54)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 44)) +} +function m(s: string, tp: T[P]): void { +>m : Symbol(m, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 24, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>a : Symbol(a, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 22)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 35)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 55)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 65)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 35)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 65)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 55)) +} +function n(s: string, tp: T[P]): void { +>n : Symbol(n, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 27, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 24)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 45)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 65)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 75)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 45)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 75)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 65)) +} + diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types new file mode 100644 index 00000000000..d5e8560d7cf --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types @@ -0,0 +1,156 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts === +// test for #15371 +function f(s: string, tp: T[P]): void { +>f : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function g(s: string, tp: T[P]): void { +>g : (s: string, tp: T[P]) => void +>T : T +>null : null +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function h(s: string, tp: T[P]): void { +>h : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function i(s: string, tp: T[P]): void { +>i : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function j(s: string, tp: T[P]): void { +>j : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function k(s: string, tp: T[P]): void { +>k : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function o(s: string, tp: T[P]): void { +>o : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function l(s: string, tp: T[P]): void { +>l : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function m(s: string, tp: T[P]): void { +>m : (s: string, tp: T[P]) => void +>T : T +>a : number +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function n(s: string, tp: T[P]): void { +>n : (s: string, tp: T[P]) => void +>T : T +>s : string +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} + diff --git a/tests/baselines/reference/nullableFunctionError.errors.txt b/tests/baselines/reference/nullableFunctionError.errors.txt new file mode 100644 index 00000000000..074afdaee4f --- /dev/null +++ b/tests/baselines/reference/nullableFunctionError.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/nullableFunctionError.ts(1,1): error TS2721: Cannot invoke an object which is possibly 'null'. +tests/cases/compiler/nullableFunctionError.ts(2,1): error TS2722: Cannot invoke an object which is possibly 'undefined'. +tests/cases/compiler/nullableFunctionError.ts(4,1): error TS2723: Cannot invoke an object which is possibly 'null' or 'undefined'. + + +==== tests/cases/compiler/nullableFunctionError.ts (3 errors) ==== + null(); + ~~~~ +!!! error TS2721: Cannot invoke an object which is possibly 'null'. + undefined(); + ~~~~~~~~~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. + let f: null | undefined; + f(); + ~ +!!! error TS2723: Cannot invoke an object which is possibly 'null' or 'undefined'. + \ No newline at end of file diff --git a/tests/baselines/reference/nullableFunctionError.js b/tests/baselines/reference/nullableFunctionError.js new file mode 100644 index 00000000000..a8b1f28c51a --- /dev/null +++ b/tests/baselines/reference/nullableFunctionError.js @@ -0,0 +1,12 @@ +//// [nullableFunctionError.ts] +null(); +undefined(); +let f: null | undefined; +f(); + + +//// [nullableFunctionError.js] +null(); +undefined(); +var f; +f(); diff --git a/tests/baselines/reference/nullableFunctionError.symbols b/tests/baselines/reference/nullableFunctionError.symbols new file mode 100644 index 00000000000..cb066bdb32d --- /dev/null +++ b/tests/baselines/reference/nullableFunctionError.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/nullableFunctionError.ts === +null(); +undefined(); +>undefined : Symbol(undefined) + +let f: null | undefined; +>f : Symbol(f, Decl(nullableFunctionError.ts, 2, 3)) + +f(); +>f : Symbol(f, Decl(nullableFunctionError.ts, 2, 3)) + diff --git a/tests/baselines/reference/nullableFunctionError.types b/tests/baselines/reference/nullableFunctionError.types new file mode 100644 index 00000000000..97697fbb564 --- /dev/null +++ b/tests/baselines/reference/nullableFunctionError.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/nullableFunctionError.ts === +null(); +>null() : any +>null : null + +undefined(); +>undefined() : any +>undefined : undefined + +let f: null | undefined; +>f : null | undefined +>null : null + +f(); +>f() : any +>f : null | undefined + diff --git a/tests/baselines/reference/objectRest.js b/tests/baselines/reference/objectRest.js index 3576ffb286c..c314377f807 100644 --- a/tests/baselines/reference/objectRest.js +++ b/tests/baselines/reference/objectRest.js @@ -85,10 +85,10 @@ var i = removable; var { removed } = i, removableRest2 = __rest(i, ["removed"]); let computed = 'b'; let computed2 = 'a'; -var _g = computed, stillNotGreat = o[_g], _h = computed2, soSo = o[_h], o = __rest(o, [typeof _g === "symbol" ? _g : _g + "", typeof _h === "symbol" ? _h : _h + ""]); -(_j = computed, stillNotGreat = o[_j], _k = computed2, soSo = o[_k], o = __rest(o, [typeof _j === "symbol" ? _j : _j + "", typeof _k === "symbol" ? _k : _k + ""])); +var _g = o, _h = computed, stillNotGreat = _g[_h], _j = computed2, soSo = _g[_j], o = __rest(_g, [typeof _h === "symbol" ? _h : _h + "", typeof _j === "symbol" ? _j : _j + ""]); +(_k = o, _l = computed, stillNotGreat = _k[_l], _m = computed2, soSo = _k[_m], o = __rest(_k, [typeof _l === "symbol" ? _l : _l + "", typeof _m === "symbol" ? _m : _m + ""])); var noContextualType = (_a) => { var { aNumber = 12 } = _a, notEmptyObject = __rest(_a, ["aNumber"]); return aNumber + notEmptyObject.anythingGoes; }; -var _d, _f, _j, _k; +var _d, _f, _k, _l, _m; diff --git a/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols b/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols index 773fb3f5760..558ec029790 100644 --- a/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols +++ b/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.symbols @@ -31,7 +31,7 @@ var r3 = c["a b"]; var r4 = c["~!@#$%^&*()_+{}|:'<>?\/.,`"]; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 26, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 39, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 51, 3)) >c : Symbol(c, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 8, 3)) ->"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(C["~!@#$%^&*()_+{}|:'<>?\/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 2, 20)) +>"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(C["~!@#$%^&*()_+{}|:'<>?/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 2, 20)) interface I { >I : Symbol(I, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 41)) @@ -63,7 +63,7 @@ var r3 = i["a b"]; var r4 = i["~!@#$%^&*()_+{}|:'<>?\/.,`"]; >r4 : Symbol(r4, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 13, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 26, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 39, 3), Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 51, 3)) >i : Symbol(i, Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 21, 3)) ->"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(I["~!@#$%^&*()_+{}|:'<>?\/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 17, 20)) +>"~!@#$%^&*()_+{}|:'<>?\/.,`" : Symbol(I["~!@#$%^&*()_+{}|:'<>?/.,`"], Decl(objectTypeWithStringNamedPropertyOfIllegalCharacters.ts, 17, 20)) var a: { diff --git a/tests/baselines/reference/parseErrorDoubleCommaInCall.errors.txt b/tests/baselines/reference/parseErrorDoubleCommaInCall.errors.txt new file mode 100644 index 00000000000..f209456d81f --- /dev/null +++ b/tests/baselines/reference/parseErrorDoubleCommaInCall.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/parseErrorDoubleCommaInCall.ts(2,10): error TS1136: Property assignment expected. + + +==== tests/cases/compiler/parseErrorDoubleCommaInCall.ts (1 errors) ==== + Boolean({ + x: 0,, + ~ +!!! error TS1136: Property assignment expected. + }); + \ No newline at end of file diff --git a/tests/baselines/reference/parseErrorDoubleCommaInCall.js b/tests/baselines/reference/parseErrorDoubleCommaInCall.js new file mode 100644 index 00000000000..f1a50cccfde --- /dev/null +++ b/tests/baselines/reference/parseErrorDoubleCommaInCall.js @@ -0,0 +1,10 @@ +//// [parseErrorDoubleCommaInCall.ts] +Boolean({ + x: 0,, +}); + + +//// [parseErrorDoubleCommaInCall.js] +Boolean({ + x: 0 +}); diff --git a/tests/baselines/reference/parseErrorDoubleCommaInCall.symbols b/tests/baselines/reference/parseErrorDoubleCommaInCall.symbols new file mode 100644 index 00000000000..fed8484d591 --- /dev/null +++ b/tests/baselines/reference/parseErrorDoubleCommaInCall.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/parseErrorDoubleCommaInCall.ts === +Boolean({ +>Boolean : Symbol(Boolean, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + x: 0,, +>x : Symbol(x, Decl(parseErrorDoubleCommaInCall.ts, 0, 9)) + +}); + diff --git a/tests/baselines/reference/parseErrorDoubleCommaInCall.types b/tests/baselines/reference/parseErrorDoubleCommaInCall.types new file mode 100644 index 00000000000..23197748490 --- /dev/null +++ b/tests/baselines/reference/parseErrorDoubleCommaInCall.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/parseErrorDoubleCommaInCall.ts === +Boolean({ +>Boolean({ x: 0,,}) : boolean +>Boolean : BooleanConstructor +>{ x: 0,,} : { x: number; } + + x: 0,, +>x : number +>0 : 0 + +}); + diff --git a/tests/baselines/reference/parserArrowFunctionExpression7.types b/tests/baselines/reference/parserArrowFunctionExpression7.types index 072a1548bd2..9edac3b8474 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression7.types +++ b/tests/baselines/reference/parserArrowFunctionExpression7.types @@ -1,10 +1,10 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression7.ts === ({ ->({ async m() { for (;;) { } }}) : { m(): Promise; } ->{ async m() { for (;;) { } }} : { m(): Promise; } +>({ async m() { for (;;) { } }}) : { m(): Promise; } +>{ async m() { for (;;) { } }} : { m(): Promise; } async m() { ->m : () => Promise +>m : () => Promise for (;;) { } diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList6.errors.txt b/tests/baselines/reference/parserErrorRecovery_ArgumentList6.errors.txt index 7562fee7936..215c8da0f4f 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList6.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList6.errors.txt @@ -1,10 +1,13 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts(1,1): error TS2304: Cannot find name 'Foo'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts(1,5): error TS1135: Argument expression expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts(1,6): error TS1005: ')' expected. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList6.ts (3 errors) ==== Foo(, ~~~ !!! error TS2304: Cannot find name 'Foo'. + ~ +!!! error TS1135: Argument expression expected. !!! error TS1005: ')' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList6.types b/tests/baselines/reference/parserErrorRecovery_ArgumentList6.types index 202483685d7..8dee378e0a9 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList6.types +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList6.types @@ -2,5 +2,4 @@ Foo(, >Foo(, : any >Foo : any -> : undefined diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.errors.txt b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.errors.txt index 3f4afaf930b..abe77ca9f1c 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.errors.txt @@ -1,13 +1,16 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts(1,1): error TS2304: Cannot find name 'Foo'. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts(1,5): error TS2304: Cannot find name 'a'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts(1,7): error TS1135: Argument expression expected. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts(1,8): error TS1005: ')' expected. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList7.ts (4 errors) ==== Foo(a,, ~~~ !!! error TS2304: Cannot find name 'Foo'. ~ !!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS1135: Argument expression expected. !!! error TS1005: ')' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.js b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.js index 94eba9445e9..dfe0f58332f 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.js +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.js @@ -2,4 +2,4 @@ Foo(a,, //// [parserErrorRecovery_ArgumentList7.js] -Foo(a, ); +Foo(a); diff --git a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.types b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.types index 9de43329a13..ca95e4563e1 100644 --- a/tests/baselines/reference/parserErrorRecovery_ArgumentList7.types +++ b/tests/baselines/reference/parserErrorRecovery_ArgumentList7.types @@ -3,5 +3,4 @@ Foo(a,, >Foo(a,, : any >Foo : any >a : any -> : undefined diff --git a/tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt b/tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt index f03b87ba947..3c94d3bd0b8 100644 --- a/tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt +++ b/tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/index.ts(2,1): error TS1005: '}' expected. +tests/cases/compiler/index.ts:2:1 - error TS1005: '}' expected. 2    diff --git a/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt b/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt index 88801e06dfd..f901d08b462 100644 --- a/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt +++ b/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt @@ -1,14 +1,11 @@ tests/cases/compiler/privacyCheckTypeOfFunction.ts(3,22): error TS4025: Exported variable 'x' has or is using private name 'foo'. -tests/cases/compiler/privacyCheckTypeOfFunction.ts(4,12): error TS4025: Exported variable 'b' has or is using private name 'foo'. -==== tests/cases/compiler/privacyCheckTypeOfFunction.ts (2 errors) ==== +==== tests/cases/compiler/privacyCheckTypeOfFunction.ts (1 errors) ==== function foo() { } export var x: typeof foo; ~~~ !!! error TS4025: Exported variable 'x' has or is using private name 'foo'. export var b = foo; - ~ -!!! error TS4025: Exported variable 'b' has or is using private name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/quickInfoDisplayPartsInternalModuleAlias.baseline b/tests/baselines/reference/quickInfoDisplayPartsInternalModuleAlias.baseline new file mode 100644 index 00000000000..c476abad356 --- /dev/null +++ b/tests/baselines/reference/quickInfoDisplayPartsInternalModuleAlias.baseline @@ -0,0 +1,722 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 66 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "", + "textSpan": { + "start": 66, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a1", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a1", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 82 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "", + "textSpan": { + "start": 82, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a1", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a1", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 104 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "", + "textSpan": { + "start": 104, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a2", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a2", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "m1", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 123 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "", + "textSpan": { + "start": 123, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a2", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "a2", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "m1", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 149 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "export", + "textSpan": { + "start": 149, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a3", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a3", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 165 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "export", + "textSpan": { + "start": 165, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a3", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a3", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 194 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "export", + "textSpan": { + "start": 194, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a4", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a4", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "m1", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsInternalModuleAlias.ts", + "position": 213 + }, + "quickInfo": { + "kind": "alias", + "kindModifiers": "export", + "textSpan": { + "start": 213, + "length": 2 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "alias", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "namespace", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a4", + "kind": "aliasName" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "import", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m2", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "a4", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "m", + "kind": "moduleName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "m1", + "kind": "moduleName" + } + ], + "documentation": [], + "tags": [] + } + } +] \ No newline at end of file diff --git a/tests/baselines/reference/quickInfoDisplayPartsLiteralLikeNames01.baseline b/tests/baselines/reference/quickInfoDisplayPartsLiteralLikeNames01.baseline index 39ab90e8e09..1d2d8216808 100644 --- a/tests/baselines/reference/quickInfoDisplayPartsLiteralLikeNames01.baseline +++ b/tests/baselines/reference/quickInfoDisplayPartsLiteralLikeNames01.baseline @@ -38,7 +38,7 @@ }, { "text": "1", - "kind": "methodName" + "kind": "stringLiteral" }, { "text": "]", @@ -310,7 +310,7 @@ }, { "text": "1", - "kind": "methodName" + "kind": "stringLiteral" }, { "text": "]", @@ -380,7 +380,7 @@ }, { "text": "1", - "kind": "methodName" + "kind": "stringLiteral" }, { "text": "]", diff --git a/tests/baselines/reference/quickInfoJsDocTags.baseline b/tests/baselines/reference/quickInfoJsDocTags.baseline index ba225209760..56f190b4446 100644 --- a/tests/baselines/reference/quickInfoJsDocTags.baseline +++ b/tests/baselines/reference/quickInfoJsDocTags.baseline @@ -63,7 +63,7 @@ ], "documentation": [ { - "text": "Doc{T} A template", + "text": "DocT} A template", "kind": "text" } ], @@ -82,7 +82,7 @@ }, { "name": "typedef", - "text": "NumOrStr " + "text": "NumOrStr" }, { "name": "property", diff --git a/tests/baselines/reference/recursiveMappedTypes.errors.txt b/tests/baselines/reference/recursiveMappedTypes.errors.txt index 440825f5319..8279f4f60a6 100644 --- a/tests/baselines/reference/recursiveMappedTypes.errors.txt +++ b/tests/baselines/reference/recursiveMappedTypes.errors.txt @@ -1,25 +1,34 @@ tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(3,6): error TS2456: Type alias 'Recurse' circularly references itself. +tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(4,11): error TS2313: Type parameter 'K' has a circular constraint. tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(7,6): error TS2456: Type alias 'Recurse1' circularly references itself. +tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(8,11): error TS2313: Type parameter 'K' has a circular constraint. tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(11,6): error TS2456: Type alias 'Recurse2' circularly references itself. +tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(12,11): error TS2313: Type parameter 'K' has a circular constraint. -==== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts (3 errors) ==== +==== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts (6 errors) ==== // Recursive mapped types simply appear empty type Recurse = { ~~~~~~~ !!! error TS2456: Type alias 'Recurse' circularly references itself. [K in keyof Recurse]: Recurse[K] + ~~~~~~~~~~~~~ +!!! error TS2313: Type parameter 'K' has a circular constraint. } type Recurse1 = { ~~~~~~~~ !!! error TS2456: Type alias 'Recurse1' circularly references itself. [K in keyof Recurse2]: Recurse2[K] + ~~~~~~~~~~~~~~ +!!! error TS2313: Type parameter 'K' has a circular constraint. } type Recurse2 = { ~~~~~~~~ !!! error TS2456: Type alias 'Recurse2' circularly references itself. [K in keyof Recurse1]: Recurse1[K] + ~~~~~~~~~~~~~~ +!!! error TS2313: Type parameter 'K' has a circular constraint. } \ No newline at end of file diff --git a/tests/baselines/reference/recursiveTypeRelations.types b/tests/baselines/reference/recursiveTypeRelations.types index 636e4db0c87..ce6d007d066 100644 --- a/tests/baselines/reference/recursiveTypeRelations.types +++ b/tests/baselines/reference/recursiveTypeRelations.types @@ -17,7 +17,7 @@ class Query> { >A : A multiply>(x: B): Query; ->multiply : (x: B) => Query +>multiply : (x: B) => Query >B : B >Attributes : { [Key in Keys]: string; } >B : B diff --git a/tests/baselines/reference/requiredInitializedParameter2.errors.txt b/tests/baselines/reference/requiredInitializedParameter2.errors.txt index 5dcec536e1b..278d5c0f359 100644 --- a/tests/baselines/reference/requiredInitializedParameter2.errors.txt +++ b/tests/baselines/reference/requiredInitializedParameter2.errors.txt @@ -1,6 +1,5 @@ -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(6,5): error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type 'I1'. + Type '(a: number, b: any) => void' is not assignable to type '() => any'. ==== tests/cases/compiler/requiredInitializedParameter2.ts (1 errors) ==== @@ -9,9 +8,8 @@ tests/cases/compiler/requiredInitializedParameter2.ts(5,7): error TS2420: Class } 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) { } + ~~~~~~ +!!! error TS2416: Property 'method' in type 'C1' is not assignable to the same property in base type 'I1'. +!!! error TS2416: Type '(a: number, b: any) => void' is not assignable to type '() => any'. } \ No newline at end of file diff --git a/tests/baselines/reference/shorthand-property-es5-es6.js b/tests/baselines/reference/shorthand-property-es5-es6.js index 671ce39795c..814d9cd2efd 100644 --- a/tests/baselines/reference/shorthand-property-es5-es6.js +++ b/tests/baselines/reference/shorthand-property-es5-es6.js @@ -11,3 +11,4 @@ var bar = { foo: foo, baz: baz }; //// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/shorthand-property-es6-amd.js b/tests/baselines/reference/shorthand-property-es6-amd.js index 9469357eea2..35d92784173 100644 --- a/tests/baselines/reference/shorthand-property-es6-amd.js +++ b/tests/baselines/reference/shorthand-property-es6-amd.js @@ -14,3 +14,4 @@ define(["require", "exports", "./foo"], function (require, exports, foo_1) { //// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/shorthand-property-es6-es6.js b/tests/baselines/reference/shorthand-property-es6-es6.js index 42c80db10a0..4800de59b7e 100644 --- a/tests/baselines/reference/shorthand-property-es6-es6.js +++ b/tests/baselines/reference/shorthand-property-es6-es6.js @@ -11,3 +11,4 @@ const bar = { foo, baz }; //// [test.d.ts] +export {}; diff --git a/tests/baselines/reference/strictFunctionTypes1.js b/tests/baselines/reference/strictFunctionTypes1.js index e802c443561..94ee06f88f8 100644 --- a/tests/baselines/reference/strictFunctionTypes1.js +++ b/tests/baselines/reference/strictFunctionTypes1.js @@ -15,6 +15,16 @@ const x1 = f1(fo, fs); // (x: string) => void const x2 = f2("abc", fo, fs); // "abc" const x3 = f3("abc", fo, fx); // "abc" | "def" const x4 = f4(fo, fs); // Func + +declare const never: never; + +const x10 = f2(never, fo, fs); // string +const x11 = f3(never, fo, fx); // "def" + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +let x = foo([]); // never //// [strictFunctionTypes1.js] @@ -23,6 +33,9 @@ var x1 = f1(fo, fs); // (x: string) => void var x2 = f2("abc", fo, fs); // "abc" var x3 = f3("abc", fo, fx); // "abc" | "def" var x4 = f4(fo, fs); // Func +var x10 = f2(never, fo, fs); // string +var x11 = f3(never, fo, fx); // "def" +var x = foo([]); // never //// [strictFunctionTypes1.d.ts] @@ -40,3 +53,8 @@ declare const x1: (x: string) => void; declare const x2 = "abc"; declare const x3: string; declare const x4: Func; +declare const never: never; +declare const x10: string; +declare const x11: "def"; +declare function foo(a: ReadonlyArray): T; +declare let x: never; diff --git a/tests/baselines/reference/strictFunctionTypes1.symbols b/tests/baselines/reference/strictFunctionTypes1.symbols index 70253411201..715ea287734 100644 --- a/tests/baselines/reference/strictFunctionTypes1.symbols +++ b/tests/baselines/reference/strictFunctionTypes1.symbols @@ -94,3 +94,34 @@ const x4 = f4(fo, fs); // Func >fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) >fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) +declare const never: never; +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) + +const x10 = f2(never, fo, fs); // string +>x10 : Symbol(x10, Decl(strictFunctionTypes1.ts, 19, 5)) +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 0, 79)) +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) + +const x11 = f3(never, fo, fx); // "def" +>x11 : Symbol(x11, Decl(strictFunctionTypes1.ts, 20, 5)) +>f3 : Symbol(f3, Decl(strictFunctionTypes1.ts, 1, 74)) +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fx : Symbol(fx, Decl(strictFunctionTypes1.ts, 9, 37)) + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +>foo : Symbol(foo, Decl(strictFunctionTypes1.ts, 20, 30)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) +>a : Symbol(a, Decl(strictFunctionTypes1.ts, 24, 24)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) + +let x = foo([]); // never +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 25, 3)) +>foo : Symbol(foo, Decl(strictFunctionTypes1.ts, 20, 30)) + diff --git a/tests/baselines/reference/strictFunctionTypes1.types b/tests/baselines/reference/strictFunctionTypes1.types index 9701d78cff0..b915e0b5f6b 100644 --- a/tests/baselines/reference/strictFunctionTypes1.types +++ b/tests/baselines/reference/strictFunctionTypes1.types @@ -100,3 +100,38 @@ const x4 = f4(fo, fs); // Func >fo : (x: Object) => void >fs : (x: string) => void +declare const never: never; +>never : never + +const x10 = f2(never, fo, fs); // string +>x10 : string +>f2(never, fo, fs) : string +>f2 : (obj: T, f1: (x: T) => void, f2: (x: T) => void) => T +>never : never +>fo : (x: Object) => void +>fs : (x: string) => void + +const x11 = f3(never, fo, fx); // "def" +>x11 : "def" +>f3(never, fo, fx) : "def" +>f3 : (obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void) => T +>never : never +>fo : (x: Object) => void +>fx : (f: (x: "def") => void) => void + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +>foo : (a: ReadonlyArray) => T +>T : T +>a : ReadonlyArray +>ReadonlyArray : ReadonlyArray +>T : T +>T : T + +let x = foo([]); // never +>x : never +>foo([]) : never +>foo : (a: ReadonlyArray) => T +>[] : never[] + diff --git a/tests/baselines/reference/subtypesOfTypeParameter.errors.txt b/tests/baselines/reference/subtypesOfTypeParameter.errors.txt index 14e2275cbf9..8983c26e153 100644 --- a/tests/baselines/reference/subtypesOfTypeParameter.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameter.errors.txt @@ -1,6 +1,5 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts(7,7): error TS2415: Class 'D1' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts(8,5): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'C3'. + Type 'U' is not assignable to type 'T'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameter.ts (1 errors) ==== @@ -11,11 +10,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D1 extends C3 { - ~~ -!!! error TS2415: Class 'D1' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. } function f1(x: T, y: U) { diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt index bd7bbeb007e..cff11049787 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt @@ -1,47 +1,37 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(17,7): error TS2415: Class 'D3' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'C3'. + Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(48,7): error TS2415: Class 'D8' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. - Type 'V' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(65,7): error TS2415: Class 'D11' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'C3'. + Type 'U' is not assignable to type 'T'. Type 'V' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'C3'. + Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(70,7): error TS2415: Class 'D12' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'C3'. + Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(110,7): error TS2415: Class 'D19' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. - Type 'V' is not assignable to type 'T'. - Type 'Date' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(132,7): error TS2415: Class 'D23' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'C3'. + Type 'U' is not assignable to type 'T'. Type 'V' is not assignable to type 'T'. Type 'Date' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(137,7): error TS2415: Class 'D24' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'U'. - Type 'Date' is not assignable to type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(154,7): error TS2415: Class 'D27' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'C3'. + Type 'V' is not assignable to type 'T'. Type 'Date' is not assignable to type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(159,7): error TS2415: Class 'D28' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'C3'. + Type 'V' is not assignable to type 'U'. Type 'Date' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'C3'. + Type 'Date' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'C3'. + Type 'Date' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(164,7): error TS2415: Class 'D29' incorrectly extends base class 'C3'. - Types of property 'foo' are incompatible. - Type 'Date' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'C3'. + Type 'Date' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. @@ -63,12 +53,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D3 extends C3 { - ~~ -!!! error TS2415: Class 'D3' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. [x: string]: T; foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } @@ -100,13 +89,12 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf // test if U is a subtype of T, U, V // only a subtype of V and itself class D8 extends C3 { - ~~ -!!! error TS2415: Class 'D8' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'V' is not assignable to type 'T'. [x: string]: T; foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } @@ -124,23 +112,21 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf // test if V is a subtype of T, U, V // only a subtype of itself class D11 extends C3 { - ~~~ -!!! error TS2415: Class 'D11' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'T'. [x: string]: T; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } class D12 extends C3 { - ~~~ -!!! error TS2415: Class 'D12' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'U'. [x: string]: U; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } @@ -181,14 +167,13 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D19 extends C3 { - ~~~ -!!! error TS2415: Class 'D19' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'V' is not assignable to type 'T'. -!!! error TS2415: Type 'Date' is not assignable to type 'T'. [x: string]: T; foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. +!!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } @@ -211,25 +196,23 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D23 extends C3 { - ~~~ -!!! error TS2415: Class 'D23' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'T'. -!!! error TS2415: Type 'Date' is not assignable to type 'T'. [x: string]: T; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. +!!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } class D24 extends C3 { - ~~~ -!!! error TS2415: Class 'D24' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'U'. -!!! error TS2415: Type 'Date' is not assignable to type 'U'. [x: string]: U; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. +!!! error TS2416: Type 'Date' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } @@ -247,34 +230,31 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D27 extends C3 { - ~~~ -!!! error TS2415: Class 'D27' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'Date' is not assignable to type 'T'. [x: string]: T; foo: Date; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'Date' is not assignable to type 'T'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. } class D28 extends C3 { - ~~~ -!!! error TS2415: Class 'D28' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'Date' is not assignable to type 'U'. [x: string]: U; foo: Date; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'Date' is not assignable to type 'U'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. } class D29 extends C3 { - ~~~ -!!! error TS2415: Class 'D29' incorrectly extends base class 'C3'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'Date' is not assignable to type 'V'. [x: string]: V; foo: Date; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'C3'. +!!! error TS2416: Type 'Date' is not assignable to type 'V'. ~~~~~~~~~~ !!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. } \ No newline at end of file diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt index 7b3d706606d..ad85188fb4d 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt @@ -1,24 +1,19 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(45,7): error TS2415: Class 'D3' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'B1'. + Type 'V' is not assignable to type 'Foo'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(55,7): error TS2415: Class 'D5' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'B1'. + Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(60,7): error TS2415: Class 'D6' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'B1'. + Type 'V' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(65,7): error TS2415: Class 'D7' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'B1'. + Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(75,7): error TS2415: Class 'D9' incorrectly extends base class 'B1'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'B1'. + Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. @@ -68,12 +63,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D3 extends B1 { - ~~ -!!! error TS2415: Class 'D3' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'Foo'. [x: string]: Foo; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'B1'. +!!! error TS2416: Type 'V' is not assignable to type 'Foo'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. } @@ -84,36 +78,33 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D5 extends B1 { - ~~ -!!! error TS2415: Class 'D5' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: U; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'B1'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } class D6 extends B1 { - ~~ -!!! error TS2415: Class 'D6' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'T'. [x: string]: T; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'B1'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } class D7 extends B1 { - ~~ -!!! error TS2415: Class 'D7' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: T; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'B1'. +!!! error TS2416: Type 'T' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. } @@ -124,12 +115,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D9 extends B1 { - ~~ -!!! error TS2415: Class 'D9' incorrectly extends base class 'B1'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'U'. [x: string]: U; foo: V; // error + ~~~ +!!! error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'B1'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. ~~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } \ No newline at end of file diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt index a7f9d3fad7f..c5adf758728 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt @@ -1,74 +1,62 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(66,11): error TS2415: Class 'D2' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'Base'. + Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(71,11): error TS2415: Class 'D3' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base'. + Type 'V' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(76,11): error TS2415: Class 'D4' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'Base'. + Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(86,11): error TS2415: Class 'D6' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base'. + Type 'V' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(91,11): error TS2415: Class 'D7' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'V'. - Type 'Foo' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base'. + Type 'T' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(96,11): error TS2415: Class 'D8' incorrectly extends base class 'Base'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'V'. - Type 'Foo' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base'. + Type 'U' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(113,11): error TS2415: Class 'D1' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'U' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(115,9): error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Base2'. + Type 'T' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'U' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(120,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(123,11): error TS2415: Class 'D3' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'V' is not assignable to type 'T'. - Type 'Foo' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base2'. + Type 'V' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'V' is not assignable to type 'T'. + Type 'Foo' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(130,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(133,11): error TS2415: Class 'D5' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'T' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(138,11): error TS2415: Class 'D6' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'V' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'V' is not assignable to type 'U'. - Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(135,9): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Base2'. + Type 'U' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'T' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base2'. + Type 'V' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'V' is not assignable to type 'U'. + Type 'Foo' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(143,11): error TS2415: Class 'D7' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'T' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'U' is not assignable to type 'V'. - Type 'Foo' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base2'. + Type 'T' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'U' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(148,11): error TS2415: Class 'D8' incorrectly extends base class 'Base2'. - Types of property 'foo' are incompatible. - Type 'U' is not assignable to type 'Foo'. - Type 'Foo' is not assignable to type 'Foo'. - Type 'T' is not assignable to type 'V'. - Type 'Foo' is not assignable to type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base2'. + Type 'U' is not assignable to type 'Foo'. + Type 'Foo' is not assignable to type 'Foo'. + Type 'T' is not assignable to type 'V'. + Type 'Foo' is not assignable to type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. @@ -139,37 +127,34 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D2, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D2' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: U + ~~~ +!!! error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. } class D3, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D3' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: V + ~~~ +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } class D4, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D4' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: T + ~~~ +!!! error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'T' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. } @@ -180,37 +165,34 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D6, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D6' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: V + ~~~ +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } class D7, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D7' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'V'. -!!! error TS2415: Type 'Foo' is not assignable to type 'V'. [x: string]: V; foo: T + ~~~ +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'T' is not assignable to type 'V'. +!!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. } class D8, U extends Foo, V extends Foo> extends Base { - ~~ -!!! error TS2415: Class 'D8' incorrectly extends base class 'Base'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'V'. -!!! error TS2415: Type 'Foo' is not assignable to type 'V'. [x: string]: V; foo: U + ~~~ +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type 'U' is not assignable to type 'V'. +!!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. } @@ -228,15 +210,14 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D1, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D1' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'U' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: T + ~~~ +!!! error TS2416: Property 'foo' in type 'D1' is not assignable to the same property in base type 'Base2'. +!!! error TS2416: Type 'T' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'U' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. } class D2, U extends Foo, V extends Foo> extends Base2 { @@ -247,15 +228,14 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D3, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D3' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'V' is not assignable to type 'T'. -!!! error TS2415: Type 'Foo' is not assignable to type 'T'. [x: string]: T; foo: V + ~~~ +!!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base2'. +!!! error TS2416: Type 'V' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'V' is not assignable to type 'T'. +!!! error TS2416: Type 'Foo' is not assignable to type 'T'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. } @@ -268,55 +248,51 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf } class D5, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D5' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'T' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: U + ~~~ +!!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Base2'. +!!! error TS2416: Type 'U' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'T' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. } class D6, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D6' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'V' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'V' is not assignable to type 'U'. -!!! error TS2415: Type 'Foo' is not assignable to type 'U'. [x: string]: U; foo: V + ~~~ +!!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base2'. +!!! error TS2416: Type 'V' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'V' is not assignable to type 'U'. +!!! error TS2416: Type 'Foo' is not assignable to type 'U'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. } class D7, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D7' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'T' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'U' is not assignable to type 'V'. -!!! error TS2415: Type 'Foo' is not assignable to type 'V'. [x: string]: V; foo: T + ~~~ +!!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base2'. +!!! error TS2416: Type 'T' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'U' is not assignable to type 'V'. +!!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. } class D8, U extends Foo, V extends Foo> extends Base2 { - ~~ -!!! error TS2415: Class 'D8' incorrectly extends base class 'Base2'. -!!! error TS2415: Types of property 'foo' are incompatible. -!!! error TS2415: Type 'U' is not assignable to type 'Foo'. -!!! error TS2415: Type 'Foo' is not assignable to type 'Foo'. -!!! error TS2415: Type 'T' is not assignable to type 'V'. -!!! error TS2415: Type 'Foo' is not assignable to type 'V'. [x: string]: V; foo: U + ~~~ +!!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base2'. +!!! error TS2416: Type 'U' is not assignable to type 'Foo'. +!!! error TS2416: Type 'Foo' is not assignable to type 'Foo'. +!!! error TS2416: Type 'T' is not assignable to type 'V'. +!!! error TS2416: Type 'Foo' is not assignable to type 'V'. ~~~~~~ !!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. } diff --git a/tests/baselines/reference/subtypingWithObjectMembers.errors.txt b/tests/baselines/reference/subtypingWithObjectMembers.errors.txt index a5d4152b451..044e4ee0f2b 100644 --- a/tests/baselines/reference/subtypingWithObjectMembers.errors.txt +++ b/tests/baselines/reference/subtypingWithObjectMembers.errors.txt @@ -1,21 +1,15 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(12,7): error TS2415: Class 'B' incorrectly extends base class 'A'. - Types of property 'bar' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(22,7): error TS2415: Class 'B2' incorrectly extends base class 'A2'. - Types of property '2.0' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(32,7): error TS2415: Class 'B3' incorrectly extends base class 'A3'. - Types of property ''2.0'' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(43,11): error TS2415: Class 'B' incorrectly extends base class 'A'. - Types of property 'bar' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(53,11): error TS2415: Class 'B2' incorrectly extends base class 'A2'. - Types of property '2.0' are incompatible. - Type 'string' is not assignable to type 'Base'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(63,11): error TS2415: Class 'B3' incorrectly extends base class 'A3'. - Types of property ''2.0'' are incompatible. - Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(14,5): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(24,5): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(34,5): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(45,9): error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(55,9): error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts(65,9): error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. + Type 'string' is not assignable to type 'Base'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithObjectMembers.ts (6 errors) ==== @@ -31,12 +25,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B extends A { - ~ -!!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Types of property 'bar' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. foo: Derived; // ok bar: string; // error + ~~~ +!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } class A2 { @@ -45,12 +38,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B2 extends A2 { - ~~ -!!! error TS2415: Class 'B2' incorrectly extends base class 'A2'. -!!! error TS2415: Types of property '2.0' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. 1: Derived; // ok 2: string; // error + ~ +!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } class A3 { @@ -59,12 +51,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B3 extends A3 { - ~~ -!!! error TS2415: Class 'B3' incorrectly extends base class 'A3'. -!!! error TS2415: Types of property ''2.0'' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. '1': Derived; // ok '2.0': string; // error + ~~~~~ +!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } module TwoLevels { @@ -74,12 +65,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B extends A { - ~ -!!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Types of property 'bar' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. foo: Derived2; // ok bar: string; // error + ~~~ +!!! error TS2416: Property 'bar' in type 'B' is not assignable to the same property in base type 'A'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } class A2 { @@ -88,12 +78,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B2 extends A2 { - ~~ -!!! error TS2415: Class 'B2' incorrectly extends base class 'A2'. -!!! error TS2415: Types of property '2.0' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. 1: Derived2; // ok 2: string; // error + ~ +!!! error TS2416: Property '2' in type 'B2' is not assignable to the same property in base type 'A2'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } class A3 { @@ -102,11 +91,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } class B3 extends A3 { - ~~ -!!! error TS2415: Class 'B3' incorrectly extends base class 'A3'. -!!! error TS2415: Types of property ''2.0'' are incompatible. -!!! error TS2415: Type 'string' is not assignable to type 'Base'. '1': Derived2; // ok '2.0': string; // error + ~~~~~ +!!! error TS2416: Property '2.0' in type 'B3' is not assignable to the same property in base type 'A3'. +!!! error TS2416: Type 'string' is not assignable to type 'Base'. } } \ No newline at end of file diff --git a/tests/baselines/reference/superAccess2.js b/tests/baselines/reference/superAccess2.js index d3aac217e22..de755361a16 100644 --- a/tests/baselines/reference/superAccess2.js +++ b/tests/baselines/reference/superAccess2.js @@ -35,7 +35,6 @@ var __extends = (this && this.__extends) || (function () { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); -var _this = this; var P = /** @class */ (function () { function P() { } diff --git a/tests/baselines/reference/superAccessCastedCall.js b/tests/baselines/reference/superAccessCastedCall.js new file mode 100644 index 00000000000..a4583b3e710 --- /dev/null +++ b/tests/baselines/reference/superAccessCastedCall.js @@ -0,0 +1,54 @@ +//// [superAccessCastedCall.ts] +class Foo { + bar(): void {} +} + +class Bar extends Foo { + x: Number; + + constructor() { + super(); + this.x = 2; + } + + bar() { + super.bar(); + (super.bar as any)(); + } +} + +let b = new Bar(); +b.bar() + +//// [superAccessCastedCall.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var Foo = /** @class */ (function () { + function Foo() { + } + Foo.prototype.bar = function () { }; + return Foo; +}()); +var Bar = /** @class */ (function (_super) { + __extends(Bar, _super); + function Bar() { + var _this = _super.call(this) || this; + _this.x = 2; + return _this; + } + Bar.prototype.bar = function () { + _super.prototype.bar.call(this); + _super.prototype.bar.call(this); + }; + return Bar; +}(Foo)); +var b = new Bar(); +b.bar(); diff --git a/tests/baselines/reference/superAccessCastedCall.symbols b/tests/baselines/reference/superAccessCastedCall.symbols new file mode 100644 index 00000000000..83b9447c3f7 --- /dev/null +++ b/tests/baselines/reference/superAccessCastedCall.symbols @@ -0,0 +1,50 @@ +=== tests/cases/compiler/superAccessCastedCall.ts === +class Foo { +>Foo : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) + + bar(): void {} +>bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) +} + +class Bar extends Foo { +>Bar : Symbol(Bar, Decl(superAccessCastedCall.ts, 2, 1)) +>Foo : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) + + x: Number; +>x : Symbol(Bar.x, Decl(superAccessCastedCall.ts, 4, 23)) +>Number : Symbol(Number, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + constructor() { + super(); +>super : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) + + this.x = 2; +>this.x : Symbol(Bar.x, Decl(superAccessCastedCall.ts, 4, 23)) +>this : Symbol(Bar, Decl(superAccessCastedCall.ts, 2, 1)) +>x : Symbol(Bar.x, Decl(superAccessCastedCall.ts, 4, 23)) + } + + bar() { +>bar : Symbol(Bar.bar, Decl(superAccessCastedCall.ts, 10, 5)) + + super.bar(); +>super.bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) +>super : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) +>bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) + + (super.bar as any)(); +>super.bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) +>super : Symbol(Foo, Decl(superAccessCastedCall.ts, 0, 0)) +>bar : Symbol(Foo.bar, Decl(superAccessCastedCall.ts, 0, 11)) + } +} + +let b = new Bar(); +>b : Symbol(b, Decl(superAccessCastedCall.ts, 18, 3)) +>Bar : Symbol(Bar, Decl(superAccessCastedCall.ts, 2, 1)) + +b.bar() +>b.bar : Symbol(Bar.bar, Decl(superAccessCastedCall.ts, 10, 5)) +>b : Symbol(b, Decl(superAccessCastedCall.ts, 18, 3)) +>bar : Symbol(Bar.bar, Decl(superAccessCastedCall.ts, 10, 5)) + diff --git a/tests/baselines/reference/superAccessCastedCall.types b/tests/baselines/reference/superAccessCastedCall.types new file mode 100644 index 00000000000..72ee3c05a7e --- /dev/null +++ b/tests/baselines/reference/superAccessCastedCall.types @@ -0,0 +1,59 @@ +=== tests/cases/compiler/superAccessCastedCall.ts === +class Foo { +>Foo : Foo + + bar(): void {} +>bar : () => void +} + +class Bar extends Foo { +>Bar : Bar +>Foo : Foo + + x: Number; +>x : Number +>Number : Number + + constructor() { + super(); +>super() : void +>super : typeof Foo + + this.x = 2; +>this.x = 2 : 2 +>this.x : Number +>this : this +>x : Number +>2 : 2 + } + + bar() { +>bar : () => void + + super.bar(); +>super.bar() : void +>super.bar : () => void +>super : Foo +>bar : () => void + + (super.bar as any)(); +>(super.bar as any)() : any +>(super.bar as any) : any +>super.bar as any : any +>super.bar : () => void +>super : Foo +>bar : () => void + } +} + +let b = new Bar(); +>b : Bar +>new Bar() : Bar +>Bar : typeof Bar + +b.bar() +>b.bar() : void +>b.bar : () => void +>b : Bar +>bar : () => void + diff --git a/tests/baselines/reference/superElementAccess.errors.txt b/tests/baselines/reference/superElementAccess.errors.txt new file mode 100644 index 00000000000..e5d8c3ea5ad --- /dev/null +++ b/tests/baselines/reference/superElementAccess.errors.txt @@ -0,0 +1,44 @@ +tests/cases/compiler/superElementAccess.ts(7,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. +tests/cases/compiler/superElementAccess.ts(8,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + + +==== tests/cases/compiler/superElementAccess.ts (2 errors) ==== + class MyBase { + m1(a: string) { return a; } + private p1() { } + m2: () => void = function () { } + d1: number = 42; + private d2: number = 42; + get value() {return 0 } + ~~~~~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + set value(v: number) { } + ~~~~~ +!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. + } + + + class MyDerived extends MyBase { + + foo() { + super["m1"]("hi"); // Should be allowed, method on base prototype + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature + + super["m2"].bind(this); // Should error, instance property, not a public instance member function + + super["p1"](); // Should error, private not public instance member function + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment + + super["value"] = 0; // Should error, instance data property not a public instance member function + + var z = super["value"]; // Should error, instance data property not a public instance member function + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superElementAccess.js b/tests/baselines/reference/superElementAccess.js new file mode 100644 index 00000000000..422b80109bb --- /dev/null +++ b/tests/baselines/reference/superElementAccess.js @@ -0,0 +1,84 @@ +//// [superElementAccess.ts] +class MyBase { + m1(a: string) { return a; } + private p1() { } + m2: () => void = function () { } + d1: number = 42; + private d2: number = 42; + get value() {return 0 } + set value(v: number) { } +} + + +class MyDerived extends MyBase { + + foo() { + super["m1"]("hi"); // Should be allowed, method on base prototype + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature + + super["m2"].bind(this); // Should error, instance property, not a public instance member function + + super["p1"](); // Should error, private not public instance member function + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment + + super["value"] = 0; // Should error, instance data property not a public instance member function + + var z = super["value"]; // Should error, instance data property not a public instance member function + } +} + +//// [superElementAccess.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var MyBase = /** @class */ (function () { + function MyBase() { + this.m2 = function () { }; + this.d1 = 42; + this.d2 = 42; + } + MyBase.prototype.m1 = function (a) { return a; }; + MyBase.prototype.p1 = function () { }; + Object.defineProperty(MyBase.prototype, "value", { + get: function () { return 0; }, + set: function (v) { }, + enumerable: true, + configurable: true + }); + return MyBase; +}()); +var MyDerived = /** @class */ (function (_super) { + __extends(MyDerived, _super); + function MyDerived() { + return _super !== null && _super.apply(this, arguments) || this; + } + MyDerived.prototype.foo = function () { + _super.prototype["m1"].call(this, "hi"); // Should be allowed, method on base prototype + var l2 = (_a = _super.prototype["m1"]).bind.call(_a, this); // Should be allowed, can access properties as well as invoke + var x = _super.prototype["m1"]; // Should be allowed, can assign to var with compatible signature + (_b = _super.prototype["m2"]).bind.call(_b, this); // Should error, instance property, not a public instance member function + _super.prototype["p1"].call(this); // Should error, private not public instance member function + var l1 = _super.prototype["d1"]; // Should error, instance data property not a public instance member function + var l1 = _super.prototype["d2"]; // Should error, instance data property not a public instance member function + _super.prototype["m1"] = function (a) { return ""; }; // Should be allowed, we will not restrict assignment + _super.prototype["value"] = 0; // Should error, instance data property not a public instance member function + var z = _super.prototype["value"]; // Should error, instance data property not a public instance member function + var _a, _b; + }; + return MyDerived; +}(MyBase)); diff --git a/tests/baselines/reference/superElementAccess.symbols b/tests/baselines/reference/superElementAccess.symbols new file mode 100644 index 00000000000..5da1450212b --- /dev/null +++ b/tests/baselines/reference/superElementAccess.symbols @@ -0,0 +1,91 @@ +=== tests/cases/compiler/superElementAccess.ts === +class MyBase { +>MyBase : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) + + m1(a: string) { return a; } +>m1 : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) +>a : Symbol(a, Decl(superElementAccess.ts, 1, 7)) +>a : Symbol(a, Decl(superElementAccess.ts, 1, 7)) + + private p1() { } +>p1 : Symbol(MyBase.p1, Decl(superElementAccess.ts, 1, 31)) + + m2: () => void = function () { } +>m2 : Symbol(MyBase.m2, Decl(superElementAccess.ts, 2, 20)) + + d1: number = 42; +>d1 : Symbol(MyBase.d1, Decl(superElementAccess.ts, 3, 36)) + + private d2: number = 42; +>d2 : Symbol(MyBase.d2, Decl(superElementAccess.ts, 4, 20)) + + get value() {return 0 } +>value : Symbol(MyBase.value, Decl(superElementAccess.ts, 5, 28), Decl(superElementAccess.ts, 6, 27)) + + set value(v: number) { } +>value : Symbol(MyBase.value, Decl(superElementAccess.ts, 5, 28), Decl(superElementAccess.ts, 6, 27)) +>v : Symbol(v, Decl(superElementAccess.ts, 7, 14)) +} + + +class MyDerived extends MyBase { +>MyDerived : Symbol(MyDerived, Decl(superElementAccess.ts, 8, 1)) +>MyBase : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) + + foo() { +>foo : Symbol(MyDerived.foo, Decl(superElementAccess.ts, 11, 32)) + + super["m1"]("hi"); // Should be allowed, method on base prototype +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m1" : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke +>l2 : Symbol(l2, Decl(superElementAccess.ts, 16, 11)) +>super["m1"].bind : Symbol(Function.bind, Decl(lib.d.ts, --, --)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m1" : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) +>bind : Symbol(Function.bind, Decl(lib.d.ts, --, --)) +>this : Symbol(MyDerived, Decl(superElementAccess.ts, 8, 1)) + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature +>x : Symbol(x, Decl(superElementAccess.ts, 18, 11)) +>a : Symbol(a, Decl(superElementAccess.ts, 18, 16)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m1" : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) + + super["m2"].bind(this); // Should error, instance property, not a public instance member function +>super["m2"].bind : Symbol(Function.bind, Decl(lib.d.ts, --, --)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m2" : Symbol(MyBase.m2, Decl(superElementAccess.ts, 2, 20)) +>bind : Symbol(Function.bind, Decl(lib.d.ts, --, --)) +>this : Symbol(MyDerived, Decl(superElementAccess.ts, 8, 1)) + + super["p1"](); // Should error, private not public instance member function +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"p1" : Symbol(MyBase.p1, Decl(superElementAccess.ts, 1, 31)) + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function +>l1 : Symbol(l1, Decl(superElementAccess.ts, 24, 11), Decl(superElementAccess.ts, 26, 11)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"d1" : Symbol(MyBase.d1, Decl(superElementAccess.ts, 3, 36)) + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function +>l1 : Symbol(l1, Decl(superElementAccess.ts, 24, 11), Decl(superElementAccess.ts, 26, 11)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"d2" : Symbol(MyBase.d2, Decl(superElementAccess.ts, 4, 20)) + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"m1" : Symbol(MyBase.m1, Decl(superElementAccess.ts, 0, 14)) +>a : Symbol(a, Decl(superElementAccess.ts, 28, 32)) + + super["value"] = 0; // Should error, instance data property not a public instance member function +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"value" : Symbol(MyBase.value, Decl(superElementAccess.ts, 5, 28), Decl(superElementAccess.ts, 6, 27)) + + var z = super["value"]; // Should error, instance data property not a public instance member function +>z : Symbol(z, Decl(superElementAccess.ts, 32, 11)) +>super : Symbol(MyBase, Decl(superElementAccess.ts, 0, 0)) +>"value" : Symbol(MyBase.value, Decl(superElementAccess.ts, 5, 28), Decl(superElementAccess.ts, 6, 27)) + } +} diff --git a/tests/baselines/reference/superElementAccess.types b/tests/baselines/reference/superElementAccess.types new file mode 100644 index 00000000000..9fa75ec6bc4 --- /dev/null +++ b/tests/baselines/reference/superElementAccess.types @@ -0,0 +1,115 @@ +=== tests/cases/compiler/superElementAccess.ts === +class MyBase { +>MyBase : MyBase + + m1(a: string) { return a; } +>m1 : (a: string) => string +>a : string +>a : string + + private p1() { } +>p1 : () => void + + m2: () => void = function () { } +>m2 : () => void +>function () { } : () => void + + d1: number = 42; +>d1 : number +>42 : 42 + + private d2: number = 42; +>d2 : number +>42 : 42 + + get value() {return 0 } +>value : number +>0 : 0 + + set value(v: number) { } +>value : number +>v : number +} + + +class MyDerived extends MyBase { +>MyDerived : MyDerived +>MyBase : MyBase + + foo() { +>foo : () => void + + super["m1"]("hi"); // Should be allowed, method on base prototype +>super["m1"]("hi") : string +>super["m1"] : (a: string) => string +>super : MyBase +>"m1" : "m1" +>"hi" : "hi" + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke +>l2 : any +>super["m1"].bind(this) : any +>super["m1"].bind : (this: Function, thisArg: any, ...argArray: any[]) => any +>super["m1"] : (a: string) => string +>super : MyBase +>"m1" : "m1" +>bind : (this: Function, thisArg: any, ...argArray: any[]) => any +>this : this + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature +>x : (a: string) => string +>a : string +>super["m1"] : (a: string) => string +>super : MyBase +>"m1" : "m1" + + super["m2"].bind(this); // Should error, instance property, not a public instance member function +>super["m2"].bind(this) : any +>super["m2"].bind : (this: Function, thisArg: any, ...argArray: any[]) => any +>super["m2"] : () => void +>super : MyBase +>"m2" : "m2" +>bind : (this: Function, thisArg: any, ...argArray: any[]) => any +>this : this + + super["p1"](); // Should error, private not public instance member function +>super["p1"]() : void +>super["p1"] : () => void +>super : MyBase +>"p1" : "p1" + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function +>l1 : number +>super["d1"] : number +>super : MyBase +>"d1" : "d1" + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function +>l1 : number +>super["d2"] : number +>super : MyBase +>"d2" : "d2" + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment +>super["m1"] = function (a: string) { return ""; } : (a: string) => string +>super["m1"] : (a: string) => string +>super : MyBase +>"m1" : "m1" +>function (a: string) { return ""; } : (a: string) => string +>a : string +>"" : "" + + super["value"] = 0; // Should error, instance data property not a public instance member function +>super["value"] = 0 : 0 +>super["value"] : number +>super : MyBase +>"value" : "value" +>0 : 0 + + var z = super["value"]; // Should error, instance data property not a public instance member function +>z : number +>super["value"] : number +>super : MyBase +>"value" : "value" + } +} diff --git a/tests/baselines/reference/superErrors.js b/tests/baselines/reference/superErrors.js index 87d4e3bb85a..952cb03fd80 100644 --- a/tests/baselines/reference/superErrors.js +++ b/tests/baselines/reference/superErrors.js @@ -63,7 +63,6 @@ var __extends = (this && this.__extends) || (function () { }; })(); function foo() { - var _this = this; // super in a non class context var x = _super.; var y = function () { return _super.; }; @@ -93,10 +92,7 @@ var RegisteredUser = /** @class */ (function (_super) { var x = function () { return _super.sayHello.call(_this); }; } // super call in a lambda in a function expression in a constructor - (function () { - var _this = this; - return function () { return _super.; }; - })(); + (function () { return function () { return _super.; }; })(); return _this; } RegisteredUser.prototype.sayHello = function () { @@ -108,13 +104,9 @@ var RegisteredUser = /** @class */ (function (_super) { var x = function () { return _super.sayHello.call(_this); }; } // super call in a lambda in a function expression in a constructor - (function () { - var _this = this; - return function () { return _super.; }; - })(); + (function () { return function () { return _super.; }; })(); }; RegisteredUser.staticFunction = function () { - var _this = this; // super in static functions var s = _super.; var x = function () { return _super.; }; diff --git a/tests/baselines/reference/superInLambdas.js b/tests/baselines/reference/superInLambdas.js index 653d3ae84c1..9bb1a87e0ea 100644 --- a/tests/baselines/reference/superInLambdas.js +++ b/tests/baselines/reference/superInLambdas.js @@ -133,7 +133,6 @@ var RegisteredUser3 = /** @class */ (function (_super) { return _this; } RegisteredUser3.prototype.sayHello = function () { - var _this = this; // super property in a nested lambda in a method var superName = function () { return function () { return function () { return _super.prototype.name; }; }; }; }; @@ -149,7 +148,6 @@ var RegisteredUser4 = /** @class */ (function (_super) { return _this; } RegisteredUser4.prototype.sayHello = function () { - var _this = this; // super in a nested lambda in a method var x = function () { return function () { return _super.prototype.; }; }; }; diff --git a/tests/baselines/reference/superPropertyAccess.js b/tests/baselines/reference/superPropertyAccess.js index cc9758a1617..8fa0984745c 100644 --- a/tests/baselines/reference/superPropertyAccess.js +++ b/tests/baselines/reference/superPropertyAccess.js @@ -69,15 +69,16 @@ var MyDerived = /** @class */ (function (_super) { } MyDerived.prototype.foo = function () { _super.prototype.m1.call(this, "hi"); // Should be allowed, method on base prototype - var l2 = _super.prototype.m1.bind(this); // Should be allowed, can access properties as well as invoke + var l2 = (_a = _super.prototype.m1).bind.call(_a, this); // Should be allowed, can access properties as well as invoke var x = _super.prototype.m1; // Should be allowed, can assign to var with compatible signature - _super.prototype.m2.bind(this); // Should error, instance property, not a public instance member function + (_b = _super.prototype.m2).bind.call(_b, this); // Should error, instance property, not a public instance member function _super.prototype.p1.call(this); // Should error, private not public instance member function var l1 = _super.prototype.d1; // Should error, instance data property not a public instance member function var l1 = _super.prototype.d2; // Should error, instance data property not a public instance member function _super.prototype.m1 = function (a) { return ""; }; // Should be allowed, we will not restrict assignment _super.prototype.value = 0; // Should error, instance data property not a public instance member function var z = _super.prototype.value; // Should error, instance data property not a public instance member function + var _a, _b; }; return MyDerived; }(MyBase)); diff --git a/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.js b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.js new file mode 100644 index 00000000000..126c123b40d --- /dev/null +++ b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.js @@ -0,0 +1,53 @@ +//// [superPropertyElementNoUnusedLexicalThisCapture.ts] +class A { x() {} } + +class B extends A { + constructor() { + super(); + } + foo() { + return () => { + super.x; + } + } + bar() { + return () => { + super["x"]; + } + } +} + +//// [superPropertyElementNoUnusedLexicalThisCapture.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var A = /** @class */ (function () { + function A() { + } + A.prototype.x = function () { }; + return A; +}()); +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super.call(this) || this; + } + B.prototype.foo = function () { + return function () { + _super.prototype.x; + }; + }; + B.prototype.bar = function () { + return function () { + _super.prototype["x"]; + }; + }; + return B; +}(A)); diff --git a/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.symbols b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.symbols new file mode 100644 index 00000000000..080268a0744 --- /dev/null +++ b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts === +class A { x() {} } +>A : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) +>x : Symbol(A.x, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 9)) + +class B extends A { +>B : Symbol(B, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 18)) +>A : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) + + constructor() { + super(); +>super : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) + } + foo() { +>foo : Symbol(B.foo, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 5, 5)) + + return () => { + super.x; +>super.x : Symbol(A.x, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 9)) +>super : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) +>x : Symbol(A.x, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 9)) + } + } + bar() { +>bar : Symbol(B.bar, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 10, 5)) + + return () => { + super["x"]; +>super : Symbol(A, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 0)) +>"x" : Symbol(A.x, Decl(superPropertyElementNoUnusedLexicalThisCapture.ts, 0, 9)) + } + } +} diff --git a/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.types b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.types new file mode 100644 index 00000000000..37048f2f1d5 --- /dev/null +++ b/tests/baselines/reference/superPropertyElementNoUnusedLexicalThisCapture.types @@ -0,0 +1,39 @@ +=== tests/cases/compiler/superPropertyElementNoUnusedLexicalThisCapture.ts === +class A { x() {} } +>A : A +>x : () => void + +class B extends A { +>B : B +>A : A + + constructor() { + super(); +>super() : void +>super : typeof A + } + foo() { +>foo : () => () => void + + return () => { +>() => { super.x; } : () => void + + super.x; +>super.x : () => void +>super : A +>x : () => void + } + } + bar() { +>bar : () => () => void + + return () => { +>() => { super["x"]; } : () => void + + super["x"]; +>super["x"] : () => void +>super : A +>"x" : "x" + } + } +} diff --git a/tests/baselines/reference/symbolProperty60.js b/tests/baselines/reference/symbolProperty60.js new file mode 100644 index 00000000000..d2a1ac92dd8 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.js @@ -0,0 +1,25 @@ +//// [symbolProperty60.ts] +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { + [Symbol.toStringTag]: string; + [key: string]: number; +} + +interface I2 { + [Symbol.toStringTag]: string; + [key: number]: boolean; +} + +declare const mySymbol: unique symbol; + +interface I3 { + [mySymbol]: string; + [key: string]: number; +} + +interface I4 { + [mySymbol]: string; + [key: number]: boolean; +} + +//// [symbolProperty60.js] diff --git a/tests/baselines/reference/symbolProperty60.symbols b/tests/baselines/reference/symbolProperty60.symbols new file mode 100644 index 00000000000..fca43277e97 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/es6/Symbols/symbolProperty60.ts === +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { +>I1 : Symbol(I1, Decl(symbolProperty60.ts, 0, 0)) + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [key: string]: number; +>key : Symbol(key, Decl(symbolProperty60.ts, 3, 5)) +} + +interface I2 { +>I2 : Symbol(I2, Decl(symbolProperty60.ts, 4, 1)) + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [key: number]: boolean; +>key : Symbol(key, Decl(symbolProperty60.ts, 8, 5)) +} + +declare const mySymbol: unique symbol; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + +interface I3 { +>I3 : Symbol(I3, Decl(symbolProperty60.ts, 11, 38)) + + [mySymbol]: string; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + + [key: string]: number; +>key : Symbol(key, Decl(symbolProperty60.ts, 15, 5)) +} + +interface I4 { +>I4 : Symbol(I4, Decl(symbolProperty60.ts, 16, 1)) + + [mySymbol]: string; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + + [key: number]: boolean; +>key : Symbol(key, Decl(symbolProperty60.ts, 20, 5)) +} diff --git a/tests/baselines/reference/symbolProperty60.types b/tests/baselines/reference/symbolProperty60.types new file mode 100644 index 00000000000..c81c003bd35 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.types @@ -0,0 +1,48 @@ +=== tests/cases/conformance/es6/Symbols/symbolProperty60.ts === +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { +>I1 : I1 + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + [key: string]: number; +>key : string +} + +interface I2 { +>I2 : I2 + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + [key: number]: boolean; +>key : number +} + +declare const mySymbol: unique symbol; +>mySymbol : unique symbol + +interface I3 { +>I3 : I3 + + [mySymbol]: string; +>mySymbol : unique symbol + + [key: string]: number; +>key : string +} + +interface I4 { +>I4 : I4 + + [mySymbol]: string; +>mySymbol : unique symbol + + [key: number]: boolean; +>key : number +} diff --git a/tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types b/tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types index 1c38ecc466c..3f1ef83a0ae 100644 --- a/tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types +++ b/tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types @@ -9,11 +9,11 @@ export = packageExport; === tests/cases/compiler/index.ts === import("package").then(({default: foo}) => foo(42)); >import("package").then(({default: foo}) => foo(42)) : Promise ->import("package").then : string) & { default: (x: number) => string; }, TResult2 = never>(onfulfilled?: (value: ((x: number) => string) & { default: (x: number) => string; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->import("package") : Promise<((x: number) => string) & { default: (x: number) => string; }> +>import("package").then : string; }, TResult2 = never>(onfulfilled?: (value: { default: (x: number) => string; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>import("package") : Promise<{ default: (x: number) => string; }> >"package" : "package" ->then : string) & { default: (x: number) => string; }, TResult2 = never>(onfulfilled?: (value: ((x: number) => string) & { default: (x: number) => string; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise ->({default: foo}) => foo(42) : ({ default: foo }: ((x: number) => string) & { default: (x: number) => string; }) => string +>then : string; }, TResult2 = never>(onfulfilled?: (value: { default: (x: number) => string; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>({default: foo}) => foo(42) : ({ default: foo }: { default: (x: number) => string; }) => string >default : any >foo : (x: number) => string >foo(42) : string diff --git a/tests/baselines/reference/systemObjectShorthandRename.js b/tests/baselines/reference/systemObjectShorthandRename.js new file mode 100644 index 00000000000..a7ac63968cd --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.js @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/systemObjectShorthandRename.ts] //// + +//// [x.ts] +export const x = 'X' +//// [index.ts] +import {x} from './x.js' + +const x2 = {x} +const a = {x2} + +const x3 = x +const b = {x3} + +//// [x.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var x; + return { + setters: [], + execute: function () { + exports_1("x", x = 'X'); + } + }; +}); +//// [index.js] +System.register(["./x.js"], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var x_js_1, x2, a, x3, b; + return { + setters: [ + function (x_js_1_1) { + x_js_1 = x_js_1_1; + } + ], + execute: function () { + x2 = { x: x_js_1.x }; + a = { x2 }; + x3 = x_js_1.x; + b = { x3 }; + } + }; +}); diff --git a/tests/baselines/reference/systemObjectShorthandRename.symbols b/tests/baselines/reference/systemObjectShorthandRename.symbols new file mode 100644 index 00000000000..3321d047ea1 --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/x.ts === +export const x = 'X' +>x : Symbol(x, Decl(x.ts, 0, 12)) + +=== tests/cases/compiler/index.ts === +import {x} from './x.js' +>x : Symbol(x, Decl(index.ts, 0, 8)) + +const x2 = {x} +>x2 : Symbol(x2, Decl(index.ts, 2, 5)) +>x : Symbol(x, Decl(index.ts, 2, 12)) + +const a = {x2} +>a : Symbol(a, Decl(index.ts, 3, 5)) +>x2 : Symbol(x2, Decl(index.ts, 3, 11)) + +const x3 = x +>x3 : Symbol(x3, Decl(index.ts, 5, 5)) +>x : Symbol(x, Decl(index.ts, 0, 8)) + +const b = {x3} +>b : Symbol(b, Decl(index.ts, 6, 5)) +>x3 : Symbol(x3, Decl(index.ts, 6, 11)) + diff --git a/tests/baselines/reference/systemObjectShorthandRename.types b/tests/baselines/reference/systemObjectShorthandRename.types new file mode 100644 index 00000000000..23f3d74c951 --- /dev/null +++ b/tests/baselines/reference/systemObjectShorthandRename.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/x.ts === +export const x = 'X' +>x : "X" +>'X' : "X" + +=== tests/cases/compiler/index.ts === +import {x} from './x.js' +>x : "X" + +const x2 = {x} +>x2 : { x: string; } +>{x} : { x: string; } +>x : string + +const a = {x2} +>a : { x2: { x: string; }; } +>{x2} : { x2: { x: string; }; } +>x2 : { x: string; } + +const x3 = x +>x3 : "X" +>x : "X" + +const b = {x3} +>b : { x3: string; } +>{x3} : { x3: string; } +>x3 : string + diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.js b/tests/baselines/reference/thisTypeInObjectLiterals2.js index ca62ee37665..7c5b6ef110b 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.js +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.js @@ -462,8 +462,8 @@ declare function defineProps(obj: T, descs: PropDescMap & ThisType): declare let p10: Point & Record<"foo", number>; declare let p11: Point & Record<"bar", number>; declare let p12: Point & { - foo: number; - bar: number; + foo: any; + bar: any; }; declare type Accessors = { [K in keyof T]: (() => T[K]) | Computed; @@ -487,6 +487,6 @@ declare let vue: { } & { f(x: string): number; } & { - test: number; - hello: string; + test: any; + hello: any; }; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.types b/tests/baselines/reference/thisTypeInObjectLiterals2.types index 746ca0eb264..fe00bdbb271 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.types +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.types @@ -672,8 +672,8 @@ p11.bar = p11.bar + 1; >1 : 1 let p12 = defineProps(p1, { ->p12 : Point & { foo: number; bar: number; } ->defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: number; bar: number; } +>p12 : Point & { foo: any; bar: any; } +>defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: any; bar: any; } >defineProps : (obj: T, descs: PropDescMap & ThisType) => T & U >p1 : Point >{ foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }} : { foo: { value: number; }; bar: { get(): number; set(value: number): void; }; } @@ -716,22 +716,22 @@ let p12 = defineProps(p1, { p12.foo = p12.foo + 1; >p12.foo = p12.foo + 1 : number >p12.foo : number ->p12 : Point & { foo: number; bar: number; } +>p12 : Point & { foo: any; bar: any; } >foo : number >p12.foo + 1 : number >p12.foo : number ->p12 : Point & { foo: number; bar: number; } +>p12 : Point & { foo: any; bar: any; } >foo : number >1 : 1 p12.bar = p12.bar + 1; >p12.bar = p12.bar + 1 : number >p12.bar : number ->p12 : Point & { foo: number; bar: number; } +>p12 : Point & { foo: any; bar: any; } >bar : number >p12.bar + 1 : number >p12.bar : number ->p12 : Point & { foo: number; bar: number; } +>p12 : Point & { foo: any; bar: any; } >bar : number >1 : 1 @@ -808,8 +808,8 @@ declare const Vue: new (options: VueOptions) => D & M & P; >P : P let vue = new Vue({ ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } ->new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } +>new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >Vue : new (options: VueOptions) => D & M & P >{ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }} : { data: () => { x: number; y: number; }; methods: { f(x: string): number; }; computed: { test(): number; hello: { get(): string; set(value: string): void; }; }; } @@ -833,7 +833,7 @@ let vue = new Vue({ return this.x; >this.x : number ->this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>this : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >x : number } }, @@ -846,7 +846,7 @@ let vue = new Vue({ return this.x; >this.x : number ->this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>this : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >x : number }, @@ -870,27 +870,27 @@ let vue = new Vue({ }); vue; ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } vue.x; >vue.x : number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >x : number vue.f("abc"); >vue.f("abc") : number >vue.f : (x: string) => number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >f : (x: string) => number >"abc" : "abc" vue.test; >vue.test : number ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >test : number vue.hello; >vue.hello : string ->vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; } >hello : string diff --git a/tests/baselines/reference/throwInEnclosingStatements.types b/tests/baselines/reference/throwInEnclosingStatements.types index e031d00147d..d46307b0ea2 100644 --- a/tests/baselines/reference/throwInEnclosingStatements.types +++ b/tests/baselines/reference/throwInEnclosingStatements.types @@ -92,15 +92,15 @@ class C { } var aa = { ->aa : { id: number; biz(): void; } ->{ id:12, biz() { throw this; }} : { id: number; biz(): void; } +>aa : { id: number; biz(): never; } +>{ id:12, biz() { throw this; }} : { id: number; biz(): never; } id:12, >id : number >12 : 12 biz() { ->biz : () => void +>biz : () => never throw this; >this : any diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js new file mode 100644 index 00000000000..4f102f14ed4 --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js @@ -0,0 +1,10 @@ +//// [transformParenthesizesConditionalSubexpression.ts] +var K = 'k' +var a = { p : (true ? { [K] : 'v'} : null) } +var b = { p : (true ? { [K] : 'v'} as any : null) } + +//// [transformParenthesizesConditionalSubexpression.js] +var K = 'k'; +var a = { p: (true ? (_a = {}, _a[K] = 'v', _a) : null) }; +var b = { p: (true ? (_b = {}, _b[K] = 'v', _b) : null) }; +var _a, _b; diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols new file mode 100644 index 00000000000..d3ae64c40d5 --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts === +var K = 'k' +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + +var a = { p : (true ? { [K] : 'v'} : null) } +>a : Symbol(a, Decl(transformParenthesizesConditionalSubexpression.ts, 1, 3)) +>p : Symbol(p, Decl(transformParenthesizesConditionalSubexpression.ts, 1, 9)) +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + +var b = { p : (true ? { [K] : 'v'} as any : null) } +>b : Symbol(b, Decl(transformParenthesizesConditionalSubexpression.ts, 2, 3)) +>p : Symbol(p, Decl(transformParenthesizesConditionalSubexpression.ts, 2, 9)) +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types new file mode 100644 index 00000000000..0ba4268d80a --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts === +var K = 'k' +>K : string +>'k' : "k" + +var a = { p : (true ? { [K] : 'v'} : null) } +>a : { p: { [x: string]: string; }; } +>{ p : (true ? { [K] : 'v'} : null) } : { p: { [x: string]: string; }; } +>p : { [x: string]: string; } +>(true ? { [K] : 'v'} : null) : { [x: string]: string; } +>true ? { [K] : 'v'} : null : { [x: string]: string; } +>true : true +>{ [K] : 'v'} : { [x: string]: string; } +>K : string +>'v' : "v" +>null : null + +var b = { p : (true ? { [K] : 'v'} as any : null) } +>b : { p: any; } +>{ p : (true ? { [K] : 'v'} as any : null) } : { p: any; } +>p : any +>(true ? { [K] : 'v'} as any : null) : any +>true ? { [K] : 'v'} as any : null : any +>true : true +>{ [K] : 'v'} as any : any +>{ [K] : 'v'} : { [x: string]: string; } +>K : string +>'v' : "v" +>null : null + diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index d66c75aaf4e..cb57cd1366b 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 003ee7ff684..6614dd9e48e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -28,7 +28,7 @@ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ - "noUnusedLocals": true /* Report errors on unused locals. */ + "noUnusedLocals": true, /* Report errors on unused locals. */ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index c04ad57e297..8c19ad58bed 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 05524339c28..f5e2b163a21 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 1681d720285..ced3eae17b8 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation: */ + "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index d66c75aaf4e..cb57cd1366b 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 11a8651947a..1356e2258f7 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation: */ + "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -19,7 +19,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */ + "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -41,6 +41,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index ed01f3e6abd..473280f675e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -39,8 +39,9 @@ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": ["jquery","mocha"] /* Type declaration files to be included in compilation. */ + "types": ["jquery","mocha"], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ /* Source Map Options */ diff --git a/tests/baselines/reference/tsxGenericAttributesType4.errors.txt b/tests/baselines/reference/tsxGenericAttributesType4.errors.txt deleted file mode 100644 index ee91f938b9f..00000000000 --- a/tests/baselines/reference/tsxGenericAttributesType4.errors.txt +++ /dev/null @@ -1,19 +0,0 @@ -tests/cases/conformance/jsx/file.tsx(11,36): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - - -==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== - import React = require('react'); - - class B1 extends React.Component { - render() { - return