mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-11 17:41:26 -06:00
Build script updates
This commit is contained in:
parent
1fc1495863
commit
0713e754e7
196
Gulpfile.js
196
Gulpfile.js
@ -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"
|
||||
]);
|
||||
200
Jakefile.js
200
Jakefile.js
@ -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');
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
71
scripts/build/cancellation.js
Normal file
71
scripts/build/cancellation.js
Normal file
@ -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;
|
||||
31
scripts/build/debounce.js
Normal file
31
scripts/build/debounce.js
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
66
scripts/build/prepend.js
Normal file
66
scripts/build/prepend.js
Normal file
@ -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.
|
||||
|
||||
143
scripts/build/sourcemaps.js
Normal file
143
scripts/build/sourcemaps.js
Normal file
@ -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;
|
||||
@ -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));
|
||||
}
|
||||
|
||||
27
scripts/build/utils.js
Normal file
27
scripts/build/utils.js
Normal file
@ -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;
|
||||
60
scripts/build/vinyl.d.ts
vendored
Normal file
60
scripts/build/vinyl.d.ts
vendored
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
1
scripts/build/vinyl.js
Normal file
1
scripts/build/vinyl.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require("vinyl");
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
8409
tests/baselines/reference/api/tsserverlibrary.d.ts
vendored
8409
tests/baselines/reference/api/tsserverlibrary.d.ts
vendored
File diff suppressed because it is too large
Load Diff
93
tests/baselines/reference/api/typescript.d.ts
vendored
93
tests/baselines/reference/api/typescript.d.ts
vendored
@ -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 */
|
||||
@ -4570,6 +4585,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 +5663,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;
|
||||
Loading…
x
Reference in New Issue
Block a user