mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' of github.com:Microsoft/TypeScript into multiple-prologue-directives
This commit is contained in:
@@ -163,7 +163,7 @@ Rostislav Galimsky <rostgal@gmail.com>
|
||||
Richard Knoll <riknoll@users.noreply.github.com> Richard Knoll <riknoll@microsoft.com>
|
||||
Richard Karmazín <richard@karmazin.cz>
|
||||
Rowan Wyborn <rwyborn@internode.on.net>
|
||||
Ryan Cavanaugh <RyanCavanaugh@users.noreply.github.com> Ryan Cavanaugh <ryan.cavanaugh@microsoft.com> Ryan Cavanaugh <ryanca@microsoft.com>
|
||||
Ryan Cavanaugh <RyanCavanaugh@users.noreply.github.com> Ryan Cavanaugh <ryan.cavanaugh@microsoft.com> Ryan Cavanaugh <ryanca@microsoft.com> Ryan Cavanaugh <the.ryan.cavanaugh@gmail.com>
|
||||
Ryohei Ikegami <iofg2100@gmail.com>
|
||||
Sarangan Rajamanickam <sarajama@microsoft.com>
|
||||
Sébastien Arod <sebastien.arod@gmail.com>
|
||||
@@ -340,4 +340,21 @@ EcoleKeine <Ecole_k@qq.com> # Ecole Keine
|
||||
Khải <hvksmr1996@gmail.com>
|
||||
rhysd <lin90162@yahoo.co.jp> # @rhysd
|
||||
Zen <843968788@qq.com> Zzzen <843968788@qq.com> # @Zzzen
|
||||
bluelovers <codelovers@users.sourceforge.net> # @bluelovers
|
||||
bluelovers <codelovers@users.sourceforge.net> # @bluelovers
|
||||
Dan Freeman <dfreeman@salsify.com>
|
||||
David Sherret <dsherret@gmail.com>
|
||||
David Staheli <dastahel@microsoft.com>
|
||||
Elizabeth Dinella <elizabeth.a.dinella@gmail.com>
|
||||
John Doe <github.john.doe@outlook.com>
|
||||
Kevin Gibbons <kevin@shapesecurity.com>
|
||||
Markus Johnsson <markus.johnsson@infviz.com>
|
||||
Martin Probst <martin@probst.io>
|
||||
Mateusz Burzyński <mateuszburzynski@gmail.com>
|
||||
Steven <steven@ceriously.com> # @styfle
|
||||
Pi Lanningham <pi.lanningham@gmail.com>
|
||||
Sam Bostock <sam.bostock@shopify.com>
|
||||
Vimal Raghubir <vraghubir0418@gmail.com>
|
||||
Vyacheslav Pukhanov <vyacheslav.pukhanov@gmail.com>
|
||||
dangoo <daniel.gooss@sinnerschrader.com> # Daniel Gooss
|
||||
krk <keremkat@gmail.com> # Kerem Kat
|
||||
micnic <micnic90@gmail.com> # Nicu Micleușanu
|
||||
|
||||
@@ -19,6 +19,7 @@ branches:
|
||||
- release-2.7
|
||||
- release-2.8
|
||||
- release-2.9
|
||||
- release-3.0
|
||||
|
||||
install:
|
||||
- npm uninstall typescript --no-save
|
||||
|
||||
+17
-1
@@ -74,7 +74,9 @@ TypeScript is authored by:
|
||||
* Dafrok Zhang
|
||||
* Dahan Gong
|
||||
* Dan Corder
|
||||
* Dan Freeman
|
||||
* Dan Quirk
|
||||
* Daniel Gooss
|
||||
* Daniel Hollocher
|
||||
* Daniel Król
|
||||
* Daniel Lehenbauer
|
||||
@@ -82,7 +84,9 @@ TypeScript is authored by:
|
||||
* David Kmenta
|
||||
* David Li
|
||||
* David Sheldrick
|
||||
* David Sherret
|
||||
* David Souther
|
||||
* David Staheli
|
||||
* Denis Nedelyaev
|
||||
* Derek P Sifford
|
||||
* Dhruv Rajvanshi
|
||||
@@ -96,6 +100,7 @@ TypeScript is authored by:
|
||||
* @e-cloud
|
||||
* Ecole Keine
|
||||
* Elisée Maurer
|
||||
* Elizabeth Dinella
|
||||
* Emilio García-Pumarino
|
||||
* Eric Grube
|
||||
* Eric Tsang
|
||||
@@ -161,6 +166,7 @@ TypeScript is authored by:
|
||||
* Joel Day
|
||||
* Joey Wilson
|
||||
* Johannes Rieken
|
||||
* John Doe
|
||||
* John Vilk
|
||||
* Jonathan Bond-Caron
|
||||
* Jonathan Park
|
||||
@@ -184,7 +190,9 @@ TypeScript is authored by:
|
||||
* Keith Mashinter
|
||||
* Ken Howard
|
||||
* Kenji Imamula
|
||||
* Kerem Kat
|
||||
* Kevin Donnelly
|
||||
* Kevin Gibbons
|
||||
* Kevin Lang
|
||||
* Khải
|
||||
* Kitson Kelly
|
||||
@@ -201,10 +209,13 @@ TypeScript is authored by:
|
||||
* Manish Giri
|
||||
* Marin Marinov
|
||||
* Marius Schulz
|
||||
* Markus Johnsson
|
||||
* Martin Hiller
|
||||
* Martin Probst
|
||||
* Martin Vseticka
|
||||
* Martyn Janes
|
||||
* Masahiro Wakame
|
||||
* Mateusz Burzyński
|
||||
* Matt Bierner
|
||||
* Matt McCutchen
|
||||
* Matt Mitchell
|
||||
@@ -223,10 +234,10 @@ TypeScript is authored by:
|
||||
* Mohamed Hegazy
|
||||
* Mohsen Azimi
|
||||
* Myles Megyesi
|
||||
* Natalie Coley
|
||||
* Nathan Shively-Sanders
|
||||
* Nathan Yee
|
||||
* Nicolas Henry
|
||||
* Nicu Micleușanu
|
||||
* @nieltg
|
||||
* Nima Zahedi
|
||||
* Noah Chen
|
||||
@@ -248,6 +259,7 @@ TypeScript is authored by:
|
||||
* Peter Burns
|
||||
* Philip Bulley
|
||||
* Philippe Voinov
|
||||
* Pi Lanningham
|
||||
* Piero Cangianiello
|
||||
* @piloopin
|
||||
* Prayag Verma
|
||||
@@ -270,6 +282,7 @@ TypeScript is authored by:
|
||||
* Rowan Wyborn
|
||||
* Ryan Cavanaugh
|
||||
* Ryohei Ikegami
|
||||
* Sam Bostock
|
||||
* Sam El-Husseini
|
||||
* Sarangan Rajamanickam
|
||||
* Sean Barag
|
||||
@@ -290,6 +303,7 @@ TypeScript is authored by:
|
||||
* Stas Vilchik
|
||||
* Stephan Ginthör
|
||||
* Steve Lucco
|
||||
* @styfle
|
||||
* Sudheesh Singanamalla
|
||||
* Sébastien Arod
|
||||
* @T18970237136
|
||||
@@ -316,8 +330,10 @@ TypeScript is authored by:
|
||||
* Vidar Tonaas Fauske
|
||||
* Viktor Zozulyak
|
||||
* Vilic Vane
|
||||
* Vimal Raghubir
|
||||
* Vladimir Kurchatkin
|
||||
* Vladimir Matveev
|
||||
* Vyacheslav Pukhanov
|
||||
* Wenlu Wang
|
||||
* Wesley Wigham
|
||||
* William Orr
|
||||
|
||||
+139
-57
@@ -24,6 +24,10 @@ const baselineAccept = require("./scripts/build/baselineAccept");
|
||||
const cmdLineOptions = require("./scripts/build/options");
|
||||
const exec = require("./scripts/build/exec");
|
||||
const browserify = require("./scripts/build/browserify");
|
||||
const debounce = require("./scripts/build/debounce");
|
||||
const prepend = require("./scripts/build/prepend");
|
||||
const { removeSourceMaps } = require("./scripts/build/sourcemaps");
|
||||
const { CancelSource, CancelError } = require("./scripts/build/cancellation");
|
||||
const { libraryTargets, generateLibs } = require("./scripts/build/lib");
|
||||
const { runConsoleTests, cleanTestDirs, writeTestConfigFile, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } = require("./scripts/build/tests");
|
||||
|
||||
@@ -44,17 +48,9 @@ const generateLocalizedDiagnosticMessagesJs = "scripts/generateLocalizedDiagnost
|
||||
const buildProtocolJs = "scripts/buildProtocol.js";
|
||||
const produceLKGJs = "scripts/produceLKG.js";
|
||||
const word2mdJs = "scripts/word2md.js";
|
||||
gulp.task("scripts", /*help*/ false, () => project.compile(scriptsProject), {
|
||||
aliases: [
|
||||
configurePrereleaseJs,
|
||||
processDiagnosticMessagesJs,
|
||||
generateLocalizedDiagnosticMessagesJs,
|
||||
produceLKGJs,
|
||||
buildProtocolJs,
|
||||
word2mdJs
|
||||
]
|
||||
});
|
||||
gulp.task("clean-scripts", /*help*/ false, () => project.clean(scriptsProject));
|
||||
const scriptsTaskAliases = [configurePrereleaseJs, processDiagnosticMessagesJs, generateLocalizedDiagnosticMessagesJs, produceLKGJs, buildProtocolJs, word2mdJs];
|
||||
gulp.task("scripts", /*help*/ false, () => project.compile(scriptsProject), { aliases: scriptsTaskAliases });
|
||||
gulp.task("clean:scripts", /*help*/ false, () => project.clean(scriptsProject), { aliases: scriptsTaskAliases.map(alias => `clean:${alias}`)});
|
||||
|
||||
// Nightly management tasks
|
||||
gulp.task(
|
||||
@@ -73,7 +69,7 @@ gulp.task(
|
||||
const importDefinitelyTypedTestsProject = "scripts/importDefinitelyTypedTests/tsconfig.json";
|
||||
const importDefinitelyTypedTestsJs = "scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.js";
|
||||
gulp.task(importDefinitelyTypedTestsJs, /*help*/ false, () => project.compile(importDefinitelyTypedTestsProject));
|
||||
gulp.task("clean:" + importDefinitelyTypedTestsJs, /*help*/ false, () => project.clean(importDefinitelyTypedTestsProject));
|
||||
gulp.task(`clean:${importDefinitelyTypedTestsJs}`, /*help*/ false, () => project.clean(importDefinitelyTypedTestsProject));
|
||||
|
||||
gulp.task(
|
||||
"importDefinitelyTypedTests",
|
||||
@@ -95,7 +91,7 @@ gulp.task(diagnosticInformationMapTs, /*help*/ false, [processDiagnosticMessages
|
||||
return exec(host, [processDiagnosticMessagesJs, diagnosticMessagesJson]);
|
||||
}
|
||||
});
|
||||
gulp.task("clean:" + diagnosticInformationMapTs, /*help*/ false, () => del([diagnosticInformationMapTs, diagnosticMessagesGeneratedJson]));
|
||||
gulp.task(`clean:${diagnosticInformationMapTs}`, /*help*/ false, () => del([diagnosticInformationMapTs, diagnosticMessagesGeneratedJson]));
|
||||
|
||||
const builtGeneratedDiagnosticMessagesJson = "built/local/diagnosticMessages.generated.json";
|
||||
gulp.task(builtGeneratedDiagnosticMessagesJson, /*help*/ false, [diagnosticInformationMapTs], () =>
|
||||
@@ -140,9 +136,10 @@ gulp.task(typescriptServicesProject, /*help*/ false, () => {
|
||||
// NOTE: flatten services so that we can properly strip @internal
|
||||
project.flatten(servicesProject, typescriptServicesProject, {
|
||||
compilerOptions: {
|
||||
"removeComments": true,
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"outFile": "typescriptServices.js"
|
||||
"declarationMap": false,
|
||||
"outFile": "typescriptServices.out.js" // must align with same task in jakefile. We fix this name below.
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -150,7 +147,16 @@ gulp.task(typescriptServicesProject, /*help*/ false, () => {
|
||||
const typescriptServicesJs = "built/local/typescriptServices.js";
|
||||
const typescriptServicesDts = "built/local/typescriptServices.d.ts";
|
||||
gulp.task(typescriptServicesJs, /*help*/ false, ["lib", "generate-diagnostics", typescriptServicesProject], () =>
|
||||
project.compile(typescriptServicesProject, { dts: files => files.pipe(convertConstEnums()) }),
|
||||
project.compile(typescriptServicesProject, {
|
||||
js: files => files
|
||||
.pipe(prepend.file(copyright))
|
||||
.pipe(rename("typescriptServices.js")),
|
||||
dts: files => files
|
||||
.pipe(removeSourceMaps())
|
||||
.pipe(prepend.file(copyright))
|
||||
.pipe(convertConstEnums())
|
||||
.pipe(rename("typescriptServices.d.ts"))
|
||||
}),
|
||||
{ aliases: [typescriptServicesDts] });
|
||||
|
||||
const typescriptJs = "built/local/typescript.js";
|
||||
@@ -179,29 +185,39 @@ gulp.task(typescriptStandaloneDts, /*help*/ false, [typescriptServicesDts], () =
|
||||
// build all 'typescriptServices'-related outputs
|
||||
gulp.task("services", /*help*/ false, [typescriptServicesJs, typescriptServicesDts, typescriptJs, typescriptDts, typescriptStandaloneDts]);
|
||||
|
||||
const useCompiler = cmdLineOptions.lkg ? "lkg" : "built";
|
||||
const useCompilerDeps = cmdLineOptions.lkg ? ["lib", "generate-diagnostics"] : [typescriptServicesJs];
|
||||
|
||||
const tscProject = "src/tsc/tsconfig.json";
|
||||
const tscJs = "built/local/tsc.js";
|
||||
gulp.task(tscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(tscProject, { typescript: "built" }));
|
||||
gulp.task(tscJs, /*help*/ false, useCompilerDeps, () =>
|
||||
project.compile(tscProject, {
|
||||
typescript: useCompiler,
|
||||
js: files => files.pipe(prepend.file(copyright))
|
||||
}));
|
||||
|
||||
const tscReleaseProject = "src/tsc/tsconfig.release.json";
|
||||
const tscReleaseJs = "built/local/tsc.release.js";
|
||||
gulp.task(tscReleaseJs, /*help*/ false, () => project.compile(tscReleaseProject));
|
||||
gulp.task(tscReleaseJs, /*help*/ false, () =>
|
||||
project.compile(tscReleaseProject, {
|
||||
js: files => files.pipe(prepend.file(copyright))
|
||||
}));
|
||||
|
||||
const cancellationTokenProject = "src/cancellationToken/tsconfig.json";
|
||||
const cancellationTokenJs = "built/local/cancellationToken.js";
|
||||
gulp.task(cancellationTokenJs, /*help*/ false, [typescriptServicesJs], () => project.compile(cancellationTokenProject, { typescript: "built" }));
|
||||
gulp.task(cancellationTokenJs, /*help*/ false, useCompilerDeps, () => project.compile(cancellationTokenProject, { typescript: useCompiler }));
|
||||
|
||||
const typingsInstallerProject = "src/typingsInstaller/tsconfig.json";
|
||||
const typingsInstallerJs = "built/local/typingsInstaller.js";
|
||||
gulp.task(typingsInstallerJs, /*help*/ false, [typescriptServicesJs], () => project.compile(typingsInstallerProject, { typescript: "built" }));
|
||||
gulp.task(typingsInstallerJs, /*help*/ false, useCompilerDeps, () => project.compile(typingsInstallerProject, { typescript: useCompiler }));
|
||||
|
||||
const tsserverProject = "src/tsserver/tsconfig.json";
|
||||
const tsserverJs = "built/local/tsserver.js";
|
||||
gulp.task(tsserverJs, /*help*/ false, [typescriptServicesJs], () => project.compile(tsserverProject, { typescript: "built" }));
|
||||
gulp.task(tsserverJs, /*help*/ false, useCompilerDeps, () => project.compile(tsserverProject, { typescript: useCompiler }));
|
||||
|
||||
const watchGuardProject = "src/watchGuard/tsconfig.json";
|
||||
const watchGuardJs = "built/local/watchGuard.js";
|
||||
gulp.task(watchGuardJs, /*help*/ false, [typescriptServicesJs], () => project.compile(watchGuardProject, { typescript: "built" }));
|
||||
gulp.task(watchGuardJs, /*help*/ false, useCompilerDeps, () => project.compile(watchGuardProject, { typescript: useCompiler }));
|
||||
|
||||
const typesMapJson = "built/local/typesMap.json";
|
||||
gulp.task(typesMapJson, /*help*/ false, [], () =>
|
||||
@@ -216,21 +232,28 @@ gulp.task(tsserverlibraryProject, /*help*/ false, () => {
|
||||
project.flatten("src/tsserver/tsconfig.json", tsserverlibraryProject, {
|
||||
exclude: ["src/tsserver/server.ts"],
|
||||
compilerOptions: {
|
||||
"removeComments": true,
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"outFile": "tsserverlibrary.js"
|
||||
"declarationMap": false,
|
||||
"outFile": "tsserverlibrary.out.js" // must align with same task in jakefile. We fix this name below.
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const tsserverlibraryJs = "built/local/tsserverlibrary.js";
|
||||
const tsserverlibraryDts = "built/local/tsserverlibrary.d.ts";
|
||||
gulp.task(tsserverlibraryJs, /*help*/ false, [typescriptServicesJs, tsserverlibraryProject], () =>
|
||||
gulp.task(tsserverlibraryJs, /*help*/ false, useCompilerDeps.concat([tsserverlibraryProject]), () =>
|
||||
project.compile(tsserverlibraryProject, {
|
||||
js: files => files
|
||||
.pipe(prepend.file(copyright))
|
||||
.pipe(rename("tsserverlibrary.js")),
|
||||
dts: files => files
|
||||
.pipe(removeSourceMaps())
|
||||
.pipe(prepend.file(copyright))
|
||||
.pipe(convertConstEnums())
|
||||
.pipe(append("\nexport = ts;\nexport as namespace ts;")),
|
||||
typescript: "built"
|
||||
.pipe(append("\nexport = ts;\nexport as namespace ts;"))
|
||||
.pipe(rename("tsserverlibrary.d.ts")),
|
||||
typescript: useCompiler
|
||||
}), { aliases: [tsserverlibraryDts] });
|
||||
|
||||
gulp.task(
|
||||
@@ -294,29 +317,29 @@ gulp.task(
|
||||
// Task to build the tests infrastructure using the built compiler
|
||||
const testRunnerProject = "src/testRunner/tsconfig.json";
|
||||
const runJs = "built/local/run.js";
|
||||
gulp.task(runJs, /*help*/ false, [typescriptServicesJs, tsserverlibraryDts], () => project.compile(testRunnerProject, { typescript: "built" }));
|
||||
gulp.task(runJs, /*help*/ false, useCompilerDeps, () => project.compile(testRunnerProject, { typescript: useCompiler }));
|
||||
|
||||
gulp.task(
|
||||
"tests",
|
||||
"Builds the test infrastructure using the built compiler",
|
||||
[runJs]);
|
||||
[runJs, tsserverlibraryDts]);
|
||||
|
||||
gulp.task(
|
||||
"runtests-parallel",
|
||||
"Runs all the tests in parallel using the built run.js file. Optional arguments are: --t[ests]=category1|category2|... --d[ebug]=true.",
|
||||
["build-rules", "tests"],
|
||||
() => runConsoleTests(runJs, "min", /*runInParallel*/ true));
|
||||
["build-rules", "tests", "services", tsserverlibraryDts],
|
||||
() => runConsoleTests(runJs, "min", /*runInParallel*/ true, /*watchMode*/ false));
|
||||
|
||||
gulp.task(
|
||||
"runtests",
|
||||
"Runs the tests using the built run.js file. Optional arguments are: --t[ests]=regex --r[eporter]=[list|spec|json|<more>] --d[ebug]=true --color[s]=false --lint=true.",
|
||||
["build-rules", "tests"],
|
||||
() => runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false));
|
||||
["build-rules", "tests", "services", tsserverlibraryDts],
|
||||
() => runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ false));
|
||||
|
||||
const webTestServerProject = "tests/webTestServer.tsconfig.json";
|
||||
const webTestServerJs = "tests/webTestServer.js";
|
||||
gulp.task(webTestServerJs, /*help*/ false, [typescriptServicesJs], () => project.compile(webTestServerProject, { typescript: "built" }));
|
||||
gulp.task("clean:" + webTestServerJs, /*help*/ false, () => project.clean(webTestServerProject));
|
||||
gulp.task(webTestServerJs, /*help*/ false, useCompilerDeps, () => project.compile(webTestServerProject, { typescript: useCompiler }));
|
||||
gulp.task(`clean:${webTestServerJs}`, /*help*/ false, () => project.clean(webTestServerProject));
|
||||
|
||||
const bundlePath = path.resolve("built/local/bundle.js");
|
||||
|
||||
@@ -392,8 +415,8 @@ gulp.task(
|
||||
// Webhost
|
||||
const webtscProject = "tests/webhost/webtsc.tsconfig.json";
|
||||
const webtscJs = "tests/webhost/webtsc.js";
|
||||
gulp.task(webtscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(webtscProject, { typescript: "built" }));
|
||||
gulp.task("clean:" + webtscJs, /*help*/ false, () => project.clean(webtscProject));
|
||||
gulp.task(webtscJs, /*help*/ false, useCompilerDeps, () => project.compile(webtscProject, { typescript: useCompiler }));
|
||||
gulp.task(`clean:${webtscJs}`, /*help*/ false, () => project.clean(webtscProject));
|
||||
|
||||
gulp.task("webhost", "Builds the tsc web host", [webtscJs], () =>
|
||||
gulp.src("built/local/lib.d.ts")
|
||||
@@ -402,8 +425,8 @@ gulp.task("webhost", "Builds the tsc web host", [webtscJs], () =>
|
||||
// Perf compiler
|
||||
const perftscProject = "tests/perftsc.tsconfig.json";
|
||||
const perftscJs = "built/local/perftsc.js";
|
||||
gulp.task(perftscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(perftscProject, { typescript: "built" }));
|
||||
gulp.task("clean:" + perftscJs, /*help*/ false, () => project.clean(perftscProject));
|
||||
gulp.task(perftscJs, /*help*/ false, useCompilerDeps, () => project.compile(perftscProject, { typescript: useCompiler }));
|
||||
gulp.task(`clean:${perftscJs}`, /*help*/ false, () => project.clean(perftscProject));
|
||||
|
||||
gulp.task(
|
||||
"perftsc",
|
||||
@@ -423,7 +446,7 @@ gulp.task(loggedIOJs, /*help*/ false, [], (done) => {
|
||||
const instrumenterProject = "src/instrumenter/tsconfig.json";
|
||||
const instrumenterJs = "built/local/instrumenter.js";
|
||||
gulp.task(instrumenterJs, /*help*/ false, () => project.compile(instrumenterProject));
|
||||
gulp.task("clean:" + instrumenterJs, /*help*/ false, () => project.clean(instrumenterProject));
|
||||
gulp.task(`clean:${instrumenterJs}`, /*help*/ false, () => project.clean(instrumenterProject));
|
||||
|
||||
gulp.task(
|
||||
"tsc-instrumented",
|
||||
@@ -479,20 +502,37 @@ gulp.task(
|
||||
gulp.task(
|
||||
"watch-tsc",
|
||||
/*help*/ false,
|
||||
["watch-diagnostics", "watch-lib", typescriptServicesJs],
|
||||
() => project.watch(tscProject, { typescript: "built" }));
|
||||
["watch-diagnostics", "watch-lib"].concat(useCompilerDeps),
|
||||
() => project.watch(tscProject, { typescript: useCompiler }));
|
||||
|
||||
const watchServicesPatterns = [
|
||||
"src/compiler/**/*",
|
||||
"src/jsTypings/**/*",
|
||||
"src/services/**/*"
|
||||
];
|
||||
|
||||
gulp.task(
|
||||
"watch-services",
|
||||
/*help*/ false,
|
||||
["watch-diagnostics", "watch-lib", typescriptServicesJs],
|
||||
() => project.watch(servicesProject, { typescript: "built" }));
|
||||
["watch-diagnostics", "watch-lib"],
|
||||
() => gulp.watch(watchServicesPatterns, ["services"]));
|
||||
|
||||
const watchLsslPatterns = [
|
||||
...watchServicesPatterns,
|
||||
"src/server/**/*",
|
||||
"src/tsserver/tsconfig.json"
|
||||
];
|
||||
|
||||
gulp.task(
|
||||
"watch-lssl",
|
||||
/*help*/ false,
|
||||
() => gulp.watch(watchLsslPatterns, ["lssl"]));
|
||||
|
||||
gulp.task(
|
||||
"watch-server",
|
||||
/*help*/ false,
|
||||
["watch-diagnostics", "watch-lib", typescriptServicesJs],
|
||||
() => project.watch(tsserverProject, { typescript: "built" }));
|
||||
["watch-diagnostics", "watch-lib"].concat(useCompilerDeps),
|
||||
() => project.watch(tsserverProject, { typescript: useCompiler }));
|
||||
|
||||
gulp.task(
|
||||
"watch-local",
|
||||
@@ -500,22 +540,64 @@ gulp.task(
|
||||
["watch-lib", "watch-tsc", "watch-services", "watch-server"]);
|
||||
|
||||
gulp.task(
|
||||
"watch",
|
||||
"Watches for changes to the build inputs for built/local/run.js executes runtests-parallel.",
|
||||
[typescriptServicesJs],
|
||||
() => project.watch(testRunnerProject, { typescript: "built" }, ["runtests-parallel"]));
|
||||
"watch-runner",
|
||||
/*help*/ false,
|
||||
useCompilerDeps,
|
||||
() => project.watch(testRunnerProject, { typescript: useCompiler }));
|
||||
|
||||
gulp.task("clean-built", /*help*/ false, ["clean:" + diagnosticInformationMapTs], () => del(["built"]));
|
||||
const watchPatterns = [
|
||||
runJs,
|
||||
typescriptDts,
|
||||
tsserverlibraryDts
|
||||
];
|
||||
|
||||
gulp.task(
|
||||
"watch",
|
||||
"Watches for changes to the build inputs for built/local/run.js, then executes runtests-parallel.",
|
||||
["build-rules", "watch-runner", "watch-services", "watch-lssl"],
|
||||
() => {
|
||||
/** @type {CancelSource | undefined} */
|
||||
let runTestsSource;
|
||||
|
||||
const fn = debounce(() => {
|
||||
runTests().catch(error => {
|
||||
if (error instanceof CancelError) {
|
||||
log.warn("Operation was canceled");
|
||||
}
|
||||
else {
|
||||
log.error(error);
|
||||
}
|
||||
});
|
||||
}, /*timeout*/ 100, { max: 500 });
|
||||
|
||||
gulp.watch(watchPatterns, () => project.wait().then(fn));
|
||||
|
||||
// NOTE: gulp.watch is far too slow when watching tests/cases/**/* as it first enumerates *every* file
|
||||
const testFilePattern = /(\.ts|[\\/]tsconfig\.json)$/;
|
||||
fs.watch("tests/cases", { recursive: true }, (_, file) => {
|
||||
if (testFilePattern.test(file)) project.wait().then(fn);
|
||||
});
|
||||
|
||||
function runTests() {
|
||||
if (runTestsSource) runTestsSource.cancel();
|
||||
runTestsSource = new CancelSource();
|
||||
return cmdLineOptions.tests || cmdLineOptions.failed
|
||||
? runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ true, runTestsSource.token)
|
||||
: runConsoleTests(runJs, "min", /*runInParallel*/ true, /*watchMode*/ true, runTestsSource.token);
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task("clean-built", /*help*/ false, [`clean:${diagnosticInformationMapTs}`], () => del(["built"]));
|
||||
gulp.task(
|
||||
"clean",
|
||||
"Cleans the compiler output, declare files, and tests",
|
||||
[
|
||||
"clean:" + importDefinitelyTypedTestsJs,
|
||||
"clean:" + webtscJs,
|
||||
"clean:" + perftscJs,
|
||||
"clean:" + instrumenterJs,
|
||||
"clean:" + webTestServerJs,
|
||||
"clean-scripts",
|
||||
`clean:${importDefinitelyTypedTestsJs}`,
|
||||
`clean:${webtscJs}`,
|
||||
`clean:${perftscJs}`,
|
||||
`clean:${instrumenterJs}`,
|
||||
`clean:${webTestServerJs}`,
|
||||
"clean:scripts",
|
||||
"clean-rules",
|
||||
"clean-built"
|
||||
]);
|
||||
+150
-50
@@ -9,6 +9,9 @@ const fold = require("travis-fold");
|
||||
const ts = require("./lib/typescript");
|
||||
const del = require("del");
|
||||
const getDirSize = require("./scripts/build/getDirSize");
|
||||
const { base64VLQFormatEncode } = require("./scripts/build/sourcemaps");
|
||||
const needsUpdate = require("./scripts/build/needsUpdate");
|
||||
const { flatten } = require("./scripts/build/project");
|
||||
|
||||
// add node_modules to path so we don't need global modules, prefer the modules by adding them first
|
||||
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
|
||||
@@ -64,9 +67,14 @@ Paths.typesMapOutput = "built/local/typesMap.json";
|
||||
Paths.typescriptFile = "built/local/typescript.js";
|
||||
Paths.servicesFile = "built/local/typescriptServices.js";
|
||||
Paths.servicesDefinitionFile = "built/local/typescriptServices.d.ts";
|
||||
Paths.servicesOutFile = "built/local/typescriptServices.out.js";
|
||||
Paths.servicesDefinitionOutFile = "built/local/typescriptServices.out.d.ts";
|
||||
Paths.typescriptDefinitionFile = "built/local/typescript.d.ts";
|
||||
Paths.typescriptStandaloneDefinitionFile = "built/local/typescript_standalone.d.ts";
|
||||
Paths.tsserverLibraryFile = "built/local/tsserverlibrary.js";
|
||||
Paths.tsserverLibraryDefinitionFile = "built/local/tsserverlibrary.d.ts";
|
||||
Paths.tsserverLibraryOutFile = "built/local/tsserverlibrary.out.js";
|
||||
Paths.tsserverLibraryDefinitionOutFile = "built/local/tsserverlibrary.out.d.ts";
|
||||
Paths.baselines = {};
|
||||
Paths.baselines.local = "tests/baselines/local";
|
||||
Paths.baselines.localTest262 = "tests/baselines/test262/local";
|
||||
@@ -101,7 +109,9 @@ const ConfigFileFor = {
|
||||
runjs: "src/testRunner",
|
||||
lint: "scripts/tslint",
|
||||
scripts: "scripts",
|
||||
all: "src"
|
||||
all: "src",
|
||||
typescriptServices: "built/local/typescriptServices.tsconfig.json",
|
||||
tsserverLibrary: "built/local/tsserverlibrary.tsconfig.json",
|
||||
};
|
||||
|
||||
const ExpectedLKGFiles = [
|
||||
@@ -124,13 +134,18 @@ desc("Builds the full compiler and services");
|
||||
task(TaskNames.local, [
|
||||
TaskNames.buildFoldStart,
|
||||
TaskNames.coreBuild,
|
||||
Paths.servicesDefinitionFile,
|
||||
Paths.typescriptFile,
|
||||
Paths.typescriptDefinitionFile,
|
||||
Paths.typescriptStandaloneDefinitionFile,
|
||||
Paths.tsserverLibraryDefinitionFile,
|
||||
TaskNames.localize,
|
||||
TaskNames.buildFoldEnd
|
||||
]);
|
||||
|
||||
task("default", [TaskNames.local]);
|
||||
|
||||
const RunTestsPrereqs = [TaskNames.lib, Paths.servicesDefinitionFile, Paths.tsserverLibraryDefinitionFile];
|
||||
const RunTestsPrereqs = [TaskNames.lib, Paths.servicesDefinitionFile, Paths.typescriptDefinitionFile, Paths.tsserverLibraryDefinitionFile];
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
||||
task(TaskNames.runtestsParallel, RunTestsPrereqs, function () {
|
||||
tsbuild([ConfigFileFor.runjs], true, () => {
|
||||
@@ -172,6 +187,9 @@ task(TaskNames.lkg, [
|
||||
TaskNames.release,
|
||||
TaskNames.local,
|
||||
Paths.servicesDefinitionFile,
|
||||
Paths.typescriptFile,
|
||||
Paths.typescriptDefinitionFile,
|
||||
Paths.typescriptStandaloneDefinitionFile,
|
||||
Paths.tsserverLibraryDefinitionFile,
|
||||
Paths.releaseCompiler,
|
||||
...libraryTargets
|
||||
@@ -333,64 +351,146 @@ file(Paths.diagnosticInformationMap, [Paths.diagnosticMessagesJson], function ()
|
||||
});
|
||||
}, { async: true });
|
||||
|
||||
// tsserverlibrary.d.ts
|
||||
file(Paths.tsserverLibraryDefinitionFile, [TaskNames.coreBuild], function() {
|
||||
const sources = ["compiler.d.ts", "jsTyping.d.ts", "services.d.ts", "server.d.ts"].map(f => path.join(Paths.builtLocal, f));
|
||||
let output = "";
|
||||
for (const f of sources) {
|
||||
output = output + "\n" + removeConstModifierFromEnumDeclarations(readFileSync(f));
|
||||
}
|
||||
output = output + "\nexport = ts;\nexport as namespace ts;";
|
||||
fs.writeFileSync(Paths.tsserverLibraryDefinitionFile, output, { encoding: "utf-8" });
|
||||
file(ConfigFileFor.tsserverLibrary, [], function () {
|
||||
flatten("src/tsserver/tsconfig.json", ConfigFileFor.tsserverLibrary, {
|
||||
exclude: ["src/tsserver/server.ts"],
|
||||
compilerOptions: {
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"declarationMap": false,
|
||||
"outFile": "tsserverlibrary.out.js"
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// typescriptservices.d.ts
|
||||
file(Paths.servicesDefinitionFile, [TaskNames.coreBuild], function() {
|
||||
// Generate a config file
|
||||
const files = [];
|
||||
recur(`src/services/tsconfig.json`);
|
||||
// tsserverlibrary.js
|
||||
// tsserverlibrary.d.ts
|
||||
file(Paths.tsserverLibraryFile, [TaskNames.coreBuild, ConfigFileFor.tsserverLibrary], function() {
|
||||
tsbuild(ConfigFileFor.tsserverLibrary, false, () => {
|
||||
if (needsUpdate([Paths.tsserverLibraryOutFile, Paths.tsserverLibraryDefinitionOutFile], [Paths.tsserverLibraryFile, Paths.tsserverLibraryDefinitionFile])) {
|
||||
const copyright = readFileSync(Paths.copyright);
|
||||
|
||||
const config = {
|
||||
extends: "../../src/tsconfig-base",
|
||||
let libraryDefinitionContent = readFileSync(Paths.tsserverLibraryDefinitionOutFile);
|
||||
libraryDefinitionContent = copyright + removeConstModifierFromEnumDeclarations(libraryDefinitionContent);
|
||||
libraryDefinitionContent += "\nexport = ts;\nexport as namespace ts;";
|
||||
fs.writeFileSync(Paths.tsserverLibraryDefinitionFile, libraryDefinitionContent, "utf8");
|
||||
|
||||
let libraryContent = readFileSync(Paths.tsserverLibraryOutFile);
|
||||
libraryContent = copyright + libraryContent;
|
||||
fs.writeFileSync(Paths.tsserverLibraryFile, libraryContent, "utf8");
|
||||
|
||||
// adjust source map for tsserverlibrary.js
|
||||
let libraryMapContent = readFileSync(Paths.tsserverLibraryOutFile + ".map");
|
||||
const map = JSON.parse(libraryMapContent);
|
||||
const lineStarts = /**@type {*}*/(ts).computeLineStarts(copyright);
|
||||
let prependMappings = "";
|
||||
for (let i = 1; i < lineStarts.length; i++) {
|
||||
prependMappings += ";";
|
||||
}
|
||||
|
||||
const offset = copyright.length - lineStarts[lineStarts.length - 1];
|
||||
if (offset > 0) {
|
||||
prependMappings += base64VLQFormatEncode(offset) + ",";
|
||||
}
|
||||
|
||||
const outputMap = {
|
||||
version: map.version,
|
||||
file: map.file,
|
||||
sources: map.sources,
|
||||
sourceRoot: map.sourceRoot,
|
||||
mappings: prependMappings + map.mappings,
|
||||
names: map.names,
|
||||
sourcesContent: map.sourcesContent
|
||||
};
|
||||
|
||||
libraryMapContent = JSON.stringify(outputMap);
|
||||
fs.writeFileSync(Paths.tsserverLibraryFile + ".map", libraryMapContent);
|
||||
}
|
||||
complete();
|
||||
});
|
||||
}, { async: true });
|
||||
task(Paths.tsserverLibraryDefinitionFile, [Paths.tsserverLibraryFile]);
|
||||
|
||||
file(ConfigFileFor.typescriptServices, [], function () {
|
||||
flatten("src/services/tsconfig.json", ConfigFileFor.typescriptServices, {
|
||||
compilerOptions: {
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"outFile": "typescriptServices.js"
|
||||
},
|
||||
files
|
||||
};
|
||||
"declarationMap": false,
|
||||
"outFile": "typescriptServices.out.js"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const configFilePath = `built/local/typescriptServices.tsconfig.json`;
|
||||
fs.writeFileSync(configFilePath, JSON.stringify(config, undefined, 2));
|
||||
tsbuild(configFilePath, false, () => {
|
||||
const servicesContent = readFileSync(Paths.servicesDefinitionFile);
|
||||
const servicesContentWithoutConstEnums = removeConstModifierFromEnumDeclarations(servicesContent);
|
||||
fs.writeFileSync(Paths.servicesDefinitionFile, servicesContentWithoutConstEnums);
|
||||
|
||||
// Also build typescript.js, typescript.js.map, and typescript.d.ts
|
||||
// typescriptServices.js
|
||||
// typescriptServices.d.ts
|
||||
file(Paths.servicesFile, [TaskNames.coreBuild, ConfigFileFor.typescriptServices], function() {
|
||||
tsbuild(ConfigFileFor.typescriptServices, false, () => {
|
||||
if (needsUpdate([Paths.servicesOutFile, Paths.servicesDefinitionOutFile], [Paths.servicesFile, Paths.servicesDefinitionFile])) {
|
||||
const copyright = readFileSync(Paths.copyright);
|
||||
|
||||
let servicesDefinitionContent = readFileSync(Paths.servicesDefinitionOutFile);
|
||||
servicesDefinitionContent = copyright + removeConstModifierFromEnumDeclarations(servicesDefinitionContent);
|
||||
fs.writeFileSync(Paths.servicesDefinitionFile, servicesDefinitionContent, "utf8");
|
||||
|
||||
let servicesContent = readFileSync(Paths.servicesOutFile);
|
||||
servicesContent = copyright + servicesContent;
|
||||
fs.writeFileSync(Paths.servicesFile, servicesContent, "utf8");
|
||||
|
||||
// adjust source map for typescriptServices.js
|
||||
let servicesMapContent = readFileSync(Paths.servicesOutFile + ".map");
|
||||
const map = JSON.parse(servicesMapContent);
|
||||
const lineStarts = /**@type {*}*/(ts).computeLineStarts(copyright);
|
||||
let prependMappings = "";
|
||||
for (let i = 1; i < lineStarts.length; i++) {
|
||||
prependMappings += ";";
|
||||
}
|
||||
|
||||
const offset = copyright.length - lineStarts[lineStarts.length - 1];
|
||||
if (offset > 0) {
|
||||
prependMappings += base64VLQFormatEncode(offset) + ",";
|
||||
}
|
||||
|
||||
const outputMap = {
|
||||
version: map.version,
|
||||
file: map.file,
|
||||
sources: map.sources,
|
||||
sourceRoot: map.sourceRoot,
|
||||
mappings: prependMappings + map.mappings,
|
||||
names: map.names,
|
||||
sourcesContent: map.sourcesContent
|
||||
};
|
||||
|
||||
servicesMapContent = JSON.stringify(outputMap);
|
||||
fs.writeFileSync(Paths.servicesFile + ".map", servicesMapContent);
|
||||
}
|
||||
|
||||
complete();
|
||||
});
|
||||
}, { async: true });
|
||||
task(Paths.servicesDefinitionFile, [Paths.servicesFile]);
|
||||
|
||||
// typescript.js
|
||||
// typescript.d.ts
|
||||
file(Paths.typescriptFile, [Paths.servicesFile], function() {
|
||||
if (needsUpdate([Paths.servicesFile, Paths.servicesDefinitionFile], [Paths.typescriptFile, Paths.typescriptDefinitionFile])) {
|
||||
jake.cpR(Paths.servicesFile, Paths.typescriptFile);
|
||||
if (fs.existsSync(Paths.servicesFile + ".map")) {
|
||||
jake.cpR(Paths.servicesFile + ".map", Paths.typescriptFile + ".map");
|
||||
}
|
||||
|
||||
fs.writeFileSync(Paths.typescriptDefinitionFile, servicesContentWithoutConstEnums + "\r\nexport = ts", { encoding: "utf-8" });
|
||||
// And typescript_standalone.d.ts
|
||||
fs.writeFileSync(Paths.typescriptStandaloneDefinitionFile, servicesContentWithoutConstEnums.replace(/declare (namespace|module) ts(\..+)? \{/g, 'declare module "typescript" {'), { encoding: "utf-8"});
|
||||
|
||||
complete();
|
||||
});
|
||||
|
||||
function recur(configPath) {
|
||||
const cfgFile = readJson(configPath);
|
||||
if (cfgFile.references) {
|
||||
for (const ref of cfgFile.references) {
|
||||
recur(path.join(path.dirname(configPath), ref.path, "tsconfig.json"));
|
||||
}
|
||||
}
|
||||
for (const file of cfgFile.files) {
|
||||
files.push(path.join(`../../`, path.dirname(configPath), file));
|
||||
}
|
||||
const content = readFileSync(Paths.servicesDefinitionFile);
|
||||
fs.writeFileSync(Paths.typescriptDefinitionFile, content + "\r\nexport = ts;", { encoding: "utf-8" });
|
||||
}
|
||||
}, { async: true });
|
||||
});
|
||||
task(Paths.typescriptDefinitionFile, [Paths.typescriptFile]);
|
||||
|
||||
// typescript_standalone.d.ts
|
||||
file(Paths.typescriptStandaloneDefinitionFile, [Paths.servicesDefinitionFile], function() {
|
||||
if (needsUpdate(Paths.servicesDefinitionFile, Paths.typescriptStandaloneDefinitionFile)) {
|
||||
const content = readFileSync(Paths.servicesDefinitionFile);
|
||||
fs.writeFileSync(Paths.typescriptStandaloneDefinitionFile, content.replace(/declare (namespace|module) ts(\..+)? \{/g, 'declare module "typescript" {'), { encoding: "utf-8"});
|
||||
}
|
||||
});
|
||||
|
||||
function getLibraryTargets() {
|
||||
/** @type {{ libs: string[], paths?: Record<string, string>, sources?: Record<string, string[]> }} */
|
||||
@@ -765,4 +865,4 @@ function getDiffTool() {
|
||||
*/
|
||||
function removeConstModifierFromEnumDeclarations(text) {
|
||||
return text.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
||||
}
|
||||
}
|
||||
+15
-101
@@ -1,120 +1,34 @@
|
||||
// @ts-check
|
||||
const Browserify = require("browserify");
|
||||
const Vinyl = require("vinyl");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const convertMap = require("convert-source-map");
|
||||
const applySourceMap = require("vinyl-sourcemaps-apply");
|
||||
const { Transform, Readable } = require("stream");
|
||||
const browserify = require("browserify");
|
||||
const Vinyl = require("./vinyl");
|
||||
const { Transform } = require("stream");
|
||||
const { streamFromFile } = require("./utils");
|
||||
const { replaceContents } = require("./sourcemaps");
|
||||
|
||||
module.exports = browserify;
|
||||
module.exports = browserifyFile;
|
||||
|
||||
/**
|
||||
* @param {import("browserify").Options} [opts]
|
||||
*/
|
||||
function browserify(opts) {
|
||||
function browserifyFile(opts) {
|
||||
return new Transform({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string | Buffer | File} input
|
||||
* @param {string | Buffer | Vinyl} input
|
||||
*/
|
||||
transform(input, _, cb) {
|
||||
if (typeof input === "string" || Buffer.isBuffer(input)) return cb(new Error("Only Vinyl files are supported."));
|
||||
try {
|
||||
const sourceMap = input.sourceMap;
|
||||
const cwd = input.cwd || process.cwd();
|
||||
const base = input.base || cwd;
|
||||
const output = /**@type {File}*/(new Vinyl({ path: input.path, base: input.base }));
|
||||
const stream = streamFromFile(input);
|
||||
const b = new Browserify(Object.assign({}, opts, { debug: !!sourceMap, basedir: input.base }));
|
||||
b.add(stream, { file: input.path, basedir: input.base });
|
||||
b.bundle((err, contents) => {
|
||||
if (err) return cb(err);
|
||||
output.contents = contents;
|
||||
if (sourceMap) {
|
||||
output.sourceMap = typeof sourceMap === "string" ? JSON.parse(sourceMap) : sourceMap;
|
||||
const sourceRoot = output.sourceMap.sourceRoot;
|
||||
makeAbsoluteSourceMap(cwd, base, output.sourceMap);
|
||||
const stringContents = contents.toString("utf8");
|
||||
const newSourceMapConverter = convertMap.fromSource(stringContents);
|
||||
if (newSourceMapConverter) {
|
||||
const newSourceMap = newSourceMapConverter.toObject();
|
||||
makeAbsoluteSourceMap(cwd, base, newSourceMap);
|
||||
applySourceMap(output, newSourceMap);
|
||||
makeRelativeSourceMap(cwd, base, sourceRoot, output.sourceMap);
|
||||
output.contents = new Buffer(convertMap.removeComments(stringContents), "utf8");
|
||||
}
|
||||
}
|
||||
cb(null, output);
|
||||
});
|
||||
browserify(Object.assign({}, opts, { debug: !!input.sourceMap, basedir: input.base }))
|
||||
.add(streamFromFile(input), { file: input.path, basedir: input.base })
|
||||
.bundle((err, contents) => {
|
||||
if (err) return cb(err);
|
||||
cb(null, replaceContents(input, contents));
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*
|
||||
* @typedef RawSourceMap
|
||||
* @property {string} version
|
||||
* @property {string} file
|
||||
* @property {string} [sourceRoot]
|
||||
* @property {string[]} sources
|
||||
* @property {string[]} [sourcesContents]
|
||||
* @property {string} mappings
|
||||
* @property {string[]} [names]
|
||||
*/
|
||||
function makeAbsoluteSourceMap(cwd = process.cwd(), base = "", sourceMap) {
|
||||
const sourceRoot = sourceMap.sourceRoot || "";
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.resolve(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.resolve(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {string} sourceRoot
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*/
|
||||
function makeRelativeSourceMap(cwd = process.cwd(), base = "", sourceRoot, sourceMap) {
|
||||
makeAbsoluteSourceMap(cwd, base, sourceMap);
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.relative(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.relative(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = sourceRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {File} file
|
||||
*/
|
||||
function streamFromFile(file) {
|
||||
return file.isBuffer() ? streamFromBuffer(file.contents) :
|
||||
file.isStream() ? file.contents :
|
||||
fs.createReadStream(file.path, { autoClose: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Buffer} buffer
|
||||
*/
|
||||
function streamFromBuffer(buffer) {
|
||||
return new Readable({
|
||||
read() {
|
||||
this.push(buffer);
|
||||
this.push(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("vinyl") & { sourceMap?: any }} File
|
||||
*/
|
||||
void 0;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// @ts-check
|
||||
const symSource = Symbol("CancelToken.source");
|
||||
const symToken = Symbol("CancelSource.token");
|
||||
const symCancellationRequested = Symbol("CancelSource.cancellationRequested");
|
||||
const symCancellationCallbacks = Symbol("CancelSource.cancellationCallbacks");
|
||||
|
||||
class CancelSource {
|
||||
constructor() {
|
||||
this[symCancellationRequested] = false;
|
||||
this[symCancellationCallbacks] = [];
|
||||
}
|
||||
|
||||
/** @type {CancelToken} */
|
||||
get token() {
|
||||
return this[symToken] || (this[symToken] = new CancelToken(this));
|
||||
}
|
||||
|
||||
cancel() {
|
||||
if (!this[symCancellationRequested]) {
|
||||
this[symCancellationRequested] = true;
|
||||
for (const callback of this[symCancellationCallbacks]) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.CancelSource = CancelSource;
|
||||
|
||||
class CancelToken {
|
||||
/**
|
||||
* @param {CancelSource} source
|
||||
*/
|
||||
constructor(source) {
|
||||
if (source[symToken]) return source[symToken];
|
||||
this[symSource] = source;
|
||||
}
|
||||
|
||||
/** @type {boolean} */
|
||||
get cancellationRequested() {
|
||||
return this[symSource][symCancellationRequested];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {() => void} callback
|
||||
*/
|
||||
subscribe(callback) {
|
||||
const source = this[symSource];
|
||||
if (source[symCancellationRequested]) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
source[symCancellationCallbacks].push(callback);
|
||||
|
||||
return {
|
||||
unsubscribe() {
|
||||
const index = source[symCancellationCallbacks].indexOf(callback);
|
||||
if (index !== -1) source[symCancellationCallbacks].splice(index, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.CancelToken = CancelToken;
|
||||
|
||||
class CancelError extends Error {
|
||||
constructor(message = "Operation was canceled") {
|
||||
super(message);
|
||||
this.name = "CancelError";
|
||||
}
|
||||
}
|
||||
exports.CancelError = CancelError;
|
||||
@@ -0,0 +1,31 @@
|
||||
// @ts-check
|
||||
module.exports = debounce;
|
||||
|
||||
/**
|
||||
* @param {() => void} cb
|
||||
* @param {number} timeout
|
||||
* @param {DebounceOptions} [opts]
|
||||
*
|
||||
* @typedef DebounceOptions
|
||||
* @property {number} [max]
|
||||
*/
|
||||
function debounce(cb, timeout, opts = {}) {
|
||||
if (timeout < 10) timeout = 10;
|
||||
let max = opts.max || 10;
|
||||
if (max < timeout) max = timeout;
|
||||
let minTimer;
|
||||
let maxTimer;
|
||||
return trigger;
|
||||
|
||||
function trigger() {
|
||||
if (max > timeout && !maxTimer) maxTimer = setTimeout(done, max);
|
||||
if (minTimer) clearTimeout(minTimer);
|
||||
minTimer = setTimeout(done, timeout);
|
||||
}
|
||||
|
||||
function done() {
|
||||
if (maxTimer) maxTimer = void clearTimeout(maxTimer);
|
||||
if (minTimer) minTimer = void clearTimeout(minTimer);
|
||||
cb();
|
||||
}
|
||||
}
|
||||
+16
-3
@@ -3,6 +3,7 @@ const cp = require("child_process");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const isWin = /^win/.test(process.platform);
|
||||
const chalk = require("./chalk");
|
||||
const { CancelToken, CancelError } = require("./cancellation");
|
||||
|
||||
module.exports = exec;
|
||||
|
||||
@@ -10,8 +11,11 @@ module.exports = exec;
|
||||
* Executes the provided command once with the supplied arguments.
|
||||
* @param {string} cmd
|
||||
* @param {string[]} args
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.ignoreExitCode]
|
||||
* @param {ExecOptions} [options]
|
||||
*
|
||||
* @typedef ExecOptions
|
||||
* @property {boolean} [ignoreExitCode]
|
||||
* @property {CancelToken} [cancelToken]
|
||||
*/
|
||||
function exec(cmd, args, options = {}) {
|
||||
return /**@type {Promise<{exitCode: number}>}*/(new Promise((resolve, reject) => {
|
||||
@@ -20,7 +24,13 @@ function exec(cmd, args, options = {}) {
|
||||
const subshellFlag = isWin ? "/c" : "-c";
|
||||
const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`];
|
||||
const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true });
|
||||
const subscription = options.cancelToken && options.cancelToken.subscribe(() => {
|
||||
ex.kill("SIGINT");
|
||||
ex.kill("SIGTERM");
|
||||
reject(new CancelError());
|
||||
});
|
||||
ex.on("exit", exitCode => {
|
||||
subscription && subscription.unsubscribe();
|
||||
if (exitCode === 0 || options.ignoreExitCode) {
|
||||
resolve({ exitCode });
|
||||
}
|
||||
@@ -28,7 +38,10 @@ function exec(cmd, args, options = {}) {
|
||||
reject(new Error(`Process exited with code: ${exitCode}`));
|
||||
}
|
||||
});
|
||||
ex.on("error", reject);
|
||||
ex.on("error", error => {
|
||||
subscription && subscription.unsubscribe();
|
||||
reject(error);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const os = require("os");
|
||||
|
||||
/** @type {CommandLineOptions} */
|
||||
module.exports = minimist(process.argv.slice(2), {
|
||||
boolean: ["debug", "inspect", "light", "colors", "lint", "soft", "fix", "failed", "keepFailed"],
|
||||
boolean: ["debug", "dirty", "inspect", "light", "colors", "lint", "lkg", "soft", "fix", "failed", "keepFailed"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit", "timeout"],
|
||||
alias: {
|
||||
"b": "browser",
|
||||
@@ -33,17 +33,21 @@ module.exports = minimist(process.argv.slice(2), {
|
||||
fix: process.env.fix || process.env.f,
|
||||
workers: process.env.workerCount || os.cpus().length,
|
||||
failed: false,
|
||||
keepFailed: false
|
||||
keepFailed: false,
|
||||
lkg: false,
|
||||
dirty: false
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @typedef TypedOptions
|
||||
* @property {boolean} debug
|
||||
* @property {boolean} dirty
|
||||
* @property {boolean} inspect
|
||||
* @property {boolean} light
|
||||
* @property {boolean} colors
|
||||
* @property {boolean} lint
|
||||
* @property {boolean} lkg
|
||||
* @property {boolean} soft
|
||||
* @property {boolean} fix
|
||||
* @property {string} browser
|
||||
@@ -56,7 +60,7 @@ module.exports = minimist(process.argv.slice(2), {
|
||||
* @property {string|number} timeout
|
||||
* @property {boolean} failed
|
||||
* @property {boolean} keepFailed
|
||||
*
|
||||
*
|
||||
* @typedef {import("minimist").ParsedArgs & TypedOptions} CommandLineOptions
|
||||
*/
|
||||
void 0;
|
||||
@@ -0,0 +1,66 @@
|
||||
// @ts-check
|
||||
const stream = require("stream");
|
||||
const Vinyl = require("./vinyl");
|
||||
const ts = require("../../lib/typescript");
|
||||
const fs = require("fs");
|
||||
const { base64VLQFormatEncode } = require("./sourcemaps");
|
||||
|
||||
module.exports = exports = prepend;
|
||||
|
||||
/**
|
||||
* @param {string | ((file: Vinyl) => string)} data
|
||||
*/
|
||||
function prepend(data) {
|
||||
return new stream.Transform({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string | Buffer | Vinyl} input
|
||||
* @param {(error: Error, data?: any) => void} cb
|
||||
*/
|
||||
transform(input, _, cb) {
|
||||
if (typeof input === "string" || Buffer.isBuffer(input)) return cb(new Error("Only Vinyl files are supported."));
|
||||
if (!input.isBuffer()) return cb(new Error("Streams not supported."));
|
||||
try {
|
||||
const output = input.clone();
|
||||
const prependContent = typeof data === "function" ? data(input) : data;
|
||||
output.contents = Buffer.concat([Buffer.from(prependContent, "utf8"), input.contents]);
|
||||
if (input.sourceMap) {
|
||||
if (typeof input.sourceMap === "string") input.sourceMap = /**@type {import("./sourcemaps").RawSourceMap}*/(JSON.parse(input.sourceMap));
|
||||
const lineStarts = /**@type {*}*/(ts).computeLineStarts(prependContent);
|
||||
let prependMappings = "";
|
||||
for (let i = 1; i < lineStarts.length; i++) {
|
||||
prependMappings += ";";
|
||||
}
|
||||
const offset = prependContent.length - lineStarts[lineStarts.length - 1];
|
||||
if (offset > 0) {
|
||||
prependMappings += base64VLQFormatEncode(offset) + ",";
|
||||
}
|
||||
output.sourceMap = {
|
||||
version: input.sourceMap.version,
|
||||
file: input.sourceMap.file,
|
||||
sources: input.sourceMap.sources,
|
||||
sourceRoot: input.sourceMap.sourceRoot,
|
||||
mappings: prependMappings + input.sourceMap.mappings,
|
||||
names: input.names,
|
||||
sourcesContent: input.sourcesContent
|
||||
};
|
||||
}
|
||||
return cb(null, output);
|
||||
}
|
||||
catch (e) {
|
||||
return cb(e);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
exports.prepend = prepend;
|
||||
|
||||
/**
|
||||
* @param {string | ((file: Vinyl) => string)} file
|
||||
*/
|
||||
function prependFile(file) {
|
||||
const data = typeof file === "string" ? fs.readFileSync(file, "utf8") :
|
||||
vinyl => fs.readFileSync(file(vinyl), "utf8");
|
||||
return prepend(data)
|
||||
}
|
||||
exports.file = prependFile;
|
||||
@@ -209,6 +209,27 @@ function flatten(projectSpec, flattenedProjectSpec, options = {}) {
|
||||
}
|
||||
exports.flatten = flatten;
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves when all pending build tasks have completed
|
||||
*/
|
||||
function wait() {
|
||||
return new Promise(resolve => {
|
||||
if (compilationGulp.allDone()) {
|
||||
resolve();
|
||||
}
|
||||
else {
|
||||
const onDone = () => {
|
||||
compilationGulp.removeListener("onDone", onDone);
|
||||
compilationGulp.removeListener("err", onDone);
|
||||
resolve();
|
||||
};
|
||||
compilationGulp.on("stop", onDone);
|
||||
compilationGulp.on("err", onDone);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.wait = wait;
|
||||
|
||||
/**
|
||||
* Resolve a TypeScript specifier into a fully-qualified module specifier and any requisite dependencies.
|
||||
* @param {string} typescript An unresolved module specifier to a TypeScript version.
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
// @ts-check
|
||||
const path = require("path");
|
||||
const Vinyl = require("./vinyl");
|
||||
const convertMap = require("convert-source-map");
|
||||
const applySourceMap = require("vinyl-sourcemaps-apply");
|
||||
const through2 = require("through2");
|
||||
|
||||
/**
|
||||
* @param {Vinyl} input
|
||||
* @param {string | Buffer} contents
|
||||
* @param {string | RawSourceMap} [sourceMap]
|
||||
*/
|
||||
function replaceContents(input, contents, sourceMap) {
|
||||
const output = input.clone();
|
||||
output.contents = typeof contents === "string" ? Buffer.from(contents, "utf8") : contents;
|
||||
if (input.sourceMap) {
|
||||
output.sourceMap = typeof input.sourceMap === "string" ? /**@type {RawSourceMap}*/(JSON.parse(input.sourceMap)) : input.sourceMap;
|
||||
if (typeof sourceMap === "string") {
|
||||
sourceMap = /**@type {RawSourceMap}*/(JSON.parse(sourceMap));
|
||||
}
|
||||
else if (sourceMap === undefined) {
|
||||
const stringContents = typeof contents === "string" ? contents : contents.toString("utf8");
|
||||
const newSourceMapConverter = convertMap.fromSource(stringContents);
|
||||
if (newSourceMapConverter) {
|
||||
sourceMap = /**@type {RawSourceMap}*/(newSourceMapConverter.toObject());
|
||||
output.contents = new Buffer(convertMap.removeMapFileComments(stringContents), "utf8");
|
||||
}
|
||||
}
|
||||
if (sourceMap) {
|
||||
const cwd = input.cwd || process.cwd();
|
||||
const base = input.base || cwd;
|
||||
const sourceRoot = output.sourceMap.sourceRoot;
|
||||
makeAbsoluteSourceMap(cwd, base, output.sourceMap);
|
||||
makeAbsoluteSourceMap(cwd, base, sourceMap);
|
||||
applySourceMap(output, sourceMap);
|
||||
makeRelativeSourceMap(cwd, base, sourceRoot, output.sourceMap);
|
||||
}
|
||||
else {
|
||||
output.sourceMap = undefined;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
exports.replaceContents = replaceContents;
|
||||
|
||||
function removeSourceMaps() {
|
||||
return through2.obj((/**@type {Vinyl}*/file, _, cb) => {
|
||||
if (file.sourceMap && file.isBuffer()) {
|
||||
file.contents = Buffer.from(convertMap.removeMapFileComments(file.contents.toString("utf8")), "utf8");
|
||||
file.sourceMap = undefined;
|
||||
}
|
||||
cb(null, file);
|
||||
});
|
||||
}
|
||||
exports.removeSourceMaps = removeSourceMaps;
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*
|
||||
* @typedef RawSourceMap
|
||||
* @property {string} version
|
||||
* @property {string} file
|
||||
* @property {string} [sourceRoot]
|
||||
* @property {string[]} sources
|
||||
* @property {string[]} [sourcesContent]
|
||||
* @property {string} mappings
|
||||
* @property {string[]} [names]
|
||||
*/
|
||||
function makeAbsoluteSourceMap(cwd = process.cwd(), base = "", sourceMap) {
|
||||
const sourceRoot = sourceMap.sourceRoot || "";
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.resolve(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.resolve(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = "";
|
||||
}
|
||||
exports.makeAbsoluteSourceMap = makeAbsoluteSourceMap;
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {string} sourceRoot
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*/
|
||||
function makeRelativeSourceMap(cwd = process.cwd(), base = "", sourceRoot, sourceMap) {
|
||||
makeAbsoluteSourceMap(cwd, base, sourceMap);
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.relative(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.relative(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = sourceRoot;
|
||||
}
|
||||
exports.makeRelativeSourceMap = makeRelativeSourceMap;
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
* @returns {never}
|
||||
*/
|
||||
function fail(message) {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
*/
|
||||
function base64FormatEncode(value) {
|
||||
return value < 0 ? fail("Invalid value") :
|
||||
value < 26 ? 0x41 /*A*/ + value :
|
||||
value < 52 ? 0x61 /*a*/ + value - 26 :
|
||||
value < 62 ? 0x30 /*0*/ + value - 52 :
|
||||
value === 62 ? 0x2B /*+*/ :
|
||||
value === 63 ? 0x2F /*/*/ :
|
||||
fail("Invalid value");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
*/
|
||||
function base64VLQFormatEncode(value) {
|
||||
if (value < 0) {
|
||||
value = ((-value) << 1) + 1;
|
||||
}
|
||||
else {
|
||||
value = value << 1;
|
||||
}
|
||||
|
||||
// Encode 5 bits at a time starting from least significant bits
|
||||
let result = "";
|
||||
do {
|
||||
let currentDigit = value & 31; // 11111
|
||||
value = value >> 5;
|
||||
if (value > 0) {
|
||||
// There are still more digits to decode, set the msb (6th bit)
|
||||
currentDigit = currentDigit | 32;
|
||||
}
|
||||
result += String.fromCharCode(base64FormatEncode(currentDigit));
|
||||
} while (value > 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
exports.base64VLQFormatEncode = base64VLQFormatEncode;
|
||||
+108
-106
@@ -1,4 +1,5 @@
|
||||
// @ts-check
|
||||
const gulp = require("./gulp");
|
||||
const del = require("del");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
@@ -6,13 +7,8 @@ const path = require("path");
|
||||
const mkdirP = require("./mkdirp");
|
||||
const cmdLineOptions = require("./options");
|
||||
const exec = require("./exec");
|
||||
const runSequence = require("run-sequence");
|
||||
const finished = require("./finished");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
|
||||
const nodeModulesPathPrefix = path.resolve("./node_modules/.bin/");
|
||||
const isWin = /^win/.test(process.platform);
|
||||
const mocha = path.join(nodeModulesPathPrefix, "mocha") + (isWin ? ".cmd" : "");
|
||||
const mochaJs = require.resolve("mocha/bin/_mocha");
|
||||
|
||||
exports.localBaseline = "tests/baselines/local/";
|
||||
exports.refBaseline = "tests/baselines/reference/";
|
||||
@@ -24,8 +20,10 @@ exports.localTest262Baseline = "internal/baselines/test262/local";
|
||||
* @param {string} runJs
|
||||
* @param {string} defaultReporter
|
||||
* @param {boolean} runInParallel
|
||||
* @param {boolean} watchMode
|
||||
* @param {InstanceType<typeof import("./cancellation").CancelToken>} [cancelToken]
|
||||
*/
|
||||
function runConsoleTests(runJs, defaultReporter, runInParallel) {
|
||||
async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, cancelToken) {
|
||||
let testTimeout = cmdLineOptions.timeout;
|
||||
let tests = cmdLineOptions.tests;
|
||||
const lintFlag = cmdLineOptions.lint;
|
||||
@@ -36,112 +34,116 @@ function runConsoleTests(runJs, defaultReporter, runInParallel) {
|
||||
const stackTraceLimit = cmdLineOptions.stackTraceLimit;
|
||||
const testConfigFile = "test.config";
|
||||
const failed = cmdLineOptions.failed;
|
||||
const keepFailed = cmdLineOptions.keepFailed || failed;
|
||||
return cleanTestDirs()
|
||||
.then(() => {
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
fs.unlinkSync(testConfigFile);
|
||||
}
|
||||
|
||||
let workerCount, taskConfigsFolder;
|
||||
if (runInParallel) {
|
||||
// generate name to store task configuration files
|
||||
const prefix = os.tmpdir() + "/ts-tests";
|
||||
let i = 1;
|
||||
do {
|
||||
taskConfigsFolder = prefix + i;
|
||||
i++;
|
||||
} while (fs.existsSync(taskConfigsFolder));
|
||||
fs.mkdirSync(taskConfigsFolder);
|
||||
|
||||
workerCount = cmdLineOptions.workers;
|
||||
}
|
||||
|
||||
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
||||
testTimeout = 400000;
|
||||
}
|
||||
|
||||
if (tests || runners || light || testTimeout || taskConfigsFolder || keepFailed) {
|
||||
writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout, keepFailed);
|
||||
}
|
||||
|
||||
const colors = cmdLineOptions.colors;
|
||||
const reporter = cmdLineOptions.reporter || defaultReporter;
|
||||
|
||||
/** @type {string} */
|
||||
let host = "node";
|
||||
|
||||
/** @type {string[]} */
|
||||
let args = [];
|
||||
|
||||
// timeout normally isn"t necessary but Travis-CI has been timing out on compiler baselines occasionally
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
args.push("-R", "scripts/failed-tests");
|
||||
args.push("-O", '"reporter=' + reporter + (keepFailed ? ",keepFailed=true" : "") + '"');
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
}
|
||||
if (colors) {
|
||||
args.push("--colors");
|
||||
}
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
if (inspect) {
|
||||
args.unshift("--inspect-brk");
|
||||
}
|
||||
else if (debug) {
|
||||
args.unshift("--debug-brk");
|
||||
}
|
||||
else {
|
||||
args.push("-t", "" + testTimeout);
|
||||
}
|
||||
args.push(runJs);
|
||||
host = mocha;
|
||||
}
|
||||
else {
|
||||
// run task to load all tests and partition them between workers
|
||||
host = "node";
|
||||
args.push(runJs);
|
||||
}
|
||||
setNodeEnvToDevelopment();
|
||||
if (failed) {
|
||||
return exec(host, ["scripts/run-failed-tests.js"].concat(args));
|
||||
}
|
||||
else {
|
||||
return exec(host, args);
|
||||
}
|
||||
})
|
||||
.then(({ exitCode }) => {
|
||||
if (exitCode !== 0) return finish(undefined, exitCode);
|
||||
if (lintFlag) return finished(runSequence("lint")).then(() => finish(), finish);
|
||||
return finish();
|
||||
}, finish);
|
||||
|
||||
/**
|
||||
* @param {any=} error
|
||||
* @param {number=} errorStatus
|
||||
*/
|
||||
function finish(error, errorStatus) {
|
||||
restoreSavedNodeEnv();
|
||||
return deleteTestConfig()
|
||||
.then(deleteTemporaryProjectOutput)
|
||||
.then(() => {
|
||||
if (error !== undefined || errorStatus !== undefined) {
|
||||
process.exit(typeof errorStatus === "number" ? errorStatus : 2);
|
||||
}
|
||||
});
|
||||
const keepFailed = cmdLineOptions.keepFailed;
|
||||
if (!cmdLineOptions.dirty) {
|
||||
await cleanTestDirs();
|
||||
}
|
||||
|
||||
function deleteTestConfig() {
|
||||
return del("test.config");
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
fs.unlinkSync(testConfigFile);
|
||||
}
|
||||
|
||||
let workerCount, taskConfigsFolder;
|
||||
if (runInParallel) {
|
||||
// generate name to store task configuration files
|
||||
const prefix = os.tmpdir() + "/ts-tests";
|
||||
let i = 1;
|
||||
do {
|
||||
taskConfigsFolder = prefix + i;
|
||||
i++;
|
||||
} while (fs.existsSync(taskConfigsFolder));
|
||||
fs.mkdirSync(taskConfigsFolder);
|
||||
|
||||
workerCount = cmdLineOptions.workers;
|
||||
}
|
||||
|
||||
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
||||
testTimeout = 400000;
|
||||
}
|
||||
|
||||
if (tests || runners || light || testTimeout || taskConfigsFolder || keepFailed) {
|
||||
writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout, keepFailed);
|
||||
}
|
||||
|
||||
const colors = cmdLineOptions.colors;
|
||||
const reporter = cmdLineOptions.reporter || defaultReporter;
|
||||
|
||||
/** @type {string[]} */
|
||||
let args = [];
|
||||
|
||||
// timeout normally isn"t necessary but Travis-CI has been timing out on compiler baselines occasionally
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
args.push(failed ? "scripts/run-failed-tests.js" : mochaJs);
|
||||
args.push("-R", "scripts/failed-tests");
|
||||
args.push("-O", '"reporter=' + reporter + (keepFailed ? ",keepFailed=true" : "") + '"');
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
}
|
||||
if (colors) {
|
||||
args.push("--colors");
|
||||
}
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
if (inspect) {
|
||||
args.unshift("--inspect-brk");
|
||||
}
|
||||
else if (debug) {
|
||||
args.unshift("--debug-brk");
|
||||
}
|
||||
else {
|
||||
args.push("-t", "" + testTimeout);
|
||||
}
|
||||
args.push(runJs);
|
||||
}
|
||||
else {
|
||||
// run task to load all tests and partition them between workers
|
||||
args.push(runJs);
|
||||
}
|
||||
|
||||
/** @type {number | undefined} */
|
||||
let errorStatus;
|
||||
|
||||
/** @type {Error | undefined} */
|
||||
let error;
|
||||
|
||||
try {
|
||||
setNodeEnvToDevelopment();
|
||||
const { exitCode } = await exec("node", args, { cancelToken });
|
||||
if (exitCode !== 0) {
|
||||
errorStatus = exitCode;
|
||||
error = new Error(`Process exited with status code ${errorStatus}.`);
|
||||
}
|
||||
else if (lintFlag) {
|
||||
await new Promise((resolve, reject) => gulp.start(["lint"], error => error ? reject(error) : resolve()));
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
errorStatus = undefined;
|
||||
error = e;
|
||||
}
|
||||
finally {
|
||||
restoreSavedNodeEnv();
|
||||
}
|
||||
|
||||
await del("test.config");
|
||||
await deleteTemporaryProjectOutput();
|
||||
|
||||
if (error !== undefined) {
|
||||
if (watchMode) {
|
||||
throw error;
|
||||
}
|
||||
else {
|
||||
log.error(error);
|
||||
process.exit(typeof errorStatus === "number" ? errorStatus : 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.runConsoleTests = runConsoleTests;
|
||||
|
||||
function cleanTestDirs() {
|
||||
return del([exports.localBaseline, exports.localRwcBaseline,])
|
||||
return del([exports.localBaseline, exports.localRwcBaseline])
|
||||
.then(() => mkdirP(exports.localRwcBaseline))
|
||||
.then(() => mkdirP(exports.localBaseline));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// @ts-check
|
||||
const fs = require("fs");
|
||||
const File = require("./vinyl");
|
||||
const { Readable } = require("stream");
|
||||
|
||||
/**
|
||||
* @param {File} file
|
||||
*/
|
||||
function streamFromFile(file) {
|
||||
return file.isBuffer() ? streamFromBuffer(file.contents) :
|
||||
file.isStream() ? file.contents :
|
||||
fs.createReadStream(file.path, { autoClose: true });
|
||||
}
|
||||
exports.streamFromFile = streamFromFile;
|
||||
|
||||
/**
|
||||
* @param {Buffer} buffer
|
||||
*/
|
||||
function streamFromBuffer(buffer) {
|
||||
return new Readable({
|
||||
read() {
|
||||
this.push(buffer);
|
||||
this.push(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.streamFromBuffer = streamFromBuffer;
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// NOTE: This makes it possible to correctly type vinyl Files under @ts-check.
|
||||
export = File;
|
||||
|
||||
declare class File<T extends File.Contents = File.Contents> {
|
||||
constructor(options?: File.VinylOptions<T>);
|
||||
|
||||
cwd: string;
|
||||
base: string;
|
||||
path: string;
|
||||
readonly history: ReadonlyArray<string>;
|
||||
contents: T;
|
||||
relative: string;
|
||||
dirname: string;
|
||||
basename: string;
|
||||
stem: string;
|
||||
extname: string;
|
||||
symlink: string | null;
|
||||
stat: import("fs").Stats | null;
|
||||
sourceMap?: import("./sourcemaps").RawSourceMap | string;
|
||||
|
||||
[custom: string]: any;
|
||||
|
||||
isBuffer(): this is T extends Buffer ? File<Buffer> : never;
|
||||
isStream(): this is T extends NodeJS.ReadableStream ? File<NodeJS.ReadableStream> : never;
|
||||
isNull(): this is T extends null ? File<null> : never;
|
||||
isDirectory(): this is T extends null ? File.Directory : never;
|
||||
isSymbolic(): this is T extends null ? File.Symbolic : never;
|
||||
clone(opts?: { contents?: boolean, deep?: boolean }): this;
|
||||
}
|
||||
|
||||
namespace File {
|
||||
export interface VinylOptions<T extends Contents = Contents> {
|
||||
cwd?: string;
|
||||
base?: string;
|
||||
path?: string;
|
||||
history?: ReadonlyArray<string>;
|
||||
stat?: import("fs").Stats;
|
||||
contents?: T;
|
||||
sourceMap?: import("./sourcemaps").RawSourceMap | string;
|
||||
[custom: string]: any;
|
||||
}
|
||||
|
||||
export type Contents = Buffer | NodeJS.ReadableStream | null;
|
||||
export type File = import("./vinyl");
|
||||
export type NullFile = File<null>;
|
||||
export type BufferFile = File<Buffer>;
|
||||
export type StreamFile = File<NodeJS.ReadableStream>;
|
||||
|
||||
export interface Directory extends NullFile {
|
||||
isNull(): true;
|
||||
isDirectory(): true;
|
||||
isSymbolic(): this is never;
|
||||
}
|
||||
|
||||
export interface Symbolic extends NullFile {
|
||||
isNull(): true;
|
||||
isDirectory(): this is never;
|
||||
isSymbolic(): true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("vinyl");
|
||||
+42
-17
@@ -4,9 +4,11 @@ const path = require("path");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
|
||||
const failingHookRegExp = /^(.*) "(before|after) (all|each)" hook$/;
|
||||
|
||||
/**
|
||||
* .failed-tests reporter
|
||||
*
|
||||
*
|
||||
* @typedef {Object} ReporterOptions
|
||||
* @property {string} [file]
|
||||
* @property {boolean} [keepFailed]
|
||||
@@ -15,7 +17,7 @@ const os = require("os");
|
||||
*/
|
||||
class FailedTestsReporter extends Mocha.reporters.Base {
|
||||
/**
|
||||
* @param {Mocha.Runner} runner
|
||||
* @param {Mocha.Runner} runner
|
||||
* @param {{ reporterOptions?: ReporterOptions }} [options]
|
||||
*/
|
||||
constructor(runner, options) {
|
||||
@@ -49,35 +51,58 @@ class FailedTestsReporter extends Mocha.reporters.Base {
|
||||
|
||||
/** @type {Mocha.Test[]} */
|
||||
this.passes = [];
|
||||
|
||||
/** @type {Mocha.Test[]} */
|
||||
|
||||
/** @type {(Mocha.Test)[]} */
|
||||
this.failures = [];
|
||||
|
||||
|
||||
runner.on("pass", test => this.passes.push(test));
|
||||
runner.on("fail", test => this.failures.push(test));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
* @param {ReadonlyArray<Mocha.Test>} passes
|
||||
* @param {ReadonlyArray<Mocha.Test>} failures
|
||||
* @param {boolean} keepFailed
|
||||
* @param {(err?: NodeJS.ErrnoException) => void} done
|
||||
* @param {string} file
|
||||
* @param {ReadonlyArray<Mocha.Test>} passes
|
||||
* @param {ReadonlyArray<Mocha.Test | Mocha.Hook>} failures
|
||||
* @param {boolean} keepFailed
|
||||
* @param {(err?: NodeJS.ErrnoException) => void} done
|
||||
*/
|
||||
static writeFailures(file, passes, failures, keepFailed, done) {
|
||||
const failingTests = new Set(fs.existsSync(file) ? readTests() : undefined);
|
||||
if (failingTests.size > 0) {
|
||||
const possiblyPassingSuites = /**@type {Set<string>}*/(new Set());
|
||||
|
||||
// Remove tests that are now passing and track suites that are now
|
||||
// possibly passing.
|
||||
if (failingTests.size > 0 && !keepFailed) {
|
||||
for (const test of passes) {
|
||||
const title = test.fullTitle().trim();
|
||||
if (title) failingTests.delete(title);
|
||||
failingTests.delete(test.fullTitle().trim());
|
||||
possiblyPassingSuites.add(test.parent.fullTitle().trim());
|
||||
}
|
||||
}
|
||||
|
||||
// Add tests that are now failing. If a hook failed, track its
|
||||
// containing suite as failing. If the suite for a test or hook was
|
||||
// possibly passing then it is now definitely failing.
|
||||
for (const test of failures) {
|
||||
const title = test.fullTitle().trim();
|
||||
if (title) failingTests.add(title);
|
||||
const suiteTitle = test.parent.fullTitle().trim();
|
||||
if (test.type === "test") {
|
||||
failingTests.add(test.fullTitle().trim());
|
||||
}
|
||||
else {
|
||||
failingTests.add(suiteTitle);
|
||||
}
|
||||
possiblyPassingSuites.delete(suiteTitle);
|
||||
}
|
||||
|
||||
// Remove all definitely passing suites.
|
||||
for (const suite of possiblyPassingSuites) {
|
||||
failingTests.delete(suite);
|
||||
}
|
||||
|
||||
if (failingTests.size > 0) {
|
||||
const failed = Array.from(failingTests).join(os.EOL);
|
||||
const failed = Array
|
||||
.from(failingTests)
|
||||
.sort()
|
||||
.join(os.EOL);
|
||||
fs.writeFile(file, failed, "utf8", done);
|
||||
}
|
||||
else if (!keepFailed && fs.existsSync(file)) {
|
||||
@@ -96,7 +121,7 @@ class FailedTestsReporter extends Mocha.reporters.Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} failures
|
||||
* @param {number} failures
|
||||
* @param {(failures: number) => void} [fn]
|
||||
*/
|
||||
done(failures, fn) {
|
||||
|
||||
@@ -54,16 +54,17 @@ async function copyScriptOutputs() {
|
||||
await copyWithCopyright("cancellationToken.js");
|
||||
await copyWithCopyright("tsc.release.js", "tsc.js");
|
||||
await copyWithCopyright("tsserver.js");
|
||||
await copyWithCopyright("typescript.js");
|
||||
await copyWithCopyright("typescriptServices.js");
|
||||
await copyFromBuiltLocal("tsserverlibrary.js"); // copyright added by build
|
||||
await copyFromBuiltLocal("typescript.js"); // copyright added by build
|
||||
await copyFromBuiltLocal("typescriptServices.js"); // copyright added by build
|
||||
await copyWithCopyright("typingsInstaller.js");
|
||||
await copyWithCopyright("watchGuard.js");
|
||||
}
|
||||
|
||||
async function copyDeclarationOutputs() {
|
||||
await copyWithCopyright("tsserverlibrary.d.ts");
|
||||
await copyWithCopyright("typescript.d.ts");
|
||||
await copyWithCopyright("typescriptServices.d.ts");
|
||||
await copyFromBuiltLocal("tsserverlibrary.d.ts"); // copyright added by build
|
||||
await copyFromBuiltLocal("typescript.d.ts"); // copyright added by build
|
||||
await copyFromBuiltLocal("typescriptServices.d.ts"); // copyright added by build
|
||||
}
|
||||
|
||||
async function writeGitAttributes() {
|
||||
|
||||
@@ -69,7 +69,12 @@ const proc = spawn(process.execPath, args, {
|
||||
proc.on('exit', (code, signal) => {
|
||||
process.on('exit', () => {
|
||||
if (grepFile) {
|
||||
fs.unlinkSync(grepFile);
|
||||
try {
|
||||
fs.unlinkSync(grepFile);
|
||||
}
|
||||
catch (e) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (signal) {
|
||||
|
||||
@@ -225,11 +225,11 @@ namespace ts {
|
||||
node.symbol = symbol;
|
||||
symbol.declarations = append(symbol.declarations, node);
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
|
||||
if (symbolFlags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.Module | SymbolFlags.Variable) && !symbol.exports) {
|
||||
symbol.exports = createSymbolTable();
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasMembers && !symbol.members) {
|
||||
if (symbolFlags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && !symbol.members) {
|
||||
symbol.members = createSymbolTable();
|
||||
}
|
||||
|
||||
|
||||
+107
-39
@@ -2417,12 +2417,12 @@ namespace ts {
|
||||
// The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
|
||||
// module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error.
|
||||
function visit(symbol: Symbol | undefined): SymbolTable | undefined {
|
||||
if (!(symbol && symbol.flags & SymbolFlags.HasExports && pushIfUnique(visitedSymbols, symbol))) {
|
||||
if (!(symbol && symbol.exports && pushIfUnique(visitedSymbols, symbol))) {
|
||||
return;
|
||||
}
|
||||
const symbols = cloneMap(symbol.exports!);
|
||||
const symbols = cloneMap(symbol.exports);
|
||||
// All export * declarations are collected in an __export symbol by the binder
|
||||
const exportStars = symbol.exports!.get(InternalSymbolName.ExportStar);
|
||||
const exportStars = symbol.exports.get(InternalSymbolName.ExportStar);
|
||||
if (exportStars) {
|
||||
const nestedSymbols = createSymbolTable();
|
||||
const lookupTable = createMap<ExportCollisionTracker>() as ExportCollisionTrackerTable;
|
||||
@@ -7702,9 +7702,13 @@ namespace ts {
|
||||
return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, TypeSystemPropertyName.ResolvedReturnType) >= 0;
|
||||
}
|
||||
|
||||
function getRestTypeOfSignature(signature: Signature) {
|
||||
function getRestTypeOfSignature(signature: Signature): Type {
|
||||
return tryGetRestTypeOfSignature(signature) || anyType;
|
||||
}
|
||||
|
||||
function tryGetRestTypeOfSignature(signature: Signature): Type | undefined {
|
||||
const type = getTypeOfRestParameter(signature);
|
||||
return type && getIndexTypeOfType(type, IndexKind.Number) || anyType;
|
||||
return type && getIndexTypeOfType(type, IndexKind.Number);
|
||||
}
|
||||
|
||||
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean): Signature {
|
||||
@@ -19069,38 +19073,7 @@ namespace ts {
|
||||
diagnostics.add(createDiagnosticForNode(node, fallbackError));
|
||||
}
|
||||
|
||||
// No signature was applicable. We have already reported the errors for the invalid signature.
|
||||
// If this is a type resolution session, e.g. Language Service, try to get better information than anySignature.
|
||||
// Pick the longest signature. This way we can get a contextual type for cases like:
|
||||
// declare function f(a: { xa: number; xb: number; }, b: number);
|
||||
// f({ |
|
||||
// Also, use explicitly-supplied type arguments if they are provided, so we can get a contextual signature in cases like:
|
||||
// declare function f<T>(k: keyof T);
|
||||
// f<Foo>("
|
||||
if (!produceDiagnostics) {
|
||||
Debug.assert(candidates.length > 0); // Else would have exited above.
|
||||
const bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === undefined ? args!.length : apparentArgumentCount);
|
||||
const candidate = candidates[bestIndex];
|
||||
|
||||
const { typeParameters } = candidate;
|
||||
if (typeParameters && callLikeExpressionMayHaveTypeArguments(node) && node.typeArguments) {
|
||||
const typeArguments = node.typeArguments.map(getTypeOfNode) as Type[]; // TODO: GH#18217
|
||||
while (typeArguments.length > typeParameters.length) {
|
||||
typeArguments.pop();
|
||||
}
|
||||
while (typeArguments.length < typeParameters.length) {
|
||||
typeArguments.push(getDefaultTypeArgumentType(isInJavaScriptFile(node)));
|
||||
}
|
||||
|
||||
const instantiated = createSignatureInstantiation(candidate, typeArguments);
|
||||
candidates[bestIndex] = instantiated;
|
||||
return instantiated;
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
return resolveErrorCall(node);
|
||||
return produceDiagnostics || !args ? resolveErrorCall(node) : getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray);
|
||||
|
||||
function chooseOverload(candidates: Signature[], relation: Map<RelationComparisonResult>, signatureHelpTrailingComma = false) {
|
||||
candidateForArgumentError = undefined;
|
||||
@@ -19171,6 +19144,97 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// No signature was applicable. We have already reported the errors for the invalid signature.
|
||||
// If this is a type resolution session, e.g. Language Service, try to get better information than anySignature.
|
||||
function getCandidateForOverloadFailure(
|
||||
node: CallLikeExpression,
|
||||
candidates: Signature[],
|
||||
args: ReadonlyArray<Expression>,
|
||||
hasCandidatesOutArray: boolean,
|
||||
): Signature {
|
||||
Debug.assert(candidates.length > 0); // Else should not have called this.
|
||||
// Normally we will combine overloads. Skip this if they have type parameters since that's hard to combine.
|
||||
// Don't do this if there is a `candidatesOutArray`,
|
||||
// because then we want the chosen best candidate to be one of the overloads, not a combination.
|
||||
return hasCandidatesOutArray || candidates.length === 1 || candidates.some(c => !!c.typeParameters)
|
||||
? pickLongestCandidateSignature(node, candidates, args)
|
||||
: createUnionOfSignaturesForOverloadFailure(candidates);
|
||||
}
|
||||
|
||||
function createUnionOfSignaturesForOverloadFailure(candidates: ReadonlyArray<Signature>): Signature {
|
||||
const thisParameters = mapDefined(candidates, c => c.thisParameter);
|
||||
let thisParameter: Symbol | undefined;
|
||||
if (thisParameters.length) {
|
||||
thisParameter = createCombinedSymbolFromTypes(thisParameters, thisParameters.map(getTypeOfParameter));
|
||||
}
|
||||
const { min: minArgumentCount, max: maxNonRestParam } = minAndMax(candidates, getNumNonRestParameters);
|
||||
const parameters: Symbol[] = [];
|
||||
for (let i = 0; i < maxNonRestParam; i++) {
|
||||
const symbols = mapDefined(candidates, ({ parameters, hasRestParameter }) => hasRestParameter ?
|
||||
i < parameters.length - 1 ? parameters[i] : last(parameters) :
|
||||
i < parameters.length ? parameters[i] : undefined);
|
||||
Debug.assert(symbols.length !== 0);
|
||||
parameters.push(createCombinedSymbolFromTypes(symbols, mapDefined(candidates, candidate => tryGetTypeAtPosition(candidate, i))));
|
||||
}
|
||||
const restParameterSymbols = mapDefined(candidates, c => c.hasRestParameter ? last(c.parameters) : undefined);
|
||||
const hasRestParameter = restParameterSymbols.length !== 0;
|
||||
if (hasRestParameter) {
|
||||
const type = createArrayType(getUnionType(mapDefined(candidates, tryGetRestTypeOfSignature), UnionReduction.Subtype));
|
||||
parameters.push(createCombinedSymbolForOverloadFailure(restParameterSymbols, type));
|
||||
}
|
||||
return createSignature(
|
||||
candidates[0].declaration,
|
||||
/*typeParameters*/ undefined, // Before calling this we tested for `!candidates.some(c => !!c.typeParameters)`.
|
||||
thisParameter,
|
||||
parameters,
|
||||
/*resolvedReturnType*/ getIntersectionType(candidates.map(getReturnTypeOfSignature)),
|
||||
/*typePredicate*/ undefined,
|
||||
minArgumentCount,
|
||||
hasRestParameter,
|
||||
/*hasLiteralTypes*/ candidates.some(c => c.hasLiteralTypes));
|
||||
}
|
||||
|
||||
function getNumNonRestParameters(signature: Signature): number {
|
||||
const numParams = signature.parameters.length;
|
||||
return signature.hasRestParameter ? numParams - 1 : numParams;
|
||||
}
|
||||
|
||||
function createCombinedSymbolFromTypes(sources: ReadonlyArray<Symbol>, types: Type[]): Symbol {
|
||||
return createCombinedSymbolForOverloadFailure(sources, getUnionType(types, UnionReduction.Subtype));
|
||||
}
|
||||
|
||||
function createCombinedSymbolForOverloadFailure(sources: ReadonlyArray<Symbol>, type: Type): Symbol {
|
||||
// This function is currently only used for erroneous overloads, so it's good enough to just use the first source.
|
||||
return createSymbolWithType(first(sources), type);
|
||||
}
|
||||
|
||||
function pickLongestCandidateSignature(node: CallLikeExpression, candidates: Signature[], args: ReadonlyArray<Expression>): Signature {
|
||||
// Pick the longest signature. This way we can get a contextual type for cases like:
|
||||
// declare function f(a: { xa: number; xb: number; }, b: number);
|
||||
// f({ |
|
||||
// Also, use explicitly-supplied type arguments if they are provided, so we can get a contextual signature in cases like:
|
||||
// declare function f<T>(k: keyof T);
|
||||
// f<Foo>("
|
||||
const bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === undefined ? args.length : apparentArgumentCount);
|
||||
const candidate = candidates[bestIndex];
|
||||
const { typeParameters } = candidate;
|
||||
if (!typeParameters) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
const typeArgumentNodes: ReadonlyArray<TypeNode> = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments || emptyArray : emptyArray;
|
||||
const typeArguments = typeArgumentNodes.map(n => getTypeOfNode(n) || anyType);
|
||||
while (typeArguments.length > typeParameters.length) {
|
||||
typeArguments.pop();
|
||||
}
|
||||
while (typeArguments.length < typeParameters.length) {
|
||||
typeArguments.push(getConstraintFromTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node)));
|
||||
}
|
||||
const instantiated = createSignatureInstantiation(candidate, typeArguments);
|
||||
candidates[bestIndex] = instantiated;
|
||||
return instantiated;
|
||||
}
|
||||
|
||||
function getLongestCandidateIndex(candidates: Signature[], argsCount: number): number {
|
||||
let maxParamsIndex = -1;
|
||||
let maxParams = -1;
|
||||
@@ -19955,6 +20019,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getTypeAtPosition(signature: Signature, pos: number): Type {
|
||||
return tryGetTypeAtPosition(signature, pos) || anyType;
|
||||
}
|
||||
|
||||
function tryGetTypeAtPosition(signature: Signature, pos: number): Type | undefined {
|
||||
const paramCount = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
if (pos < paramCount) {
|
||||
return getTypeOfParameter(signature.parameters[pos]);
|
||||
@@ -19970,9 +20038,9 @@ namespace ts {
|
||||
return tupleRestType;
|
||||
}
|
||||
}
|
||||
return getIndexTypeOfType(restType, IndexKind.Number) || anyType;
|
||||
return getIndexTypeOfType(restType, IndexKind.Number);
|
||||
}
|
||||
return anyType;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getRestTypeAtPosition(source: Signature, pos: number): Type {
|
||||
|
||||
@@ -2864,6 +2864,10 @@
|
||||
"category": "Error",
|
||||
"code": 5070
|
||||
},
|
||||
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.": {
|
||||
"category": "Error",
|
||||
"code": 5071
|
||||
},
|
||||
|
||||
"Generates a sourcemap for each corresponding '.d.ts' file.": {
|
||||
"category": "Message",
|
||||
|
||||
@@ -2548,6 +2548,10 @@ namespace ts {
|
||||
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
|
||||
}
|
||||
// Any emit other than common js is error
|
||||
else if (getEmitModuleKind(options) !== ModuleKind.CommonJS) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs, "resolveJsonModule", "module");
|
||||
}
|
||||
}
|
||||
|
||||
// there has to be common source directory if user specified --outdir || --sourceRoot
|
||||
|
||||
@@ -171,8 +171,8 @@ namespace ts {
|
||||
}
|
||||
const t = getTypeOfSymbol(symbol);
|
||||
visitType(t); // Should handle members on classes and such
|
||||
if (symbol.flags & SymbolFlags.HasExports) {
|
||||
symbol.exports!.forEach(visitSymbol);
|
||||
if (symbol.exports) {
|
||||
symbol.exports.forEach(visitSymbol);
|
||||
}
|
||||
forEach(symbol.declarations, d => {
|
||||
// Type queries are too far resolved when we just visit the symbol's type
|
||||
|
||||
+65
-31
@@ -332,9 +332,9 @@ namespace ts {
|
||||
/*@internal*/
|
||||
export interface RecursiveDirectoryWatcherHost {
|
||||
watchDirectory: HostWatchDirectory;
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
getAccessibleSortedChildDirectories(path: string): ReadonlyArray<string>;
|
||||
directoryExists(dir: string): boolean;
|
||||
filePathComparer: Comparer<string>;
|
||||
realpath(s: string): string;
|
||||
}
|
||||
|
||||
@@ -345,60 +345,94 @@ namespace ts {
|
||||
*/
|
||||
/*@internal*/
|
||||
export function createRecursiveDirectoryWatcher(host: RecursiveDirectoryWatcherHost): (directoryName: string, callback: DirectoryWatcherCallback) => FileWatcher {
|
||||
type ChildWatches = ReadonlyArray<DirectoryWatcher>;
|
||||
interface DirectoryWatcher extends FileWatcher {
|
||||
childWatches: ChildWatches;
|
||||
interface ChildDirectoryWatcher extends FileWatcher {
|
||||
dirName: string;
|
||||
}
|
||||
type ChildWatches = ReadonlyArray<ChildDirectoryWatcher>;
|
||||
interface HostDirectoryWatcher {
|
||||
watcher: FileWatcher;
|
||||
childWatches: ChildWatches;
|
||||
refCount: number;
|
||||
}
|
||||
|
||||
const cache = createMap<HostDirectoryWatcher>();
|
||||
const callbackCache = createMultiMap<DirectoryWatcherCallback>();
|
||||
const filePathComparer = getStringComparer(!host.useCaseSensitiveFileNames);
|
||||
const toCanonicalFilePath = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
|
||||
return createDirectoryWatcher;
|
||||
|
||||
/**
|
||||
* Create the directory watcher for the dirPath.
|
||||
*/
|
||||
function createDirectoryWatcher(dirName: string, callback: DirectoryWatcherCallback): DirectoryWatcher {
|
||||
const watcher = host.watchDirectory(dirName, fileName => {
|
||||
// Call the actual callback
|
||||
callback(fileName);
|
||||
function createDirectoryWatcher(dirName: string, callback?: DirectoryWatcherCallback): ChildDirectoryWatcher {
|
||||
const dirPath = toCanonicalFilePath(dirName) as Path;
|
||||
let directoryWatcher = cache.get(dirPath);
|
||||
if (directoryWatcher) {
|
||||
directoryWatcher.refCount++;
|
||||
}
|
||||
else {
|
||||
directoryWatcher = {
|
||||
watcher: host.watchDirectory(dirName, fileName => {
|
||||
// Call the actual callback
|
||||
callbackCache.forEach((callbacks, rootDirName) => {
|
||||
if (rootDirName === dirPath || (startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === directorySeparator)) {
|
||||
callbacks.forEach(callback => callback(fileName));
|
||||
}
|
||||
});
|
||||
|
||||
// Iterate through existing children and update the watches if needed
|
||||
updateChildWatches(result, callback);
|
||||
});
|
||||
// Iterate through existing children and update the watches if needed
|
||||
updateChildWatches(dirName, dirPath);
|
||||
}),
|
||||
refCount: 1,
|
||||
childWatches: emptyArray
|
||||
};
|
||||
cache.set(dirPath, directoryWatcher);
|
||||
updateChildWatches(dirName, dirPath);
|
||||
}
|
||||
|
||||
let result: DirectoryWatcher = {
|
||||
close: () => {
|
||||
watcher.close();
|
||||
result.childWatches.forEach(closeFileWatcher);
|
||||
result = undefined!;
|
||||
},
|
||||
if (callback) {
|
||||
callbackCache.add(dirPath, callback);
|
||||
}
|
||||
|
||||
return {
|
||||
dirName,
|
||||
childWatches: emptyArray
|
||||
close: () => {
|
||||
const directoryWatcher = Debug.assertDefined(cache.get(dirPath));
|
||||
if (callback) callbackCache.remove(dirPath, callback);
|
||||
directoryWatcher.refCount--;
|
||||
|
||||
if (directoryWatcher.refCount) return;
|
||||
|
||||
cache.delete(dirPath);
|
||||
closeFileWatcherOf(directoryWatcher);
|
||||
directoryWatcher.childWatches.forEach(closeFileWatcher);
|
||||
}
|
||||
};
|
||||
updateChildWatches(result, callback);
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateChildWatches(watcher: DirectoryWatcher, callback: DirectoryWatcherCallback) {
|
||||
function updateChildWatches(dirName: string, dirPath: Path) {
|
||||
// Iterate through existing children and update the watches if needed
|
||||
if (watcher) {
|
||||
watcher.childWatches = watchChildDirectories(watcher.dirName, watcher.childWatches, callback);
|
||||
const parentWatcher = cache.get(dirPath);
|
||||
if (parentWatcher) {
|
||||
parentWatcher.childWatches = watchChildDirectories(dirName, parentWatcher.childWatches);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch the directories in the parentDir
|
||||
*/
|
||||
function watchChildDirectories(parentDir: string, existingChildWatches: ChildWatches, callback: DirectoryWatcherCallback): ChildWatches {
|
||||
let newChildWatches: DirectoryWatcher[] | undefined;
|
||||
enumerateInsertsAndDeletes<string, DirectoryWatcher>(
|
||||
function watchChildDirectories(parentDir: string, existingChildWatches: ChildWatches): ChildWatches {
|
||||
let newChildWatches: ChildDirectoryWatcher[] | undefined;
|
||||
enumerateInsertsAndDeletes<string, ChildDirectoryWatcher>(
|
||||
host.directoryExists(parentDir) ? mapDefined(host.getAccessibleSortedChildDirectories(parentDir), child => {
|
||||
const childFullName = getNormalizedAbsolutePath(child, parentDir);
|
||||
// Filter our the symbolic link directories since those arent included in recursive watch
|
||||
// which is same behaviour when recursive: true is passed to fs.watch
|
||||
return host.filePathComparer(childFullName, host.realpath(childFullName)) === Comparison.EqualTo ? childFullName : undefined;
|
||||
return filePathComparer(childFullName, normalizePath(host.realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined;
|
||||
}) : emptyArray,
|
||||
existingChildWatches,
|
||||
(child, childWatcher) => host.filePathComparer(child, childWatcher.dirName),
|
||||
(child, childWatcher) => filePathComparer(child, childWatcher.dirName),
|
||||
createAndAddChildDirectoryWatcher,
|
||||
closeFileWatcher,
|
||||
addChildDirectoryWatcher
|
||||
@@ -410,14 +444,14 @@ namespace ts {
|
||||
* Create new childDirectoryWatcher and add it to the new ChildDirectoryWatcher list
|
||||
*/
|
||||
function createAndAddChildDirectoryWatcher(childName: string) {
|
||||
const result = createDirectoryWatcher(childName, callback);
|
||||
const result = createDirectoryWatcher(childName);
|
||||
addChildDirectoryWatcher(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add child directory watcher to the new ChildDirectoryWatcher list
|
||||
*/
|
||||
function addChildDirectoryWatcher(childWatcher: DirectoryWatcher) {
|
||||
function addChildDirectoryWatcher(childWatcher: ChildDirectoryWatcher) {
|
||||
(newChildWatches || (newChildWatches = [])).push(childWatcher);
|
||||
}
|
||||
}
|
||||
@@ -710,7 +744,7 @@ namespace ts {
|
||||
createWatchDirectoryUsing(dynamicPollingWatchFile || createDynamicPriorityPollingWatchFile({ getModifiedTime, setTimeout })) :
|
||||
watchDirectoryUsingFsWatch;
|
||||
const watchDirectoryRecursively = createRecursiveDirectoryWatcher({
|
||||
filePathComparer: getStringComparer(!useCaseSensitiveFileNames),
|
||||
useCaseSensitiveFileNames,
|
||||
directoryExists,
|
||||
getAccessibleSortedChildDirectories: path => getAccessibleFileSystemEntries(path).directories,
|
||||
watchDirectory,
|
||||
|
||||
@@ -2994,9 +2994,9 @@ namespace ts {
|
||||
*/
|
||||
/* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
getSuggestionForNonexistentExport(node: Identifier, target: Symbol): string | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentExport(node: Identifier, target: Symbol): string | undefined;
|
||||
getBaseConstraintOfType(type: Type): Type | undefined;
|
||||
getDefaultFromTypeParameter(type: Type): Type | undefined;
|
||||
|
||||
@@ -3439,9 +3439,6 @@ namespace ts {
|
||||
|
||||
ExportHasLocal = Function | Class | Enum | ValueModule,
|
||||
|
||||
HasExports = Class | Enum | Module | Variable,
|
||||
HasMembers = Class | Interface | TypeLiteral | ObjectLiteral,
|
||||
|
||||
BlockScoped = BlockScopedVariable | Class | Enum,
|
||||
|
||||
PropertyOrAccessor = Property | Accessor,
|
||||
|
||||
@@ -8087,4 +8087,20 @@ namespace ts {
|
||||
Debug.assert(index !== -1);
|
||||
return arr.slice(index);
|
||||
}
|
||||
|
||||
export function minAndMax<T>(arr: ReadonlyArray<T>, getValue: (value: T) => number): { readonly min: number, readonly max: number } {
|
||||
Debug.assert(arr.length !== 0);
|
||||
let min = getValue(arr[0]);
|
||||
let max = min;
|
||||
for (let i = 1; i < arr.length; i++) {
|
||||
const value = getValue(arr[i]);
|
||||
if (value < min) {
|
||||
min = value;
|
||||
}
|
||||
else if (value > max) {
|
||||
max = value;
|
||||
}
|
||||
}
|
||||
return { min, max };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ namespace ts {
|
||||
case WatchLogLevel.TriggerOnly:
|
||||
return createFileWatcherWithTriggerLogging;
|
||||
case WatchLogLevel.Verbose:
|
||||
return createFileWatcherWithLogging;
|
||||
return addWatch === <any>watchDirectory ? createDirectoryWatcherWithLogging : createFileWatcherWithLogging;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,6 +413,25 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function createDirectoryWatcherWithLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
|
||||
const watchInfo = `${watchCaption}:: Added:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
|
||||
log(watchInfo);
|
||||
const start = timestamp();
|
||||
const watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
|
||||
const elapsed = timestamp() - start;
|
||||
log(`Elapsed:: ${elapsed}ms ${watchInfo}`);
|
||||
return {
|
||||
close: () => {
|
||||
const watchInfo = `${watchCaption}:: Close:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
|
||||
log(watchInfo);
|
||||
const start = timestamp();
|
||||
watcher.close();
|
||||
const elapsed = timestamp() - start;
|
||||
log(`Elapsed:: ${elapsed}ms ${watchInfo}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createFileWatcherWithTriggerLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
|
||||
return addWatch(host, file, (fileName, cbOptional) => {
|
||||
const triggerredInfo = `${watchCaption}:: Triggered with ${fileName}${cbOptional !== undefined ? cbOptional : ""}:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
|
||||
|
||||
@@ -352,9 +352,9 @@ interface Array<T> {}`
|
||||
if (tscWatchDirectory === Tsc_WatchDirectory.WatchFile) {
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => this.watchFile(directory, () => cb(directory), PollingInterval.Medium);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
useCaseSensitiveFileNames: this.useCaseSensitiveFileNames,
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
@@ -362,9 +362,9 @@ interface Array<T> {}`
|
||||
else if (tscWatchDirectory === Tsc_WatchDirectory.NonRecursiveWatchDirectory) {
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => this.watchDirectory(directory, fileName => cb(fileName), /*recursive*/ false);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
useCaseSensitiveFileNames: this.useCaseSensitiveFileNames,
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
@@ -373,9 +373,9 @@ interface Array<T> {}`
|
||||
const watchFile = createDynamicPriorityPollingWatchFile(this);
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => watchFile(directory, () => cb(directory), PollingInterval.Medium);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
useCaseSensitiveFileNames: this.useCaseSensitiveFileNames,
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* @internal */
|
||||
declare namespace ts.server {
|
||||
export type ActionSet = "action::set";
|
||||
export type ActionInvalidate = "action::invalidate";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
namespace ts.server {
|
||||
/*@internal*/
|
||||
export interface ScriptInfoVersion {
|
||||
svc: number;
|
||||
text: number;
|
||||
|
||||
@@ -1837,7 +1837,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private mapTextChangeToCodeEdit(project: Project, change: FileTextChanges): protocol.FileCodeEdits {
|
||||
return mapTextChangesToCodeEdits(change, project.getSourceFileOrConfigFile(this.normalizePath(change.fileName)));
|
||||
return mapTextChangesToCodeEditsForFile(change, project.getSourceFileOrConfigFile(this.normalizePath(change.fileName)));
|
||||
}
|
||||
|
||||
private mapTextChangeToCodeEditUsingScriptInfo(change: FileTextChanges): protocol.FileCodeEdits {
|
||||
@@ -2357,8 +2357,8 @@ namespace ts.server {
|
||||
return { file: fileName, start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) };
|
||||
}
|
||||
|
||||
function mapTextChangesToCodeEdits(textChanges: FileTextChanges, sourceFile: SourceFile | undefined): protocol.FileCodeEdits {
|
||||
Debug.assert(!!textChanges.isNewFile === !sourceFile);
|
||||
function mapTextChangesToCodeEditsForFile(textChanges: FileTextChanges, sourceFile: SourceFile | undefined): protocol.FileCodeEdits {
|
||||
Debug.assert(!!textChanges.isNewFile === !sourceFile, "Expected isNewFile for (only) new files", () => JSON.stringify({ isNewFile: textChanges.isNewFile, hasSourceFile: !!sourceFile }));
|
||||
if (sourceFile) {
|
||||
return {
|
||||
fileName: textChanges.fileName,
|
||||
|
||||
+12
-10
@@ -111,20 +111,22 @@ namespace ts.Completions {
|
||||
function completionInfoFromData(sourceFile: SourceFile, typeChecker: TypeChecker, compilerOptions: CompilerOptions, log: Log, completionData: CompletionData, preferences: UserPreferences): CompletionInfo | undefined {
|
||||
const { symbols, completionKind, isInSnippetScope, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, literals, symbolToOriginInfoMap, recommendedCompletion, isJsxInitializer } = completionData;
|
||||
|
||||
if (sourceFile.languageVariant === LanguageVariant.JSX && location && location.parent && isJsxClosingElement(location.parent)) {
|
||||
if (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 = <div> </ /*1*/>
|
||||
// The completion list at "1" will contain "div" with type any
|
||||
// var x = <div> </ /*1*/
|
||||
// The completion list at "1" will contain "div>" with type any
|
||||
// And at `<div> </ /*1*/ >` (with a closing `>`), the completion list will contain "div".
|
||||
const tagName = location.parent.parent.openingElement.tagName;
|
||||
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false,
|
||||
entries: [{
|
||||
name: tagName.getFullText(),
|
||||
kind: ScriptElementKind.classElement,
|
||||
kindModifiers: undefined,
|
||||
sortText: "0",
|
||||
}]};
|
||||
const hasClosingAngleBracket = !!findChildOfKind(location.parent, SyntaxKind.GreaterThanToken, sourceFile);
|
||||
const entry: CompletionEntry = {
|
||||
name: tagName.getFullText(sourceFile) + (hasClosingAngleBracket ? "" : ">"),
|
||||
kind: ScriptElementKind.classElement,
|
||||
kindModifiers: undefined,
|
||||
sortText: "0",
|
||||
};
|
||||
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [entry] };
|
||||
}
|
||||
|
||||
const entries: CompletionEntry[] = [];
|
||||
|
||||
@@ -1463,12 +1463,14 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** Gets all symbols for one property. Does not get symbols for every property. */
|
||||
function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): ReadonlyArray<Symbol> {
|
||||
function getPropertySymbolsFromContextualType(node: ObjectLiteralElementWithName, checker: TypeChecker): ReadonlyArray<Symbol> {
|
||||
const contextualType = checker.getContextualType(<ObjectLiteralExpression>node.parent);
|
||||
const name = getNameFromPropertyName(node.name!);
|
||||
const symbol = contextualType && name && contextualType.getProperty(name);
|
||||
if (!contextualType) return emptyArray;
|
||||
const name = getNameFromPropertyName(node.name);
|
||||
if (!name) return emptyArray;
|
||||
const symbol = contextualType.getProperty(name);
|
||||
return symbol ? [symbol] :
|
||||
contextualType && contextualType.isUnion() ? mapDefined(contextualType.types, t => t.getProperty(name!)) : emptyArray; // TODO: GH#18217
|
||||
contextualType.isUnion() ? mapDefined(contextualType.types, t => t.getProperty(name)) : emptyArray;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1884,11 +1884,16 @@ namespace ts {
|
||||
if (!token) return undefined;
|
||||
const element = token.kind === SyntaxKind.GreaterThanToken && isJsxOpeningElement(token.parent) ? token.parent.parent
|
||||
: isJsxText(token) ? token.parent : undefined;
|
||||
if (element && !tagNamesAreEquivalent(element.openingElement.tagName, element.closingElement.tagName)) {
|
||||
if (element && isUnclosedTag(element)) {
|
||||
return { newText: `</${element.openingElement.tagName.getText(sourceFile)}>` };
|
||||
}
|
||||
}
|
||||
|
||||
function isUnclosedTag({ openingElement, closingElement, parent }: JsxElement): boolean {
|
||||
return !tagNamesAreEquivalent(openingElement.tagName, closingElement.tagName) ||
|
||||
isJsxElement(parent) && tagNamesAreEquivalent(openingElement.tagName, parent.openingElement.tagName) && isUnclosedTag(parent);
|
||||
}
|
||||
|
||||
function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined {
|
||||
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
const range = formatting.getRangeOfEnclosingComment(sourceFile, position);
|
||||
@@ -2181,21 +2186,23 @@ namespace ts {
|
||||
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
|
||||
*/
|
||||
/* @internal */
|
||||
export function getContainingObjectLiteralElement(node: Node): ObjectLiteralElement | undefined {
|
||||
export function getContainingObjectLiteralElement(node: Node): ObjectLiteralElementWithName | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
if (node.parent.kind === SyntaxKind.ComputedPropertyName) {
|
||||
return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
|
||||
return isObjectLiteralElement(node.parent.parent) ? node.parent.parent as ObjectLiteralElementWithName : undefined;
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.Identifier:
|
||||
return isObjectLiteralElement(node.parent) &&
|
||||
(node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) &&
|
||||
node.parent.name === node ? node.parent : undefined;
|
||||
node.parent.name === node ? node.parent as ObjectLiteralElementWithName : undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/* @internal */
|
||||
export type ObjectLiteralElementWithName = ObjectLiteralElement & { name: PropertyName };
|
||||
|
||||
/* @internal */
|
||||
export function getPropertySymbolsFromContextualType(typeChecker: TypeChecker, node: ObjectLiteralElement): Symbol[] {
|
||||
|
||||
@@ -8589,10 +8589,10 @@ export const x = 10;`
|
||||
tscWatchDirectory === Tsc_WatchDirectory.WatchFile ?
|
||||
expectedWatchedFiles :
|
||||
createMap();
|
||||
// For failed resolution lookup and tsconfig files
|
||||
mapOfDirectories.set(projectFolder, 2);
|
||||
// For failed resolution lookup and tsconfig files => cached so only watched only once
|
||||
mapOfDirectories.set(projectFolder, 1);
|
||||
// Through above recursive watches
|
||||
mapOfDirectories.set(projectSrcFolder, 2);
|
||||
mapOfDirectories.set(projectSrcFolder, 1);
|
||||
// node_modules/@types folder
|
||||
mapOfDirectories.set(`${projectFolder}/${nodeModulesAtTypes}`, 1);
|
||||
const expectedCompletions = ["file1"];
|
||||
|
||||
+1475
-6934
File diff suppressed because it is too large
Load Diff
+91
-7
@@ -1,3 +1,18 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.0";
|
||||
/** The version of the TypeScript compiler release */
|
||||
@@ -1918,9 +1933,6 @@ declare namespace ts {
|
||||
getAmbientModules(): Symbol[];
|
||||
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
getSuggestionForNonexistentExport(node: Identifier, target: Symbol): string | undefined;
|
||||
getBaseConstraintOfType(type: Type): Type | undefined;
|
||||
getDefaultFromTypeParameter(type: Type): Type | undefined;
|
||||
/**
|
||||
@@ -2063,8 +2075,6 @@ declare namespace ts {
|
||||
AliasExcludes = 2097152,
|
||||
ModuleMember = 2623475,
|
||||
ExportHasLocal = 944,
|
||||
HasExports = 1955,
|
||||
HasMembers = 6240,
|
||||
BlockScoped = 418,
|
||||
PropertyOrAccessor = 98308,
|
||||
ClassMember = 106500
|
||||
@@ -4570,6 +4580,80 @@ declare namespace ts {
|
||||
function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string>;
|
||||
function formatUpToDateStatus<T>(configFileName: string, status: UpToDateStatus, relName: (fileName: string) => string, formatMessage: (message: DiagnosticMessage, ...args: string[]) => T): T | undefined;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
type ActionPackageInstalled = "action::packageInstalled";
|
||||
type EventTypesRegistry = "event::typesRegistry";
|
||||
type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
type EventEndInstallTypes = "event::endInstallTypes";
|
||||
type EventInitializationFailed = "event::initializationFailed";
|
||||
interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
interface TypingInstallerRequestWithProjectName {
|
||||
readonly projectName: string;
|
||||
}
|
||||
interface DiscoverTypings extends TypingInstallerRequestWithProjectName {
|
||||
readonly fileNames: string[];
|
||||
readonly projectRootPath: Path;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly cachePath?: string;
|
||||
readonly kind: "discover";
|
||||
}
|
||||
interface CloseProject extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "closeProject";
|
||||
}
|
||||
interface TypesRegistryRequest {
|
||||
readonly kind: "typesRegistry";
|
||||
}
|
||||
interface InstallPackageRequest extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "installPackage";
|
||||
readonly fileName: Path;
|
||||
readonly packageName: string;
|
||||
readonly projectRootPath: Path;
|
||||
}
|
||||
interface PackageInstalledResponse extends ProjectResponse {
|
||||
readonly kind: ActionPackageInstalled;
|
||||
readonly success: boolean;
|
||||
readonly message: string;
|
||||
}
|
||||
interface InitializationFailedResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventInitializationFailed;
|
||||
readonly message: string;
|
||||
}
|
||||
interface ProjectResponse extends TypingInstallerResponse {
|
||||
readonly projectName: string;
|
||||
}
|
||||
interface InvalidateCachedTypings extends ProjectResponse {
|
||||
readonly kind: ActionInvalidate;
|
||||
}
|
||||
interface InstallTypes extends ProjectResponse {
|
||||
readonly kind: EventBeginInstallTypes | EventEndInstallTypes;
|
||||
readonly eventId: number;
|
||||
readonly typingsInstallerVersion: string;
|
||||
readonly packagesToInstall: ReadonlyArray<string>;
|
||||
}
|
||||
interface BeginInstallTypes extends InstallTypes {
|
||||
readonly kind: EventBeginInstallTypes;
|
||||
}
|
||||
interface EndInstallTypes extends InstallTypes {
|
||||
readonly kind: EventEndInstallTypes;
|
||||
readonly installSuccess: boolean;
|
||||
}
|
||||
interface SetTypings extends ProjectResponse {
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typings: string[];
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly kind: ActionSet;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
interface Node {
|
||||
getSourceFile(): SourceFile;
|
||||
@@ -5574,5 +5658,5 @@ declare namespace ts {
|
||||
*/
|
||||
function transform<T extends Node>(source: T | T[], transformers: TransformerFactory<T>[], compilerOptions?: CompilerOptions): TransformationResult<T>;
|
||||
}
|
||||
//# sourceMappingURL=typescriptServices.d.ts.map
|
||||
export = ts
|
||||
|
||||
export = ts;
|
||||
@@ -2,6 +2,10 @@ tests/cases/conformance/salsa/a.js(4,17): error TS2339: Property 'toFixed' does
|
||||
Property 'toFixed' does not exist on type 'string'.
|
||||
tests/cases/conformance/salsa/a.js(5,16): error TS2339: Property 'toFixed' does not exist on type 'string | number'.
|
||||
Property 'toFixed' does not exist on type 'string'.
|
||||
tests/cases/conformance/salsa/mod1.js(2,1): error TS2323: Cannot redeclare exported variable 'bothBefore'.
|
||||
tests/cases/conformance/salsa/mod1.js(4,1): error TS2323: Cannot redeclare exported variable 'bothBefore'.
|
||||
tests/cases/conformance/salsa/mod1.js(5,1): error TS2323: Cannot redeclare exported variable 'bothAfter'.
|
||||
tests/cases/conformance/salsa/mod1.js(10,1): error TS2323: Cannot redeclare exported variable 'bothAfter'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/salsa/a.js (2 errors) ====
|
||||
@@ -21,16 +25,24 @@ tests/cases/conformance/salsa/a.js(5,16): error TS2339: Property 'toFixed' does
|
||||
==== tests/cases/conformance/salsa/requires.d.ts (0 errors) ====
|
||||
declare var module: { exports: any };
|
||||
declare function require(name: string): any;
|
||||
==== tests/cases/conformance/salsa/mod1.js (0 errors) ====
|
||||
==== tests/cases/conformance/salsa/mod1.js (4 errors) ====
|
||||
/// <reference path='./requires.d.ts' />
|
||||
module.exports.bothBefore = 'string'
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2323: Cannot redeclare exported variable 'bothBefore'.
|
||||
A.justExport = 4
|
||||
A.bothBefore = 2
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2323: Cannot redeclare exported variable 'bothBefore'.
|
||||
A.bothAfter = 3
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2323: Cannot redeclare exported variable 'bothAfter'.
|
||||
module.exports = A
|
||||
function A() {
|
||||
this.p = 1
|
||||
}
|
||||
module.exports.bothAfter = 'string'
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2323: Cannot redeclare exported variable 'bothAfter'.
|
||||
module.exports.justProperty = 'string'
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
error TS5070: Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.
|
||||
tests/cases/compiler/file1.ts(1,1): error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'.
|
||||
tests/cases/compiler/file1.ts(1,20): error TS2307: Cannot find module './b.json'.
|
||||
|
||||
|
||||
!!! error TS5070: Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.
|
||||
==== tests/cases/compiler/file1.ts (2 errors) ====
|
||||
import * as b from './b.json';
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'.
|
||||
~~~~~~~~~~
|
||||
!!! error TS2307: Cannot find module './b.json'.
|
||||
|
||||
==== tests/cases/compiler/b.json (0 errors) ====
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleEmitNone.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/file1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
@@ -0,0 +1,4 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : any
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleEmitUndefined.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
//// [out/file1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
"a": true,
|
||||
>"a" : Symbol("a", Decl(b.json, 0, 1))
|
||||
|
||||
"b": "hello"
|
||||
>"b" : Symbol("b", Decl(b.json, 1, 14))
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : { "a": boolean; "b": string; }
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
|
||||
|
||||
"a": true,
|
||||
>"a" : boolean
|
||||
>true : true
|
||||
|
||||
"b": "hello"
|
||||
>"b" : string
|
||||
>"hello" : "hello"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
|
||||
|
||||
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
==== tests/cases/compiler/file1.ts (0 errors) ====
|
||||
import * as b from './b.json';
|
||||
|
||||
==== tests/cases/compiler/b.json (0 errors) ====
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmd.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
//// [out/file1.js]
|
||||
define(["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
"a": true,
|
||||
>"a" : Symbol("a", Decl(b.json, 0, 1))
|
||||
|
||||
"b": "hello"
|
||||
>"b" : Symbol("b", Decl(b.json, 1, 14))
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : { "a": boolean; "b": string; }
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
|
||||
|
||||
"a": true,
|
||||
>"a" : boolean
|
||||
>true : true
|
||||
|
||||
"b": "hello"
|
||||
>"b" : string
|
||||
>"hello" : "hello"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
|
||||
|
||||
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
==== tests/cases/compiler/file1.ts (0 errors) ====
|
||||
import * as b from './b.json';
|
||||
|
||||
==== tests/cases/compiler/b.json (0 errors) ====
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
//// [out/file1.js]
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
"a": true,
|
||||
>"a" : Symbol("a", Decl(b.json, 0, 1))
|
||||
|
||||
"b": "hello"
|
||||
>"b" : Symbol("b", Decl(b.json, 1, 14))
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : { "a": boolean; "b": string; }
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
|
||||
|
||||
"a": true,
|
||||
>"a" : boolean
|
||||
>true : true
|
||||
|
||||
"b": "hello"
|
||||
>"b" : string
|
||||
>"hello" : "hello"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
|
||||
|
||||
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
==== tests/cases/compiler/file1.ts (0 errors) ====
|
||||
import * as b from './b.json';
|
||||
|
||||
==== tests/cases/compiler/b.json (0 errors) ====
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
//// [out/file1.js]
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
"a": true,
|
||||
>"a" : Symbol("a", Decl(b.json, 0, 1))
|
||||
|
||||
"b": "hello"
|
||||
>"b" : Symbol("b", Decl(b.json, 1, 14))
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : { "a": boolean; "b": string; }
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
|
||||
|
||||
"a": true,
|
||||
>"a" : boolean
|
||||
>true : true
|
||||
|
||||
"b": "hello"
|
||||
>"b" : string
|
||||
>"hello" : "hello"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
tests/cases/compiler/file1.ts(1,1): error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'.
|
||||
|
||||
|
||||
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
==== tests/cases/compiler/file1.ts (1 errors) ====
|
||||
import * as b from './b.json';
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'.
|
||||
|
||||
==== tests/cases/compiler/b.json (0 errors) ====
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitNone.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
//// [out/file1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
"a": true,
|
||||
>"a" : Symbol("a", Decl(b.json, 0, 1))
|
||||
|
||||
"b": "hello"
|
||||
>"b" : Symbol("b", Decl(b.json, 1, 14))
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : { "a": boolean; "b": string; }
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
|
||||
|
||||
"a": true,
|
||||
>"a" : boolean
|
||||
>true : true
|
||||
|
||||
"b": "hello"
|
||||
>"b" : string
|
||||
>"hello" : "hello"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
|
||||
|
||||
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
==== tests/cases/compiler/file1.ts (0 errors) ====
|
||||
import * as b from './b.json';
|
||||
|
||||
==== tests/cases/compiler/b.json (0 errors) ====
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitSystem.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
//// [out/file1.js]
|
||||
System.register([], function (exports_1, context_1) {
|
||||
"use strict";
|
||||
var __moduleName = context_1 && context_1.id;
|
||||
return {
|
||||
setters: [],
|
||||
execute: function () {
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
"a": true,
|
||||
>"a" : Symbol("a", Decl(b.json, 0, 1))
|
||||
|
||||
"b": "hello"
|
||||
>"b" : Symbol("b", Decl(b.json, 1, 14))
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : { "a": boolean; "b": string; }
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
|
||||
|
||||
"a": true,
|
||||
>"a" : boolean
|
||||
>true : true
|
||||
|
||||
"b": "hello"
|
||||
>"b" : string
|
||||
>"hello" : "hello"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
|
||||
|
||||
!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.
|
||||
==== tests/cases/compiler/file1.ts (0 errors) ====
|
||||
import * as b from './b.json';
|
||||
|
||||
==== tests/cases/compiler/b.json (0 errors) ====
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitUmd.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
//// [out/file1.js]
|
||||
(function (factory) {
|
||||
if (typeof module === "object" && typeof module.exports === "object") {
|
||||
var v = factory(require, exports);
|
||||
if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
define(["require", "exports"], factory);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
"a": true,
|
||||
>"a" : Symbol("a", Decl(b.json, 0, 1))
|
||||
|
||||
"b": "hello"
|
||||
>"b" : Symbol("b", Decl(b.json, 1, 14))
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : { "a": boolean; "b": string; }
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
|
||||
|
||||
"a": true,
|
||||
>"a" : boolean
|
||||
>true : true
|
||||
|
||||
"b": "hello"
|
||||
>"b" : string
|
||||
>"hello" : "hello"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitUndefined.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
import * as b from './b.json';
|
||||
|
||||
//// [b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
|
||||
//// [out/b.json]
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
//// [out/file1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : Symbol(b, Decl(file1.ts, 0, 6))
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
"a": true,
|
||||
>"a" : Symbol("a", Decl(b.json, 0, 1))
|
||||
|
||||
"b": "hello"
|
||||
>"b" : Symbol("b", Decl(b.json, 1, 14))
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
=== tests/cases/compiler/file1.ts ===
|
||||
import * as b from './b.json';
|
||||
>b : { "a": boolean; "b": string; }
|
||||
|
||||
=== tests/cases/compiler/b.json ===
|
||||
{
|
||||
>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; }
|
||||
|
||||
"a": true,
|
||||
>"a" : boolean
|
||||
>true : true
|
||||
|
||||
"b": "hello"
|
||||
>"b" : string
|
||||
>"hello" : "hello"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// @module: none
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// @module: amd
|
||||
// @moduleResolution: node
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// @module: es2015
|
||||
// @moduleResolution: node
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// @module: esnext
|
||||
// @moduleResolution: node
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// @module: none
|
||||
// @moduleResolution: node
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// @module: system
|
||||
// @moduleResolution: node
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// @module: umd
|
||||
// @moduleResolution: node
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// @moduleResolution: node
|
||||
// @outdir: out/
|
||||
// @fullEmitPaths: true
|
||||
// @resolveJsonModule: true
|
||||
|
||||
// @Filename: file1.ts
|
||||
import * as b from './b.json';
|
||||
|
||||
// @Filename: b.json
|
||||
{
|
||||
"a": true,
|
||||
"b": "hello"
|
||||
}
|
||||
@@ -1,20 +1,51 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /a.tsx
|
||||
// Using separate files for each example to avoid unclosed JSX tags affecting other tests.
|
||||
|
||||
// @Filename: /0.tsx
|
||||
////const x = <div>/*0*/;
|
||||
|
||||
// @Filename: /1.tsx
|
||||
////const x = <div> foo/*1*/ </div>;
|
||||
|
||||
// @Filename: /2.tsx
|
||||
////const x = <div></div>/*2*/;
|
||||
|
||||
// @Filename: /3.tsx
|
||||
////const x = <div/>/*3*/;
|
||||
|
||||
// @Filename: /4.tsx
|
||||
////const x = <div>
|
||||
//// <p>/*4*/
|
||||
//// </div>
|
||||
////</p>;
|
||||
|
||||
// @Filename: /5.tsx
|
||||
////const x = <div> text /*5*/;
|
||||
|
||||
// @Filename: /6.tsx
|
||||
////const x = <div>
|
||||
//// <div>/*6*/
|
||||
////</div>;
|
||||
|
||||
// @Filename: /7.tsx
|
||||
////const x = <div>
|
||||
//// <p>/*7*/
|
||||
////</div>;
|
||||
|
||||
// @Filename: /8.tsx
|
||||
////const x = <div>
|
||||
//// <div>/*8*/</div>
|
||||
////</div>;
|
||||
|
||||
verify.jsxClosingTag({
|
||||
0: { newText: "</div>" },
|
||||
1: undefined,
|
||||
2: undefined,
|
||||
3: undefined,
|
||||
4: { newText: "</p>" },
|
||||
5: { newText: "</div>" },
|
||||
6: { newText: "</div>" },
|
||||
7: { newText: "</p>" },
|
||||
8: undefined,
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ edit.deleteAtCaret('constructor(val: T) { }'.length);
|
||||
verify.quickInfos({
|
||||
Asig: "constructor A<string>(): A<string>",
|
||||
Bsig: "constructor B<string>(val: string): B<string>",
|
||||
Csig: "constructor C<T>(): C<T>", // Cannot resolve signature
|
||||
Csig: "constructor C<{}>(): C<{}>", // Cannot resolve signature
|
||||
Dsig: "constructor D<string>(val: string): D<string>" // Cannot resolve signature
|
||||
});
|
||||
|
||||
@@ -37,6 +37,6 @@ edit.deleteAtCaret("val: T".length);
|
||||
verify.quickInfos({
|
||||
Asig: "constructor A<string>(): A<string>",
|
||||
Bsig: "constructor B<string>(val: string): B<string>",
|
||||
Csig: "constructor C<T>(): C<T>", // Cannot resolve signature
|
||||
Csig: "constructor C<{}>(): C<{}>", // Cannot resolve signature
|
||||
Dsig: "constructor D<string>(): D<string>"
|
||||
});
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////interface A { a: number }
|
||||
////interface B { b: number }
|
||||
////declare function f(a: A): void;
|
||||
////declare function f(b: B): void;
|
||||
////f({ /**/ });
|
||||
|
||||
verify.completions({ marker: "", exact: ["a", "b"] });
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////interface A { a: number }
|
||||
////interface B { b: number }
|
||||
////interface C { c: number }
|
||||
////declare function f(a: A): void;
|
||||
////declare function f(...bs: B[]): void;
|
||||
////declare function f(...cs: C[]): void;
|
||||
////f({ /*1*/ });
|
||||
////f({ a: 1 }, { /*2*/ });
|
||||
|
||||
verify.completions(
|
||||
{ marker: "1", exact: ["a", "b", "c"] },
|
||||
{ marker: "2", exact: ["b", "c"] },
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////interface A { a: number }
|
||||
////interface B { b: number }
|
||||
////declare function f(n: number): A;
|
||||
////declare function f(s: string): B;
|
||||
////f()./**/
|
||||
|
||||
verify.completions({ marker: "", exact: ["a", "b"] });
|
||||
@@ -42,7 +42,7 @@ verify.completions(
|
||||
|
||||
{ marker: "openTag", includes: "div", triggerCharacter: "<" },
|
||||
{ marker: "lessThan", exact: undefined, triggerCharacter: "<" },
|
||||
{ marker: "closeTag", exact: "div", triggerCharacter: "/" },
|
||||
{ marker: "closeTag", exact: "div>", triggerCharacter: "/" },
|
||||
{ marker: "path", exact: "importMe", triggerCharacter: "/", isNewIdentifierLocation: true },
|
||||
{ marker: "divide", exact: undefined, triggerCharacter: "/" },
|
||||
);
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
////foo7(1, <string>(/*7*/ // signature help shows y as T
|
||||
|
||||
verify.signatureHelp(
|
||||
{ marker: "1", text: "foo1<T>(x: number, callback: (y1: T) => number): void" },
|
||||
{ marker: "1", text: "foo1(x: number, callback: (y1: {}) => number): void" },
|
||||
// TODO: GH#23631
|
||||
// { marker: "2", text: "foo2(x: number, callback: (y2: {}) => number): void" },
|
||||
{ marker: "3", text: "foo3<T>(x: number, callback: (y3: T) => number): void" },
|
||||
{ marker: "3", text: "foo3(x: number, callback: (y3: {}) => number): void" },
|
||||
// TODO: GH#23631
|
||||
// { marker: "4", text: "foo4(x: number, callback: (y4: string) => number): void" },
|
||||
{ marker: "5", text: "foo5(x: number, callback: (y5: string) => number): void" },
|
||||
@@ -31,4 +31,4 @@ goTo.marker('6');
|
||||
// verify.signatureHelp({ text: "foo6(x: number, callback: (y6: {}) => number): void" });
|
||||
edit.insert('string>(null,null);'); // need to make this line parse so we can get reasonable LS answers to later tests
|
||||
|
||||
verify.signatureHelp({ marker: "7", text: "foo7<T>(x: number, callback: (y7: T) => number): void" });
|
||||
verify.signatureHelp({ marker: "7", text: "foo7(x: number, callback: (y7: {}) => number): void" });
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
////foo7(1, <string>(/*7*/ // signature help shows y as T
|
||||
|
||||
verify.signatureHelp(
|
||||
{ marker: "1", text: "foo1<T>(x: number, callback: (y1: T) => number): void" },
|
||||
{ marker: "2", text: "foo2<T>(x: number, callback: (y2: T) => number): void" },
|
||||
{ marker: "3", text: "foo3<T>(x: number, callback: (y3: T) => number): void" },
|
||||
{ marker: "1", text: "foo1(x: number, callback: (y1: {}) => number): void" },
|
||||
{ marker: "2", text: "foo2(x: number, callback: (y2: {}) => number): void" },
|
||||
{ marker: "3", text: "foo3(x: number, callback: (y3: {}) => number): void" },
|
||||
{ marker: "4", text: "foo4(x: number, callback: (y4: string) => number): void" },
|
||||
{ marker: "5", text: "foo5(x: number, callback: (y5: string) => number): void" },
|
||||
);
|
||||
@@ -35,4 +35,4 @@ goTo.marker('6');
|
||||
verify.signatureHelp({ text: "foo6(x: number, callback: (y6: {}) => number): void" });
|
||||
edit.insert('string>(null,null);'); // need to make this line parse so we can get reasonable LS answers to later tests
|
||||
|
||||
verify.signatureHelp({ marker: "7", text: "foo7<T>(x: number, callback: (y7: T) => number): void" })
|
||||
verify.signatureHelp({ marker: "7", text: "foo7(x: number, callback: (y7: {}) => number): void" })
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
////fo/**/o()
|
||||
|
||||
goTo.marker();
|
||||
verify.quickInfoIs("function foo<T>(x: T): void", "Do some foo things");
|
||||
verify.quickInfoIs("function foo<any>(x: any): void", "Do some foo things");
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
verify.signatureHelp({
|
||||
marker: "",
|
||||
text: "find<T>(l: T[], x: T): T",
|
||||
text: "find(l: any[], x: any): any",
|
||||
docComment: "Find an item",
|
||||
tags: [
|
||||
// TODO: GH#24130 (see PR #24600's commits for potential fix)
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
//// export var Foo: any = null;
|
||||
//// }
|
||||
//// const j = <NS.Foo>Hello!/**/
|
||||
////
|
||||
////
|
||||
|
||||
goTo.marker();
|
||||
edit.insert("</");
|
||||
verify.completionListContains("NS.Foo");
|
||||
verify.not.completionListContains("Foo");
|
||||
verify.completionListCount(1);
|
||||
verify.completions({ exact: "NS.Foo>" });
|
||||
|
||||
@@ -509,7 +509,7 @@
|
||||
//// function f<T extends A>(s: T, x: Exclude<A, T>, y: string) {}
|
||||
//// f("_499", /*3*/);
|
||||
//// type Decomposed/*4*/ = {[K in A]: Foo[K]}
|
||||
//// type LongTuple/*5*/ = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17.18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70];
|
||||
//// type LongTuple/*5*/ = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17.18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70];
|
||||
//// type DeeplyMapped/*6*/ = {[K in keyof Foo]: {[K2 in keyof Foo]: [K, K2, Foo[K], Foo[K2]]}}
|
||||
|
||||
goTo.marker("1");
|
||||
@@ -519,7 +519,7 @@ verify.quickInfoIs(`type Less = "_1" | "_2" | "_3" | "_4" | "_5" | "_6" | "_7" |
|
||||
goTo.marker("3");
|
||||
verify.signatureHelp({
|
||||
marker: "3",
|
||||
text: `f<T extends "_0" | "_1" | "_2" | "_3" | "_4" | "_5" | "_6" | "_7" | "_8" | "_9" | "_10" | "_11" | "_12" | "_13" | "_14" | "_15" | "_16" | "_17" | "_18" | "_19" | "_20" | "_21" | "_22" | "_23" | "_24" | ... 474 more ... | "_499">(s: T, x: Exclude<"_0", T> | Exclude<"_1", T> | Exclude<"_2", T> | Exclude<"_3", T> | Exclude<"_4", T> | Exclude<"_5", T> | Exclude<"_6", T> | Exclude<"_7", T> | Exclude<...> | ... 490 more ... | Exclude<...>, y: string): void`
|
||||
text: `f(s: "_0" | "_1" | "_2" | "_3" | "_4" | "_5" | "_6" | "_7" | "_8" | "_9" | "_10" | "_11" | "_12" | "_13" | "_14" | "_15" | "_16" | "_17" | "_18" | "_19" | "_20" | "_21" | "_22" | "_23" | "_24" | ... 474 more ... | "_499", x: never, y: string): void`
|
||||
});
|
||||
goTo.marker("4");
|
||||
verify.quickInfoIs(`type Decomposed = {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////declare function f<T>(x: number): T;
|
||||
////const x/**/ = f();
|
||||
|
||||
verify.quickInfoAt("", "const x: {}");
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
verify.signatureHelp(
|
||||
{ marker: "1", text: "f(x: number, y: string): number" },
|
||||
{ marker: "2", text: "f<T = boolean, U = string>(x: T, y: U): T" },
|
||||
{ marker: "2", text: "f(x: {}, y: {}): {}" },
|
||||
// too few -- fill in rest with {}
|
||||
{ marker: "3", text: "f(x: number, y: {}): number" },
|
||||
// too many -- ignore extra type arguments
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
|
||||
verify.signatureHelp(
|
||||
{ marker: "1", text: "f1(a: any): a is number" },
|
||||
{ marker: "2", text: "f2<T>(a: any): a is T" },
|
||||
{ marker: "2", text: "f2(a: any): a is {}" },
|
||||
{ marker: "3", text: "f3(a: any, ...b: any[]): a is number", isVariadic: true },
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ goTo.marker("1");
|
||||
|
||||
edit.insert("(");
|
||||
verify.signatureHelp({
|
||||
text: "bar<U>(x: U, y: U): U",
|
||||
text: "bar(x: {}, y: {}): {}",
|
||||
triggerReason: {
|
||||
kind: "characterTyped",
|
||||
triggerCharacter: "(",
|
||||
|
||||
@@ -9,6 +9,4 @@
|
||||
//// }
|
||||
//// var x1 = <div><//**/
|
||||
|
||||
goTo.marker();
|
||||
verify.completionListCount(1);
|
||||
verify.completionListContains('div');
|
||||
verify.completions({ marker: "", exact: "div>" });
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user