mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into fixIifeIndentation
This commit is contained in:
@@ -17,6 +17,8 @@ Andy Hanson <anhans@microsoft.com> Andy <anhans@microsoft.com>
|
||||
Anil Anar <anilanar@hotmail.com>
|
||||
Anton Tolmachev <myste@mail.ru>
|
||||
Anubha Mathur <anubmat@microsoft.com> anubmat <anubmat@microsoft.com>
|
||||
Armando Aguirre <armando.aguirre@microsoft.com>
|
||||
Arnaud Tournier <ltearno@gmail.com>
|
||||
Arnavion <arnavion@gmail.com> # Arnav Singh
|
||||
Arthur Ozga <aozgaa@umich.edu> Arthur Ozga <t-arthoz@microsoft.com> Arthur Ozga <aozgaa-ms@outlook.com> Arthur Ozga <aozgaa@users.noreply.github.com> Arthur Ozga <arozga@microsoft.com>
|
||||
Asad Saeeduddin <masaeedu@gmail.com>
|
||||
@@ -26,6 +28,7 @@ Bill Ticehurst <billti@hotmail.com> Bill Ticehurst <billti@microsoft.com>
|
||||
Ben Duffield <jebavarde@gmail.com>
|
||||
Ben Mosher <me@benmosher.com>
|
||||
Benjamin Bock <bb@users.noreply.github.com>
|
||||
Benjamin Lichtman <uniqueiniquity@users.noreply.github.com> uniqueiniquity <blichtman623@gmail.com>
|
||||
Blake Embrey <hello@blakeembrey.com>
|
||||
Bowden Kelly <wilkelly@microsoft.com>
|
||||
Brett Mayen <bmayen@midnightsnacks.net>
|
||||
@@ -59,6 +62,7 @@ Evan Sebastian <evanlhoini@gmail.com>
|
||||
Eyas <eyas.sharaiha@gmail.com> # Eyas Sharaiha
|
||||
Fabian Cook <faybecook@gmail.com>
|
||||
falsandtru <falsandtru@users.noreply.github.com> # @falsandtru
|
||||
Filipe Silva <filipematossilva@gmail.com>
|
||||
flowmemo <flowmemo@outlook.com> # @flowmemo
|
||||
Frank Wallis <fwallis@outlook.com>
|
||||
František Žiacik <fziacik@gratex.com> František Žiacik <ziacik@gmail.com>
|
||||
@@ -192,7 +196,7 @@ TruongSinh Tran-Nguyen <i@truongsinh.pro>
|
||||
vilicvane <i@vilic.info> # Vilic Vane
|
||||
Vladimir Matveev <vladima@microsoft.com> vladima <vladima@microsoft.com> v2m <desco.by@gmail.com>
|
||||
Vadi Taslim <vadz77@hotmail.com>
|
||||
Wesley Wigham <t-weswig@microsoft.com> Wesley Wigham <wwigham@gmail.com>
|
||||
Wesley Wigham <t-weswig@microsoft.com> Wesley Wigham <wwigham@gmail.com> Wesley Wigham <wewigham@microsoft.com>
|
||||
York Yao <plantain-00@users.noreply.github.com> york yao <yaoao12306@outlook.com> yaoyao <yaoyao12306@163.com>
|
||||
Yuichi Nukiyama <oscar.wilde84@hotmail.co.jp> YuichiNukiyama <oscar.wilde84@hotmail.co.jp>
|
||||
Zev Spitz <shivisi@etrog.net.il>
|
||||
@@ -267,4 +271,9 @@ Reiner Dolp <reiner-dolp@users.noreply.github.com>
|
||||
t_ <t-mrt@users.noreply.github.com> # @t_
|
||||
TravCav <xurrux@gmail.com> # @TravCav
|
||||
Vladimir Kurchatkin <vladimir.kurchatkin@gmail.com>
|
||||
William Orr <will@worrbase.com>
|
||||
William Orr <will@worrbase.com>
|
||||
Francois Wouts <f@codonut.com>
|
||||
Jan Melcher <jan.melcher@aeb.com> Jan Melcher <mail@jan-melcher.de>
|
||||
Matt Mitchell <mmitche@microsoft.com>
|
||||
Maxwell Paul Brickner <mbrickn@users.noreply.github.com>
|
||||
Tycho Grouwstra <tychogrouwstra@gmail.com>
|
||||
+2
-1
@@ -16,4 +16,5 @@ Jakefile.js
|
||||
.gitattributes
|
||||
.settings/
|
||||
.travis.yml
|
||||
.vscode/
|
||||
.vscode/
|
||||
test.config
|
||||
@@ -16,6 +16,7 @@ matrix:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.5
|
||||
|
||||
install:
|
||||
- npm uninstall typescript --no-save
|
||||
|
||||
@@ -25,6 +25,8 @@ TypeScript is authored by:
|
||||
* Anton Khlynovskiy
|
||||
* Anton Tolmachev
|
||||
* Anubha Mathur
|
||||
* Armando Aguirre
|
||||
* Arnaud Tournier
|
||||
* Arnav Singh
|
||||
* Arthur Ozga
|
||||
* Asad Saeeduddin
|
||||
@@ -33,6 +35,7 @@ TypeScript is authored by:
|
||||
* Ben Duffield
|
||||
* Ben Mosher
|
||||
* Benjamin Bock
|
||||
* Benjamin Lichtman
|
||||
* Benny Neugebauer
|
||||
* Bill Ticehurst
|
||||
* Blaine Bublitz
|
||||
@@ -85,7 +88,9 @@ TypeScript is authored by:
|
||||
* Eyas Sharaiha
|
||||
* Fabian Cook
|
||||
* @falsandtru
|
||||
* Filipe Silva
|
||||
* @flowmemo
|
||||
* Francois Wouts
|
||||
* Frank Wallis
|
||||
* Franklin Tse
|
||||
* František Žiacik
|
||||
@@ -112,6 +117,7 @@ TypeScript is authored by:
|
||||
* Jakub Młokosiewicz
|
||||
* James Henry
|
||||
* James Whitney
|
||||
* Jan Melcher
|
||||
* Jason Freeman
|
||||
* Jason Jarrett
|
||||
* Jason Killian
|
||||
@@ -162,9 +168,11 @@ TypeScript is authored by:
|
||||
* Masahiro Wakame
|
||||
* Matt Bierner
|
||||
* Matt McCutchen
|
||||
* Matt Mitchell
|
||||
* Mattias Buelens
|
||||
* Mattias Buelens
|
||||
* Max Deepfield
|
||||
* Maxwell Paul Brickner
|
||||
* Micah Zoltu
|
||||
* Michael
|
||||
* Michael Bromley
|
||||
@@ -243,6 +251,7 @@ TypeScript is authored by:
|
||||
* Torben Fitschen
|
||||
* @TravCav
|
||||
* TruongSinh Tran-Nguyen
|
||||
* Tycho Grouwstra
|
||||
* Vadi Taslim
|
||||
* Vidar Tonaas Fauske
|
||||
* Viktor Zozulyak
|
||||
|
||||
+23
-28
@@ -31,8 +31,6 @@ import merge2 = require("merge2");
|
||||
import * as os from "os";
|
||||
import fold = require("travis-fold");
|
||||
const gulp = helpMaker(originalGulp);
|
||||
const mochaParallel = require("./scripts/mocha-parallel.js");
|
||||
const {runTestsInParallel} = mochaParallel;
|
||||
|
||||
Error.stackTraceLimit = 1000;
|
||||
|
||||
@@ -463,10 +461,11 @@ gulp.task(serverFile, /*help*/ false, [servicesFile, typingsInstallerJs, cancell
|
||||
.pipe(gulp.dest("src/server"));
|
||||
});
|
||||
|
||||
const typesMapJson = path.join(builtLocalDirectory, "typesMap.json");
|
||||
const tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
|
||||
const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
|
||||
|
||||
gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile], (done) => {
|
||||
gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (done) => {
|
||||
const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
|
||||
const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src()
|
||||
.pipe(sourcemaps.init())
|
||||
@@ -485,6 +484,15 @@ gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile], (done) => {
|
||||
]);
|
||||
});
|
||||
|
||||
gulp.task(typesMapJson, /*help*/ false, [], () => {
|
||||
return gulp.src("src/server/typesMap.json")
|
||||
.pipe(insert.transform((contents, file) => {
|
||||
JSON.parse(contents);
|
||||
return contents;
|
||||
}))
|
||||
.pipe(gulp.dest(builtLocalDirectory));
|
||||
});
|
||||
|
||||
gulp.task("lssl", "Builds language service server library", [tsserverLibraryFile]);
|
||||
gulp.task("local", "Builds the full compiler and services", [builtLocalCompiler, servicesFile, serverFile, builtGeneratedDiagnosticMessagesJSON, tsserverLibraryFile]);
|
||||
gulp.task("tsc", "Builds only the compiler", [builtLocalCompiler]);
|
||||
@@ -658,26 +666,9 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
}
|
||||
else {
|
||||
// run task to load all tests and partition them between workers
|
||||
const args = [];
|
||||
args.push("-R", "min");
|
||||
if (colors) {
|
||||
args.push("--colors");
|
||||
}
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
args.push(run);
|
||||
setNodeEnvToDevelopment();
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout, noColors: colors === " --no-colors " }, function(err) {
|
||||
// last worker clean everything and runs linter in case if there were no errors
|
||||
del(taskConfigsFolder).then(() => {
|
||||
if (!err) {
|
||||
lintThenFinish();
|
||||
}
|
||||
else {
|
||||
finish(err);
|
||||
}
|
||||
});
|
||||
exec(host, [run], lintThenFinish, function(e, status) {
|
||||
finish(e, status);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -701,7 +692,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
|
||||
function finish(error?: any, errorStatus?: number) {
|
||||
restoreSavedNodeEnv();
|
||||
deleteTemporaryProjectOutput().then(() => {
|
||||
deleteTestConfig().then(deleteTemporaryProjectOutput).then(() => {
|
||||
if (error !== undefined || errorStatus !== undefined) {
|
||||
failWithStatus(error, errorStatus);
|
||||
}
|
||||
@@ -710,6 +701,10 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteTestConfig() {
|
||||
return del("test.config");
|
||||
}
|
||||
}
|
||||
|
||||
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"], (done) => {
|
||||
@@ -776,7 +771,7 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo
|
||||
const file = new Vinyl({ contents, path: bundlePath });
|
||||
console.log(`Fixing sourcemaps for ${file.path}`);
|
||||
// assumes contents is a Buffer, since that's what browserify yields
|
||||
const maps = convertMap.fromSource(stringContent, /*largeSource*/ true).toObject();
|
||||
const maps = convertMap.fromSource(stringContent).toObject();
|
||||
delete maps.sourceRoot;
|
||||
maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s));
|
||||
// Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths)
|
||||
@@ -826,7 +821,7 @@ function cleanTestDirs(done: (e?: any) => void) {
|
||||
|
||||
// used to pass data from jake command line directly to run.js
|
||||
function writeTestConfigFile(tests: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string) {
|
||||
const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, light, workerCount, stackTraceLimit, taskConfigsFolder });
|
||||
const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, light, workerCount, stackTraceLimit, taskConfigsFolder, noColor: !cmdLineOptions["colors"] });
|
||||
console.log("Running tests with config: " + testConfigContents);
|
||||
fs.writeFileSync("test.config", testConfigContents);
|
||||
}
|
||||
@@ -968,7 +963,7 @@ const instrumenterPath = path.join(harnessDirectory, "instrumenter.ts");
|
||||
const instrumenterJsPath = path.join(builtLocalDirectory, "instrumenter.js");
|
||||
gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({
|
||||
outFile: instrumenterJsPath,
|
||||
module: "commonjs",
|
||||
target: "es5",
|
||||
lib: [
|
||||
"es6",
|
||||
@@ -980,8 +975,8 @@ gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
|
||||
.pipe(newer(instrumenterJsPath))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(tsc(settings))
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(sourcemaps.write(builtLocalDirectory))
|
||||
.pipe(gulp.dest(builtLocalDirectory));
|
||||
});
|
||||
|
||||
gulp.task("tsc-instrumented", "Builds an instrumented tsc.js", ["local", loggedIOJsPath, instrumenterJsPath, servicesFile], (done) => {
|
||||
|
||||
+40
-24
@@ -1,11 +1,11 @@
|
||||
// This file contains the build logic for the public repo
|
||||
// @ts-check
|
||||
|
||||
var fs = require("fs");
|
||||
var os = require("os");
|
||||
var path = require("path");
|
||||
var child_process = require("child_process");
|
||||
var fold = require("travis-fold");
|
||||
var runTestsInParallel = require("./scripts/mocha-parallel").runTestsInParallel;
|
||||
var ts = require("./lib/typescript");
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ else if (process.env.PATH !== undefined) {
|
||||
|
||||
function filesFromConfig(configPath) {
|
||||
var configText = fs.readFileSync(configPath).toString();
|
||||
var config = ts.parseConfigFileTextToJson(configPath, configText, /*stripComments*/ true);
|
||||
var config = ts.parseConfigFileTextToJson(configPath, configText);
|
||||
if (config.error) {
|
||||
throw new Error(diagnosticsToString([config.error]));
|
||||
}
|
||||
@@ -88,6 +88,8 @@ var watchGuardSources = filesFromConfig(path.join(serverDirectory, "watchGuard/t
|
||||
var serverSources = filesFromConfig(path.join(serverDirectory, "tsconfig.json"))
|
||||
var languageServiceLibrarySources = filesFromConfig(path.join(serverDirectory, "tsconfig.library.json"));
|
||||
|
||||
var typesMapOutputPath = path.join(builtLocalDirectory, 'typesMap.json');
|
||||
|
||||
var harnessCoreSources = [
|
||||
"harness.ts",
|
||||
"virtualFileSystem.ts",
|
||||
@@ -102,6 +104,9 @@ var harnessCoreSources = [
|
||||
"loggedIO.ts",
|
||||
"rwcRunner.ts",
|
||||
"test262Runner.ts",
|
||||
"./parallel/shared.ts",
|
||||
"./parallel/host.ts",
|
||||
"./parallel/worker.ts",
|
||||
"runner.ts"
|
||||
].map(function (f) {
|
||||
return path.join(harnessDirectory, f);
|
||||
@@ -140,6 +145,8 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"transform.ts",
|
||||
"customTransforms.ts",
|
||||
"programMissingFiles.ts",
|
||||
"symbolWalker.ts",
|
||||
"languageService.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
@@ -423,6 +430,7 @@ var buildProtocolTs = path.join(scriptsDirectory, "buildProtocol.ts");
|
||||
var buildProtocolJs = path.join(scriptsDirectory, "buildProtocol.js");
|
||||
var buildProtocolDts = path.join(builtLocalDirectory, "protocol.d.ts");
|
||||
var typescriptServicesDts = path.join(builtLocalDirectory, "typescriptServices.d.ts");
|
||||
var typesMapJson = path.join(builtLocalDirectory, "typesMap.json");
|
||||
|
||||
file(buildProtocolTs);
|
||||
|
||||
@@ -587,6 +595,16 @@ var serverFile = path.join(builtLocalDirectory, "tsserver.js");
|
||||
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright, cancellationTokenFile, typingsInstallerFile, watchGuardFile].concat(serverSources).concat(servicesSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], preserveConstEnums: true, lib: "es6" });
|
||||
var tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
|
||||
var tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
|
||||
file(typesMapOutputPath, function() {
|
||||
var content = fs.readFileSync(path.join(serverDirectory, 'typesMap.json'));
|
||||
// Validate that it's valid JSON
|
||||
try {
|
||||
JSON.parse(content.toString());
|
||||
} catch (e) {
|
||||
console.log("Parse error in typesMap.json: " + e);
|
||||
}
|
||||
fs.writeFileSync(typesMapOutputPath, content);
|
||||
});
|
||||
compileFile(
|
||||
tsserverLibraryFile,
|
||||
languageServiceLibrarySources,
|
||||
@@ -609,7 +627,7 @@ compileFile(
|
||||
|
||||
// Local target to build the language service server library
|
||||
desc("Builds language service server library");
|
||||
task("lssl", [tsserverLibraryFile, tsserverLibraryDefinitionFile]);
|
||||
task("lssl", [tsserverLibraryFile, tsserverLibraryDefinitionFile, typesMapOutputPath]);
|
||||
|
||||
desc("Emit the start of the build fold");
|
||||
task("build-fold-start", [], function () {
|
||||
@@ -638,7 +656,6 @@ task("release", function () {
|
||||
// Set the default task to "local"
|
||||
task("default", ["local"]);
|
||||
|
||||
|
||||
// Cleans the built directory
|
||||
desc("Cleans the compiler output, declare files, and tests");
|
||||
task("clean", function () {
|
||||
@@ -726,7 +743,7 @@ desc("Builds the test infrastructure using the built compiler");
|
||||
task("tests", ["local", run].concat(libraryTargets));
|
||||
|
||||
function exec(cmd, completeHandler, errorHandler) {
|
||||
var ex = jake.createExec([cmd], { windowsVerbatimArguments: true });
|
||||
var ex = jake.createExec([cmd], { windowsVerbatimArguments: true, interactive: true });
|
||||
// Add listeners for output and error
|
||||
ex.addListener("stdout", function (output) {
|
||||
process.stdout.write(output);
|
||||
@@ -752,15 +769,16 @@ function exec(cmd, completeHandler, errorHandler) {
|
||||
ex.run();
|
||||
}
|
||||
|
||||
const del = require("del");
|
||||
function cleanTestDirs() {
|
||||
// Clean the local baselines directory
|
||||
if (fs.existsSync(localBaseline)) {
|
||||
jake.rmRf(localBaseline);
|
||||
del.sync(localBaseline);
|
||||
}
|
||||
|
||||
// Clean the local Rwc baselines directory
|
||||
if (fs.existsSync(localRwcBaseline)) {
|
||||
jake.rmRf(localRwcBaseline);
|
||||
del.sync(localRwcBaseline);
|
||||
}
|
||||
|
||||
jake.mkdirP(localRwcBaseline);
|
||||
@@ -769,13 +787,14 @@ function cleanTestDirs() {
|
||||
}
|
||||
|
||||
// used to pass data from jake command line directly to run.js
|
||||
function writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit) {
|
||||
function writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit, colors) {
|
||||
var testConfigContents = JSON.stringify({
|
||||
test: tests ? [tests] : undefined,
|
||||
light: light,
|
||||
workerCount: workerCount,
|
||||
taskConfigsFolder: taskConfigsFolder,
|
||||
stackTraceLimit: stackTraceLimit
|
||||
stackTraceLimit: stackTraceLimit,
|
||||
noColor: !colors
|
||||
});
|
||||
fs.writeFileSync('test.config', testConfigContents);
|
||||
}
|
||||
@@ -817,7 +836,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
}
|
||||
|
||||
if (tests || light || taskConfigsFolder) {
|
||||
writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit);
|
||||
writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit, colors);
|
||||
}
|
||||
|
||||
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
||||
@@ -880,19 +899,15 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
var savedNodeEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = "development";
|
||||
var startTime = mark();
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: !colors }, function (err) {
|
||||
exec(host + " " + run, function () {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
measure(startTime);
|
||||
// last worker clean everything and runs linter in case if there were no errors
|
||||
deleteTemporaryProjectOutput();
|
||||
jake.rmRf(taskConfigsFolder);
|
||||
if (err) {
|
||||
fail(err);
|
||||
}
|
||||
else {
|
||||
runLinter();
|
||||
complete();
|
||||
}
|
||||
runLinter();
|
||||
finish();
|
||||
}, function (e, status) {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
measure(startTime);
|
||||
finish(status);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -955,8 +970,8 @@ desc("Runs the tests using the built run.js file like 'jake runtests'. Syntax is
|
||||
task("runtests-browser", ["browserify", nodeServerOutFile], function () {
|
||||
cleanTestDirs();
|
||||
host = "node";
|
||||
browser = process.env.browser || process.env.b || (os.platform() === "linux" ? "chrome" : "IE");
|
||||
tests = process.env.test || process.env.tests || process.env.t;
|
||||
var browser = process.env.browser || process.env.b || (os.platform() === "linux" ? "chrome" : "IE");
|
||||
var tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
var testConfigFile = 'test.config';
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
@@ -1028,6 +1043,7 @@ function acceptBaseline(sourceFolder, targetFolder) {
|
||||
if (fs.existsSync(target)) {
|
||||
fs.unlinkSync(target);
|
||||
}
|
||||
jake.mkdirP(path.dirname(target));
|
||||
fs.renameSync(path.join(sourceFolder, filename), target);
|
||||
}
|
||||
}
|
||||
@@ -1086,7 +1102,7 @@ file(loggedIOJsPath, [builtLocalDirectory, loggedIOpath], function () {
|
||||
|
||||
var instrumenterPath = harnessDirectory + 'instrumenter.ts';
|
||||
var instrumenterJsPath = builtLocalDirectory + 'instrumenter.js';
|
||||
compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath].concat(libraryTargets), [], /*useBuiltCompiler*/ true, { lib: "es6", types: ["node"] });
|
||||
compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath].concat(libraryTargets), [], /*useBuiltCompiler*/ true, { lib: "es6", types: ["node"], noOutFile: true, outDir: builtLocalDirectory });
|
||||
|
||||
desc("Builds an instrumented tsc.js");
|
||||
task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function () {
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
|
||||
For the latest stable version:
|
||||
|
||||
```
|
||||
```bash
|
||||
npm install -g typescript
|
||||
```
|
||||
|
||||
For our nightly builds:
|
||||
|
||||
```
|
||||
```bash
|
||||
npm install -g typescript@next
|
||||
```
|
||||
|
||||
@@ -50,19 +50,19 @@ In order to build the TypeScript compiler, ensure that you have [Git](https://gi
|
||||
|
||||
Clone a copy of the repo:
|
||||
|
||||
```
|
||||
```bash
|
||||
git clone https://github.com/Microsoft/TypeScript.git
|
||||
```
|
||||
|
||||
Change to the TypeScript directory:
|
||||
|
||||
```
|
||||
```bash
|
||||
cd TypeScript
|
||||
```
|
||||
|
||||
Install Gulp tools and dev dependencies:
|
||||
|
||||
```
|
||||
```bash
|
||||
npm install -g gulp
|
||||
npm install
|
||||
```
|
||||
@@ -88,7 +88,7 @@ gulp help # List the above commands.
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
```bash
|
||||
node built/local/tsc.js hello.ts
|
||||
```
|
||||
|
||||
|
||||
@@ -69,3 +69,5 @@ function createCancellationToken(args) {
|
||||
}
|
||||
}
|
||||
module.exports = createCancellationToken;
|
||||
|
||||
//# sourceMappingURL=cancellationToken.js.map
|
||||
|
||||
Vendored
+5
-5
@@ -236,7 +236,7 @@ interface ObjectConstructor {
|
||||
* Returns the names of the enumerable properties and methods of an object.
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
keys(o: any): string[];
|
||||
keys(o: {}): string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1000,12 +1000,12 @@ interface ReadonlyArray<T> {
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: T[][]): T[];
|
||||
concat(...items: ReadonlyArray<T>[]): T[];
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: (T | T[])[]): T[];
|
||||
concat(...items: (T | ReadonlyArray<T>)[]): T[];
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
|
||||
@@ -1119,12 +1119,12 @@ interface Array<T> {
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: T[][]): T[];
|
||||
concat(...items: ReadonlyArray<T>[]): T[];
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: (T | T[])[]): T[];
|
||||
concat(...items: (T | ReadonlyArray<T>)[]): T[];
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
|
||||
|
||||
Vendored
+1
-1
@@ -130,7 +130,7 @@ interface Map<K, V> {
|
||||
readonly [Symbol.toStringTag]: "Map";
|
||||
}
|
||||
|
||||
interface WeakMap<K extends object, V>{
|
||||
interface WeakMap<K extends object, V> {
|
||||
readonly [Symbol.toStringTag]: "WeakMap";
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1824
File diff suppressed because it is too large
Load Diff
Vendored
+1824
File diff suppressed because it is too large
Load Diff
Vendored
+5
-5
@@ -236,7 +236,7 @@ interface ObjectConstructor {
|
||||
* Returns the names of the enumerable properties and methods of an object.
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
keys(o: any): string[];
|
||||
keys(o: {}): string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1000,12 +1000,12 @@ interface ReadonlyArray<T> {
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: T[][]): T[];
|
||||
concat(...items: ReadonlyArray<T>[]): T[];
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: (T | T[])[]): T[];
|
||||
concat(...items: (T | ReadonlyArray<T>)[]): T[];
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
|
||||
@@ -1119,12 +1119,12 @@ interface Array<T> {
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: T[][]): T[];
|
||||
concat(...items: ReadonlyArray<T>[]): T[];
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: (T | T[])[]): T[];
|
||||
concat(...items: (T | ReadonlyArray<T>)[]): T[];
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
|
||||
|
||||
Vendored
+6
-6
@@ -236,7 +236,7 @@ interface ObjectConstructor {
|
||||
* Returns the names of the enumerable properties and methods of an object.
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
keys(o: any): string[];
|
||||
keys(o: {}): string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1000,12 +1000,12 @@ interface ReadonlyArray<T> {
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: T[][]): T[];
|
||||
concat(...items: ReadonlyArray<T>[]): T[];
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: (T | T[])[]): T[];
|
||||
concat(...items: (T | ReadonlyArray<T>)[]): T[];
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
|
||||
@@ -1119,12 +1119,12 @@ interface Array<T> {
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: T[][]): T[];
|
||||
concat(...items: ReadonlyArray<T>[]): T[];
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: (T | T[])[]): T[];
|
||||
concat(...items: (T | ReadonlyArray<T>)[]): T[];
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
|
||||
@@ -5689,7 +5689,7 @@ interface Map<K, V> {
|
||||
readonly [Symbol.toStringTag]: "Map";
|
||||
}
|
||||
|
||||
interface WeakMap<K extends object, V>{
|
||||
interface WeakMap<K extends object, V> {
|
||||
readonly [Symbol.toStringTag]: "WeakMap";
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1824
File diff suppressed because it is too large
Load Diff
+2648
-755
File diff suppressed because it is too large
Load Diff
+3014
-1451
File diff suppressed because it is too large
Load Diff
Vendored
+136
-179
@@ -50,7 +50,7 @@ declare namespace ts {
|
||||
pos: number;
|
||||
end: number;
|
||||
}
|
||||
enum SyntaxKind {
|
||||
const enum SyntaxKind {
|
||||
Unknown = 0,
|
||||
EndOfFileToken = 1,
|
||||
SingleLineCommentTrivia = 2,
|
||||
@@ -374,7 +374,7 @@ declare namespace ts {
|
||||
FirstJSDocTagNode = 276,
|
||||
LastJSDocTagNode = 285,
|
||||
}
|
||||
enum NodeFlags {
|
||||
const enum NodeFlags {
|
||||
None = 0,
|
||||
Let = 1,
|
||||
Const = 2,
|
||||
@@ -402,7 +402,7 @@ declare namespace ts {
|
||||
ContextFlags = 96256,
|
||||
TypeExcludesFlags = 20480,
|
||||
}
|
||||
enum ModifierFlags {
|
||||
const enum ModifierFlags {
|
||||
None = 0,
|
||||
Export = 1,
|
||||
Ambient = 2,
|
||||
@@ -422,7 +422,7 @@ declare namespace ts {
|
||||
TypeScriptModifier = 2270,
|
||||
ExportDefault = 513,
|
||||
}
|
||||
enum JsxFlags {
|
||||
const enum JsxFlags {
|
||||
None = 0,
|
||||
IntrinsicNamedElement = 1,
|
||||
IntrinsicIndexedElement = 2,
|
||||
@@ -1175,7 +1175,7 @@ declare namespace ts {
|
||||
interface CatchClause extends Node {
|
||||
kind: SyntaxKind.CatchClause;
|
||||
parent?: TryStatement;
|
||||
variableDeclaration: VariableDeclaration;
|
||||
variableDeclaration?: VariableDeclaration;
|
||||
block: Block;
|
||||
}
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
@@ -1432,7 +1432,7 @@ declare namespace ts {
|
||||
jsDocTypeTag?: JSDocTypeTag;
|
||||
isArrayType?: boolean;
|
||||
}
|
||||
enum FlowFlags {
|
||||
const enum FlowFlags {
|
||||
Unreachable = 1,
|
||||
Start = 2,
|
||||
BranchLabel = 4,
|
||||
@@ -1452,38 +1452,39 @@ declare namespace ts {
|
||||
interface FlowLock {
|
||||
locked?: boolean;
|
||||
}
|
||||
interface AfterFinallyFlow extends FlowNode, FlowLock {
|
||||
interface AfterFinallyFlow extends FlowNodeBase, FlowLock {
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface PreFinallyFlow extends FlowNode {
|
||||
interface PreFinallyFlow extends FlowNodeBase {
|
||||
antecedent: FlowNode;
|
||||
lock: FlowLock;
|
||||
}
|
||||
interface FlowNode {
|
||||
type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation;
|
||||
interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number;
|
||||
}
|
||||
interface FlowStart extends FlowNode {
|
||||
interface FlowStart extends FlowNodeBase {
|
||||
container?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
}
|
||||
interface FlowLabel extends FlowNode {
|
||||
interface FlowLabel extends FlowNodeBase {
|
||||
antecedents: FlowNode[];
|
||||
}
|
||||
interface FlowAssignment extends FlowNode {
|
||||
interface FlowAssignment extends FlowNodeBase {
|
||||
node: Expression | VariableDeclaration | BindingElement;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowCondition extends FlowNode {
|
||||
interface FlowCondition extends FlowNodeBase {
|
||||
expression: Expression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowSwitchClause extends FlowNode {
|
||||
interface FlowSwitchClause extends FlowNodeBase {
|
||||
switchStatement: SwitchStatement;
|
||||
clauseStart: number;
|
||||
clauseEnd: number;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowArrayMutation extends FlowNode {
|
||||
interface FlowArrayMutation extends FlowNodeBase {
|
||||
node: CallExpression | BinaryExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
@@ -1607,6 +1608,7 @@ declare namespace ts {
|
||||
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol | undefined;
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
@@ -1684,7 +1686,7 @@ declare namespace ts {
|
||||
reportInaccessibleThisError(): void;
|
||||
reportPrivateInBaseOfClassExpression(propertyName: string): void;
|
||||
}
|
||||
enum TypeFormatFlags {
|
||||
const enum TypeFormatFlags {
|
||||
None = 0,
|
||||
WriteArrayAsGenericType = 1,
|
||||
UseTypeOfFunction = 4,
|
||||
@@ -1696,18 +1698,18 @@ declare namespace ts {
|
||||
UseFullyQualifiedType = 256,
|
||||
InFirstTypeArgument = 512,
|
||||
InTypeAlias = 1024,
|
||||
UseTypeAliasValue = 2048,
|
||||
SuppressAnyReturnType = 4096,
|
||||
AddUndefined = 8192,
|
||||
WriteClassExpressionAsTypeLiteral = 16384,
|
||||
InArrayType = 32768,
|
||||
UseAliasDefinedOutsideCurrentScope = 65536,
|
||||
}
|
||||
enum SymbolFormatFlags {
|
||||
const enum SymbolFormatFlags {
|
||||
None = 0,
|
||||
WriteTypeParametersOrArguments = 1,
|
||||
UseOnlyExternalAliasing = 2,
|
||||
}
|
||||
enum TypePredicateKind {
|
||||
const enum TypePredicateKind {
|
||||
This = 0,
|
||||
Identifier = 1,
|
||||
}
|
||||
@@ -1724,7 +1726,7 @@ declare namespace ts {
|
||||
parameterIndex: number;
|
||||
}
|
||||
type TypePredicate = IdentifierTypePredicate | ThisTypePredicate;
|
||||
enum SymbolFlags {
|
||||
const enum SymbolFlags {
|
||||
None = 0,
|
||||
FunctionScopedVariable = 1,
|
||||
BlockScopedVariable = 2,
|
||||
@@ -1794,7 +1796,7 @@ declare namespace ts {
|
||||
exports?: SymbolTable;
|
||||
globalExports?: SymbolTable;
|
||||
}
|
||||
enum InternalSymbolName {
|
||||
const enum InternalSymbolName {
|
||||
Call = "__call",
|
||||
Constructor = "__constructor",
|
||||
New = "__new",
|
||||
@@ -1832,7 +1834,7 @@ declare namespace ts {
|
||||
clear(): void;
|
||||
}
|
||||
type SymbolTable = UnderscoreEscapedMap<Symbol>;
|
||||
enum TypeFlags {
|
||||
const enum TypeFlags {
|
||||
Any = 1,
|
||||
String = 2,
|
||||
Number = 4,
|
||||
@@ -1889,7 +1891,7 @@ declare namespace ts {
|
||||
}
|
||||
interface EnumType extends Type {
|
||||
}
|
||||
enum ObjectFlags {
|
||||
const enum ObjectFlags {
|
||||
Class = 1,
|
||||
Interface = 2,
|
||||
Reference = 4,
|
||||
@@ -1951,7 +1953,7 @@ declare namespace ts {
|
||||
interface IndexType extends Type {
|
||||
type: TypeVariable | UnionOrIntersectionType;
|
||||
}
|
||||
enum SignatureKind {
|
||||
const enum SignatureKind {
|
||||
Call = 0,
|
||||
Construct = 1,
|
||||
}
|
||||
@@ -1960,7 +1962,7 @@ declare namespace ts {
|
||||
typeParameters?: TypeParameter[];
|
||||
parameters: Symbol[];
|
||||
}
|
||||
enum IndexKind {
|
||||
const enum IndexKind {
|
||||
String = 0,
|
||||
Number = 1,
|
||||
}
|
||||
@@ -1969,7 +1971,7 @@ declare namespace ts {
|
||||
isReadonly: boolean;
|
||||
declaration?: SignatureDeclaration;
|
||||
}
|
||||
enum InferencePriority {
|
||||
const enum InferencePriority {
|
||||
NakedTypeVariable = 1,
|
||||
MappedType = 2,
|
||||
ReturnType = 4,
|
||||
@@ -1982,11 +1984,17 @@ declare namespace ts {
|
||||
topLevel: boolean;
|
||||
isFixed: boolean;
|
||||
}
|
||||
enum InferenceFlags {
|
||||
const enum InferenceFlags {
|
||||
InferUnionTypes = 1,
|
||||
NoDefault = 2,
|
||||
AnyDefault = 4,
|
||||
}
|
||||
const enum Ternary {
|
||||
False = 0,
|
||||
Maybe = 1,
|
||||
True = -1,
|
||||
}
|
||||
type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary;
|
||||
interface JsFileExtensionInfo {
|
||||
extension: string;
|
||||
isMixedContent: boolean;
|
||||
@@ -2073,6 +2081,7 @@ declare namespace ts {
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
preserveConstEnums?: boolean;
|
||||
preserveSymlinks?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
jsxFactory?: string;
|
||||
@@ -2118,13 +2127,13 @@ declare namespace ts {
|
||||
ES2015 = 5,
|
||||
ESNext = 6,
|
||||
}
|
||||
enum JsxEmit {
|
||||
const enum JsxEmit {
|
||||
None = 0,
|
||||
Preserve = 1,
|
||||
React = 2,
|
||||
ReactNative = 3,
|
||||
}
|
||||
enum NewLineKind {
|
||||
const enum NewLineKind {
|
||||
CarriageReturnLineFeed = 0,
|
||||
LineFeed = 1,
|
||||
}
|
||||
@@ -2132,7 +2141,7 @@ declare namespace ts {
|
||||
line: number;
|
||||
character: number;
|
||||
}
|
||||
enum ScriptKind {
|
||||
const enum ScriptKind {
|
||||
Unknown = 0,
|
||||
JS = 1,
|
||||
JSX = 2,
|
||||
@@ -2141,7 +2150,7 @@ declare namespace ts {
|
||||
External = 5,
|
||||
JSON = 6,
|
||||
}
|
||||
enum ScriptTarget {
|
||||
const enum ScriptTarget {
|
||||
ES3 = 0,
|
||||
ES5 = 1,
|
||||
ES2015 = 2,
|
||||
@@ -2150,7 +2159,7 @@ declare namespace ts {
|
||||
ESNext = 5,
|
||||
Latest = 5,
|
||||
}
|
||||
enum LanguageVariant {
|
||||
const enum LanguageVariant {
|
||||
Standard = 0,
|
||||
JSX = 1,
|
||||
}
|
||||
@@ -2163,7 +2172,7 @@ declare namespace ts {
|
||||
wildcardDirectories?: MapLike<WatchDirectoryFlags>;
|
||||
compileOnSave?: boolean;
|
||||
}
|
||||
enum WatchDirectoryFlags {
|
||||
const enum WatchDirectoryFlags {
|
||||
None = 0,
|
||||
Recursive = 1,
|
||||
}
|
||||
@@ -2186,8 +2195,13 @@ declare namespace ts {
|
||||
}
|
||||
interface ResolvedModuleFull extends ResolvedModule {
|
||||
extension: Extension;
|
||||
packageId?: PackageId;
|
||||
}
|
||||
enum Extension {
|
||||
interface PackageId {
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
const enum Extension {
|
||||
Ts = ".ts",
|
||||
Tsx = ".tsx",
|
||||
Dts = ".d.ts",
|
||||
@@ -2229,7 +2243,7 @@ declare namespace ts {
|
||||
text: string;
|
||||
skipTrivia?: (pos: number) => number;
|
||||
}
|
||||
enum EmitFlags {
|
||||
const enum EmitFlags {
|
||||
SingleLine = 1,
|
||||
AdviseOnEmitNode = 2,
|
||||
NoSubstitution = 4,
|
||||
@@ -2265,7 +2279,7 @@ declare namespace ts {
|
||||
readonly text: string;
|
||||
readonly priority?: number;
|
||||
}
|
||||
enum EmitHint {
|
||||
const enum EmitHint {
|
||||
SourceFile = 0,
|
||||
Expression = 1,
|
||||
IdentifierName = 2,
|
||||
@@ -2326,7 +2340,7 @@ declare namespace ts {
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "2.5";
|
||||
const versionMajorMinor = "2.6";
|
||||
const version: string;
|
||||
}
|
||||
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
|
||||
@@ -2402,6 +2416,8 @@ declare namespace ts {
|
||||
function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray<TextChangeRange>): TextChangeRange;
|
||||
function getTypeParameterOwner(d: Declaration): Declaration;
|
||||
function isParameterPropertyDeclaration(node: Node): boolean;
|
||||
function isEmptyBindingPattern(node: BindingName): node is BindingPattern;
|
||||
function isEmptyBindingElement(node: BindingElement): boolean;
|
||||
function getCombinedModifierFlags(node: Node): ModifierFlags;
|
||||
function getCombinedNodeFlags(node: Node): NodeFlags;
|
||||
function validateLocaleAndSetLanguage(locale: string, sys: {
|
||||
@@ -2959,8 +2975,8 @@ declare namespace ts {
|
||||
function updateDefaultClause(node: DefaultClause, statements: ReadonlyArray<Statement>): DefaultClause;
|
||||
function createHeritageClause(token: HeritageClause["token"], types: ReadonlyArray<ExpressionWithTypeArguments>): HeritageClause;
|
||||
function updateHeritageClause(node: HeritageClause, types: ReadonlyArray<ExpressionWithTypeArguments>): HeritageClause;
|
||||
function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block): CatchClause;
|
||||
function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block): CatchClause;
|
||||
function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause;
|
||||
function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause;
|
||||
function createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment;
|
||||
function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment;
|
||||
function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment;
|
||||
@@ -3197,6 +3213,7 @@ declare namespace ts {
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[];
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion;
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
@@ -3288,7 +3305,7 @@ declare namespace ts {
|
||||
fileName: string;
|
||||
highlightSpans: HighlightSpan[];
|
||||
}
|
||||
enum HighlightSpanKind {
|
||||
const enum HighlightSpanKind {
|
||||
none = "none",
|
||||
definition = "definition",
|
||||
reference = "reference",
|
||||
@@ -3483,7 +3500,7 @@ declare namespace ts {
|
||||
outputFiles: OutputFile[];
|
||||
emitSkipped: boolean;
|
||||
}
|
||||
enum OutputFileType {
|
||||
const enum OutputFileType {
|
||||
JavaScript = 0,
|
||||
SourceMap = 1,
|
||||
Declaration = 2,
|
||||
@@ -3493,7 +3510,7 @@ declare namespace ts {
|
||||
writeByteOrderMark: boolean;
|
||||
text: string;
|
||||
}
|
||||
enum EndOfLineState {
|
||||
const enum EndOfLineState {
|
||||
None = 0,
|
||||
InMultiLineCommentTrivia = 1,
|
||||
InSingleQuoteStringLiteral = 2,
|
||||
@@ -3525,7 +3542,7 @@ declare namespace ts {
|
||||
getClassificationsForLine(text: string, lexState: EndOfLineState, syntacticClassifierAbsent: boolean): ClassificationResult;
|
||||
getEncodedLexicalClassifications(text: string, endOfLineState: EndOfLineState, syntacticClassifierAbsent: boolean): Classifications;
|
||||
}
|
||||
enum ScriptElementKind {
|
||||
const enum ScriptElementKind {
|
||||
unknown = "",
|
||||
warning = "warning",
|
||||
keyword = "keyword",
|
||||
@@ -3560,7 +3577,7 @@ declare namespace ts {
|
||||
externalModuleName = "external module name",
|
||||
jsxAttribute = "JSX attribute",
|
||||
}
|
||||
enum ScriptElementKindModifier {
|
||||
const enum ScriptElementKindModifier {
|
||||
none = "",
|
||||
publicMemberModifier = "public",
|
||||
privateMemberModifier = "private",
|
||||
@@ -3570,7 +3587,7 @@ declare namespace ts {
|
||||
staticModifier = "static",
|
||||
abstractModifier = "abstract",
|
||||
}
|
||||
enum ClassificationTypeNames {
|
||||
const enum ClassificationTypeNames {
|
||||
comment = "comment",
|
||||
identifier = "identifier",
|
||||
keyword = "keyword",
|
||||
@@ -3595,7 +3612,7 @@ declare namespace ts {
|
||||
jsxText = "jsx text",
|
||||
jsxAttributeStringLiteralValue = "jsx attribute string literal value",
|
||||
}
|
||||
enum ClassificationType {
|
||||
const enum ClassificationType {
|
||||
comment = 1,
|
||||
identifier = 2,
|
||||
keyword = 3,
|
||||
@@ -3687,7 +3704,10 @@ declare namespace ts.server {
|
||||
error: undefined;
|
||||
} | {
|
||||
module: undefined;
|
||||
error: {};
|
||||
error: {
|
||||
stack?: string;
|
||||
message?: string;
|
||||
};
|
||||
};
|
||||
interface ServerHost extends System {
|
||||
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
@@ -3770,6 +3790,7 @@ declare namespace ts.server {
|
||||
const LogFile = "--logFile";
|
||||
const EnableTelemetry = "--enableTelemetry";
|
||||
const TypingSafeListLocation = "--typingSafeListLocation";
|
||||
const TypesMapLocation = "--typesMapLocation";
|
||||
const NpmLocation = "--npmLocation";
|
||||
}
|
||||
function hasArgument(argumentName: string): boolean;
|
||||
@@ -3838,9 +3859,6 @@ declare namespace ts.server {
|
||||
function isInferredProjectName(name: string): boolean;
|
||||
function makeInferredProjectName(counter: number): string;
|
||||
function createSortedArray<T>(): SortedArray<T>;
|
||||
function toSortedArray(arr: string[]): SortedArray<string>;
|
||||
function toSortedArray<T>(arr: T[], comparer: Comparer<T>): SortedArray<T>;
|
||||
function enumerateInsertsAndDeletes<T>(newItems: SortedReadonlyArray<T>, oldItems: SortedReadonlyArray<T>, inserted: (newItem: T) => void, deleted: (oldItem: T) => void, compare?: Comparer<T>): void;
|
||||
class ThrottledOperations {
|
||||
private readonly host;
|
||||
private pendingTimeouts;
|
||||
@@ -3857,13 +3875,12 @@ declare namespace ts.server {
|
||||
scheduleCollect(): void;
|
||||
private static run(self);
|
||||
}
|
||||
function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): void;
|
||||
function removeSorted<T>(array: SortedArray<T>, remove: T, compare: Comparer<T>): void;
|
||||
}
|
||||
declare namespace ts.server.protocol {
|
||||
enum CommandTypes {
|
||||
const enum CommandTypes {
|
||||
Brace = "brace",
|
||||
BraceCompletion = "braceCompletion",
|
||||
GetSpanOfEnclosingComment = "getSpanOfEnclosingComment",
|
||||
Change = "change",
|
||||
Close = "close",
|
||||
Completions = "completions",
|
||||
@@ -3951,6 +3968,13 @@ declare namespace ts.server.protocol {
|
||||
interface TodoCommentsResponse extends Response {
|
||||
body?: TodoComment[];
|
||||
}
|
||||
interface SpanOfEnclosingCommentRequest extends FileLocationRequest {
|
||||
command: CommandTypes.GetSpanOfEnclosingComment;
|
||||
arguments: SpanOfEnclosingCommentRequestArgs;
|
||||
}
|
||||
interface SpanOfEnclosingCommentRequestArgs extends FileLocationRequestArgs {
|
||||
onlyMultiLine: boolean;
|
||||
}
|
||||
interface IndentationRequest extends FileLocationRequest {
|
||||
command: CommandTypes.Indentation;
|
||||
arguments: IndentationRequestArgs;
|
||||
@@ -4168,7 +4192,7 @@ declare namespace ts.server.protocol {
|
||||
}
|
||||
interface RenameResponseBody {
|
||||
info: RenameInfo;
|
||||
locs: SpanGroup[];
|
||||
locs: ReadonlyArray<SpanGroup>;
|
||||
}
|
||||
interface RenameResponse extends Response {
|
||||
body?: RenameResponseBody;
|
||||
@@ -4248,6 +4272,7 @@ declare namespace ts.server.protocol {
|
||||
}
|
||||
interface SetCompilerOptionsForInferredProjectsArgs {
|
||||
options: ExternalProjectCompilerOptions;
|
||||
projectRootPath?: string;
|
||||
}
|
||||
interface SetCompilerOptionsForInferredProjectsResponse extends Response {
|
||||
}
|
||||
@@ -4603,7 +4628,7 @@ declare namespace ts.server.protocol {
|
||||
interface NavTreeResponse extends Response {
|
||||
body?: NavigationTree;
|
||||
}
|
||||
enum IndentStyle {
|
||||
const enum IndentStyle {
|
||||
None = "None",
|
||||
Block = "Block",
|
||||
Smart = "Smart",
|
||||
@@ -4681,6 +4706,7 @@ declare namespace ts.server.protocol {
|
||||
paths?: MapLike<string[]>;
|
||||
plugins?: PluginImport[];
|
||||
preserveConstEnums?: boolean;
|
||||
preserveSymlinks?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
removeComments?: boolean;
|
||||
@@ -4700,13 +4726,13 @@ declare namespace ts.server.protocol {
|
||||
typeRoots?: string[];
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
enum JsxEmit {
|
||||
const enum JsxEmit {
|
||||
None = "None",
|
||||
Preserve = "Preserve",
|
||||
ReactNative = "ReactNative",
|
||||
React = "React",
|
||||
}
|
||||
enum ModuleKind {
|
||||
const enum ModuleKind {
|
||||
None = "None",
|
||||
CommonJS = "CommonJS",
|
||||
AMD = "AMD",
|
||||
@@ -4714,20 +4740,24 @@ declare namespace ts.server.protocol {
|
||||
System = "System",
|
||||
ES6 = "ES6",
|
||||
ES2015 = "ES2015",
|
||||
ESNext = "ESNext",
|
||||
}
|
||||
enum ModuleResolutionKind {
|
||||
const enum ModuleResolutionKind {
|
||||
Classic = "Classic",
|
||||
Node = "Node",
|
||||
}
|
||||
enum NewLineKind {
|
||||
const enum NewLineKind {
|
||||
Crlf = "Crlf",
|
||||
Lf = "Lf",
|
||||
}
|
||||
enum ScriptTarget {
|
||||
const enum ScriptTarget {
|
||||
ES3 = "ES3",
|
||||
ES5 = "ES5",
|
||||
ES6 = "ES6",
|
||||
ES2015 = "ES2015",
|
||||
ES2016 = "ES2016",
|
||||
ES2017 = "ES2017",
|
||||
ESNext = "ESNext",
|
||||
}
|
||||
}
|
||||
declare namespace ts.server {
|
||||
@@ -4750,6 +4780,7 @@ declare namespace ts.server {
|
||||
host: ServerHost;
|
||||
cancellationToken: ServerCancellationToken;
|
||||
useSingleInferredProject: boolean;
|
||||
useInferredProjectPerProjectRoot: boolean;
|
||||
typingsInstaller: ITypingsInstaller;
|
||||
byteLength: (buf: string, encoding?: string) => number;
|
||||
hrtime: (start?: number[]) => number[];
|
||||
@@ -4757,8 +4788,8 @@ declare namespace ts.server {
|
||||
canUseEvents: boolean;
|
||||
eventHandler?: ProjectServiceEventHandler;
|
||||
throttleWaitMilliseconds?: number;
|
||||
globalPlugins?: string[];
|
||||
pluginProbeLocations?: string[];
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
allowLocalPluginLoads?: boolean;
|
||||
}
|
||||
class Session implements EventSender {
|
||||
@@ -4780,13 +4811,13 @@ declare namespace ts.server {
|
||||
private defaultEventHandler(event);
|
||||
logError(err: Error, cmd: string): void;
|
||||
send(msg: protocol.Message): void;
|
||||
configFileDiagnosticEvent(triggerFile: string, configFile: string, diagnostics: Diagnostic[]): void;
|
||||
configFileDiagnosticEvent(triggerFile: string, configFile: string, diagnostics: ReadonlyArray<Diagnostic>): void;
|
||||
event<T>(info: T, eventName: string): void;
|
||||
output(info: any, cmdName: string, reqSeq?: number, errorMsg?: string): void;
|
||||
private semanticCheck(file, project);
|
||||
private syntacticCheck(file, project);
|
||||
private updateProjectStructure(seq, matchSeq, ms?);
|
||||
private updateErrorCheck(next, checkList, seq, matchSeq, ms?, followMs?, requireOpen?);
|
||||
private updateProjectStructure();
|
||||
private updateErrorCheck(next, checkList, ms, requireOpen?);
|
||||
private cleanProjects(caption, projects);
|
||||
private cleanup();
|
||||
private getEncodedSemanticClassifications(args);
|
||||
@@ -4820,6 +4851,7 @@ declare namespace ts.server {
|
||||
private getOutliningSpans(args);
|
||||
private getTodoComments(args);
|
||||
private getDocCommentTemplate(args);
|
||||
private getSpanOfEnclosingComment(args);
|
||||
private getIndentation(args);
|
||||
private getBreakpointStatement(args);
|
||||
private getNameOrDottedNameSpan(args);
|
||||
@@ -4878,38 +4910,10 @@ declare namespace ts.server {
|
||||
}
|
||||
}
|
||||
declare namespace ts.server {
|
||||
interface LineCollection {
|
||||
charCount(): number;
|
||||
lineCount(): number;
|
||||
isLeaf(): this is LineLeaf;
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void;
|
||||
}
|
||||
interface AbsolutePositionAndLineText {
|
||||
absolutePosition: number;
|
||||
lineText: string | undefined;
|
||||
}
|
||||
enum CharRangeSection {
|
||||
PreStart = 0,
|
||||
Start = 1,
|
||||
Entire = 2,
|
||||
Mid = 3,
|
||||
End = 4,
|
||||
PostEnd = 5,
|
||||
}
|
||||
interface ILineIndexWalker {
|
||||
goSubtree: boolean;
|
||||
done: boolean;
|
||||
leaf(relativeStart: number, relativeLength: number, lineCollection: LineLeaf): void;
|
||||
pre?(relativeStart: number, relativeLength: number, lineCollection: LineCollection, parent: LineNode, nodeType: CharRangeSection): void;
|
||||
post?(relativeStart: number, relativeLength: number, lineCollection: LineCollection, parent: LineNode, nodeType: CharRangeSection): void;
|
||||
}
|
||||
class TextChange {
|
||||
pos: number;
|
||||
deleteLen: number;
|
||||
insertedText: string;
|
||||
constructor(pos: number, deleteLen: number, insertedText?: string);
|
||||
getTextChangeRange(): TextChangeRange;
|
||||
}
|
||||
class ScriptVersionCache {
|
||||
private changes;
|
||||
private readonly versions;
|
||||
@@ -4921,79 +4925,17 @@ declare namespace ts.server {
|
||||
private versionToIndex(version);
|
||||
private currentVersionToIndex();
|
||||
edit(pos: number, deleteLen: number, insertedText?: string): void;
|
||||
latest(): LineIndexSnapshot;
|
||||
latestVersion(): number;
|
||||
reload(script: string): void;
|
||||
getSnapshot(): LineIndexSnapshot;
|
||||
getSnapshot(): IScriptSnapshot;
|
||||
private _getSnapshot();
|
||||
getSnapshotVersion(): number;
|
||||
getLineInfo(line: number): AbsolutePositionAndLineText;
|
||||
lineOffsetToPosition(line: number, column: number): number;
|
||||
positionToLineOffset(position: number): protocol.Location;
|
||||
lineToTextSpan(line: number): TextSpan;
|
||||
getTextChangesBetweenVersions(oldVersion: number, newVersion: number): TextChangeRange;
|
||||
static fromString(script: string): ScriptVersionCache;
|
||||
}
|
||||
class LineIndexSnapshot implements IScriptSnapshot {
|
||||
readonly version: number;
|
||||
readonly cache: ScriptVersionCache;
|
||||
readonly index: LineIndex;
|
||||
readonly changesSincePreviousVersion: ReadonlyArray<TextChange>;
|
||||
constructor(version: number, cache: ScriptVersionCache, index: LineIndex, changesSincePreviousVersion?: ReadonlyArray<TextChange>);
|
||||
getText(rangeStart: number, rangeEnd: number): string;
|
||||
getLength(): number;
|
||||
getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange;
|
||||
}
|
||||
class LineIndex {
|
||||
root: LineNode;
|
||||
checkEdits: boolean;
|
||||
absolutePositionOfStartOfLine(oneBasedLine: number): number;
|
||||
positionToLineOffset(position: number): protocol.Location;
|
||||
private positionToColumnAndLineText(position);
|
||||
lineNumberToInfo(oneBasedLine: number): AbsolutePositionAndLineText;
|
||||
load(lines: string[]): void;
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void;
|
||||
getText(rangeStart: number, rangeLength: number): string;
|
||||
getLength(): number;
|
||||
every(f: (ll: LineLeaf, s: number, len: number) => boolean, rangeStart: number, rangeEnd?: number): boolean;
|
||||
edit(pos: number, deleteLength: number, newText?: string): LineIndex;
|
||||
private static buildTreeFromBottom(nodes);
|
||||
static linesFromText(text: string): {
|
||||
lines: string[];
|
||||
lineMap: number[];
|
||||
};
|
||||
}
|
||||
class LineNode implements LineCollection {
|
||||
private readonly children;
|
||||
totalChars: number;
|
||||
totalLines: number;
|
||||
constructor(children?: LineCollection[]);
|
||||
isLeaf(): boolean;
|
||||
updateCounts(): void;
|
||||
private execWalk(rangeStart, rangeLength, walkFns, childIndex, nodeType);
|
||||
private skipChild(relativeStart, relativeLength, childIndex, walkFns, nodeType);
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void;
|
||||
charOffsetToLineInfo(lineNumberAccumulator: number, relativePosition: number): {
|
||||
oneBasedLine: number;
|
||||
zeroBasedColumn: number;
|
||||
lineText: string | undefined;
|
||||
};
|
||||
lineNumberToInfo(relativeOneBasedLine: number, positionAccumulator: number): {
|
||||
position: number;
|
||||
leaf: LineLeaf | undefined;
|
||||
};
|
||||
private childFromLineNumber(relativeOneBasedLine, positionAccumulator);
|
||||
private childFromCharOffset(lineNumberAccumulator, relativePosition);
|
||||
private splitAfter(childIndex);
|
||||
remove(child: LineCollection): void;
|
||||
private findChildIndex(child);
|
||||
insertAt(child: LineCollection, nodes: LineCollection[]): LineNode[];
|
||||
add(collection: LineCollection): void;
|
||||
charCount(): number;
|
||||
lineCount(): number;
|
||||
}
|
||||
class LineLeaf implements LineCollection {
|
||||
text: string;
|
||||
constructor(text: string);
|
||||
isLeaf(): boolean;
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void;
|
||||
charCount(): number;
|
||||
lineCount(): number;
|
||||
}
|
||||
}
|
||||
declare namespace ts.server {
|
||||
class ScriptInfo {
|
||||
@@ -5174,7 +5116,7 @@ declare namespace ts.server {
|
||||
private projectStructureVersion;
|
||||
private projectStateVersion;
|
||||
private typingFiles;
|
||||
protected projectErrors: Diagnostic[];
|
||||
protected projectErrors: ReadonlyArray<Diagnostic>;
|
||||
typesVersion: number;
|
||||
isNonTsProject(): boolean;
|
||||
isJsOnlyProject(): boolean;
|
||||
@@ -5182,8 +5124,8 @@ declare namespace ts.server {
|
||||
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {};
|
||||
constructor(projectName: string, projectKind: ProjectKind, projectService: ProjectService, documentRegistry: DocumentRegistry, hasExplicitListOfFiles: boolean, languageServiceEnabled: boolean, compilerOptions: CompilerOptions, compileOnSaveEnabled: boolean);
|
||||
private setInternalCompilerOptionsForEmittingJsFiles();
|
||||
getGlobalProjectErrors(): Diagnostic[];
|
||||
getAllProjectErrors(): Diagnostic[];
|
||||
getGlobalProjectErrors(): ReadonlyArray<Diagnostic>;
|
||||
getAllProjectErrors(): ReadonlyArray<Diagnostic>;
|
||||
getLanguageService(ensureSynchronized?: boolean): LanguageService;
|
||||
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[];
|
||||
getProjectVersion(): string;
|
||||
@@ -5203,6 +5145,7 @@ declare namespace ts.server {
|
||||
getRootScriptInfos(): ScriptInfo[];
|
||||
getScriptInfos(): ScriptInfo[];
|
||||
getFileEmitOutput(info: ScriptInfo, emitOnlyDtsFiles: boolean): EmitOutput;
|
||||
getExcludedFiles(): ReadonlyArray<NormalizedPath>;
|
||||
getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean): NormalizedPath[];
|
||||
hasConfigFile(configFilePath: NormalizedPath): boolean;
|
||||
getAllEmittableFiles(): string[];
|
||||
@@ -5228,12 +5171,13 @@ declare namespace ts.server {
|
||||
protected removeRoot(info: ScriptInfo): void;
|
||||
}
|
||||
class InferredProject extends Project {
|
||||
readonly projectRootPath: string | undefined;
|
||||
private static readonly newName;
|
||||
private _isJsInferredProject;
|
||||
toggleJsInferredProject(isJsInferredProject: boolean): void;
|
||||
setCompilerOptions(options?: CompilerOptions): void;
|
||||
directoriesWatchedForTsconfig: string[];
|
||||
constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions);
|
||||
constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, projectRootPath?: string);
|
||||
addRoot(info: ScriptInfo): void;
|
||||
removeRoot(info: ScriptInfo): void;
|
||||
getProjectRootPath(): string;
|
||||
@@ -5257,7 +5201,7 @@ declare namespace ts.server {
|
||||
private enablePlugin(pluginConfigEntry, searchPaths);
|
||||
private enableProxy(pluginModuleFactory, configEntry);
|
||||
getProjectRootPath(): string;
|
||||
setProjectErrors(projectErrors: Diagnostic[]): void;
|
||||
setProjectErrors(projectErrors: ReadonlyArray<Diagnostic>): void;
|
||||
setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void;
|
||||
getTypeAcquisition(): TypeAcquisition;
|
||||
getExternalFiles(): SortedReadonlyArray<string>;
|
||||
@@ -5275,11 +5219,13 @@ declare namespace ts.server {
|
||||
externalProjectName: string;
|
||||
compileOnSaveEnabled: boolean;
|
||||
private readonly projectFilePath;
|
||||
excludedFiles: ReadonlyArray<NormalizedPath>;
|
||||
private typeAcquisition;
|
||||
constructor(externalProjectName: string, projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, languageServiceEnabled: boolean, compileOnSaveEnabled: boolean, projectFilePath?: string);
|
||||
getExcludedFiles(): ReadonlyArray<NormalizedPath>;
|
||||
getProjectRootPath(): string;
|
||||
getTypeAcquisition(): TypeAcquisition;
|
||||
setProjectErrors(projectErrors: Diagnostic[]): void;
|
||||
setProjectErrors(projectErrors: ReadonlyArray<Diagnostic>): void;
|
||||
setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void;
|
||||
}
|
||||
}
|
||||
@@ -5301,7 +5247,7 @@ declare namespace ts.server {
|
||||
data: {
|
||||
triggerFile: string;
|
||||
configFileName: string;
|
||||
diagnostics: Diagnostic[];
|
||||
diagnostics: ReadonlyArray<Diagnostic>;
|
||||
};
|
||||
}
|
||||
interface ProjectLanguageServiceStateEvent {
|
||||
@@ -5353,11 +5299,15 @@ declare namespace ts.server {
|
||||
types?: string[];
|
||||
};
|
||||
}
|
||||
interface TypesMapFile {
|
||||
typesMap: SafeList;
|
||||
simpleMap: string[];
|
||||
}
|
||||
function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings;
|
||||
function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin;
|
||||
function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind;
|
||||
function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX;
|
||||
function combineProjectOutput<T>(projects: Project[], action: (project: Project) => T[], comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean): T[];
|
||||
function combineProjectOutput<T>(projects: ReadonlyArray<Project>, action: (project: Project) => ReadonlyArray<T>, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean): T[];
|
||||
interface HostConfiguration {
|
||||
formatCodeOptions: FormatCodeSettings;
|
||||
hostInfo: string;
|
||||
@@ -5365,19 +5315,21 @@ declare namespace ts.server {
|
||||
}
|
||||
interface OpenConfiguredProjectResult {
|
||||
configFileName?: NormalizedPath;
|
||||
configFileErrors?: Diagnostic[];
|
||||
configFileErrors?: ReadonlyArray<Diagnostic>;
|
||||
}
|
||||
interface ProjectServiceOptions {
|
||||
host: ServerHost;
|
||||
logger: Logger;
|
||||
cancellationToken: HostCancellationToken;
|
||||
useSingleInferredProject: boolean;
|
||||
useInferredProjectPerProjectRoot: boolean;
|
||||
typingsInstaller: ITypingsInstaller;
|
||||
eventHandler?: ProjectServiceEventHandler;
|
||||
throttleWaitMilliseconds?: number;
|
||||
globalPlugins?: string[];
|
||||
pluginProbeLocations?: string[];
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
allowLocalPluginLoads?: boolean;
|
||||
typesMapLocation?: string;
|
||||
}
|
||||
class ProjectService {
|
||||
readonly typingsCache: TypingsCache;
|
||||
@@ -5389,7 +5341,7 @@ declare namespace ts.server {
|
||||
readonly configuredProjects: ConfiguredProject[];
|
||||
readonly openFiles: ScriptInfo[];
|
||||
private compilerOptionsForInferredProjects;
|
||||
private compileOnSaveForInferredProjects;
|
||||
private compilerOptionsForInferredProjectsPerProjectRoot;
|
||||
private readonly projectToSizeMap;
|
||||
private readonly directoryWatchers;
|
||||
private readonly throttledOperations;
|
||||
@@ -5402,19 +5354,22 @@ declare namespace ts.server {
|
||||
readonly logger: Logger;
|
||||
readonly cancellationToken: HostCancellationToken;
|
||||
readonly useSingleInferredProject: boolean;
|
||||
readonly useInferredProjectPerProjectRoot: boolean;
|
||||
readonly typingsInstaller: ITypingsInstaller;
|
||||
readonly throttleWaitMilliseconds?: number;
|
||||
private readonly eventHandler?;
|
||||
readonly globalPlugins: ReadonlyArray<string>;
|
||||
readonly pluginProbeLocations: ReadonlyArray<string>;
|
||||
readonly allowLocalPluginLoads: boolean;
|
||||
readonly typesMapLocation: string | undefined;
|
||||
private readonly seenProjects;
|
||||
constructor(opts: ProjectServiceOptions);
|
||||
ensureInferredProjectsUpToDate_TestOnly(): void;
|
||||
getCompilerOptionsForInferredProjects(): CompilerOptions;
|
||||
onUpdateLanguageServiceStateForProject(project: Project, languageServiceEnabled: boolean): void;
|
||||
private loadTypesMap();
|
||||
updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void;
|
||||
setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions): void;
|
||||
setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions, projectRootPath?: string): void;
|
||||
stopWatchingDirectory(directory: string): void;
|
||||
findProject(projectName: string): Project;
|
||||
getDefaultProjectForFile(fileName: NormalizedPath, refreshInferredProjects: boolean): Project;
|
||||
@@ -5431,7 +5386,7 @@ declare namespace ts.server {
|
||||
private onConfigFileAddedForInferredProject(fileName);
|
||||
private getCanonicalFileName(fileName);
|
||||
private removeProject(project);
|
||||
private assignScriptInfoToInferredProjectIfNecessary(info, addToListOfOpenFiles);
|
||||
private assignScriptInfoToInferredProjectIfNecessary(info, addToListOfOpenFiles, projectRootPath?);
|
||||
private closeOpenFile(info);
|
||||
private deleteOrphanScriptInfoNotInAnyProject();
|
||||
private openOrUpdateConfiguredProjectForFile(fileName, projectRootPath?);
|
||||
@@ -5450,7 +5405,10 @@ declare namespace ts.server {
|
||||
private openConfigFile(configFileName, clientFileName?);
|
||||
private updateNonInferredProject<T>(project, newUncheckedFiles, propertyReader, newOptions, newTypeAcquisition, compileOnSave, configFileErrors);
|
||||
private updateConfiguredProject(project);
|
||||
createInferredProjectWithRootFileIfNecessary(root: ScriptInfo): InferredProject;
|
||||
private getOrCreateInferredProjectForProjectRootPathIfEnabled(root, projectRootPath);
|
||||
private getOrCreateSingleInferredProjectIfEnabled();
|
||||
private createInferredProject(isSingleInferredProject?, projectRootPath?);
|
||||
createInferredProjectWithRootFileIfNecessary(root: ScriptInfo, projectRootPath?: string): InferredProject;
|
||||
getOrCreateScriptInfo(uncheckedFileName: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind): ScriptInfo;
|
||||
getScriptInfo(uncheckedFileName: string): ScriptInfo;
|
||||
watchClosedScriptInfo(info: ScriptInfo): void;
|
||||
@@ -5471,8 +5429,7 @@ declare namespace ts.server {
|
||||
private static readonly filenameEscapeRegexp;
|
||||
private static escapeFilenameForRegex(filename);
|
||||
resetSafeList(): void;
|
||||
loadSafeList(fileName: string): void;
|
||||
applySafeList(proj: protocol.ExternalProject): void;
|
||||
applySafeList(proj: protocol.ExternalProject): NormalizedPath[];
|
||||
openExternalProject(proj: protocol.ExternalProject, suppressRefreshOfInferredProjects?: boolean): void;
|
||||
}
|
||||
}
|
||||
|
||||
+3341
-1804
File diff suppressed because it is too large
Load Diff
Vendored
+65
-20
@@ -1210,7 +1210,7 @@ declare namespace ts {
|
||||
interface CatchClause extends Node {
|
||||
kind: SyntaxKind.CatchClause;
|
||||
parent?: TryStatement;
|
||||
variableDeclaration: VariableDeclaration;
|
||||
variableDeclaration?: VariableDeclaration;
|
||||
block: Block;
|
||||
}
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
@@ -1496,38 +1496,39 @@ declare namespace ts {
|
||||
interface FlowLock {
|
||||
locked?: boolean;
|
||||
}
|
||||
interface AfterFinallyFlow extends FlowNode, FlowLock {
|
||||
interface AfterFinallyFlow extends FlowNodeBase, FlowLock {
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface PreFinallyFlow extends FlowNode {
|
||||
interface PreFinallyFlow extends FlowNodeBase {
|
||||
antecedent: FlowNode;
|
||||
lock: FlowLock;
|
||||
}
|
||||
interface FlowNode {
|
||||
type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation;
|
||||
interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number;
|
||||
}
|
||||
interface FlowStart extends FlowNode {
|
||||
interface FlowStart extends FlowNodeBase {
|
||||
container?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
}
|
||||
interface FlowLabel extends FlowNode {
|
||||
interface FlowLabel extends FlowNodeBase {
|
||||
antecedents: FlowNode[];
|
||||
}
|
||||
interface FlowAssignment extends FlowNode {
|
||||
interface FlowAssignment extends FlowNodeBase {
|
||||
node: Expression | VariableDeclaration | BindingElement;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowCondition extends FlowNode {
|
||||
interface FlowCondition extends FlowNodeBase {
|
||||
expression: Expression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowSwitchClause extends FlowNode {
|
||||
interface FlowSwitchClause extends FlowNodeBase {
|
||||
switchStatement: SwitchStatement;
|
||||
clauseStart: number;
|
||||
clauseEnd: number;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowArrayMutation extends FlowNode {
|
||||
interface FlowArrayMutation extends FlowNodeBase {
|
||||
node: CallExpression | BinaryExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
@@ -1696,6 +1697,15 @@ declare namespace ts {
|
||||
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol | undefined;
|
||||
/**
|
||||
* If a symbol is a local symbol with an associated exported symbol, returns the exported symbol.
|
||||
* Otherwise returns its input.
|
||||
* For example, at `export type T = number;`:
|
||||
* - `getSymbolAtLocation` at the location `T` will return the exported symbol for `T`.
|
||||
* - But the result of `getSymbolsInScope` will contain the *local* symbol for `T`, not the exported symbol.
|
||||
* - Calling `getExportSymbolOfSymbol` on that local symbol will return the exported symbol.
|
||||
*/
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
@@ -1790,11 +1800,11 @@ declare namespace ts {
|
||||
UseFullyQualifiedType = 256,
|
||||
InFirstTypeArgument = 512,
|
||||
InTypeAlias = 1024,
|
||||
UseTypeAliasValue = 2048,
|
||||
SuppressAnyReturnType = 4096,
|
||||
AddUndefined = 8192,
|
||||
WriteClassExpressionAsTypeLiteral = 16384,
|
||||
InArrayType = 32768,
|
||||
UseAliasDefinedOutsideCurrentScope = 65536,
|
||||
}
|
||||
enum SymbolFormatFlags {
|
||||
None = 0,
|
||||
@@ -2056,6 +2066,7 @@ declare namespace ts {
|
||||
interface TypeVariable extends Type {
|
||||
}
|
||||
interface TypeParameter extends TypeVariable {
|
||||
/** Retrieve using getConstraintFromTypeParameter */
|
||||
constraint: Type;
|
||||
default?: Type;
|
||||
}
|
||||
@@ -2103,6 +2114,21 @@ declare namespace ts {
|
||||
NoDefault = 2,
|
||||
AnyDefault = 4,
|
||||
}
|
||||
/**
|
||||
* Ternary values are defined such that
|
||||
* x & y is False if either x or y is False.
|
||||
* x & y is Maybe if either x or y is Maybe, but neither x or y is False.
|
||||
* x & y is True if both x and y are True.
|
||||
* x | y is False if both x and y are False.
|
||||
* x | y is Maybe if either x or y is Maybe, but neither x or y is True.
|
||||
* x | y is True if either x or y is True.
|
||||
*/
|
||||
enum Ternary {
|
||||
False = 0,
|
||||
Maybe = 1,
|
||||
True = -1,
|
||||
}
|
||||
type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary;
|
||||
interface JsFileExtensionInfo {
|
||||
extension: string;
|
||||
isMixedContent: boolean;
|
||||
@@ -2195,6 +2221,7 @@ declare namespace ts {
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
preserveConstEnums?: boolean;
|
||||
preserveSymlinks?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
jsxFactory?: string;
|
||||
@@ -2300,6 +2327,10 @@ declare namespace ts {
|
||||
readFile(fileName: string): string | undefined;
|
||||
trace?(s: string): void;
|
||||
directoryExists?(directoryName: string): boolean;
|
||||
/**
|
||||
* Resolve a symbolic link.
|
||||
* @see https://nodejs.org/api/fs.html#fs_fs_realpathsync_path_options
|
||||
*/
|
||||
realpath?(path: string): string;
|
||||
getCurrentDirectory?(): string;
|
||||
getDirectories?(path: string): string[];
|
||||
@@ -2314,17 +2345,13 @@ declare namespace ts {
|
||||
interface ResolvedModule {
|
||||
/** Path of the file the module was resolved to. */
|
||||
resolvedFileName: string;
|
||||
/**
|
||||
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be a proper external module:
|
||||
* - be a .d.ts file
|
||||
* - use top level imports\exports
|
||||
* - don't use tripleslash references
|
||||
*/
|
||||
/** True if `resolvedFileName` comes from `node_modules`. */
|
||||
isExternalLibraryImport?: boolean;
|
||||
}
|
||||
/**
|
||||
* ResolvedModule with an explicitly provided `extension` property.
|
||||
* Prefer this over `ResolvedModule`.
|
||||
* If changing this, remember to change `moduleResolutionIsEqualTo`.
|
||||
*/
|
||||
interface ResolvedModuleFull extends ResolvedModule {
|
||||
/**
|
||||
@@ -2332,6 +2359,21 @@ declare namespace ts {
|
||||
* This is optional for backwards-compatibility, but will be added if not provided.
|
||||
*/
|
||||
extension: Extension;
|
||||
packageId?: PackageId;
|
||||
}
|
||||
/**
|
||||
* Unique identifier with a package name and version.
|
||||
* If changing this, remember to change `packageIdIsEqual`.
|
||||
*/
|
||||
interface PackageId {
|
||||
/**
|
||||
* Name of the package.
|
||||
* Should not include `@types`.
|
||||
* If accessing a non-index file, this should include its name e.g. "foo/bar".
|
||||
*/
|
||||
name: string;
|
||||
/** Version of the package, e.g. "1.2.3" */
|
||||
version: string;
|
||||
}
|
||||
enum Extension {
|
||||
Ts = ".ts",
|
||||
@@ -2593,7 +2635,7 @@ declare namespace ts {
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "2.5";
|
||||
const versionMajorMinor = "2.6";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -2741,6 +2783,8 @@ declare namespace ts {
|
||||
function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray<TextChangeRange>): TextChangeRange;
|
||||
function getTypeParameterOwner(d: Declaration): Declaration;
|
||||
function isParameterPropertyDeclaration(node: Node): boolean;
|
||||
function isEmptyBindingPattern(node: BindingName): node is BindingPattern;
|
||||
function isEmptyBindingElement(node: BindingElement): boolean;
|
||||
function getCombinedModifierFlags(node: Node): ModifierFlags;
|
||||
function getCombinedNodeFlags(node: Node): NodeFlags;
|
||||
/**
|
||||
@@ -3310,8 +3354,8 @@ declare namespace ts {
|
||||
function updateDefaultClause(node: DefaultClause, statements: ReadonlyArray<Statement>): DefaultClause;
|
||||
function createHeritageClause(token: HeritageClause["token"], types: ReadonlyArray<ExpressionWithTypeArguments>): HeritageClause;
|
||||
function updateHeritageClause(node: HeritageClause, types: ReadonlyArray<ExpressionWithTypeArguments>): HeritageClause;
|
||||
function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block): CatchClause;
|
||||
function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block): CatchClause;
|
||||
function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause;
|
||||
function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause;
|
||||
function createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment;
|
||||
function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment;
|
||||
function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment;
|
||||
@@ -3773,6 +3817,7 @@ declare namespace ts {
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[];
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion;
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
|
||||
+3070
-1394
File diff suppressed because it is too large
Load Diff
Vendored
+65
-20
@@ -1210,7 +1210,7 @@ declare namespace ts {
|
||||
interface CatchClause extends Node {
|
||||
kind: SyntaxKind.CatchClause;
|
||||
parent?: TryStatement;
|
||||
variableDeclaration: VariableDeclaration;
|
||||
variableDeclaration?: VariableDeclaration;
|
||||
block: Block;
|
||||
}
|
||||
type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
@@ -1496,38 +1496,39 @@ declare namespace ts {
|
||||
interface FlowLock {
|
||||
locked?: boolean;
|
||||
}
|
||||
interface AfterFinallyFlow extends FlowNode, FlowLock {
|
||||
interface AfterFinallyFlow extends FlowNodeBase, FlowLock {
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface PreFinallyFlow extends FlowNode {
|
||||
interface PreFinallyFlow extends FlowNodeBase {
|
||||
antecedent: FlowNode;
|
||||
lock: FlowLock;
|
||||
}
|
||||
interface FlowNode {
|
||||
type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation;
|
||||
interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number;
|
||||
}
|
||||
interface FlowStart extends FlowNode {
|
||||
interface FlowStart extends FlowNodeBase {
|
||||
container?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
}
|
||||
interface FlowLabel extends FlowNode {
|
||||
interface FlowLabel extends FlowNodeBase {
|
||||
antecedents: FlowNode[];
|
||||
}
|
||||
interface FlowAssignment extends FlowNode {
|
||||
interface FlowAssignment extends FlowNodeBase {
|
||||
node: Expression | VariableDeclaration | BindingElement;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowCondition extends FlowNode {
|
||||
interface FlowCondition extends FlowNodeBase {
|
||||
expression: Expression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowSwitchClause extends FlowNode {
|
||||
interface FlowSwitchClause extends FlowNodeBase {
|
||||
switchStatement: SwitchStatement;
|
||||
clauseStart: number;
|
||||
clauseEnd: number;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowArrayMutation extends FlowNode {
|
||||
interface FlowArrayMutation extends FlowNodeBase {
|
||||
node: CallExpression | BinaryExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
@@ -1696,6 +1697,15 @@ declare namespace ts {
|
||||
getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[];
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol | undefined;
|
||||
/**
|
||||
* If a symbol is a local symbol with an associated exported symbol, returns the exported symbol.
|
||||
* Otherwise returns its input.
|
||||
* For example, at `export type T = number;`:
|
||||
* - `getSymbolAtLocation` at the location `T` will return the exported symbol for `T`.
|
||||
* - But the result of `getSymbolsInScope` will contain the *local* symbol for `T`, not the exported symbol.
|
||||
* - Calling `getExportSymbolOfSymbol` on that local symbol will return the exported symbol.
|
||||
*/
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
@@ -1790,11 +1800,11 @@ declare namespace ts {
|
||||
UseFullyQualifiedType = 256,
|
||||
InFirstTypeArgument = 512,
|
||||
InTypeAlias = 1024,
|
||||
UseTypeAliasValue = 2048,
|
||||
SuppressAnyReturnType = 4096,
|
||||
AddUndefined = 8192,
|
||||
WriteClassExpressionAsTypeLiteral = 16384,
|
||||
InArrayType = 32768,
|
||||
UseAliasDefinedOutsideCurrentScope = 65536,
|
||||
}
|
||||
enum SymbolFormatFlags {
|
||||
None = 0,
|
||||
@@ -2056,6 +2066,7 @@ declare namespace ts {
|
||||
interface TypeVariable extends Type {
|
||||
}
|
||||
interface TypeParameter extends TypeVariable {
|
||||
/** Retrieve using getConstraintFromTypeParameter */
|
||||
constraint: Type;
|
||||
default?: Type;
|
||||
}
|
||||
@@ -2103,6 +2114,21 @@ declare namespace ts {
|
||||
NoDefault = 2,
|
||||
AnyDefault = 4,
|
||||
}
|
||||
/**
|
||||
* Ternary values are defined such that
|
||||
* x & y is False if either x or y is False.
|
||||
* x & y is Maybe if either x or y is Maybe, but neither x or y is False.
|
||||
* x & y is True if both x and y are True.
|
||||
* x | y is False if both x and y are False.
|
||||
* x | y is Maybe if either x or y is Maybe, but neither x or y is True.
|
||||
* x | y is True if either x or y is True.
|
||||
*/
|
||||
enum Ternary {
|
||||
False = 0,
|
||||
Maybe = 1,
|
||||
True = -1,
|
||||
}
|
||||
type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary;
|
||||
interface JsFileExtensionInfo {
|
||||
extension: string;
|
||||
isMixedContent: boolean;
|
||||
@@ -2195,6 +2221,7 @@ declare namespace ts {
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
preserveConstEnums?: boolean;
|
||||
preserveSymlinks?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
jsxFactory?: string;
|
||||
@@ -2300,6 +2327,10 @@ declare namespace ts {
|
||||
readFile(fileName: string): string | undefined;
|
||||
trace?(s: string): void;
|
||||
directoryExists?(directoryName: string): boolean;
|
||||
/**
|
||||
* Resolve a symbolic link.
|
||||
* @see https://nodejs.org/api/fs.html#fs_fs_realpathsync_path_options
|
||||
*/
|
||||
realpath?(path: string): string;
|
||||
getCurrentDirectory?(): string;
|
||||
getDirectories?(path: string): string[];
|
||||
@@ -2314,17 +2345,13 @@ declare namespace ts {
|
||||
interface ResolvedModule {
|
||||
/** Path of the file the module was resolved to. */
|
||||
resolvedFileName: string;
|
||||
/**
|
||||
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be a proper external module:
|
||||
* - be a .d.ts file
|
||||
* - use top level imports\exports
|
||||
* - don't use tripleslash references
|
||||
*/
|
||||
/** True if `resolvedFileName` comes from `node_modules`. */
|
||||
isExternalLibraryImport?: boolean;
|
||||
}
|
||||
/**
|
||||
* ResolvedModule with an explicitly provided `extension` property.
|
||||
* Prefer this over `ResolvedModule`.
|
||||
* If changing this, remember to change `moduleResolutionIsEqualTo`.
|
||||
*/
|
||||
interface ResolvedModuleFull extends ResolvedModule {
|
||||
/**
|
||||
@@ -2332,6 +2359,21 @@ declare namespace ts {
|
||||
* This is optional for backwards-compatibility, but will be added if not provided.
|
||||
*/
|
||||
extension: Extension;
|
||||
packageId?: PackageId;
|
||||
}
|
||||
/**
|
||||
* Unique identifier with a package name and version.
|
||||
* If changing this, remember to change `packageIdIsEqual`.
|
||||
*/
|
||||
interface PackageId {
|
||||
/**
|
||||
* Name of the package.
|
||||
* Should not include `@types`.
|
||||
* If accessing a non-index file, this should include its name e.g. "foo/bar".
|
||||
*/
|
||||
name: string;
|
||||
/** Version of the package, e.g. "1.2.3" */
|
||||
version: string;
|
||||
}
|
||||
enum Extension {
|
||||
Ts = ".ts",
|
||||
@@ -2593,7 +2635,7 @@ declare namespace ts {
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "2.5";
|
||||
const versionMajorMinor = "2.6";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -2741,6 +2783,8 @@ declare namespace ts {
|
||||
function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray<TextChangeRange>): TextChangeRange;
|
||||
function getTypeParameterOwner(d: Declaration): Declaration;
|
||||
function isParameterPropertyDeclaration(node: Node): boolean;
|
||||
function isEmptyBindingPattern(node: BindingName): node is BindingPattern;
|
||||
function isEmptyBindingElement(node: BindingElement): boolean;
|
||||
function getCombinedModifierFlags(node: Node): ModifierFlags;
|
||||
function getCombinedNodeFlags(node: Node): NodeFlags;
|
||||
/**
|
||||
@@ -3310,8 +3354,8 @@ declare namespace ts {
|
||||
function updateDefaultClause(node: DefaultClause, statements: ReadonlyArray<Statement>): DefaultClause;
|
||||
function createHeritageClause(token: HeritageClause["token"], types: ReadonlyArray<ExpressionWithTypeArguments>): HeritageClause;
|
||||
function updateHeritageClause(node: HeritageClause, types: ReadonlyArray<ExpressionWithTypeArguments>): HeritageClause;
|
||||
function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block): CatchClause;
|
||||
function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block): CatchClause;
|
||||
function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block): CatchClause;
|
||||
function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block): CatchClause;
|
||||
function createPropertyAssignment(name: string | PropertyName, initializer: Expression): PropertyAssignment;
|
||||
function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression): PropertyAssignment;
|
||||
function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression): ShorthandPropertyAssignment;
|
||||
@@ -3773,6 +3817,7 @@ declare namespace ts {
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[];
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion;
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
|
||||
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
|
||||
|
||||
+3070
-1394
File diff suppressed because it is too large
Load Diff
+1492
-323
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -17,6 +17,6 @@ nodeVersions.each { nodeVer ->
|
||||
}
|
||||
|
||||
Utilities.standardJobSetup(newJob, project, true, "*/${branch}")
|
||||
Utilities.setMachineAffinity(newJob, 'Ubuntu', '20161020')
|
||||
Utilities.setMachineAffinity(newJob, 'Ubuntu14.04', '20161020')
|
||||
Utilities.addGithubPRTriggerForBranch(newJob, branch, "TypeScript Test Run ${newJobName}")
|
||||
}
|
||||
|
||||
+2
-1
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "2.5.0",
|
||||
"version": "2.6.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -49,6 +49,7 @@
|
||||
"@types/run-sequence": "latest",
|
||||
"@types/through2": "latest",
|
||||
"browserify": "latest",
|
||||
"browser-resolve": "^1.11.2",
|
||||
"chai": "latest",
|
||||
"convert-source-map": "latest",
|
||||
"del": "latest",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/// <reference path="..\src\harness\external\node.d.ts" />
|
||||
|
||||
/**
|
||||
* You should have ts-node installed globally before executing this, probably!
|
||||
* Otherwise you'll need to compile this script before you start bisecting!
|
||||
*/
|
||||
import cp = require('child_process');
|
||||
import fs = require('fs');
|
||||
|
||||
@@ -42,8 +44,8 @@ jake.on('close', jakeExitCode => {
|
||||
});
|
||||
} else {
|
||||
console.log('Unknown command line arguments.');
|
||||
console.log('Usage (compile errors): git bisect run scripts\bisect.js "foo.ts --module amd" compiles');
|
||||
console.log('Usage (emit check): git bisect run scripts\bisect.js bar.ts emits bar.js "_this = this"');
|
||||
console.log('Usage (compile errors): git bisect run ts-node scripts\bisect-test.ts "../failure.ts --module amd" !compiles');
|
||||
console.log('Usage (emit check): git bisect run ts-node scripts\bisect-test.ts bar.ts emits bar.js "_this = this"');
|
||||
// Aborts the 'git bisect run' process
|
||||
process.exit(-1);
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
echo off
|
||||
IF NOT EXIST scripts\bisect.cmd GOTO :wrongdir
|
||||
IF "%1" == "" GOTO :usage
|
||||
IF "%1" == "GO" GOTO :run
|
||||
GOTO :copy
|
||||
|
||||
:usage
|
||||
echo Usage: bisect GoodCommit BadCommit test.ts compiles
|
||||
echo Usage: bisect GoodCommit BadCommit test.ts emits test.js "var x = 3"
|
||||
GOTO :eof
|
||||
|
||||
:copy
|
||||
copy scripts\bisect.cmd scripts\bisect-fresh.cmd
|
||||
scripts\bisect-fresh GO %*
|
||||
GOTO :eof
|
||||
|
||||
:run
|
||||
call jake local
|
||||
node built/local/tsc.js scripts/bisect-test.ts --module commonjs
|
||||
git bisect start %2 %3
|
||||
git bisect run node scripts/bisect-test.js %4 %5 %6 %7
|
||||
del scripts\bisect-test.js
|
||||
del scripts\bisect-fresh.cmd
|
||||
GOTO :eof
|
||||
|
||||
:wrongdir
|
||||
@echo Run this file from the repo folder, not the scripts folder
|
||||
GOTO :eof
|
||||
|
||||
:eof
|
||||
@@ -7,11 +7,15 @@ function endsWith(s: string, suffix: string) {
|
||||
return s.lastIndexOf(suffix, s.length - suffix.length) !== -1;
|
||||
}
|
||||
|
||||
function isStringEnum(declaration: ts.EnumDeclaration) {
|
||||
return declaration.members.length && declaration.members.every(m => m.initializer && m.initializer.kind === ts.SyntaxKind.StringLiteral);
|
||||
}
|
||||
|
||||
class DeclarationsWalker {
|
||||
private visitedTypes: ts.Type[] = [];
|
||||
private text = "";
|
||||
private removedTypes: ts.Type[] = [];
|
||||
|
||||
|
||||
private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
|
||||
}
|
||||
|
||||
@@ -19,7 +23,7 @@ class DeclarationsWalker {
|
||||
let text = "declare namespace ts.server.protocol {\n";
|
||||
var walker = new DeclarationsWalker(typeChecker, protocolFile);
|
||||
walker.visitTypeNodes(protocolFile);
|
||||
text = walker.text
|
||||
text = walker.text
|
||||
? `declare namespace ts.server.protocol {\n${walker.text}}`
|
||||
: "";
|
||||
if (walker.removedTypes) {
|
||||
@@ -52,7 +56,7 @@ class DeclarationsWalker {
|
||||
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
|
||||
return;
|
||||
}
|
||||
if (decl.kind === ts.SyntaxKind.EnumDeclaration) {
|
||||
if (decl.kind === ts.SyntaxKind.EnumDeclaration && !isStringEnum(decl as ts.EnumDeclaration)) {
|
||||
this.removedTypes.push(type);
|
||||
return;
|
||||
}
|
||||
@@ -91,7 +95,7 @@ class DeclarationsWalker {
|
||||
for (const type of heritageClauses[0].types) {
|
||||
this.processTypeOfNode(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -110,7 +114,7 @@ class DeclarationsWalker {
|
||||
this.processType(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptServicesDts: string) {
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Base = require('mocha').reporters.Base;
|
||||
|
||||
/**
|
||||
* Expose `None`.
|
||||
*/
|
||||
|
||||
exports = module.exports = None;
|
||||
|
||||
/**
|
||||
* Initialize a new `None` test reporter.
|
||||
*
|
||||
* @api public
|
||||
* @param {Runner} runner
|
||||
*/
|
||||
function None(runner) {
|
||||
Base.call(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Base.prototype`.
|
||||
*/
|
||||
None.prototype.__proto__ = Base.prototype;
|
||||
@@ -1,405 +0,0 @@
|
||||
var tty = require("tty")
|
||||
, readline = require("readline")
|
||||
, fs = require("fs")
|
||||
, path = require("path")
|
||||
, child_process = require("child_process")
|
||||
, os = require("os")
|
||||
, mocha = require("mocha")
|
||||
, Base = mocha.reporters.Base
|
||||
, color = Base.color
|
||||
, cursor = Base.cursor
|
||||
, ms = require("mocha/lib/ms");
|
||||
|
||||
var isatty = tty.isatty(1) && tty.isatty(2);
|
||||
var tapRangePattern = /^(\d+)\.\.(\d+)(?:$|\r\n?|\n)/;
|
||||
var tapTestPattern = /^(not\sok|ok)\s+(\d+)\s+(?:-\s+)?(.*)$/;
|
||||
var tapCommentPattern = /^#(?: (tests|pass|fail) (\d+)$)?/;
|
||||
|
||||
exports.runTestsInParallel = runTestsInParallel;
|
||||
exports.ProgressBars = ProgressBars;
|
||||
|
||||
function runTestsInParallel(taskConfigsFolder, run, options, cb) {
|
||||
if (options === undefined) options = { };
|
||||
|
||||
return discoverTests(run, options, function (error) {
|
||||
if (error) {
|
||||
return cb(error);
|
||||
}
|
||||
|
||||
return runTests(taskConfigsFolder, run, options, cb);
|
||||
});
|
||||
}
|
||||
|
||||
function discoverTests(run, options, cb) {
|
||||
console.log("Discovering tests...");
|
||||
|
||||
var cmd = "mocha -R " + require.resolve("./mocha-none-reporter.js") + " " + run;
|
||||
var p = spawnProcess(cmd);
|
||||
p.on("exit", function (status) {
|
||||
if (status) {
|
||||
cb(new Error("Process exited with code " + status));
|
||||
}
|
||||
else {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function runTests(taskConfigsFolder, run, options, cb) {
|
||||
var configFiles = fs.readdirSync(taskConfigsFolder);
|
||||
var numPartitions = configFiles.length;
|
||||
if (numPartitions <= 0) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Running tests on " + numPartitions + " threads...");
|
||||
|
||||
var partitions = Array(numPartitions);
|
||||
var progressBars = new ProgressBars();
|
||||
progressBars.enable();
|
||||
|
||||
var counter = numPartitions;
|
||||
configFiles.forEach(runTestsInPartition);
|
||||
|
||||
function runTestsInPartition(file, index) {
|
||||
var partition = {
|
||||
file: path.join(taskConfigsFolder, file),
|
||||
tests: 0,
|
||||
passed: 0,
|
||||
failed: 0,
|
||||
completed: 0,
|
||||
current: undefined,
|
||||
start: undefined,
|
||||
end: undefined,
|
||||
catastrophicError: "",
|
||||
failures: []
|
||||
};
|
||||
partitions[index] = partition;
|
||||
|
||||
// Set up the progress bar.
|
||||
updateProgress(0);
|
||||
|
||||
// Start the background process.
|
||||
var cmd = "mocha -t " + (options.testTimeout || 20000) + " -R tap --no-colors " + run + " --config='" + partition.file + "'";
|
||||
var p = spawnProcess(cmd);
|
||||
var rl = readline.createInterface({
|
||||
input: p.stdout,
|
||||
terminal: false
|
||||
});
|
||||
|
||||
var rlError = readline.createInterface({
|
||||
input: p.stderr,
|
||||
terminal: false
|
||||
});
|
||||
|
||||
rl.on("line", onmessage);
|
||||
rlError.on("line", onErrorMessage);
|
||||
p.on("exit", onexit)
|
||||
|
||||
function onErrorMessage(line) {
|
||||
partition.catastrophicError += line + os.EOL;
|
||||
}
|
||||
|
||||
function onmessage(line) {
|
||||
if (partition.start === undefined) {
|
||||
partition.start = Date.now();
|
||||
}
|
||||
|
||||
var rangeMatch = tapRangePattern.exec(line);
|
||||
if (rangeMatch) {
|
||||
partition.tests = parseInt(rangeMatch[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
var testMatch = tapTestPattern.exec(line);
|
||||
if (testMatch) {
|
||||
var test = {
|
||||
result: testMatch[1],
|
||||
id: parseInt(testMatch[2]),
|
||||
name: testMatch[3],
|
||||
output: []
|
||||
};
|
||||
|
||||
partition.current = test;
|
||||
partition.completed++;
|
||||
|
||||
if (test.result === "ok") {
|
||||
partition.passed++;
|
||||
}
|
||||
else {
|
||||
partition.failed++;
|
||||
partition.failures.push(test);
|
||||
}
|
||||
|
||||
var progress = partition.completed / partition.tests;
|
||||
if (progress < 1) {
|
||||
updateProgress(progress);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var commentMatch = tapCommentPattern.exec(line);
|
||||
if (commentMatch) {
|
||||
switch (commentMatch[1]) {
|
||||
case "tests":
|
||||
partition.current = undefined;
|
||||
partition.tests = parseInt(commentMatch[2]);
|
||||
break;
|
||||
|
||||
case "pass":
|
||||
partition.passed = parseInt(commentMatch[2]);
|
||||
break;
|
||||
|
||||
case "fail":
|
||||
partition.failed = parseInt(commentMatch[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (partition.current) {
|
||||
partition.current.output.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
function onexit(code) {
|
||||
if (partition.end === undefined) {
|
||||
partition.end = Date.now();
|
||||
}
|
||||
|
||||
partition.duration = partition.end - partition.start;
|
||||
var isPartitionFail = partition.failed || code !== 0;
|
||||
var summaryColor = isPartitionFail ? "fail" : "green";
|
||||
var summarySymbol = isPartitionFail ? Base.symbols.err : Base.symbols.ok;
|
||||
|
||||
var summaryTests = (isPartitionFail ? partition.passed + "/" + partition.tests : partition.passed) + " passing";
|
||||
var summaryDuration = "(" + ms(partition.duration) + ")";
|
||||
var savedUseColors = Base.useColors;
|
||||
Base.useColors = !options.noColors;
|
||||
|
||||
var summary = color(summaryColor, summarySymbol + " " + summaryTests) + " " + color("light", summaryDuration);
|
||||
Base.useColors = savedUseColors;
|
||||
|
||||
updateProgress(1, summary);
|
||||
|
||||
signal();
|
||||
}
|
||||
|
||||
function updateProgress(percentComplete, title) {
|
||||
var progressColor = "pending";
|
||||
if (partition.failed) {
|
||||
progressColor = "fail";
|
||||
}
|
||||
|
||||
progressBars.update(
|
||||
index,
|
||||
percentComplete,
|
||||
progressColor,
|
||||
title
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function signal() {
|
||||
counter--;
|
||||
|
||||
if (counter <= 0) {
|
||||
var reporter = new Base(),
|
||||
stats = reporter.stats,
|
||||
failures = reporter.failures;
|
||||
|
||||
var duration = 0;
|
||||
var catastrophicError = "";
|
||||
for (var i = 0; i < numPartitions; i++) {
|
||||
var partition = partitions[i];
|
||||
stats.passes += partition.passed;
|
||||
stats.failures += partition.failed;
|
||||
stats.tests += partition.tests;
|
||||
duration += partition.duration;
|
||||
if (partition.catastrophicError !== "") {
|
||||
// Partition is written out to a temporary file as a JSON object.
|
||||
// Below is an example of how the partition JSON object looks like
|
||||
// {
|
||||
// "light":false,
|
||||
// "tasks":[
|
||||
// {
|
||||
// "runner":"compiler",
|
||||
// "files":["tests/cases/compiler/es6ImportNamedImportParsingError.ts"]
|
||||
// }
|
||||
// ],
|
||||
// "runUnitTests":false
|
||||
// }
|
||||
var jsonText = fs.readFileSync(partition.file);
|
||||
var configObj = JSON.parse(jsonText);
|
||||
if (configObj.tasks && configObj.tasks[0]) {
|
||||
catastrophicError += "Error from one or more of these files: " + configObj.tasks[0].files + os.EOL;
|
||||
catastrophicError += partition.catastrophicError;
|
||||
catastrophicError += os.EOL;
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < partition.failures.length; j++) {
|
||||
var failure = partition.failures[j];
|
||||
failures.push(makeMochaTest(failure));
|
||||
}
|
||||
}
|
||||
|
||||
stats.duration = duration;
|
||||
progressBars.disable();
|
||||
|
||||
if (options.noColors) {
|
||||
var savedUseColors = Base.useColors;
|
||||
Base.useColors = false;
|
||||
reporter.epilogue();
|
||||
Base.useColors = savedUseColors;
|
||||
}
|
||||
else {
|
||||
reporter.epilogue();
|
||||
}
|
||||
|
||||
if (catastrophicError !== "") {
|
||||
return cb(new Error(catastrophicError));
|
||||
}
|
||||
if (stats.failures) {
|
||||
return cb(new Error("Test failures reported: " + stats.failures));
|
||||
}
|
||||
else {
|
||||
return cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function makeMochaTest(test) {
|
||||
return {
|
||||
fullTitle: function() {
|
||||
return test.name;
|
||||
},
|
||||
err: {
|
||||
message: test.output[0],
|
||||
stack: test.output.join(os.EOL)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
|
||||
if (process.env.path !== undefined) {
|
||||
process.env.path = nodeModulesPathPrefix + process.env.path;
|
||||
} else if (process.env.PATH !== undefined) {
|
||||
process.env.PATH = nodeModulesPathPrefix + process.env.PATH;
|
||||
}
|
||||
|
||||
function spawnProcess(cmd, options) {
|
||||
var shell = process.platform === "win32" ? "cmd" : "/bin/sh";
|
||||
var prefix = process.platform === "win32" ? "/c" : "-c";
|
||||
return child_process.spawn(shell, [prefix, cmd], { windowsVerbatimArguments: true });
|
||||
}
|
||||
|
||||
function ProgressBars(options) {
|
||||
if (!options) options = {};
|
||||
var open = options.open || '[';
|
||||
var close = options.close || ']';
|
||||
var complete = options.complete || '▬';
|
||||
var incomplete = options.incomplete || Base.symbols.dot;
|
||||
var maxWidth = Math.floor(Base.window.width * .30) - open.length - close.length - 2;
|
||||
var width = minMax(options.width || maxWidth, 10, maxWidth);
|
||||
this._options = {
|
||||
open: open,
|
||||
complete: complete,
|
||||
incomplete: incomplete,
|
||||
close: close,
|
||||
width: width
|
||||
};
|
||||
|
||||
this._progressBars = [];
|
||||
this._lineCount = 0;
|
||||
this._enabled = false;
|
||||
}
|
||||
ProgressBars.prototype = {
|
||||
enable: function () {
|
||||
if (!this._enabled) {
|
||||
process.stdout.write(os.EOL);
|
||||
this._enabled = true;
|
||||
}
|
||||
},
|
||||
disable: function () {
|
||||
if (this._enabled) {
|
||||
process.stdout.write(os.EOL);
|
||||
this._enabled = false;
|
||||
}
|
||||
},
|
||||
update: function (index, percentComplete, color, title) {
|
||||
percentComplete = minMax(percentComplete, 0, 1);
|
||||
|
||||
var progressBar = this._progressBars[index] || (this._progressBars[index] = { });
|
||||
var width = this._options.width;
|
||||
var n = Math.floor(width * percentComplete);
|
||||
var i = width - n;
|
||||
if (n === progressBar.lastN && title === progressBar.title && color === progressBar.progressColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
progressBar.lastN = n;
|
||||
progressBar.title = title;
|
||||
progressBar.progressColor = color;
|
||||
|
||||
var progress = " ";
|
||||
progress += this._color('progress', this._options.open);
|
||||
progress += this._color(color, fill(this._options.complete, n));
|
||||
progress += this._color('progress', fill(this._options.incomplete, i));
|
||||
progress += this._color('progress', this._options.close);
|
||||
|
||||
if (title) {
|
||||
progress += this._color('progress', ' ' + title);
|
||||
}
|
||||
|
||||
if (progressBar.text !== progress) {
|
||||
progressBar.text = progress;
|
||||
this._render(index);
|
||||
}
|
||||
},
|
||||
_render: function (index) {
|
||||
if (!this._enabled || !isatty) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.hide();
|
||||
readline.moveCursor(process.stdout, -process.stdout.columns, -this._lineCount);
|
||||
var lineCount = 0;
|
||||
var numProgressBars = this._progressBars.length;
|
||||
for (var i = 0; i < numProgressBars; i++) {
|
||||
if (i === index) {
|
||||
readline.clearLine(process.stdout, 1);
|
||||
process.stdout.write(this._progressBars[i].text + os.EOL);
|
||||
}
|
||||
else {
|
||||
readline.moveCursor(process.stdout, -process.stdout.columns, +1);
|
||||
}
|
||||
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
this._lineCount = lineCount;
|
||||
cursor.show();
|
||||
},
|
||||
_color: function (type, text) {
|
||||
return type && !this._options.noColors ? color(type, text) : text;
|
||||
}
|
||||
};
|
||||
|
||||
function fill(ch, size) {
|
||||
var s = "";
|
||||
while (s.length < size) {
|
||||
s += ch;
|
||||
}
|
||||
|
||||
return s.length > size ? s.substr(0, size) : s;
|
||||
}
|
||||
|
||||
function minMax(value, min, max) {
|
||||
if (value < min) return min;
|
||||
if (value > max) return max;
|
||||
return value;
|
||||
}
|
||||
+8
-15
@@ -203,9 +203,11 @@ namespace ts {
|
||||
node.symbol = symbol;
|
||||
|
||||
if (!symbol.declarations) {
|
||||
symbol.declarations = [];
|
||||
symbol.declarations = [node];
|
||||
}
|
||||
else {
|
||||
symbol.declarations.push(node);
|
||||
}
|
||||
symbol.declarations.push(node);
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
|
||||
symbol.exports = createSymbolTable();
|
||||
@@ -282,17 +284,8 @@ namespace ts {
|
||||
const index = indexOf(functionType.parameters, node);
|
||||
return "arg" + index as __String;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
const parentNode = node.parent && node.parent.parent;
|
||||
let nameFromParentNode: __String;
|
||||
if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) {
|
||||
if ((<VariableStatement>parentNode).declarationList.declarations.length > 0) {
|
||||
const nameIdentifier = (<VariableStatement>parentNode).declarationList.declarations[0].name;
|
||||
if (isIdentifier(nameIdentifier)) {
|
||||
nameFromParentNode = nameIdentifier.escapedText;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nameFromParentNode;
|
||||
const name = getNameOfJSDocTypedef(node as JSDocTypedefTag);
|
||||
return typeof name !== "undefined" ? name.escapedText : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,7 +591,7 @@ namespace ts {
|
||||
// Binding of JsDocComment should be done before the current block scope container changes.
|
||||
// because the scope of JsDocComment should not be affected by whether the current node is a
|
||||
// container or not.
|
||||
if (node.jsDoc) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
for (const j of node.jsDoc) {
|
||||
bind(j);
|
||||
@@ -1931,7 +1924,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTagIfAny(node: Node) {
|
||||
if (!node.jsDoc) {
|
||||
if (!hasJSDocNodes(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+844
-633
File diff suppressed because it is too large
Load Diff
@@ -1057,7 +1057,7 @@ namespace ts {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText));
|
||||
}
|
||||
const value = convertPropertyValueToJson(element.initializer, option);
|
||||
if (typeof keyText !== "undefined" && typeof value !== "undefined") {
|
||||
if (typeof keyText !== "undefined") {
|
||||
result[keyText] = value;
|
||||
// Notify key value set, if user asked for it
|
||||
if (jsonConversionNotifier &&
|
||||
@@ -1104,7 +1104,7 @@ namespace ts {
|
||||
return false;
|
||||
|
||||
case SyntaxKind.NullKeyword:
|
||||
reportInvalidOptionValue(!!option);
|
||||
reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for
|
||||
return null; // tslint:disable-line:no-null-keyword
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
@@ -1189,6 +1189,7 @@ namespace ts {
|
||||
|
||||
function isCompilerOptionsValue(option: CommandLineOption, value: any): value is CompilerOptionsValue {
|
||||
if (option) {
|
||||
if (isNullOrUndefined(value)) return true; // All options are undefinable/nullable
|
||||
if (option.type === "list") {
|
||||
return isArray(value);
|
||||
}
|
||||
@@ -1379,6 +1380,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isNullOrUndefined(x: any): x is null | undefined {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
return x === undefined || x === null;
|
||||
}
|
||||
|
||||
function directoryOfCombinedPath(fileName: string, basePath: string) {
|
||||
// Use the `identity` function to avoid canonicalizing the path, as it must remain noncanonical
|
||||
// until consistient casing errors are reported
|
||||
return getDirectoryPath(toPath(fileName, basePath, identity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the contents of a config file from json or json source file (tsconfig.json).
|
||||
* @param json The contents of the config file to parse
|
||||
@@ -1419,7 +1431,7 @@ namespace ts {
|
||||
|
||||
function getFileNames(): ExpandResult {
|
||||
let fileNames: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "files")) {
|
||||
if (hasProperty(raw, "files") && !isNullOrUndefined(raw["files"])) {
|
||||
if (isArray(raw["files"])) {
|
||||
fileNames = <ReadonlyArray<string>>raw["files"];
|
||||
if (fileNames.length === 0) {
|
||||
@@ -1432,7 +1444,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let includeSpecs: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "include")) {
|
||||
if (hasProperty(raw, "include") && !isNullOrUndefined(raw["include"])) {
|
||||
if (isArray(raw["include"])) {
|
||||
includeSpecs = <ReadonlyArray<string>>raw["include"];
|
||||
}
|
||||
@@ -1442,7 +1454,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let excludeSpecs: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "exclude")) {
|
||||
if (hasProperty(raw, "exclude") && !isNullOrUndefined(raw["exclude"])) {
|
||||
if (isArray(raw["exclude"])) {
|
||||
excludeSpecs = <ReadonlyArray<string>>raw["exclude"];
|
||||
}
|
||||
@@ -1461,7 +1473,7 @@ namespace ts {
|
||||
includeSpecs = ["**/*"];
|
||||
}
|
||||
|
||||
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors, extraFileExtensions, sourceFile);
|
||||
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
|
||||
|
||||
if (result.fileNames.length === 0 && !hasProperty(raw, "files") && resolutionStack.length === 0) {
|
||||
errors.push(
|
||||
@@ -1552,7 +1564,7 @@ namespace ts {
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
getCanonicalFileName: (fileName: string) => string,
|
||||
configFileName: string,
|
||||
configFileName: string | undefined,
|
||||
errors: Push<Diagnostic>
|
||||
): ParsedTsconfig {
|
||||
if (hasProperty(json, "excludes")) {
|
||||
@@ -1571,7 +1583,8 @@ namespace ts {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
|
||||
}
|
||||
else {
|
||||
extendedConfigPath = getExtendsConfigPath(json.extends, host, basePath, getCanonicalFileName, errors, createCompilerDiagnostic);
|
||||
const newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
|
||||
extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, getCanonicalFileName, errors, createCompilerDiagnostic);
|
||||
}
|
||||
}
|
||||
return { raw: json, options, typeAcquisition, extendedConfigPath };
|
||||
@@ -1582,7 +1595,7 @@ namespace ts {
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
getCanonicalFileName: (fileName: string) => string,
|
||||
configFileName: string,
|
||||
configFileName: string | undefined,
|
||||
errors: Push<Diagnostic>
|
||||
): ParsedTsconfig {
|
||||
const options = getDefaultCompilerOptions(configFileName);
|
||||
@@ -1603,10 +1616,11 @@ namespace ts {
|
||||
onSetValidOptionKeyValueInRoot(key: string, _keyNode: PropertyName, value: CompilerOptionsValue, valueNode: Expression) {
|
||||
switch (key) {
|
||||
case "extends":
|
||||
const newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
|
||||
extendedConfigPath = getExtendsConfigPath(
|
||||
<string>value,
|
||||
host,
|
||||
basePath,
|
||||
newBase,
|
||||
getCanonicalFileName,
|
||||
errors,
|
||||
(message, arg0) =>
|
||||
@@ -1803,6 +1817,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function normalizeOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue {
|
||||
if (isNullOrUndefined(value)) return undefined;
|
||||
if (option.type === "list") {
|
||||
const listOption = <CommandLineOptionOfListType>option;
|
||||
if (listOption.element.isFilePath || typeof listOption.element.type !== "string") {
|
||||
@@ -1827,6 +1842,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Push<Diagnostic>) {
|
||||
if (isNullOrUndefined(value)) return undefined;
|
||||
const key = value.toLowerCase();
|
||||
const val = opt.type.get(key);
|
||||
if (val !== undefined) {
|
||||
@@ -1977,7 +1993,7 @@ namespace ts {
|
||||
// remove a literal file.
|
||||
if (fileNames) {
|
||||
for (const fileName of fileNames) {
|
||||
const file = combinePaths(basePath, fileName);
|
||||
const file = getNormalizedAbsolutePath(fileName, basePath);
|
||||
literalFileMap.set(keyMapper(file), file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace ts {
|
||||
let declarationListContainerEnd = -1;
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentText: string;
|
||||
let currentLineMap: number[];
|
||||
let currentLineMap: ReadonlyArray<number>;
|
||||
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[];
|
||||
let hasWrittenComment = false;
|
||||
let disabled: boolean = printerOptions.removeComments;
|
||||
|
||||
+63
-33
@@ -4,11 +4,20 @@
|
||||
namespace ts {
|
||||
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
|
||||
// If changing the text in this section, be sure to test `configureNightly` too.
|
||||
export const versionMajorMinor = "2.5";
|
||||
export const versionMajorMinor = "2.6";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0`;
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
export function isExternalModuleNameRelative(moduleName: string): boolean {
|
||||
// TypeScript 1.0 spec (April 2014): 11.2.1
|
||||
// An external module name is "relative" if the first term is "." or "..".
|
||||
// Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
|
||||
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
|
||||
@@ -40,7 +49,6 @@ namespace ts {
|
||||
return new MapCtr<T>() as UnderscoreEscapedMap<T>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createSymbolTable(symbols?: ReadonlyArray<Symbol>): SymbolTable {
|
||||
const result = createMap<Symbol>() as SymbolTable;
|
||||
if (symbols) {
|
||||
@@ -715,7 +723,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function sum<T extends Record<K, number>, K extends string>(array: T[], prop: K): number {
|
||||
export function sum<T extends Record<K, number>, K extends string>(array: ReadonlyArray<T>, prop: K): number {
|
||||
let result = 0;
|
||||
for (const v of array) {
|
||||
// Note: we need the following type assertion because of GH #17069
|
||||
@@ -771,6 +779,32 @@ namespace ts {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the value was added.
|
||||
*/
|
||||
export function pushIfUnique<T>(array: T[], toAdd: T): boolean {
|
||||
if (contains(array, toAdd)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
array.push(toAdd);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array.
|
||||
*/
|
||||
export function appendIfUnique<T>(array: T[] | undefined, toAdd: T): T[] {
|
||||
if (array) {
|
||||
pushIfUnique(array, toAdd);
|
||||
return array;
|
||||
}
|
||||
else {
|
||||
return [toAdd];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stable sort of an array. Elements equal to each other maintain their relative position in the array.
|
||||
*/
|
||||
@@ -1194,6 +1228,9 @@ namespace ts {
|
||||
/** Does nothing. */
|
||||
export function noop(): void {}
|
||||
|
||||
/** Returns its argument. */
|
||||
export function identity<T>(x: T) { return x; }
|
||||
|
||||
/** Throws an error because a function is not implemented. */
|
||||
export function notImplemented(): never {
|
||||
throw new Error("Not implemented");
|
||||
@@ -1257,7 +1294,7 @@ namespace ts {
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
|
||||
return t => reduceLeft<(t: T) => T, T>(args, (u, f) => f(u), t);
|
||||
return t => reduceLeft(args, (u, f) => f(u), t);
|
||||
}
|
||||
else if (d) {
|
||||
return t => d(c(b(a(t))));
|
||||
@@ -1290,14 +1327,12 @@ namespace ts {
|
||||
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic {
|
||||
const end = start + length;
|
||||
|
||||
Debug.assertGreaterThanOrEqual(start, 0);
|
||||
Debug.assertGreaterThanOrEqual(length, 0);
|
||||
|
||||
if (file) {
|
||||
Debug.assertLessThanOrEqual(start, file.text.length);
|
||||
Debug.assertLessThanOrEqual(end, file.text.length);
|
||||
Debug.assertLessThanOrEqual(start + length, file.text.length);
|
||||
}
|
||||
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
@@ -1359,7 +1394,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: string[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -1543,16 +1578,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function normalizePath(path: string): string {
|
||||
return normalizePathAndParts(path).path;
|
||||
}
|
||||
|
||||
export function normalizePathAndParts(path: string): { path: string, parts: string[] } {
|
||||
path = normalizeSlashes(path);
|
||||
const rootLength = getRootLength(path);
|
||||
const root = path.substr(0, rootLength);
|
||||
const normalized = getNormalizedParts(path, rootLength);
|
||||
if (normalized.length) {
|
||||
const joinedParts = root + normalized.join(directorySeparator);
|
||||
return pathEndsWithDirectorySeparator(path) ? joinedParts + directorySeparator : joinedParts;
|
||||
const parts = getNormalizedParts(path, rootLength);
|
||||
if (parts.length) {
|
||||
const joinedParts = root + parts.join(directorySeparator);
|
||||
return { path: pathEndsWithDirectorySeparator(path) ? joinedParts + directorySeparator : joinedParts, parts };
|
||||
}
|
||||
else {
|
||||
return root;
|
||||
return { path: root, parts };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1576,18 +1615,10 @@ namespace ts {
|
||||
return path && !isRootedDiskPath(path) && path.indexOf("://") !== -1;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function pathIsRelative(path: string): boolean {
|
||||
return /^\.\.?($|[\\/])/.test(path);
|
||||
}
|
||||
|
||||
export function isExternalModuleNameRelative(moduleName: string): boolean {
|
||||
// TypeScript 1.0 spec (April 2014): 11.2.1
|
||||
// An external module name is "relative" if the first term is "." or "..".
|
||||
// Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
|
||||
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
|
||||
}
|
||||
|
||||
/** @deprecated Use `!isExternalModuleNameRelative(moduleName)` instead. */
|
||||
export function moduleHasNonRelativeName(moduleName: string): boolean {
|
||||
return !isExternalModuleNameRelative(moduleName);
|
||||
@@ -1611,7 +1642,6 @@ namespace ts {
|
||||
return moduleResolution;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
let seenAsterisk = false;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
@@ -1836,17 +1866,14 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function startsWith(str: string, prefix: string): boolean {
|
||||
return str.lastIndexOf(prefix, 0) === 0;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function removePrefix(str: string, prefix: string): string {
|
||||
return startsWith(str, prefix) ? str.substr(prefix.length) : str;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function endsWith(str: string, suffix: string): boolean {
|
||||
const expectedPos = str.length - suffix.length;
|
||||
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
|
||||
@@ -1860,7 +1887,6 @@ namespace ts {
|
||||
return path.length > extension.length && endsWith(path, extension);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function fileExtensionIsOneOf(path: string, extensions: ReadonlyArray<string>): boolean {
|
||||
for (const extension of extensions) {
|
||||
if (fileExtensionIs(path, extension)) {
|
||||
@@ -1877,7 +1903,6 @@ namespace ts {
|
||||
const reservedCharacterPattern = /[^\w\s\/]/g;
|
||||
const wildcardCharCodes = [CharacterCodes.asterisk, CharacterCodes.question];
|
||||
|
||||
/* @internal */
|
||||
export const commonPackageFolders: ReadonlyArray<string> = ["node_modules", "bower_components", "jspm_packages"];
|
||||
|
||||
const implicitExcludePathRegexPattern = `(?!(${commonPackageFolders.join("|")})(/|$))`;
|
||||
@@ -2419,7 +2444,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function fail(message?: string, stackCrawlMark?: Function): void {
|
||||
export function fail(message?: string, stackCrawlMark?: Function): never {
|
||||
debugger;
|
||||
const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure.");
|
||||
if ((<any>Error).captureStackTrace) {
|
||||
@@ -2428,6 +2453,10 @@ namespace ts {
|
||||
throw e;
|
||||
}
|
||||
|
||||
export function assertNever(member: never, message?: string, stackCrawlMark?: Function): never {
|
||||
return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever);
|
||||
}
|
||||
|
||||
export function getFunctionName(func: Function) {
|
||||
if (typeof func !== "function") {
|
||||
return "";
|
||||
@@ -2495,7 +2524,6 @@ namespace ts {
|
||||
* Return an exact match if possible, or a pattern match, or undefined.
|
||||
* (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
|
||||
*/
|
||||
/* @internal */
|
||||
export function matchPatternOrExact(patternStrings: ReadonlyArray<string>, candidate: string): string | Pattern | undefined {
|
||||
const patterns: Pattern[] = [];
|
||||
for (const patternString of patternStrings) {
|
||||
@@ -2512,7 +2540,6 @@ namespace ts {
|
||||
return findBestPatternMatch(patterns, _ => _, candidate);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function patternText({prefix, suffix}: Pattern): string {
|
||||
return `${prefix}*${suffix}`;
|
||||
}
|
||||
@@ -2521,14 +2548,12 @@ namespace ts {
|
||||
* Given that candidate matches pattern, returns the text matching the '*'.
|
||||
* E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
|
||||
*/
|
||||
/* @internal */
|
||||
export function matchedText(pattern: Pattern, candidate: string): string {
|
||||
Debug.assert(isPatternMatch(pattern, candidate));
|
||||
return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length);
|
||||
}
|
||||
|
||||
/** Return the object corresponding to the best pattern to match `candidate`. */
|
||||
/* @internal */
|
||||
export function findBestPatternMatch<T>(values: ReadonlyArray<T>, getPattern: (value: T) => Pattern, candidate: string): T | undefined {
|
||||
let matchedValue: T | undefined = undefined;
|
||||
// use length of prefix as betterness criteria
|
||||
@@ -2551,7 +2576,6 @@ namespace ts {
|
||||
endsWith(candidate, suffix);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function tryParsePattern(pattern: string): Pattern | undefined {
|
||||
// This should be verified outside of here and a proper error thrown.
|
||||
Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
|
||||
@@ -2596,4 +2620,10 @@ namespace ts {
|
||||
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
|
||||
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
|
||||
}
|
||||
|
||||
export function and<T>(f: (arg: T) => boolean, g: (arg: T) => boolean) {
|
||||
return (arg: T) => f(arg) && g(arg);
|
||||
}
|
||||
|
||||
export function assertTypeIsNever(_: never): void {}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace ts {
|
||||
let enclosingDeclaration: Node;
|
||||
let resultHasExternalModuleIndicator: boolean;
|
||||
let currentText: string;
|
||||
let currentLineMap: number[];
|
||||
let currentLineMap: ReadonlyArray<number>;
|
||||
let currentIdentifiers: Map<string>;
|
||||
let isCurrentFileExternalModule: boolean;
|
||||
let reportedDeclarationError = false;
|
||||
|
||||
@@ -627,11 +627,11 @@
|
||||
"category": "Error",
|
||||
"code": 1200
|
||||
},
|
||||
"Import assignment cannot be used when targeting ECMAScript 2015 modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead.": {
|
||||
"Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead.": {
|
||||
"category": "Error",
|
||||
"code": 1202
|
||||
},
|
||||
"Export assignment cannot be used when targeting ECMAScript 2015 modules. Consider using 'export default' or another module format instead.": {
|
||||
"Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.": {
|
||||
"category": "Error",
|
||||
"code": 1203
|
||||
},
|
||||
@@ -1912,6 +1912,18 @@
|
||||
"category": "Error",
|
||||
"code": 2560
|
||||
},
|
||||
"Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?": {
|
||||
"category": "Error",
|
||||
"code": 2561
|
||||
},
|
||||
"Base class expressions cannot reference class type parameters.": {
|
||||
"category": "Error",
|
||||
"code": 2562
|
||||
},
|
||||
"The containing function or module body is too large for control flow analysis.": {
|
||||
"category": "Error",
|
||||
"code": 2563
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -2200,6 +2212,10 @@
|
||||
"category": "Error",
|
||||
"code": 2713
|
||||
},
|
||||
"The expression of an export assignment must be an identifier or qualified name in an ambient context.": {
|
||||
"category": "Error",
|
||||
"code": 2714
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -2670,7 +2686,7 @@
|
||||
"category": "Message",
|
||||
"code": 6015
|
||||
},
|
||||
"Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.": {
|
||||
"Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.": {
|
||||
"category": "Message",
|
||||
"code": 6016
|
||||
},
|
||||
@@ -3090,7 +3106,7 @@
|
||||
"category": "Message",
|
||||
"code": 6132
|
||||
},
|
||||
"'{0}' is declared but never used.": {
|
||||
"'{0}' is declared but its value is never read.": {
|
||||
"category": "Error",
|
||||
"code": 6133
|
||||
},
|
||||
@@ -3110,7 +3126,7 @@
|
||||
"category": "Error",
|
||||
"code": 6137
|
||||
},
|
||||
"Property '{0}' is declared but never used.": {
|
||||
"Property '{0}' is declared but its value is never read.": {
|
||||
"category": "Error",
|
||||
"code": 6138
|
||||
},
|
||||
@@ -3130,10 +3146,6 @@
|
||||
"category": "Error",
|
||||
"code": 6142
|
||||
},
|
||||
"Module '{0}' was resolved to '{1}', but '--allowJs' is not set.": {
|
||||
"category": "Error",
|
||||
"code": 6143
|
||||
},
|
||||
"Module '{0}' was resolved as locally declared ambient module in file '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6144
|
||||
@@ -3688,7 +3700,7 @@
|
||||
"code": 95003
|
||||
},
|
||||
|
||||
"Extract function into '{0}'": {
|
||||
"Extract to {0}": {
|
||||
"category": "Message",
|
||||
"code": 95004
|
||||
}
|
||||
|
||||
+86
-98
@@ -406,6 +406,14 @@ namespace ts {
|
||||
setWriter(/*output*/ undefined);
|
||||
}
|
||||
|
||||
// TODO: Should this just be `emit`?
|
||||
// See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034
|
||||
function emitIfPresent(node: Node | undefined) {
|
||||
if (node) {
|
||||
emit(node);
|
||||
}
|
||||
}
|
||||
|
||||
function emit(node: Node) {
|
||||
pipelineEmitWithNotification(EmitHint.Unspecified, node);
|
||||
}
|
||||
@@ -451,6 +459,7 @@ namespace ts {
|
||||
case EmitHint.SourceFile: return pipelineEmitSourceFile(node);
|
||||
case EmitHint.IdentifierName: return pipelineEmitIdentifierName(node);
|
||||
case EmitHint.Expression: return pipelineEmitExpression(node);
|
||||
case EmitHint.MappedTypeParameter: return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration));
|
||||
case EmitHint.Unspecified: return pipelineEmitUnspecified(node);
|
||||
}
|
||||
}
|
||||
@@ -465,6 +474,12 @@ namespace ts {
|
||||
emitIdentifier(<Identifier>node);
|
||||
}
|
||||
|
||||
function emitMappedTypeParameter(node: TypeParameterDeclaration): void {
|
||||
emit(node.name);
|
||||
write(" in ");
|
||||
emit(node.constraint);
|
||||
}
|
||||
|
||||
function pipelineEmitUnspecified(node: Node): void {
|
||||
const kind = node.kind;
|
||||
|
||||
@@ -898,9 +913,9 @@ namespace ts {
|
||||
function emitParameter(node: ParameterDeclaration) {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
writeIfPresent(node.dotDotDotToken, "...");
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitWithPrefix(": ", node.type);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
}
|
||||
@@ -918,7 +933,7 @@ namespace ts {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitWithPrefix(": ", node.type);
|
||||
write(";");
|
||||
}
|
||||
@@ -927,7 +942,7 @@ namespace ts {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitWithPrefix(": ", node.type);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
write(";");
|
||||
@@ -937,7 +952,7 @@ namespace ts {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitTypeParameters(node, node.typeParameters);
|
||||
emitParameters(node, node.parameters);
|
||||
emitWithPrefix(": ", node.type);
|
||||
@@ -947,9 +962,9 @@ namespace ts {
|
||||
function emitMethodDeclaration(node: MethodDeclaration) {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
writeIfPresent(node.asteriskToken, "*");
|
||||
emitIfPresent(node.asteriskToken);
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitIfPresent(node.questionToken);
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
|
||||
@@ -1035,10 +1050,8 @@ namespace ts {
|
||||
|
||||
function emitTypeLiteral(node: TypeLiteralNode) {
|
||||
write("{");
|
||||
// If the literal is empty, do not add spaces between braces.
|
||||
if (node.members.length > 0) {
|
||||
emitList(node, node.members, getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers);
|
||||
}
|
||||
const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers;
|
||||
emitList(node, node.members, flags | ListFormat.NoSpaceIfEmpty);
|
||||
write("}");
|
||||
}
|
||||
|
||||
@@ -1094,13 +1107,16 @@ namespace ts {
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
}
|
||||
writeIfPresent(node.readonlyToken, "readonly ");
|
||||
if (node.readonlyToken) {
|
||||
emit(node.readonlyToken);
|
||||
write(" ");
|
||||
}
|
||||
|
||||
write("[");
|
||||
emit(node.typeParameter.name);
|
||||
write(" in ");
|
||||
emit(node.typeParameter.constraint);
|
||||
pipelineEmitWithNotification(EmitHint.MappedTypeParameter, node.typeParameter);
|
||||
write("]");
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
|
||||
emitIfPresent(node.questionToken);
|
||||
write(": ");
|
||||
emit(node.type);
|
||||
write(";");
|
||||
@@ -1148,7 +1164,7 @@ namespace ts {
|
||||
|
||||
function emitBindingElement(node: BindingElement) {
|
||||
emitWithSuffix(node.propertyName, ": ");
|
||||
writeIfPresent(node.dotDotDotToken, "...");
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
emit(node.name);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
}
|
||||
@@ -1159,33 +1175,22 @@ namespace ts {
|
||||
|
||||
function emitArrayLiteralExpression(node: ArrayLiteralExpression) {
|
||||
const elements = node.elements;
|
||||
if (elements.length === 0) {
|
||||
write("[]");
|
||||
}
|
||||
else {
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine);
|
||||
}
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
emitExpressionList(node, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine);
|
||||
}
|
||||
|
||||
function emitObjectLiteralExpression(node: ObjectLiteralExpression) {
|
||||
const properties = node.properties;
|
||||
if (properties.length === 0) {
|
||||
write("{}");
|
||||
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
|
||||
if (indentedFlag) {
|
||||
increaseIndent();
|
||||
}
|
||||
else {
|
||||
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
|
||||
if (indentedFlag) {
|
||||
increaseIndent();
|
||||
}
|
||||
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
emitList(node, properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine);
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
emitList(node, node.properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine);
|
||||
|
||||
if (indentedFlag) {
|
||||
decreaseIndent();
|
||||
}
|
||||
if (indentedFlag) {
|
||||
decreaseIndent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1286,7 +1291,8 @@ namespace ts {
|
||||
emitTypeParameters(node, node.typeParameters);
|
||||
emitParametersForArrow(node, node.parameters);
|
||||
emitWithPrefix(": ", node.type);
|
||||
write(" =>");
|
||||
write(" ");
|
||||
emit(node.equalsGreaterThanToken);
|
||||
}
|
||||
|
||||
function emitDeleteExpression(node: DeleteExpression) {
|
||||
@@ -1364,13 +1370,13 @@ namespace ts {
|
||||
|
||||
emitExpression(node.condition);
|
||||
increaseIndentIf(indentBeforeQuestion, " ");
|
||||
write("?");
|
||||
emit(node.questionToken);
|
||||
increaseIndentIf(indentAfterQuestion, " ");
|
||||
emitExpression(node.whenTrue);
|
||||
decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion);
|
||||
|
||||
increaseIndentIf(indentBeforeColon, " ");
|
||||
write(":");
|
||||
emit(node.colonToken);
|
||||
increaseIndentIf(indentAfterColon, " ");
|
||||
emitExpression(node.whenFalse);
|
||||
decreaseIndentIf(indentBeforeColon, indentAfterColon);
|
||||
@@ -1382,7 +1388,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitYieldExpression(node: YieldExpression) {
|
||||
write(node.asteriskToken ? "yield*" : "yield");
|
||||
write("yield");
|
||||
emit(node.asteriskToken);
|
||||
emitExpressionWithPrefix(" ", node.expression);
|
||||
}
|
||||
|
||||
@@ -1433,29 +1440,18 @@ namespace ts {
|
||||
//
|
||||
|
||||
function emitBlock(node: Block) {
|
||||
if (isSingleLineEmptyBlock(node)) {
|
||||
writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node);
|
||||
write(" ");
|
||||
writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node);
|
||||
}
|
||||
else {
|
||||
writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node);
|
||||
emitBlockStatements(node);
|
||||
// We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted
|
||||
increaseIndent();
|
||||
emitLeadingCommentsOfPosition(node.statements.end);
|
||||
decreaseIndent();
|
||||
writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node);
|
||||
}
|
||||
writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node);
|
||||
emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node));
|
||||
// We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted
|
||||
increaseIndent();
|
||||
emitLeadingCommentsOfPosition(node.statements.end);
|
||||
decreaseIndent();
|
||||
writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node);
|
||||
}
|
||||
|
||||
function emitBlockStatements(node: BlockLike) {
|
||||
if (getEmitFlags(node) & EmitFlags.SingleLine) {
|
||||
emitList(node, node.statements, ListFormat.SingleLineBlockStatements);
|
||||
}
|
||||
else {
|
||||
emitList(node, node.statements, ListFormat.MultiLineBlockStatements);
|
||||
}
|
||||
function emitBlockStatements(node: BlockLike, forceSingleLine: boolean) {
|
||||
const format = forceSingleLine || getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineBlockStatements : ListFormat.MultiLineBlockStatements;
|
||||
emitList(node, node.statements, format);
|
||||
}
|
||||
|
||||
function emitVariableStatement(node: VariableStatement) {
|
||||
@@ -1662,7 +1658,9 @@ namespace ts {
|
||||
function emitFunctionDeclarationOrExpression(node: FunctionDeclaration | FunctionExpression) {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
write(node.asteriskToken ? "function* " : "function ");
|
||||
write("function");
|
||||
emitIfPresent(node.asteriskToken);
|
||||
write(" ");
|
||||
emitIdentifierName(node.name);
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
@@ -1880,16 +1878,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitModuleBlock(node: ModuleBlock) {
|
||||
if (isEmptyBlock(node)) {
|
||||
write("{ }");
|
||||
}
|
||||
else {
|
||||
pushNameGenerationScope();
|
||||
write("{");
|
||||
emitBlockStatements(node);
|
||||
write("}");
|
||||
popNameGenerationScope();
|
||||
}
|
||||
pushNameGenerationScope();
|
||||
write("{");
|
||||
emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node));
|
||||
write("}");
|
||||
popNameGenerationScope();
|
||||
}
|
||||
|
||||
function emitCaseBlock(node: CaseBlock) {
|
||||
@@ -2068,9 +2061,7 @@ namespace ts {
|
||||
function emitJsxExpression(node: JsxExpression) {
|
||||
if (node.expression) {
|
||||
write("{");
|
||||
if (node.dotDotDotToken) {
|
||||
write("...");
|
||||
}
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
emitExpression(node.expression);
|
||||
write("}");
|
||||
}
|
||||
@@ -2128,13 +2119,12 @@ namespace ts {
|
||||
emitTrailingCommentsOfPosition(statements.pos);
|
||||
}
|
||||
|
||||
let format = ListFormat.CaseOrDefaultClauseStatements;
|
||||
if (emitAsSingleStatement) {
|
||||
write(" ");
|
||||
emit(statements[0]);
|
||||
}
|
||||
else {
|
||||
emitList(parentNode, statements, ListFormat.CaseOrDefaultClauseStatements);
|
||||
format &= ~(ListFormat.MultiLine | ListFormat.Indented);
|
||||
}
|
||||
emitList(parentNode, statements, format);
|
||||
}
|
||||
|
||||
function emitHeritageClause(node: HeritageClause) {
|
||||
@@ -2384,7 +2374,7 @@ namespace ts {
|
||||
|
||||
function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray<ParameterDeclaration>) {
|
||||
if (canEmitSimpleArrowHead(parentNode, parameters)) {
|
||||
emit(parameters[0]);
|
||||
emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis);
|
||||
}
|
||||
else {
|
||||
emitParameters(parentNode, parameters);
|
||||
@@ -2409,8 +2399,14 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const isEmpty = isUndefined || children.length === 0 || start >= children.length || count === 0;
|
||||
const isEmpty = isUndefined || start >= children.length || count === 0;
|
||||
if (isEmpty && format & ListFormat.OptionalIfEmpty) {
|
||||
if (onBeforeEmitNodeArray) {
|
||||
onBeforeEmitNodeArray(children);
|
||||
}
|
||||
if (onAfterEmitNodeArray) {
|
||||
onAfterEmitNodeArray(children);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2427,7 +2423,7 @@ namespace ts {
|
||||
if (format & ListFormat.MultiLine) {
|
||||
writeLine();
|
||||
}
|
||||
else if (format & ListFormat.SpaceBetweenBraces) {
|
||||
else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) {
|
||||
write(" ");
|
||||
}
|
||||
}
|
||||
@@ -2519,7 +2515,7 @@ namespace ts {
|
||||
// 2
|
||||
// /* end of element 2 */
|
||||
// ];
|
||||
if (previousSibling && delimiter && previousSibling.end !== parentNode.end) {
|
||||
if (previousSibling && delimiter && previousSibling.end !== parentNode.end && !(getEmitFlags(previousSibling) & EmitFlags.NoTrailingComments)) {
|
||||
emitLeadingCommentsOfPosition(previousSibling.end);
|
||||
}
|
||||
|
||||
@@ -2568,12 +2564,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function writeIfPresent(node: Node, text: string) {
|
||||
if (node) {
|
||||
write(text);
|
||||
}
|
||||
}
|
||||
|
||||
function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) {
|
||||
return onEmitSourceMapOfToken
|
||||
? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText)
|
||||
@@ -2584,7 +2574,7 @@ namespace ts {
|
||||
if (onBeforeEmitToken) {
|
||||
onBeforeEmitToken(node);
|
||||
}
|
||||
writeTokenText(node.kind);
|
||||
write(tokenToString(node.kind));
|
||||
if (onAfterEmitToken) {
|
||||
onAfterEmitToken(node);
|
||||
}
|
||||
@@ -2756,11 +2746,6 @@ namespace ts {
|
||||
&& !rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile);
|
||||
}
|
||||
|
||||
function isSingleLineEmptyBlock(block: Block) {
|
||||
return !block.multiLine
|
||||
&& isEmptyBlock(block);
|
||||
}
|
||||
|
||||
function isEmptyBlock(block: BlockLike) {
|
||||
return block.statements.length === 0
|
||||
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
|
||||
@@ -3107,6 +3092,9 @@ namespace ts {
|
||||
NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list.
|
||||
NoInterveningComments = 1 << 17, // Do not emit comments between each node
|
||||
|
||||
NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces.
|
||||
SingleElement = 1 << 19,
|
||||
|
||||
// Precomputed Formats
|
||||
Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments,
|
||||
HeritageClauses = SingleLine | SpaceBetweenSiblings,
|
||||
@@ -3118,7 +3106,7 @@ namespace ts {
|
||||
IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine,
|
||||
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings,
|
||||
ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings,
|
||||
ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces,
|
||||
ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty,
|
||||
ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets,
|
||||
CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
|
||||
CallExpressionArguments = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis,
|
||||
|
||||
+105
-17
@@ -281,7 +281,7 @@ namespace ts {
|
||||
|| node.questionToken !== questionToken
|
||||
|| node.type !== type
|
||||
|| node.initializer !== initializer
|
||||
? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer), node)
|
||||
? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -773,13 +773,13 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createLiteralTypeNode(literal: Expression) {
|
||||
export function createLiteralTypeNode(literal: LiteralTypeNode["literal"]) {
|
||||
const node = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode;
|
||||
node.literal = literal;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateLiteralTypeNode(node: LiteralTypeNode, literal: Expression) {
|
||||
export function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]) {
|
||||
return node.literal !== literal
|
||||
? updateNode(createLiteralTypeNode(literal), node)
|
||||
: node;
|
||||
@@ -1016,19 +1016,49 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
/* @deprecated */ export function updateArrowFunction(
|
||||
node: ArrowFunction,
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
parameters: ReadonlyArray<ParameterDeclaration>,
|
||||
type: TypeNode | undefined,
|
||||
body: ConciseBody): ArrowFunction;
|
||||
export function updateArrowFunction(
|
||||
node: ArrowFunction,
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
parameters: ReadonlyArray<ParameterDeclaration>,
|
||||
type: TypeNode | undefined,
|
||||
body: ConciseBody) {
|
||||
equalsGreaterThanToken: Token<SyntaxKind.EqualsGreaterThanToken>,
|
||||
body: ConciseBody): ArrowFunction;
|
||||
export function updateArrowFunction(
|
||||
node: ArrowFunction,
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
parameters: ReadonlyArray<ParameterDeclaration>,
|
||||
type: TypeNode | undefined,
|
||||
equalsGreaterThanTokenOrBody: Token<SyntaxKind.EqualsGreaterThanToken> | ConciseBody,
|
||||
bodyOrUndefined?: ConciseBody,
|
||||
): ArrowFunction {
|
||||
let equalsGreaterThanToken: Token<SyntaxKind.EqualsGreaterThanToken>;
|
||||
let body: ConciseBody;
|
||||
if (bodyOrUndefined === undefined) {
|
||||
equalsGreaterThanToken = node.equalsGreaterThanToken;
|
||||
body = cast(equalsGreaterThanTokenOrBody, isConciseBody);
|
||||
}
|
||||
else {
|
||||
equalsGreaterThanToken = cast(equalsGreaterThanTokenOrBody, (n): n is Token<SyntaxKind.EqualsGreaterThanToken> =>
|
||||
n.kind === SyntaxKind.EqualsGreaterThanToken);
|
||||
body = bodyOrUndefined;
|
||||
}
|
||||
|
||||
return node.modifiers !== modifiers
|
||||
|| node.typeParameters !== typeParameters
|
||||
|| node.parameters !== parameters
|
||||
|| node.type !== type
|
||||
|| node.equalsGreaterThanToken !== equalsGreaterThanToken
|
||||
|| node.body !== body
|
||||
? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, node.equalsGreaterThanToken, body), node)
|
||||
? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -1135,11 +1165,31 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateConditional(node: ConditionalExpression, condition: Expression, whenTrue: Expression, whenFalse: Expression) {
|
||||
/* @deprecated */ export function updateConditional(
|
||||
node: ConditionalExpression,
|
||||
condition: Expression,
|
||||
whenTrue: Expression,
|
||||
whenFalse: Expression): ConditionalExpression;
|
||||
export function updateConditional(
|
||||
node: ConditionalExpression,
|
||||
condition: Expression,
|
||||
questionToken: Token<SyntaxKind.QuestionToken>,
|
||||
whenTrue: Expression,
|
||||
colonToken: Token<SyntaxKind.ColonToken>,
|
||||
whenFalse: Expression): ConditionalExpression;
|
||||
export function updateConditional(node: ConditionalExpression, condition: Expression, ...args: any[]) {
|
||||
if (args.length === 2) {
|
||||
const [whenTrue, whenFalse] = args;
|
||||
return updateConditional(node, condition, node.questionToken, whenTrue, node.colonToken, whenFalse);
|
||||
}
|
||||
Debug.assert(args.length === 4);
|
||||
const [questionToken, whenTrue, colonToken, whenFalse] = args;
|
||||
return node.condition !== condition
|
||||
|| node.questionToken !== questionToken
|
||||
|| node.whenTrue !== whenTrue
|
||||
|| node.colonToken !== colonToken
|
||||
|| node.whenFalse !== whenFalse
|
||||
? updateNode(createConditional(condition, node.questionToken, whenTrue, node.colonToken, whenFalse), node)
|
||||
? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -2339,13 +2389,13 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createBundle(sourceFiles: SourceFile[]) {
|
||||
export function createBundle(sourceFiles: ReadonlyArray<SourceFile>) {
|
||||
const node = <Bundle>createNode(SyntaxKind.Bundle);
|
||||
node.sourceFiles = sourceFiles;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateBundle(node: Bundle, sourceFiles: SourceFile[]) {
|
||||
export function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>) {
|
||||
if (node.sourceFiles !== sourceFiles) {
|
||||
return createBundle(sourceFiles);
|
||||
}
|
||||
@@ -2372,6 +2422,24 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression;
|
||||
export function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
|
||||
export function createImmediatelyInvokedArrowFunction(statements: Statement[], param?: ParameterDeclaration, paramValue?: Expression) {
|
||||
return createCall(
|
||||
createArrowFunction(
|
||||
/*modifiers*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ param ? [param] : [],
|
||||
/*type*/ undefined,
|
||||
/*equalsGreaterThanToken*/ undefined,
|
||||
createBlock(statements, /*multiLine*/ true)
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
/*argumentsArray*/ paramValue ? [paramValue] : []
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export function createComma(left: Expression, right: Expression) {
|
||||
return <Expression>createBinary(left, SyntaxKind.CommaToken, right);
|
||||
}
|
||||
@@ -2636,9 +2704,7 @@ namespace ts {
|
||||
if (some(helpers)) {
|
||||
const emitNode = getOrCreateEmitNode(node);
|
||||
for (const helper of helpers) {
|
||||
if (!contains(emitNode.helpers, helper)) {
|
||||
emitNode.helpers = append(emitNode.helpers, helper);
|
||||
}
|
||||
emitNode.helpers = appendIfUnique(emitNode.helpers, helper);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
@@ -2680,9 +2746,7 @@ namespace ts {
|
||||
const helper = sourceEmitHelpers[i];
|
||||
if (predicate(helper)) {
|
||||
helpersRemoved++;
|
||||
if (!contains(targetEmitNode.helpers, helper)) {
|
||||
targetEmitNode.helpers = append(targetEmitNode.helpers, helper);
|
||||
}
|
||||
targetEmitNode.helpers = appendIfUnique(targetEmitNode.helpers, helper);
|
||||
}
|
||||
else if (helpersRemoved > 0) {
|
||||
sourceEmitHelpers[i - helpersRemoved] = helper;
|
||||
@@ -4040,8 +4104,31 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions.
|
||||
*
|
||||
* A parenthesized expression can be ignored when all of the following are true:
|
||||
*
|
||||
* - It's `pos` and `end` are not -1
|
||||
* - It does not have a custom source map range
|
||||
* - It does not have a custom comment range
|
||||
* - It does not have synthetic leading or trailing comments
|
||||
*
|
||||
* If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around
|
||||
* the expression to maintain precedence, a new parenthesized expression should be created automatically when
|
||||
* the containing expression is created/updated.
|
||||
*/
|
||||
function isIgnorableParen(node: Expression) {
|
||||
return node.kind === SyntaxKind.ParenthesizedExpression
|
||||
&& nodeIsSynthesized(node)
|
||||
&& nodeIsSynthesized(getSourceMapRange(node))
|
||||
&& nodeIsSynthesized(getCommentRange(node))
|
||||
&& !some(getSyntheticLeadingComments(node))
|
||||
&& !some(getSyntheticTrailingComments(node));
|
||||
}
|
||||
|
||||
export function recreateOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression {
|
||||
if (outerExpression && isOuterExpression(outerExpression, kinds)) {
|
||||
if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
|
||||
return updateOuterExpression(
|
||||
outerExpression,
|
||||
recreateOuterExpressions(outerExpression.expression, innerExpression)
|
||||
@@ -4071,7 +4158,8 @@ namespace ts {
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
let create = hasExportStarsToExportValues
|
||||
&& moduleKind !== ModuleKind.System
|
||||
&& moduleKind !== ModuleKind.ES2015;
|
||||
&& moduleKind !== ModuleKind.ES2015
|
||||
&& moduleKind !== ModuleKind.ESNext;
|
||||
if (!create) {
|
||||
const helpers = getEmitHelpers(node);
|
||||
if (helpers) {
|
||||
|
||||
@@ -51,13 +51,17 @@ namespace ts {
|
||||
DtsOnly /** Only '.d.ts' */
|
||||
}
|
||||
|
||||
interface PathAndPackageId {
|
||||
readonly fileName: string;
|
||||
readonly packageId: PackageId;
|
||||
}
|
||||
/** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
|
||||
function resolvedTypeScriptOnly(resolved: Resolved | undefined): string | undefined {
|
||||
function resolvedTypeScriptOnly(resolved: Resolved | undefined): PathAndPackageId | undefined {
|
||||
if (!resolved) {
|
||||
return undefined;
|
||||
}
|
||||
Debug.assert(extensionIsTypeScript(resolved.extension));
|
||||
return resolved.path;
|
||||
return { fileName: resolved.path, packageId: resolved.packageId };
|
||||
}
|
||||
|
||||
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
@@ -201,18 +205,18 @@ namespace ts {
|
||||
let resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined;
|
||||
if (resolved) {
|
||||
if (!options.preserveSymlinks) {
|
||||
resolved = realPath(resolved, host, traceEnabled);
|
||||
resolved = { ...resolved, fileName: realPath(resolved.fileName, host, traceEnabled) };
|
||||
}
|
||||
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, primary);
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved.fileName, primary);
|
||||
}
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName: resolved };
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName: resolved.fileName, packageId: resolved.packageId };
|
||||
}
|
||||
|
||||
return { resolvedTypeReferenceDirective, failedLookupLocations };
|
||||
|
||||
function primaryLookup(): string | undefined {
|
||||
function primaryLookup(): PathAndPackageId | undefined {
|
||||
// Check primary library paths
|
||||
if (typeRoots && typeRoots.length) {
|
||||
if (traceEnabled) {
|
||||
@@ -237,8 +241,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function secondaryLookup(): string | undefined {
|
||||
let resolvedFile: string;
|
||||
function secondaryLookup(): PathAndPackageId | undefined {
|
||||
let resolvedFile: PathAndPackageId;
|
||||
const initialLocationForSecondaryLookup = containingFile && getDirectoryPath(containingFile);
|
||||
|
||||
if (initialLocationForSecondaryLookup !== undefined) {
|
||||
@@ -675,7 +679,7 @@ namespace ts {
|
||||
if (extension !== undefined) {
|
||||
const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
if (path !== undefined) {
|
||||
return { path, extension, packageId: undefined };
|
||||
return noPackageId({ path, ext: extension });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,9 +751,10 @@ namespace ts {
|
||||
return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
|
||||
}
|
||||
else {
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName));
|
||||
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
|
||||
return resolved && toSearchResult({ resolved, isExternalLibraryImport: false });
|
||||
// Treat explicit "node_modules" import as an external library import.
|
||||
return resolved && toSearchResult({ resolved, isExternalLibraryImport: contains(parts, "node_modules") });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -874,38 +879,49 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true): Resolved | undefined {
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
|
||||
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) {
|
||||
const { packageJsonContent, packageId } = considerPackageJson
|
||||
? getPackageJsonInfo(candidate, "", failedLookupLocations, onlyRecordFailures, state)
|
||||
: { packageJsonContent: undefined, packageId: undefined };
|
||||
return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent));
|
||||
}
|
||||
|
||||
let packageId: PackageId | undefined;
|
||||
|
||||
if (considerPackageJson) {
|
||||
const packageJsonPath = pathToPackageJson(candidate);
|
||||
if (directoryExists && state.host.fileExists(packageJsonPath)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
const jsonContent = readJson(packageJsonPath, state.host);
|
||||
|
||||
if (typeof jsonContent.name === "string" && typeof jsonContent.version === "string") {
|
||||
packageId = { name: jsonContent.name, version: jsonContent.version };
|
||||
}
|
||||
|
||||
const fromPackageJson = loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state);
|
||||
if (fromPackageJson) {
|
||||
return withPackageId(packageId, fromPackageJson);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (directoryExists && state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.File_0_does_not_exist, packageJsonPath);
|
||||
}
|
||||
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
|
||||
failedLookupLocations.push(packageJsonPath);
|
||||
}
|
||||
function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJson | undefined): PathAndExtension | undefined {
|
||||
const fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, extensions, candidate, failedLookupLocations, state);
|
||||
if (fromPackageJson) {
|
||||
return fromPackageJson;
|
||||
}
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
|
||||
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
|
||||
}
|
||||
|
||||
return withPackageId(packageId, loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state));
|
||||
function getPackageJsonInfo(
|
||||
nodeModuleDirectory: string,
|
||||
subModuleName: string,
|
||||
failedLookupLocations: Push<string>,
|
||||
onlyRecordFailures: boolean,
|
||||
{ host, traceEnabled }: ModuleResolutionState,
|
||||
): { packageJsonContent: PackageJson | undefined, packageId: PackageId | undefined } {
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host);
|
||||
const packageJsonPath = pathToPackageJson(nodeModuleDirectory);
|
||||
if (directoryExists && host.fileExists(packageJsonPath)) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
const packageJsonContent = readJson(packageJsonPath, host);
|
||||
const packageId: PackageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
|
||||
? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version }
|
||||
: undefined;
|
||||
return { packageJsonContent, packageId };
|
||||
}
|
||||
else {
|
||||
if (directoryExists && traceEnabled) {
|
||||
trace(host, Diagnostics.File_0_does_not_exist, packageJsonPath);
|
||||
}
|
||||
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
|
||||
failedLookupLocations.push(packageJsonPath);
|
||||
return { packageJsonContent: undefined, packageId: undefined };
|
||||
}
|
||||
}
|
||||
|
||||
function loadModuleFromPackageJson(jsonContent: PackageJson, extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, state: ModuleResolutionState): PathAndExtension | undefined {
|
||||
@@ -960,10 +976,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
|
||||
const { top, rest } = getNameOfTopDirectory(moduleName);
|
||||
const packageRootPath = combinePaths(nodeModulesFolder, top);
|
||||
const { packageJsonContent, packageId } = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state);
|
||||
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
|
||||
const pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
|
||||
loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent);
|
||||
return withPackageId(packageId, pathAndExtension);
|
||||
}
|
||||
|
||||
return loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
|
||||
loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
|
||||
function getNameOfTopDirectory(name: string): { top: string, rest: string } {
|
||||
const idx = name.indexOf(directorySeparator);
|
||||
return idx === -1 ? { top: name, rest: "" } : { top: name.slice(0, idx), rest: name.slice(idx + 1) };
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache): SearchResult<Resolved> {
|
||||
|
||||
+115
-131
@@ -438,8 +438,10 @@ namespace ts {
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression);
|
||||
}
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
visitNode(cbNode, tag);
|
||||
if ((node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) {
|
||||
visitNode(cbNode, tag);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
@@ -729,7 +731,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
|
||||
function addJSDocComment<T extends Node>(node: T): T {
|
||||
function addJSDocComment<T extends HasJSDoc>(node: T): T {
|
||||
const comments = getJSDocCommentRanges(node, sourceFile.text);
|
||||
if (comments) {
|
||||
for (const comment of comments) {
|
||||
@@ -768,7 +770,7 @@ namespace ts {
|
||||
const saveParent = parent;
|
||||
parent = n;
|
||||
forEachChild(n, visitNode);
|
||||
if (n.jsDoc) {
|
||||
if (hasJSDocNodes(n)) {
|
||||
for (const jsDoc of n.jsDoc) {
|
||||
jsDoc.parent = n;
|
||||
parent = jsDoc;
|
||||
@@ -940,10 +942,6 @@ namespace ts {
|
||||
return scanner.getStartPos();
|
||||
}
|
||||
|
||||
function getNodeEnd(): number {
|
||||
return scanner.getStartPos();
|
||||
}
|
||||
|
||||
// Use this function to access the current token instead of reading the currentToken
|
||||
// variable. Since function results aren't narrowed in control flow analysis, this ensures
|
||||
// that the type checker doesn't make wrong assumptions about the type of the current
|
||||
@@ -1135,13 +1133,14 @@ namespace ts {
|
||||
new TokenConstructor(kind, pos, pos);
|
||||
}
|
||||
|
||||
function createNodeArray<T extends Node>(elements?: T[], pos?: number): MutableNodeArray<T> {
|
||||
const array = <MutableNodeArray<T>>(elements || []);
|
||||
if (!(pos >= 0)) {
|
||||
pos = getNodePos();
|
||||
}
|
||||
function createNodeArray<T extends Node>(elements: T[], pos: number, end?: number): NodeArray<T> {
|
||||
// Since the element list of a node array is typically created by starting with an empty array and
|
||||
// repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for
|
||||
// small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation.
|
||||
const length = elements.length;
|
||||
const array = <MutableNodeArray<T>>(length >= 1 && length <= 4 ? elements.slice() : elements);
|
||||
array.pos = pos;
|
||||
array.end = pos;
|
||||
array.end = end === undefined ? scanner.getStartPos() : end;
|
||||
return array;
|
||||
}
|
||||
|
||||
@@ -1208,7 +1207,10 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
return createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics.Identifier_expected);
|
||||
// Only for end of file because the error gets reported incorrectly on embedded script tags.
|
||||
const reportAtCurrentPosition = token() === SyntaxKind.EndOfFileToken;
|
||||
|
||||
return createMissingNode<Identifier>(SyntaxKind.Identifier, reportAtCurrentPosition, diagnosticMessage || Diagnostics.Identifier_expected);
|
||||
}
|
||||
|
||||
function parseIdentifier(diagnosticMessage?: DiagnosticMessage): Identifier {
|
||||
@@ -1527,12 +1529,13 @@ namespace ts {
|
||||
function parseList<T extends Node>(kind: ParsingContext, parseElement: () => T): NodeArray<T> {
|
||||
const saveParsingContext = parsingContext;
|
||||
parsingContext |= 1 << kind;
|
||||
const result = createNodeArray<T>();
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
|
||||
while (!isListTerminator(kind)) {
|
||||
if (isListElement(kind, /*inErrorRecovery*/ false)) {
|
||||
const element = parseListElement(kind, parseElement);
|
||||
result.push(element);
|
||||
list.push(element);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -1542,9 +1545,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
result.end = getNodeEnd();
|
||||
parsingContext = saveParsingContext;
|
||||
return result;
|
||||
return createNodeArray(list, listPos);
|
||||
}
|
||||
|
||||
function parseListElement<T extends Node>(parsingContext: ParsingContext, parseElement: () => T): T {
|
||||
@@ -1874,13 +1876,14 @@ namespace ts {
|
||||
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray<T> {
|
||||
const saveParsingContext = parsingContext;
|
||||
parsingContext |= 1 << kind;
|
||||
const result = createNodeArray<T>();
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
|
||||
let commaStart = -1; // Meaning the previous token was not a comma
|
||||
while (true) {
|
||||
if (isListElement(kind, /*inErrorRecovery*/ false)) {
|
||||
const startPos = scanner.getStartPos();
|
||||
result.push(parseListElement(kind, parseElement));
|
||||
list.push(parseListElement(kind, parseElement));
|
||||
commaStart = scanner.getTokenPos();
|
||||
|
||||
if (parseOptional(SyntaxKind.CommaToken)) {
|
||||
@@ -1924,6 +1927,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
parsingContext = saveParsingContext;
|
||||
const result = createNodeArray(list, listPos);
|
||||
// Recording the trailing comma is deliberately done after the previous
|
||||
// loop, and not just if we see a list terminator. This is because the list
|
||||
// may have ended incorrectly, but it is still important to know if there
|
||||
@@ -1933,14 +1938,11 @@ namespace ts {
|
||||
// Always preserve a trailing comma by marking it on the NodeArray
|
||||
result.hasTrailingComma = true;
|
||||
}
|
||||
|
||||
result.end = getNodeEnd();
|
||||
parsingContext = saveParsingContext;
|
||||
return result;
|
||||
}
|
||||
|
||||
function createMissingList<T extends Node>(): NodeArray<T> {
|
||||
return createNodeArray<T>();
|
||||
return createNodeArray<T>([], getNodePos());
|
||||
}
|
||||
|
||||
function parseBracketedList<T extends Node>(kind: ParsingContext, parseElement: () => T, open: SyntaxKind, close: SyntaxKind): NodeArray<T> {
|
||||
@@ -2015,15 +2017,15 @@ namespace ts {
|
||||
template.head = parseTemplateHead();
|
||||
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
|
||||
|
||||
const templateSpans = createNodeArray<TemplateSpan>();
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
|
||||
do {
|
||||
templateSpans.push(parseTemplateSpan());
|
||||
list.push(parseTemplateSpan());
|
||||
}
|
||||
while (lastOrUndefined(templateSpans).literal.kind === SyntaxKind.TemplateMiddle);
|
||||
while (lastOrUndefined(list).literal.kind === SyntaxKind.TemplateMiddle);
|
||||
|
||||
templateSpans.end = getNodeEnd();
|
||||
template.templateSpans = templateSpans;
|
||||
template.templateSpans = createNodeArray(list, listPos);
|
||||
|
||||
return finishNode(template);
|
||||
}
|
||||
@@ -2158,7 +2160,7 @@ namespace ts {
|
||||
const result = <JSDocFunctionType>createNode(SyntaxKind.JSDocFunctionType);
|
||||
nextToken();
|
||||
fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type | SignatureFlags.JSDoc, result);
|
||||
return finishNode(result);
|
||||
return addJSDocComment(finishNode(result));
|
||||
}
|
||||
const node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
|
||||
node.typeName = parseIdentifierName();
|
||||
@@ -2237,10 +2239,11 @@ namespace ts {
|
||||
return token() === SyntaxKind.DotDotDotToken ||
|
||||
isIdentifierOrPattern() ||
|
||||
isModifierKind(token()) ||
|
||||
token() === SyntaxKind.AtToken || isStartOfType();
|
||||
token() === SyntaxKind.AtToken ||
|
||||
isStartOfType(/*inStartOfParameter*/ true);
|
||||
}
|
||||
|
||||
function parseParameter(): ParameterDeclaration {
|
||||
function parseParameter(requireEqualsToken?: boolean): ParameterDeclaration {
|
||||
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter);
|
||||
if (token() === SyntaxKind.ThisKeyword) {
|
||||
node.name = createIdentifier(/*isIdentifier*/ true);
|
||||
@@ -2269,19 +2272,11 @@ namespace ts {
|
||||
|
||||
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
|
||||
node.type = parseParameterType();
|
||||
node.initializer = parseBindingElementInitializer(/*inParameter*/ true);
|
||||
node.initializer = parseInitializer(/*inParameter*/ true, requireEqualsToken);
|
||||
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseBindingElementInitializer(inParameter: boolean) {
|
||||
return inParameter ? parseParameterInitializer() : parseNonParameterInitializer();
|
||||
}
|
||||
|
||||
function parseParameterInitializer() {
|
||||
return parseInitializer(/*inParameter*/ true);
|
||||
}
|
||||
|
||||
function fillSignature(
|
||||
returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken,
|
||||
flags: SignatureFlags,
|
||||
@@ -2290,25 +2285,27 @@ namespace ts {
|
||||
signature.typeParameters = parseTypeParameters();
|
||||
}
|
||||
signature.parameters = parseParameterList(flags);
|
||||
signature.type = parseReturnType(returnToken, !!(flags & SignatureFlags.Type));
|
||||
}
|
||||
|
||||
const returnTokenRequired = returnToken === SyntaxKind.EqualsGreaterThanToken;
|
||||
if (returnTokenRequired) {
|
||||
function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined {
|
||||
return shouldParseReturnType(returnToken, isType) ? parseTypeOrTypePredicate() : undefined;
|
||||
}
|
||||
function shouldParseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean {
|
||||
if (returnToken === SyntaxKind.EqualsGreaterThanToken) {
|
||||
parseExpected(returnToken);
|
||||
signature.type = parseTypeOrTypePredicate();
|
||||
return true;
|
||||
}
|
||||
else if (parseOptional(returnToken)) {
|
||||
signature.type = parseTypeOrTypePredicate();
|
||||
else if (parseOptional(SyntaxKind.ColonToken)) {
|
||||
return true;
|
||||
}
|
||||
else if (flags & SignatureFlags.Type) {
|
||||
const start = scanner.getTokenPos();
|
||||
const length = scanner.getTextPos() - start;
|
||||
const backwardToken = parseOptional(returnToken === SyntaxKind.ColonToken ? SyntaxKind.EqualsGreaterThanToken : SyntaxKind.ColonToken);
|
||||
if (backwardToken) {
|
||||
// This is easy to get backward, especially in type contexts, so parse the type anyway
|
||||
signature.type = parseTypeOrTypePredicate();
|
||||
parseErrorAtPosition(start, length, Diagnostics._0_expected, tokenToString(returnToken));
|
||||
}
|
||||
else if (isType && token() === SyntaxKind.EqualsGreaterThanToken) {
|
||||
// This is easy to get backward, especially in type contexts, so parse the type anyway
|
||||
parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken));
|
||||
nextToken();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseParameterList(flags: SignatureFlags) {
|
||||
@@ -2332,7 +2329,8 @@ namespace ts {
|
||||
setYieldContext(!!(flags & SignatureFlags.Yield));
|
||||
setAwaitContext(!!(flags & SignatureFlags.Await));
|
||||
|
||||
const result = parseDelimitedList(ParsingContext.Parameters, flags & SignatureFlags.JSDoc ? parseJSDocParameter : parseParameter);
|
||||
const result = parseDelimitedList(ParsingContext.Parameters,
|
||||
flags & SignatureFlags.JSDoc ? parseJSDocParameter : () => parseParameter(!!(flags & SignatureFlags.RequireCompleteParameterList)));
|
||||
|
||||
setYieldContext(savedYieldContext);
|
||||
setAwaitContext(savedAwaitContext);
|
||||
@@ -2363,7 +2361,7 @@ namespace ts {
|
||||
parseSemicolon();
|
||||
}
|
||||
|
||||
function parseSignatureMember(kind: SyntaxKind): CallSignatureDeclaration | ConstructSignatureDeclaration {
|
||||
function parseSignatureMember(kind: SyntaxKind.CallSignature | SyntaxKind.ConstructSignature): CallSignatureDeclaration | ConstructSignatureDeclaration {
|
||||
const node = <CallSignatureDeclaration | ConstructSignatureDeclaration>createNode(kind);
|
||||
if (kind === SyntaxKind.ConstructSignature) {
|
||||
parseExpected(SyntaxKind.NewKeyword);
|
||||
@@ -2443,7 +2441,7 @@ namespace ts {
|
||||
node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
|
||||
node.type = parseTypeAnnotation();
|
||||
parseTypeMemberSemicolon();
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parsePropertyOrMethodSignature(fullStart: number, modifiers: NodeArray<Modifier>): PropertySignature | MethodSignature {
|
||||
@@ -2603,7 +2601,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.NewKeyword);
|
||||
}
|
||||
fillSignature(SyntaxKind.EqualsGreaterThanToken, SignatureFlags.Type, node);
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseKeywordAndNoDot(): TypeNode | undefined {
|
||||
@@ -2619,16 +2617,9 @@ namespace ts {
|
||||
unaryMinusExpression.operator = SyntaxKind.MinusToken;
|
||||
nextToken();
|
||||
}
|
||||
let expression: UnaryExpression;
|
||||
switch (token()) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
expression = parseLiteralLikeNode(token()) as LiteralExpression;
|
||||
break;
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
expression = parseTokenNode();
|
||||
}
|
||||
let expression: BooleanLiteral | LiteralExpression | PrefixUnaryExpression = token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword
|
||||
? parseTokenNode<BooleanLiteral>()
|
||||
: parseLiteralLikeNode(token()) as LiteralExpression;
|
||||
if (negative) {
|
||||
unaryMinusExpression.operand = expression;
|
||||
finishNode(unaryMinusExpression);
|
||||
@@ -2664,6 +2655,7 @@ namespace ts {
|
||||
return parseJSDocNodeWithType(SyntaxKind.JSDocVariadicType);
|
||||
case SyntaxKind.ExclamationToken:
|
||||
return parseJSDocNodeWithType(SyntaxKind.JSDocNonNullableType);
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
@@ -2696,7 +2688,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isStartOfType(): boolean {
|
||||
function isStartOfType(inStartOfParameter?: boolean): boolean {
|
||||
switch (token()) {
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
@@ -2721,13 +2713,16 @@ namespace ts {
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
case SyntaxKind.AsteriskToken:
|
||||
case SyntaxKind.QuestionToken:
|
||||
case SyntaxKind.ExclamationToken:
|
||||
case SyntaxKind.DotDotDotToken:
|
||||
return true;
|
||||
case SyntaxKind.MinusToken:
|
||||
return lookAhead(nextTokenIsNumericLiteral);
|
||||
return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral);
|
||||
case SyntaxKind.OpenParenToken:
|
||||
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
|
||||
// or something that starts a type. We don't want to consider things like '(1)' a type.
|
||||
return lookAhead(isStartOfParenthesizedOrFunctionType);
|
||||
return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType);
|
||||
default:
|
||||
return isIdentifier();
|
||||
}
|
||||
@@ -2801,13 +2796,12 @@ namespace ts {
|
||||
parseOptional(operator);
|
||||
let type = parseConstituentType();
|
||||
if (token() === operator) {
|
||||
const types = createNodeArray<TypeNode>([type], type.pos);
|
||||
const types = [type];
|
||||
while (parseOptional(operator)) {
|
||||
types.push(parseConstituentType());
|
||||
}
|
||||
types.end = getNodeEnd();
|
||||
const node = <UnionOrIntersectionTypeNode>createNode(kind, type.pos);
|
||||
node.types = types;
|
||||
node.types = createNodeArray(types, type.pos);
|
||||
type = finishNode(node);
|
||||
}
|
||||
return type;
|
||||
@@ -3013,7 +3007,7 @@ namespace ts {
|
||||
return expr;
|
||||
}
|
||||
|
||||
function parseInitializer(inParameter: boolean): Expression {
|
||||
function parseInitializer(inParameter: boolean, requireEqualsToken?: boolean): Expression {
|
||||
if (token() !== SyntaxKind.EqualsToken) {
|
||||
// It's not uncommon during typing for the user to miss writing the '=' token. Check if
|
||||
// there is no newline after the last token and if we're on an expression. If so, parse
|
||||
@@ -3028,11 +3022,17 @@ namespace ts {
|
||||
// do not try to parse initializer
|
||||
return undefined;
|
||||
}
|
||||
if (inParameter && requireEqualsToken) {
|
||||
// = is required when speculatively parsing arrow function parameters,
|
||||
// so return a fake initializer as a signal that the equals token was missing
|
||||
const result = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics._0_expected, "=") as Identifier;
|
||||
result.escapedText = "= not found" as __String;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Initializer[In, Yield] :
|
||||
// = AssignmentExpression[?In, ?Yield]
|
||||
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
return parseAssignmentExpressionOrHigher();
|
||||
}
|
||||
@@ -3173,8 +3173,7 @@ namespace ts {
|
||||
parameter.name = identifier;
|
||||
finishNode(parameter);
|
||||
|
||||
node.parameters = createNodeArray<ParameterDeclaration>([parameter], parameter.pos);
|
||||
node.parameters.end = parameter.end;
|
||||
node.parameters = createNodeArray<ParameterDeclaration>([parameter], parameter.pos, parameter.end);
|
||||
|
||||
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>");
|
||||
node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
|
||||
@@ -3348,8 +3347,7 @@ namespace ts {
|
||||
function tryParseAsyncSimpleArrowFunctionExpression(): ArrowFunction | undefined {
|
||||
// We do a check here so that we won't be doing unnecessarily call to "lookAhead"
|
||||
if (token() === SyntaxKind.AsyncKeyword) {
|
||||
const isUnParenthesizedAsyncArrowFunction = lookAhead(isUnParenthesizedAsyncArrowFunctionWorker);
|
||||
if (isUnParenthesizedAsyncArrowFunction === Tristate.True) {
|
||||
if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === Tristate.True) {
|
||||
const asyncModifier = parseModifiersForArrowFunction();
|
||||
const expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
|
||||
return parseSimpleArrowFunctionExpression(<Identifier>expr, asyncModifier);
|
||||
@@ -3383,7 +3381,6 @@ namespace ts {
|
||||
const node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction);
|
||||
node.modifiers = parseModifiersForArrowFunction();
|
||||
const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None;
|
||||
|
||||
// Arrow functions are never generators.
|
||||
//
|
||||
// If we're speculatively parsing a signature for a parenthesized arrow function, then
|
||||
@@ -3406,7 +3403,8 @@ namespace ts {
|
||||
// - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
|
||||
//
|
||||
// So we need just a bit of lookahead to ensure that it can only be a signature.
|
||||
if (!allowAmbiguity && token() !== SyntaxKind.EqualsGreaterThanToken && token() !== SyntaxKind.OpenBraceToken) {
|
||||
if (!allowAmbiguity && ((token() !== SyntaxKind.EqualsGreaterThanToken && token() !== SyntaxKind.OpenBraceToken) ||
|
||||
find(node.parameters, p => p.initializer && ts.isIdentifier(p.initializer) && p.initializer.escapedText === "= not found"))) {
|
||||
// Returning undefined here will cause our caller to rewind to where we started from.
|
||||
return undefined;
|
||||
}
|
||||
@@ -4024,7 +4022,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseJsxChildren(openingTagName: LeftHandSideExpression): NodeArray<JsxChild> {
|
||||
const result = createNodeArray<JsxChild>();
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
const saveParsingContext = parsingContext;
|
||||
parsingContext |= 1 << ParsingContext.JsxChildren;
|
||||
|
||||
@@ -4045,15 +4044,13 @@ namespace ts {
|
||||
}
|
||||
const child = parseJsxChild();
|
||||
if (child) {
|
||||
result.push(child);
|
||||
list.push(child);
|
||||
}
|
||||
}
|
||||
|
||||
result.end = scanner.getTokenPos();
|
||||
|
||||
parsingContext = saveParsingContext;
|
||||
|
||||
return result;
|
||||
return createNodeArray(list, listPos);
|
||||
}
|
||||
|
||||
function parseJsxAttributes(): JsxAttributes {
|
||||
@@ -5156,7 +5153,7 @@ namespace ts {
|
||||
const node = <BindingElement>createNode(SyntaxKind.BindingElement);
|
||||
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
|
||||
node.name = parseIdentifierOrPattern();
|
||||
node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
|
||||
node.initializer = parseInitializer(/*inParameter*/ false);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -5173,7 +5170,7 @@ namespace ts {
|
||||
node.propertyName = propertyName;
|
||||
node.name = parseIdentifierOrPattern();
|
||||
}
|
||||
node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
|
||||
node.initializer = parseInitializer(/*inParameter*/ false);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -5212,7 +5209,7 @@ namespace ts {
|
||||
node.name = parseIdentifierOrPattern();
|
||||
node.type = parseTypeAnnotation();
|
||||
if (!isInOrOfKeyword(token())) {
|
||||
node.initializer = parseInitializer(/*inParameter*/ false);
|
||||
node.initializer = parseNonParameterInitializer();
|
||||
}
|
||||
return finishNode(node);
|
||||
}
|
||||
@@ -5446,27 +5443,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseDecorators(): NodeArray<Decorator> {
|
||||
let decorators: NodeArray<Decorator> & Decorator[];
|
||||
let list: Decorator[];
|
||||
const listPos = getNodePos();
|
||||
while (true) {
|
||||
const decoratorStart = getNodePos();
|
||||
if (!parseOptional(SyntaxKind.AtToken)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const decorator = <Decorator>createNode(SyntaxKind.Decorator, decoratorStart);
|
||||
decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
|
||||
finishNode(decorator);
|
||||
if (!decorators) {
|
||||
decorators = createNodeArray<Decorator>([decorator], decoratorStart);
|
||||
}
|
||||
else {
|
||||
decorators.push(decorator);
|
||||
}
|
||||
(list || (list = [])).push(decorator);
|
||||
}
|
||||
if (decorators) {
|
||||
decorators.end = getNodeEnd();
|
||||
}
|
||||
return decorators;
|
||||
return list && createNodeArray(list, listPos);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5477,7 +5466,8 @@ namespace ts {
|
||||
* In such situations, 'permitInvalidConstAsModifier' should be set to true.
|
||||
*/
|
||||
function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray<Modifier> | undefined {
|
||||
let modifiers: MutableNodeArray<Modifier> | undefined;
|
||||
let list: Modifier[];
|
||||
const listPos = getNodePos();
|
||||
while (true) {
|
||||
const modifierStart = scanner.getStartPos();
|
||||
const modifierKind = token();
|
||||
@@ -5496,17 +5486,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
const modifier = finishNode(<Modifier>createNode(modifierKind, modifierStart));
|
||||
if (!modifiers) {
|
||||
modifiers = createNodeArray<Modifier>([modifier], modifierStart);
|
||||
}
|
||||
else {
|
||||
modifiers.push(modifier);
|
||||
}
|
||||
(list || (list = [])).push(modifier);
|
||||
}
|
||||
if (modifiers) {
|
||||
modifiers.end = scanner.getStartPos();
|
||||
}
|
||||
return modifiers;
|
||||
return list && createNodeArray(list, listPos);
|
||||
}
|
||||
|
||||
function parseModifiersForArrowFunction(): NodeArray<Modifier> {
|
||||
@@ -5517,9 +5499,7 @@ namespace ts {
|
||||
nextToken();
|
||||
const modifier = finishNode(<Modifier>createNode(modifierKind, modifierStart));
|
||||
modifiers = createNodeArray<Modifier>([modifier], modifierStart);
|
||||
modifiers.end = scanner.getStartPos();
|
||||
}
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
@@ -6177,7 +6157,7 @@ namespace ts {
|
||||
return jsDoc ? { jsDoc, diagnostics } : undefined;
|
||||
}
|
||||
|
||||
export function parseJSDocComment(parent: Node, start: number, length: number): JSDoc {
|
||||
export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc {
|
||||
const saveToken = currentToken;
|
||||
const saveParseDiagnosticsLength = parseDiagnostics.length;
|
||||
const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
|
||||
@@ -6221,7 +6201,9 @@ namespace ts {
|
||||
Debug.assert(start <= end);
|
||||
Debug.assert(end <= content.length);
|
||||
|
||||
let tags: MutableNodeArray<JSDocTag>;
|
||||
let tags: JSDocTag[];
|
||||
let tagsPos: number;
|
||||
let tagsEnd: number;
|
||||
const comments: string[] = [];
|
||||
let result: JSDoc;
|
||||
|
||||
@@ -6354,7 +6336,7 @@ namespace ts {
|
||||
|
||||
function createJSDocComment(): JSDoc {
|
||||
const result = <JSDoc>createNode(SyntaxKind.JSDocComment, start);
|
||||
result.tags = tags;
|
||||
result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd);
|
||||
result.comment = comments.length ? comments.join("") : undefined;
|
||||
return finishNode(result, end);
|
||||
}
|
||||
@@ -6494,12 +6476,13 @@ namespace ts {
|
||||
tag.comment = comments.join("");
|
||||
|
||||
if (!tags) {
|
||||
tags = createNodeArray([tag], tag.pos);
|
||||
tags = [tag];
|
||||
tagsPos = tag.pos;
|
||||
}
|
||||
else {
|
||||
tags.push(tag);
|
||||
}
|
||||
tags.end = tag.end;
|
||||
tagsEnd = tag.end;
|
||||
}
|
||||
|
||||
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
||||
@@ -6666,19 +6649,18 @@ namespace ts {
|
||||
if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
|
||||
let child: JSDocTypeTag | JSDocPropertyTag | false;
|
||||
let jsdocTypeLiteral: JSDocTypeLiteral;
|
||||
let alreadyHasTypeTag = false;
|
||||
let childTypeTag: JSDocTypeTag;
|
||||
const start = scanner.getStartPos();
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Property))) {
|
||||
if (!jsdocTypeLiteral) {
|
||||
jsdocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, start);
|
||||
}
|
||||
if (child.kind === SyntaxKind.JSDocTypeTag) {
|
||||
if (alreadyHasTypeTag) {
|
||||
if (childTypeTag) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
jsdocTypeLiteral.jsDocTypeTag = child;
|
||||
alreadyHasTypeTag = true;
|
||||
childTypeTag = child;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -6692,7 +6674,9 @@ namespace ts {
|
||||
if (typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType) {
|
||||
jsdocTypeLiteral.isArrayType = true;
|
||||
}
|
||||
typedefTag.typeExpression = finishNode(jsdocTypeLiteral);
|
||||
typedefTag.typeExpression = childTypeTag && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
|
||||
childTypeTag.typeExpression :
|
||||
finishNode(jsdocTypeLiteral);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6799,7 +6783,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Type parameter list looks like '@template T,U,V'
|
||||
const typeParameters = createNodeArray<TypeParameterDeclaration>();
|
||||
const typeParameters = [];
|
||||
const typeParametersPos = getNodePos();
|
||||
|
||||
while (true) {
|
||||
const name = parseJSDocIdentifierName();
|
||||
@@ -6827,9 +6812,8 @@ namespace ts {
|
||||
const result = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.typeParameters = typeParameters;
|
||||
result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
|
||||
finishNode(result);
|
||||
typeParameters.end = result.end;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -6992,7 +6976,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
forEachChild(node, visitNode, visitArray);
|
||||
if (node.jsDoc) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
for (const jsDocComment of node.jsDoc) {
|
||||
forEachChild(jsDocComment, visitNode, visitArray);
|
||||
}
|
||||
|
||||
+93
-61
@@ -205,13 +205,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
|
||||
let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
program.getGlobalDiagnostics(cancellationToken),
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken));
|
||||
const diagnostics = [
|
||||
...program.getOptionsDiagnostics(cancellationToken),
|
||||
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
...program.getGlobalDiagnostics(cancellationToken),
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (program.getCompilerOptions().declaration) {
|
||||
diagnostics = diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
}
|
||||
|
||||
return sortAndDeduplicateDiagnostics(diagnostics);
|
||||
@@ -223,7 +225,7 @@ namespace ts {
|
||||
getNewLine(): string;
|
||||
}
|
||||
|
||||
export function formatDiagnostics(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string {
|
||||
export function formatDiagnostics(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string {
|
||||
let output = "";
|
||||
|
||||
for (const diagnostic of diagnostics) {
|
||||
@@ -243,7 +245,7 @@ namespace ts {
|
||||
const redForegroundEscapeSequence = "\u001b[91m";
|
||||
const yellowForegroundEscapeSequence = "\u001b[93m";
|
||||
const blueForegroundEscapeSequence = "\u001b[93m";
|
||||
const gutterStyleSequence = "\u001b[100;30m";
|
||||
const gutterStyleSequence = "\u001b[30;47m";
|
||||
const gutterSeparator = " ";
|
||||
const resetEscapeSequence = "\u001b[0m";
|
||||
const ellipsis = "...";
|
||||
@@ -266,7 +268,7 @@ namespace ts {
|
||||
return s;
|
||||
}
|
||||
|
||||
export function formatDiagnosticsWithColorAndContext(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string {
|
||||
export function formatDiagnosticsWithColorAndContext(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string {
|
||||
let output = "";
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (diagnostic.file) {
|
||||
@@ -282,12 +284,12 @@ namespace ts {
|
||||
gutterWidth = Math.max(ellipsis.length, gutterWidth);
|
||||
}
|
||||
|
||||
output += sys.newLine;
|
||||
output += host.getNewLine();
|
||||
for (let i = firstLine; i <= lastLine; i++) {
|
||||
// If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
|
||||
// so we'll skip ahead to the second-to-last line.
|
||||
if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
|
||||
output += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + sys.newLine;
|
||||
output += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
|
||||
i = lastLine - 1;
|
||||
}
|
||||
|
||||
@@ -299,7 +301,7 @@ namespace ts {
|
||||
|
||||
// Output the gutter and the actual contents of the line.
|
||||
output += formatAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
|
||||
output += lineContent + sys.newLine;
|
||||
output += lineContent + host.getNewLine();
|
||||
|
||||
// Output the gutter and the error span for the line using tildes.
|
||||
output += formatAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
|
||||
@@ -321,17 +323,17 @@ namespace ts {
|
||||
}
|
||||
output += resetEscapeSequence;
|
||||
|
||||
output += sys.newLine;
|
||||
output += host.getNewLine();
|
||||
}
|
||||
|
||||
output += sys.newLine;
|
||||
output += host.getNewLine();
|
||||
output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
|
||||
}
|
||||
|
||||
const categoryColor = getCategoryFormat(diagnostic.category);
|
||||
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||
output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }`;
|
||||
output += sys.newLine;
|
||||
output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }`;
|
||||
output += host.getNewLine();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -399,7 +401,7 @@ namespace ts {
|
||||
* @param oldProgram - Reuses an old program structure.
|
||||
* @returns A 'Program' object.
|
||||
*/
|
||||
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
|
||||
export function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
|
||||
let program: Program;
|
||||
let files: SourceFile[] = [];
|
||||
let commonSourceDirectory: string;
|
||||
@@ -436,6 +438,8 @@ namespace ts {
|
||||
host = host || createCompilerHost(options);
|
||||
|
||||
let skipDefaultLib = options.noLib;
|
||||
const getDefaultLibraryFileName = memoize(() => host.getDefaultLibFileName(options));
|
||||
const defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : getDirectoryPath(getDefaultLibraryFileName());
|
||||
const programDiagnostics = createDiagnosticCollection();
|
||||
const currentDirectory = host.getCurrentDirectory();
|
||||
const supportedExtensions = getSupportedExtensions(options);
|
||||
@@ -511,12 +515,11 @@ namespace ts {
|
||||
// If '--lib' is not specified, include default library file according to '--target'
|
||||
// otherwise, using options specified in '--lib' instead of '--target' default library file
|
||||
if (!options.lib) {
|
||||
processRootFile(host.getDefaultLibFileName(options), /*isDefaultLib*/ true);
|
||||
processRootFile(getDefaultLibraryFileName(), /*isDefaultLib*/ true);
|
||||
}
|
||||
else {
|
||||
const libDirectory = host.getDefaultLibLocation ? host.getDefaultLibLocation() : getDirectoryPath(host.getDefaultLibFileName(options));
|
||||
forEach(options.lib, libFileName => {
|
||||
processRootFile(combinePaths(libDirectory, libFileName), /*isDefaultLib*/ true);
|
||||
processRootFile(combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -555,6 +558,7 @@ namespace ts {
|
||||
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
|
||||
getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
|
||||
isSourceFileFromExternalLibrary,
|
||||
isSourceFileDefaultLibrary,
|
||||
dropDiagnosticsProducingTypeChecker,
|
||||
getSourceFileFromReference,
|
||||
sourceFileToPackageName,
|
||||
@@ -888,7 +892,7 @@ namespace ts {
|
||||
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
|
||||
const moduleNames = getModuleNames(newSourceFile);
|
||||
const oldProgramState = { program: oldProgram, file: oldSourceFile, modifiedFilePaths };
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState);
|
||||
// ensure that module resolution results are still correct
|
||||
@@ -975,6 +979,18 @@ namespace ts {
|
||||
return sourceFilesFoundSearchingNodeModules.get(file.path);
|
||||
}
|
||||
|
||||
function isSourceFileDefaultLibrary(file: SourceFile): boolean {
|
||||
if (file.hasNoDefaultLib) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (defaultLibraryPath && defaultLibraryPath.length !== 0) {
|
||||
return containsPath(defaultLibraryPath, file.path, currentDirectory, /*ignoreCase*/ !host.useCaseSensitiveFileNames());
|
||||
}
|
||||
|
||||
return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
|
||||
}
|
||||
|
||||
function getDiagnosticsProducingTypeChecker() {
|
||||
return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ true));
|
||||
}
|
||||
@@ -996,7 +1012,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
let declarationDiagnostics: Diagnostic[] = [];
|
||||
let declarationDiagnostics: ReadonlyArray<Diagnostic> = [];
|
||||
|
||||
if (options.noEmit) {
|
||||
return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
|
||||
@@ -1006,10 +1022,12 @@ namespace ts {
|
||||
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
|
||||
// get any preEmit diagnostics, not just the ones
|
||||
if (options.noEmitOnError) {
|
||||
const diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
program.getGlobalDiagnostics(cancellationToken),
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken));
|
||||
const diagnostics = [
|
||||
...program.getOptionsDiagnostics(cancellationToken),
|
||||
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
...program.getGlobalDiagnostics(cancellationToken),
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
|
||||
declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
|
||||
@@ -1060,8 +1078,8 @@ namespace ts {
|
||||
|
||||
function getDiagnosticsHelper(
|
||||
sourceFile: SourceFile,
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[],
|
||||
cancellationToken: CancellationToken): Diagnostic[] {
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => ReadonlyArray<Diagnostic>,
|
||||
cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
if (sourceFile) {
|
||||
return getDiagnostics(sourceFile, cancellationToken);
|
||||
}
|
||||
@@ -1073,15 +1091,15 @@ namespace ts {
|
||||
}));
|
||||
}
|
||||
|
||||
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
const options = program.getCompilerOptions();
|
||||
// collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
|
||||
if (!sourceFile || options.out || options.outFile) {
|
||||
@@ -1092,7 +1110,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): ReadonlyArray<Diagnostic> {
|
||||
// For JavaScript files, we report semantic errors for using TypeScript-only
|
||||
// constructs from within a JavaScript file as syntactic errors.
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
@@ -1204,7 +1222,7 @@ namespace ts {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
|
||||
return;
|
||||
}
|
||||
// falls through
|
||||
// falls through
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
@@ -1286,7 +1304,7 @@ namespace ts {
|
||||
diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
// falls through
|
||||
// falls through
|
||||
case SyntaxKind.VariableStatement:
|
||||
// Check modifiers
|
||||
if (nodes === (<ClassDeclaration | FunctionLikeDeclaration | VariableStatement>parent).modifiers) {
|
||||
@@ -1334,8 +1352,8 @@ namespace ts {
|
||||
if (isConstValid) {
|
||||
continue;
|
||||
}
|
||||
// to report error,
|
||||
// falls through
|
||||
// to report error,
|
||||
// falls through
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
@@ -1423,19 +1441,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function processRootFile(fileName: string, isDefaultLib: boolean) {
|
||||
processSourceFile(normalizePath(fileName), isDefaultLib);
|
||||
processSourceFile(normalizePath(fileName), isDefaultLib, /*packageId*/ undefined);
|
||||
}
|
||||
|
||||
function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean {
|
||||
return a.fileName === b.fileName;
|
||||
}
|
||||
|
||||
function moduleNameIsEqualTo(a: LiteralExpression, b: LiteralExpression): boolean {
|
||||
return a.text === b.text;
|
||||
}
|
||||
|
||||
function getTextOfLiteral(literal: LiteralExpression): string {
|
||||
return literal.text;
|
||||
function moduleNameIsEqualTo(a: StringLiteral | Identifier, b: StringLiteral | Identifier): boolean {
|
||||
return a.kind === SyntaxKind.StringLiteral
|
||||
? b.kind === SyntaxKind.StringLiteral && a.text === b.text
|
||||
: b.kind === SyntaxKind.Identifier && a.escapedText === b.escapedText;
|
||||
}
|
||||
|
||||
function collectExternalModuleReferences(file: SourceFile): void {
|
||||
@@ -1448,7 +1464,7 @@ namespace ts {
|
||||
|
||||
// file.imports may not be undefined if there exists dynamic import
|
||||
let imports: StringLiteral[];
|
||||
let moduleAugmentations: StringLiteral[];
|
||||
let moduleAugmentations: Array<StringLiteral | Identifier>;
|
||||
let ambientModules: string[];
|
||||
|
||||
// If we are importing helpers, we need to add a synthetic reference to resolve the
|
||||
@@ -1477,7 +1493,7 @@ namespace ts {
|
||||
|
||||
return;
|
||||
|
||||
function collectModuleReferences(node: Node, inAmbientModule: boolean): void {
|
||||
function collectModuleReferences(node: Statement, inAmbientModule: boolean): void {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
@@ -1499,8 +1515,8 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) {
|
||||
const moduleName = <StringLiteral>(<ModuleDeclaration>node).name; // TODO: GH#17347
|
||||
const nameText = ts.getTextOfIdentifierOrLiteral(moduleName);
|
||||
const moduleName = (<ModuleDeclaration>node).name;
|
||||
const nameText = getTextOfIdentifierOrLiteral(moduleName);
|
||||
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
|
||||
// This will happen in two cases:
|
||||
// - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
|
||||
@@ -1551,10 +1567,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getSourceFileFromReferenceWorker(
|
||||
fileName: string,
|
||||
getSourceFile: (fileName: string) => SourceFile | undefined,
|
||||
fail?: (diagnostic: DiagnosticMessage, ...argument: string[]) => void,
|
||||
refFile?: SourceFile): SourceFile | undefined {
|
||||
fileName: string,
|
||||
getSourceFile: (fileName: string) => SourceFile | undefined,
|
||||
fail?: (diagnostic: DiagnosticMessage, ...argument: string[]) => void,
|
||||
refFile?: SourceFile): SourceFile | undefined {
|
||||
|
||||
if (hasExtension(fileName)) {
|
||||
if (!options.allowNonTsExtensions && !forEach(supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
|
||||
@@ -1589,9 +1605,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** This has side effects through `findSourceFile`. */
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): void {
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, packageId: PackageId | undefined, refFile?: SourceFile, refPos?: number, refEnd?: number): void {
|
||||
getSourceFileFromReferenceWorker(fileName,
|
||||
fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, /*packageId*/ undefined),
|
||||
fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, packageId),
|
||||
(diagnostic, ...args) => {
|
||||
fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined
|
||||
? createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...args)
|
||||
@@ -1673,7 +1689,7 @@ namespace ts {
|
||||
});
|
||||
|
||||
if (packageId) {
|
||||
const packageIdKey = `${packageId.name}@${packageId.version}`;
|
||||
const packageIdKey = `${packageId.name}/${packageId.subModuleName}@${packageId.version}`;
|
||||
const fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
|
||||
if (fileFromPackageId) {
|
||||
// Some other SourceFile already exists with this package name and version.
|
||||
@@ -1733,7 +1749,7 @@ namespace ts {
|
||||
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
|
||||
processSourceFile(referencedFileName, isDefaultLib, file, ref.pos, ref.end);
|
||||
processSourceFile(referencedFileName, isDefaultLib, /*packageId*/ undefined, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1764,7 +1780,7 @@ namespace ts {
|
||||
if (resolvedTypeReferenceDirective) {
|
||||
if (resolvedTypeReferenceDirective.primary) {
|
||||
// resolved from the primary path
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
}
|
||||
else {
|
||||
// If we already resolved to this file, it must have been a secondary reference. Check file contents
|
||||
@@ -1787,7 +1803,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// First resolution of this library
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1817,8 +1833,7 @@ namespace ts {
|
||||
collectExternalModuleReferences(file);
|
||||
if (file.imports.length || file.moduleAugmentations.length) {
|
||||
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
|
||||
const nonGlobalAugmentation = filter(file.moduleAugmentations, (moduleAugmentation) => moduleAugmentation.kind === SyntaxKind.StringLiteral);
|
||||
const moduleNames = map(concatenate(file.imports, nonGlobalAugmentation), getTextOfLiteral);
|
||||
const moduleNames = getModuleNames(file);
|
||||
const oldProgramState = { program: oldProgram, file, modifiedFilePaths };
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
@@ -1831,7 +1846,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
const isFromNodeModulesSearch = resolution.isExternalLibraryImport;
|
||||
const isJsFileFromNodeModules = isFromNodeModulesSearch && !extensionIsTypeScript(resolution.extension);
|
||||
const isJsFile = !extensionIsTypeScript(resolution.extension);
|
||||
const isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile;
|
||||
const resolvedFileName = resolution.resolvedFileName;
|
||||
|
||||
if (isFromNodeModulesSearch) {
|
||||
@@ -1846,7 +1862,12 @@ namespace ts {
|
||||
const elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
|
||||
// Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
|
||||
// This may still end up being an untyped module -- the file won't be included but imports will be allowed.
|
||||
const shouldAddFile = resolvedFileName && !getResolutionDiagnostic(options, resolution) && !options.noResolve && i < file.imports.length && !elideImport;
|
||||
const shouldAddFile = resolvedFileName
|
||||
&& !getResolutionDiagnostic(options, resolution)
|
||||
&& !options.noResolve
|
||||
&& i < file.imports.length
|
||||
&& !elideImport
|
||||
&& !(isJsFile && !options.allowJs);
|
||||
|
||||
if (elideImport) {
|
||||
modulesWithElidedImports.set(file.path, true);
|
||||
@@ -2221,7 +2242,7 @@ namespace ts {
|
||||
return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
|
||||
}
|
||||
function needAllowJs() {
|
||||
return options.allowJs ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_allowJs_is_not_set;
|
||||
return options.allowJs || !options.noImplicitAny ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2229,4 +2250,15 @@ namespace ts {
|
||||
Debug.assert(names.every(name => name !== undefined), "A name is undefined.", () => JSON.stringify(names));
|
||||
return names;
|
||||
}
|
||||
|
||||
function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] {
|
||||
const res = imports.map(i => i.text);
|
||||
for (const aug of moduleAugmentations) {
|
||||
if (aug.kind === SyntaxKind.StringLiteral) {
|
||||
res.push(aug.text);
|
||||
}
|
||||
// Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,13 +337,13 @@ namespace ts {
|
||||
Debug.assert(res < lineStarts[line + 1]);
|
||||
}
|
||||
else if (debugText !== undefined) {
|
||||
Debug.assert(res < debugText.length);
|
||||
Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getLineStarts(sourceFile: SourceFileLike): number[] {
|
||||
export function getLineStarts(sourceFile: SourceFileLike): ReadonlyArray<number> {
|
||||
return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/** @internal */
|
||||
namespace ts {
|
||||
export function createGetSymbolWalker(
|
||||
getRestTypeOfSignature: (sig: Signature) => Type,
|
||||
getReturnTypeOfSignature: (sig: Signature) => Type,
|
||||
getBaseTypes: (type: Type) => Type[],
|
||||
resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType,
|
||||
getTypeOfSymbol: (sym: Symbol) => Type,
|
||||
getResolvedSymbol: (node: Node) => Symbol,
|
||||
getIndexTypeOfStructuredType: (type: Type, kind: IndexKind) => Type,
|
||||
getConstraintFromTypeParameter: (typeParameter: TypeParameter) => Type,
|
||||
getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier) {
|
||||
|
||||
return getSymbolWalker;
|
||||
|
||||
function getSymbolWalker(accept: (symbol: Symbol) => boolean = () => true): SymbolWalker {
|
||||
const visitedTypes = createMap<Type>(); // Key is id as string
|
||||
const visitedSymbols = createMap<Symbol>(); // Key is id as string
|
||||
|
||||
return {
|
||||
walkType: type => {
|
||||
visitedTypes.clear();
|
||||
visitedSymbols.clear();
|
||||
visitType(type);
|
||||
return { visitedTypes: arrayFrom(visitedTypes.values()), visitedSymbols: arrayFrom(visitedSymbols.values()) };
|
||||
},
|
||||
walkSymbol: symbol => {
|
||||
visitedTypes.clear();
|
||||
visitedSymbols.clear();
|
||||
visitSymbol(symbol);
|
||||
return { visitedTypes: arrayFrom(visitedTypes.values()), visitedSymbols: arrayFrom(visitedSymbols.values()) };
|
||||
},
|
||||
};
|
||||
|
||||
function visitType(type: Type): void {
|
||||
if (!type) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typeIdString = type.id.toString();
|
||||
if (visitedTypes.has(typeIdString)) {
|
||||
return;
|
||||
}
|
||||
visitedTypes.set(typeIdString, type);
|
||||
|
||||
// Reuse visitSymbol to visit the type's symbol,
|
||||
// but be sure to bail on recuring into the type if accept declines the symbol.
|
||||
const shouldBail = visitSymbol(type.symbol);
|
||||
if (shouldBail) return;
|
||||
|
||||
// Visit the type's related types, if any
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
const objectType = type as ObjectType;
|
||||
const objectFlags = objectType.objectFlags;
|
||||
if (objectFlags & ObjectFlags.Reference) {
|
||||
visitTypeReference(type as TypeReference);
|
||||
}
|
||||
if (objectFlags & ObjectFlags.Mapped) {
|
||||
visitMappedType(type as MappedType);
|
||||
}
|
||||
if (objectFlags & (ObjectFlags.Class | ObjectFlags.Interface)) {
|
||||
visitInterfaceType(type as InterfaceType);
|
||||
}
|
||||
if (objectFlags & (ObjectFlags.Tuple | ObjectFlags.Anonymous)) {
|
||||
visitObjectType(objectType);
|
||||
}
|
||||
}
|
||||
if (type.flags & TypeFlags.TypeParameter) {
|
||||
visitTypeParameter(type as TypeParameter);
|
||||
}
|
||||
if (type.flags & TypeFlags.UnionOrIntersection) {
|
||||
visitUnionOrIntersectionType(type as UnionOrIntersectionType);
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
visitIndexType(type as IndexType);
|
||||
}
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
visitIndexedAccessType(type as IndexedAccessType);
|
||||
}
|
||||
}
|
||||
|
||||
function visitTypeList(types: Type[]): void {
|
||||
if (!types) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
visitType(types[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function visitTypeReference(type: TypeReference): void {
|
||||
visitType(type.target);
|
||||
visitTypeList(type.typeArguments);
|
||||
}
|
||||
|
||||
function visitTypeParameter(type: TypeParameter): void {
|
||||
visitType(getConstraintFromTypeParameter(type));
|
||||
}
|
||||
|
||||
function visitUnionOrIntersectionType(type: UnionOrIntersectionType): void {
|
||||
visitTypeList(type.types);
|
||||
}
|
||||
|
||||
function visitIndexType(type: IndexType): void {
|
||||
visitType(type.type);
|
||||
}
|
||||
|
||||
function visitIndexedAccessType(type: IndexedAccessType): void {
|
||||
visitType(type.objectType);
|
||||
visitType(type.indexType);
|
||||
visitType(type.constraint);
|
||||
}
|
||||
|
||||
function visitMappedType(type: MappedType): void {
|
||||
visitType(type.typeParameter);
|
||||
visitType(type.constraintType);
|
||||
visitType(type.templateType);
|
||||
visitType(type.modifiersType);
|
||||
}
|
||||
|
||||
function visitSignature(signature: Signature): void {
|
||||
if (signature.typePredicate) {
|
||||
visitType(signature.typePredicate.type);
|
||||
}
|
||||
visitTypeList(signature.typeParameters);
|
||||
|
||||
for (const parameter of signature.parameters){
|
||||
visitSymbol(parameter);
|
||||
}
|
||||
visitType(getRestTypeOfSignature(signature));
|
||||
visitType(getReturnTypeOfSignature(signature));
|
||||
}
|
||||
|
||||
function visitInterfaceType(interfaceT: InterfaceType): void {
|
||||
visitObjectType(interfaceT);
|
||||
visitTypeList(interfaceT.typeParameters);
|
||||
visitTypeList(getBaseTypes(interfaceT));
|
||||
visitType(interfaceT.thisType);
|
||||
}
|
||||
|
||||
function visitObjectType(type: ObjectType): void {
|
||||
const stringIndexType = getIndexTypeOfStructuredType(type, IndexKind.String);
|
||||
visitType(stringIndexType);
|
||||
const numberIndexType = getIndexTypeOfStructuredType(type, IndexKind.Number);
|
||||
visitType(numberIndexType);
|
||||
|
||||
// The two checks above *should* have already resolved the type (if needed), so this should be cached
|
||||
const resolved = resolveStructuredTypeMembers(type);
|
||||
for (const signature of resolved.callSignatures) {
|
||||
visitSignature(signature);
|
||||
}
|
||||
for (const signature of resolved.constructSignatures) {
|
||||
visitSignature(signature);
|
||||
}
|
||||
for (const p of resolved.properties) {
|
||||
visitSymbol(p);
|
||||
}
|
||||
}
|
||||
|
||||
function visitSymbol(symbol: Symbol): boolean {
|
||||
if (!symbol) {
|
||||
return;
|
||||
}
|
||||
const symbolIdString = getSymbolId(symbol).toString();
|
||||
if (visitedSymbols.has(symbolIdString)) {
|
||||
return;
|
||||
}
|
||||
visitedSymbols.set(symbolIdString, symbol);
|
||||
if (!accept(symbol)) {
|
||||
return true;
|
||||
}
|
||||
const t = getTypeOfSymbol(symbol);
|
||||
visitType(t); // Should handle members on classes and such
|
||||
if (symbol.flags & SymbolFlags.HasExports) {
|
||||
symbol.exports.forEach(visitSymbol);
|
||||
}
|
||||
forEach(symbol.declarations, d => {
|
||||
// Type queries are too far resolved when we just visit the symbol's type
|
||||
// (their type resolved directly to the member deeply referenced)
|
||||
// So to get the intervening symbols, we need to check if there's a type
|
||||
// query node on any of the symbol's declarations and get symbols there
|
||||
if ((d as any).type && (d as any).type.kind === SyntaxKind.TypeQuery) {
|
||||
const query = (d as any).type as TypeQueryNode;
|
||||
const entity = getResolvedSymbol(getFirstIdentifier(query.exprName));
|
||||
visitSymbol(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ namespace ts {
|
||||
* @param transforms An array of `TransformerFactory` callbacks.
|
||||
* @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
|
||||
*/
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: T[], transformers: TransformerFactory<T>[], allowDtsFiles: boolean): TransformationResult<T> {
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: ReadonlyArray<T>, transformers: ReadonlyArray<TransformerFactory<T>>, allowDtsFiles: boolean): TransformationResult<T> {
|
||||
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
|
||||
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
|
||||
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];
|
||||
|
||||
@@ -409,7 +409,7 @@ namespace ts {
|
||||
*/
|
||||
function createDestructuringPropertyAccess(flattenContext: FlattenContext, value: Expression, propertyName: PropertyName): LeftHandSideExpression {
|
||||
if (isComputedPropertyName(propertyName)) {
|
||||
const argumentExpression = ensureIdentifier(flattenContext, propertyName.expression, /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
|
||||
const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
|
||||
return createElementAccess(value, argumentExpression);
|
||||
}
|
||||
else if (isStringOrNumericLiteral(propertyName)) {
|
||||
|
||||
@@ -339,64 +339,12 @@ namespace ts {
|
||||
&& !(<ReturnStatement>node).expression;
|
||||
}
|
||||
|
||||
function isClassLikeVariableStatement(node: Node) {
|
||||
if (!isVariableStatement(node)) return false;
|
||||
const variable = singleOrUndefined((<VariableStatement>node).declarationList.declarations);
|
||||
return variable
|
||||
&& variable.initializer
|
||||
&& isIdentifier(variable.name)
|
||||
&& (isClassLike(variable.initializer)
|
||||
|| (isAssignmentExpression(variable.initializer)
|
||||
&& isIdentifier(variable.initializer.left)
|
||||
&& isClassLike(variable.initializer.right)));
|
||||
}
|
||||
|
||||
function isTypeScriptClassWrapper(node: Node) {
|
||||
const call = tryCast(node, isCallExpression);
|
||||
if (!call || isParseTreeNode(call) ||
|
||||
some(call.typeArguments) ||
|
||||
some(call.arguments)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const func = tryCast(skipOuterExpressions(call.expression), isFunctionExpression);
|
||||
if (!func || isParseTreeNode(func) ||
|
||||
some(func.typeParameters) ||
|
||||
some(func.parameters) ||
|
||||
func.type ||
|
||||
!func.body) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const statements = func.body.statements;
|
||||
if (statements.length < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const firstStatement = statements[0];
|
||||
if (isParseTreeNode(firstStatement) ||
|
||||
!isClassLike(firstStatement) &&
|
||||
!isClassLikeVariableStatement(firstStatement)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const lastStatement = elementAt(statements, -1);
|
||||
const returnStatement = tryCast(isVariableStatement(lastStatement) ? elementAt(statements, -2) : lastStatement, isReturnStatement);
|
||||
if (!returnStatement ||
|
||||
!returnStatement.expression ||
|
||||
!isIdentifier(skipOuterExpressions(returnStatement.expression))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function shouldVisitNode(node: Node): boolean {
|
||||
return (node.transformFlags & TransformFlags.ContainsES2015) !== 0
|
||||
|| convertedLoopState !== undefined
|
||||
|| (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && (isStatement(node) || (node.kind === SyntaxKind.Block)))
|
||||
|| (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
|
||||
|| isTypeScriptClassWrapper(node);
|
||||
|| (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0;
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
@@ -3308,13 +3256,14 @@ namespace ts {
|
||||
* @param node a CallExpression.
|
||||
*/
|
||||
function visitCallExpression(node: CallExpression) {
|
||||
if (isTypeScriptClassWrapper(node)) {
|
||||
if (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) {
|
||||
return visitTypeScriptClassWrapper(node);
|
||||
}
|
||||
|
||||
if (node.transformFlags & TransformFlags.ES2015) {
|
||||
return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true);
|
||||
}
|
||||
|
||||
return updateCall(
|
||||
node,
|
||||
visitNode(node.expression, callExpressionVisitor, isExpression),
|
||||
@@ -3357,7 +3306,7 @@ namespace ts {
|
||||
|
||||
// We skip any outer expressions in a number of places to get to the innermost
|
||||
// expression, but we will restore them later to preserve comments and source maps.
|
||||
const body = cast(skipOuterExpressions(node.expression), isFunctionExpression).body;
|
||||
const body = cast(cast(skipOuterExpressions(node.expression), isArrowFunction).body, isBlock);
|
||||
|
||||
// The class statements are the statements generated by visiting the first statement of the
|
||||
// body (1), while all other statements are added to remainingStatements (2)
|
||||
|
||||
@@ -21,9 +21,6 @@ namespace ts {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
|
||||
// These variables contain state that changes as we descend into the tree.
|
||||
let currentSourceFile: SourceFile;
|
||||
|
||||
/**
|
||||
* Keeps track of whether expression substitution has been enabled for specific edge cases.
|
||||
* They are persisted between each SourceFile transformation and should not be reset.
|
||||
@@ -51,12 +48,8 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
currentSourceFile = node;
|
||||
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
return visited;
|
||||
}
|
||||
|
||||
@@ -197,9 +190,10 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
node.equalsGreaterThanToken,
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
: visitFunctionBody(node.body, visitor, context),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,8 +158,8 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function chunkObjectLiteralElements(elements: ReadonlyArray<ObjectLiteralElement>): Expression[] {
|
||||
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
|
||||
function chunkObjectLiteralElements(elements: ReadonlyArray<ObjectLiteralElementLike>): Expression[] {
|
||||
let chunkObject: ObjectLiteralElementLike[];
|
||||
const objects: Expression[] = [];
|
||||
for (const e of elements) {
|
||||
if (e.kind === SyntaxKind.SpreadAssignment) {
|
||||
@@ -179,7 +179,7 @@ namespace ts {
|
||||
chunkObject.push(createPropertyAssignment(p.name, visitNode(p.initializer, visitor, isExpression)));
|
||||
}
|
||||
else {
|
||||
chunkObject.push(e as ShorthandPropertyAssignment);
|
||||
chunkObject.push(visitNode(e, visitor, isObjectLiteralElementLike));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -595,7 +595,8 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
node.equalsGreaterThanToken,
|
||||
transformFunctionBody(node),
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
|
||||
@@ -244,7 +244,6 @@ namespace ts {
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
let renamedCatchVariables: Map<boolean>;
|
||||
let renamedCatchVariableDeclarations: Identifier[];
|
||||
|
||||
@@ -300,12 +299,9 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
currentSourceFile = node;
|
||||
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
return visited;
|
||||
}
|
||||
|
||||
@@ -1639,8 +1635,13 @@ namespace ts {
|
||||
|
||||
function transformAndEmitContinueStatement(node: ContinueStatement): void {
|
||||
const label = findContinueTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined);
|
||||
Debug.assert(label > 0, "Expected continue statment to point to a valid Label.");
|
||||
emitBreak(label, /*location*/ node);
|
||||
if (label > 0) {
|
||||
emitBreak(label, /*location*/ node);
|
||||
}
|
||||
else {
|
||||
// invalid continue without a containing loop. Leave the node as is, per #17875.
|
||||
emitStatement(node);
|
||||
}
|
||||
}
|
||||
|
||||
function visitContinueStatement(node: ContinueStatement): Statement {
|
||||
@@ -1656,8 +1657,13 @@ namespace ts {
|
||||
|
||||
function transformAndEmitBreakStatement(node: BreakStatement): void {
|
||||
const label = findBreakTarget(node.label ? unescapeLeadingUnderscores(node.label.escapedText) : undefined);
|
||||
Debug.assert(label > 0, "Expected break statment to point to a valid Label.");
|
||||
emitBreak(label, /*location*/ node);
|
||||
if (label > 0) {
|
||||
emitBreak(label, /*location*/ node);
|
||||
}
|
||||
else {
|
||||
// invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875.
|
||||
emitStatement(node);
|
||||
}
|
||||
}
|
||||
|
||||
function visitBreakStatement(node: BreakStatement): Statement {
|
||||
@@ -2351,27 +2357,27 @@ namespace ts {
|
||||
* @param labelText An optional name of a containing labeled statement.
|
||||
*/
|
||||
function findBreakTarget(labelText?: string): Label {
|
||||
Debug.assert(blocks !== undefined);
|
||||
if (labelText) {
|
||||
for (let i = blockStack.length - 1; i >= 0; i--) {
|
||||
const block = blockStack[i];
|
||||
if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
|
||||
return block.breakLabel;
|
||||
if (blockStack) {
|
||||
if (labelText) {
|
||||
for (let i = blockStack.length - 1; i >= 0; i--) {
|
||||
const block = blockStack[i];
|
||||
if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
|
||||
return block.breakLabel;
|
||||
}
|
||||
else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
|
||||
return block.breakLabel;
|
||||
}
|
||||
}
|
||||
else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
|
||||
return block.breakLabel;
|
||||
}
|
||||
else {
|
||||
for (let i = blockStack.length - 1; i >= 0; i--) {
|
||||
const block = blockStack[i];
|
||||
if (supportsUnlabeledBreak(block)) {
|
||||
return block.breakLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = blockStack.length - 1; i >= 0; i--) {
|
||||
const block = blockStack[i];
|
||||
if (supportsUnlabeledBreak(block)) {
|
||||
return block.breakLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2381,24 +2387,24 @@ namespace ts {
|
||||
* @param labelText An optional name of a containing labeled statement.
|
||||
*/
|
||||
function findContinueTarget(labelText?: string): Label {
|
||||
Debug.assert(blocks !== undefined);
|
||||
if (labelText) {
|
||||
for (let i = blockStack.length - 1; i >= 0; i--) {
|
||||
const block = blockStack[i];
|
||||
if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
|
||||
return block.continueLabel;
|
||||
if (blockStack) {
|
||||
if (labelText) {
|
||||
for (let i = blockStack.length - 1; i >= 0; i--) {
|
||||
const block = blockStack[i];
|
||||
if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
|
||||
return block.continueLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = blockStack.length - 1; i >= 0; i--) {
|
||||
const block = blockStack[i];
|
||||
if (supportsUnlabeledContinue(block)) {
|
||||
return block.continueLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = blockStack.length - 1; i >= 0; i--) {
|
||||
const block = blockStack[i];
|
||||
if (supportsUnlabeledContinue(block)) {
|
||||
return block.continueLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,7 @@ namespace ts {
|
||||
*/
|
||||
function transformUMDModule(node: SourceFile) {
|
||||
const { aliasedModuleNames, unaliasedModuleNames, importAliasNames } = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ false);
|
||||
const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions);
|
||||
const umdHeader = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
@@ -260,6 +261,8 @@ namespace ts {
|
||||
createIdentifier("define"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
// Add the module name (if provided).
|
||||
...(moduleName ? [moduleName] : []),
|
||||
createArrayLiteral([
|
||||
createLiteral("require"),
|
||||
createLiteral("exports"),
|
||||
@@ -430,26 +433,29 @@ namespace ts {
|
||||
*/
|
||||
function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
|
||||
if (currentModuleInfo.exportEquals) {
|
||||
if (emitAsReturn) {
|
||||
const statement = createReturn(currentModuleInfo.exportEquals.expression);
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
}
|
||||
else {
|
||||
const statement = createStatement(
|
||||
createAssignment(
|
||||
createPropertyAccess(
|
||||
createIdentifier("module"),
|
||||
"exports"
|
||||
),
|
||||
currentModuleInfo.exportEquals.expression
|
||||
)
|
||||
);
|
||||
const expressionResult = visitNode(currentModuleInfo.exportEquals.expression, importCallExpressionVisitor);
|
||||
if (expressionResult) {
|
||||
if (emitAsReturn) {
|
||||
const statement = createReturn(expressionResult);
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
}
|
||||
else {
|
||||
const statement = createStatement(
|
||||
createAssignment(
|
||||
createPropertyAccess(
|
||||
createIdentifier("module"),
|
||||
"exports"
|
||||
),
|
||||
expressionResult
|
||||
)
|
||||
);
|
||||
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -497,7 +503,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function importCallExpressionVisitor(node: Node): VisitResult<Node> {
|
||||
function importCallExpressionVisitor(node: Expression): VisitResult<Expression> {
|
||||
// This visitor does not need to descend into the tree if there is no dynamic import,
|
||||
// as export/import statements are only transformed at the top level of a file.
|
||||
if (!(node.transformFlags & TransformFlags.ContainsDynamicImport)) {
|
||||
@@ -1204,7 +1210,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (hasModifier(decl, ModifierFlags.Export)) {
|
||||
const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : decl.name;
|
||||
const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : getDeclarationName(decl);
|
||||
statements = appendExportStatement(statements, exportName, getLocalName(decl), /*location*/ decl);
|
||||
}
|
||||
|
||||
|
||||
@@ -1132,7 +1132,8 @@ namespace ts {
|
||||
*/
|
||||
function createExportExpression(name: Identifier | StringLiteral, value: Expression) {
|
||||
const exportName = isIdentifier(name) ? createLiteral(name) : name;
|
||||
return createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]);
|
||||
setEmitFlags(value, getEmitFlags(value) | EmitFlags.NoComments);
|
||||
return setCommentRange(createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -151,7 +151,17 @@ namespace ts {
|
||||
break;
|
||||
}
|
||||
|
||||
recordEmittedDeclarationInScope(node);
|
||||
// Record these declarations provided that they have a name.
|
||||
if ((node as ClassDeclaration | FunctionDeclaration).name) {
|
||||
recordEmittedDeclarationInScope(node as ClassDeclaration | FunctionDeclaration);
|
||||
}
|
||||
else {
|
||||
// These nodes should always have names unless they are default-exports;
|
||||
// however, class declaration parsing allows for undefined names, so syntactically invalid
|
||||
// programs may also have an undefined name.
|
||||
Debug.assert(node.kind === SyntaxKind.ClassDeclaration || hasModifier(node, ModifierFlags.Default));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -198,6 +208,24 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function sourceElementVisitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return visitEllidableStatement(<ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration>node);
|
||||
default:
|
||||
return visitorWorker(node);
|
||||
}
|
||||
}
|
||||
|
||||
function visitEllidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult<Node> {
|
||||
const parsed = getParseTreeNode(node);
|
||||
if (parsed !== node) {
|
||||
// If the node has been transformed by a `before` transformer, perform no ellision on it
|
||||
// As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
|
||||
return node;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return visitImportDeclaration(<ImportDeclaration>node);
|
||||
@@ -208,7 +236,7 @@ namespace ts {
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return visitExportDeclaration(<ExportDeclaration>node);
|
||||
default:
|
||||
return visitorWorker(node);
|
||||
Debug.fail("Unhandled ellided statement");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,7 +521,7 @@ namespace ts {
|
||||
|
||||
function visitSourceFile(node: SourceFile) {
|
||||
const alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) &&
|
||||
!(isExternalModule(node) && moduleKind === ModuleKind.ES2015);
|
||||
!(isExternalModule(node) && moduleKind >= ModuleKind.ES2015);
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
|
||||
@@ -603,13 +631,16 @@ namespace ts {
|
||||
|
||||
addRange(statements, context.endLexicalEnvironment());
|
||||
|
||||
const iife = createImmediatelyInvokedArrowFunction(statements);
|
||||
setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper);
|
||||
|
||||
const varStatement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false),
|
||||
/*type*/ undefined,
|
||||
createImmediatelyInvokedFunctionExpression(statements)
|
||||
iife
|
||||
)
|
||||
])
|
||||
);
|
||||
@@ -1934,7 +1965,7 @@ namespace ts {
|
||||
const name = getMutableClone(<Identifier>node);
|
||||
name.flags &= ~NodeFlags.Synthesized;
|
||||
name.original = undefined;
|
||||
name.parent = currentScope;
|
||||
name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
|
||||
if (useFallback) {
|
||||
return createLogicalAnd(
|
||||
createStrictInequality(
|
||||
@@ -2278,7 +2309,8 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
node.equalsGreaterThanToken,
|
||||
visitFunctionBody(node.body, visitor, context),
|
||||
);
|
||||
return updated;
|
||||
}
|
||||
@@ -2633,42 +2665,40 @@ namespace ts {
|
||||
return isExportOfNamespace(node)
|
||||
|| (isExternalModuleExport(node)
|
||||
&& moduleKind !== ModuleKind.ES2015
|
||||
&& moduleKind !== ModuleKind.ESNext
|
||||
&& moduleKind !== ModuleKind.System);
|
||||
}
|
||||
|
||||
/**
|
||||
* Records that a declaration was emitted in the current scope, if it was the first
|
||||
* declaration for the provided symbol.
|
||||
*
|
||||
* NOTE: if there is ever a transformation above this one, we may not be able to rely
|
||||
* on symbol names.
|
||||
*/
|
||||
function recordEmittedDeclarationInScope(node: Node) {
|
||||
const name = node.symbol && node.symbol.escapedName;
|
||||
if (name) {
|
||||
if (!currentScopeFirstDeclarationsOfName) {
|
||||
currentScopeFirstDeclarationsOfName = createUnderscoreEscapedMap<Node>();
|
||||
}
|
||||
function recordEmittedDeclarationInScope(node: FunctionDeclaration | ClassDeclaration | ModuleDeclaration | EnumDeclaration) {
|
||||
if (!currentScopeFirstDeclarationsOfName) {
|
||||
currentScopeFirstDeclarationsOfName = createUnderscoreEscapedMap<Node>();
|
||||
}
|
||||
|
||||
if (!currentScopeFirstDeclarationsOfName.has(name)) {
|
||||
currentScopeFirstDeclarationsOfName.set(name, node);
|
||||
}
|
||||
const name = declaredNameInScope(node);
|
||||
if (!currentScopeFirstDeclarationsOfName.has(name)) {
|
||||
currentScopeFirstDeclarationsOfName.set(name, node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a declaration is the first declaration with the same name emitted
|
||||
* in the current scope.
|
||||
* Determines whether a declaration is the first declaration with
|
||||
* the same name emitted in the current scope.
|
||||
*/
|
||||
function isFirstEmittedDeclarationInScope(node: Node) {
|
||||
function isFirstEmittedDeclarationInScope(node: ModuleDeclaration | EnumDeclaration) {
|
||||
if (currentScopeFirstDeclarationsOfName) {
|
||||
const name = node.symbol && node.symbol.escapedName;
|
||||
if (name) {
|
||||
return currentScopeFirstDeclarationsOfName.get(name) === node;
|
||||
}
|
||||
const name = declaredNameInScope(node);
|
||||
return currentScopeFirstDeclarationsOfName.get(name) === node;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
function declaredNameInScope(node: FunctionDeclaration | ClassDeclaration | ModuleDeclaration | EnumDeclaration): __String {
|
||||
Debug.assertNode(node.name, isIdentifier);
|
||||
return (node.name as Identifier).escapedText;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2746,7 +2776,7 @@ namespace ts {
|
||||
return createNotEmittedStatement(node);
|
||||
}
|
||||
|
||||
Debug.assert(isIdentifier(node.name), "TypeScript module should have an Identifier name.");
|
||||
Debug.assertNode(node.name, isIdentifier, "A TypeScript namespace should have an Identifier name.");
|
||||
enableSubstitutionForNamespaceExports();
|
||||
|
||||
const statements: Statement[] = [];
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace ts {
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
|
||||
if (name && !uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
|
||||
+4
-5
@@ -100,7 +100,6 @@ namespace ts {
|
||||
const commandLine = parseCommandLine(args);
|
||||
let configFileName: string; // Configuration file name (if any)
|
||||
let cachedConfigFileText: string; // Cached configuration file text, used for reparsing (if any)
|
||||
let configFileWatcher: FileWatcher; // Configuration file watcher
|
||||
let directoryWatcher: FileWatcher; // Directory watcher to monitor source file addition/removal
|
||||
let cachedProgram: Program; // Program cached from last compilation
|
||||
let rootFileNames: string[]; // Root fileNames for compilation
|
||||
@@ -189,7 +188,7 @@ namespace ts {
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
if (configFileName) {
|
||||
configFileWatcher = sys.watchFile(configFileName, configFileChanged);
|
||||
sys.watchFile(configFileName, configFileChanged);
|
||||
}
|
||||
if (sys.watchDirectory && configFileName) {
|
||||
const directory = ts.getDirectoryPath(configFileName);
|
||||
@@ -469,7 +468,7 @@ namespace ts {
|
||||
let diagnostics: Diagnostic[];
|
||||
|
||||
// First get and report any syntactic errors.
|
||||
diagnostics = program.getSyntacticDiagnostics();
|
||||
diagnostics = program.getSyntacticDiagnostics().slice();
|
||||
|
||||
// If we didn't have any syntactic errors, then also try getting the global and
|
||||
// semantic errors.
|
||||
@@ -477,13 +476,13 @@ namespace ts {
|
||||
diagnostics = program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
|
||||
|
||||
if (diagnostics.length === 0) {
|
||||
diagnostics = program.getSemanticDiagnostics();
|
||||
diagnostics = program.getSemanticDiagnostics().slice();
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, emit and report any errors we ran into.
|
||||
const emitOutput = program.emit();
|
||||
diagnostics = diagnostics.concat(emitOutput.diagnostics);
|
||||
addRange(diagnostics, emitOutput.diagnostics);
|
||||
|
||||
reportDiagnostics(sortAndDeduplicateDiagnostics(diagnostics), compilerHost);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"parser.ts",
|
||||
"utilities.ts",
|
||||
"binder.ts",
|
||||
"symbolWalker.ts",
|
||||
"checker.ts",
|
||||
"factory.ts",
|
||||
"visitor.ts",
|
||||
|
||||
+163
-84
@@ -516,8 +516,6 @@ namespace ts {
|
||||
parent?: Node; // Parent node (initialized by binding)
|
||||
/* @internal */ original?: Node; // The original node if this is an updated node.
|
||||
/* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms).
|
||||
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
|
||||
/* @internal */ jsDocCache?: ReadonlyArray<JSDocTag>; // Cache for getJSDocTags
|
||||
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
|
||||
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
||||
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
|
||||
@@ -528,6 +526,44 @@ namespace ts {
|
||||
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
|
||||
}
|
||||
|
||||
export interface JSDocContainer {
|
||||
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
|
||||
/* @internal */ jsDocCache?: ReadonlyArray<JSDocTag>; // Cache for getJSDocTags
|
||||
}
|
||||
|
||||
export type HasJSDoc =
|
||||
| ParameterDeclaration
|
||||
| CallSignatureDeclaration
|
||||
| ConstructSignatureDeclaration
|
||||
| MethodSignature
|
||||
| PropertySignature
|
||||
| ArrowFunction
|
||||
| ParenthesizedExpression
|
||||
| SpreadAssignment
|
||||
| ShorthandPropertyAssignment
|
||||
| PropertyAssignment
|
||||
| FunctionExpression
|
||||
| LabeledStatement
|
||||
| ExpressionStatement
|
||||
| VariableStatement
|
||||
| FunctionDeclaration
|
||||
| ConstructorDeclaration
|
||||
| MethodDeclaration
|
||||
| PropertyDeclaration
|
||||
| AccessorDeclaration
|
||||
| ClassLikeDeclaration
|
||||
| InterfaceDeclaration
|
||||
| TypeAliasDeclaration
|
||||
| EnumMember
|
||||
| EnumDeclaration
|
||||
| ModuleDeclaration
|
||||
| ImportEqualsDeclaration
|
||||
| IndexSignatureDeclaration
|
||||
| FunctionTypeNode
|
||||
| ConstructorTypeNode
|
||||
| JSDocFunctionType
|
||||
| EndOfFileToken;
|
||||
|
||||
/* @internal */
|
||||
export type MutableNodeArray<T extends Node> = NodeArray<T> & T[];
|
||||
|
||||
@@ -546,7 +582,7 @@ namespace ts {
|
||||
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
export type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
|
||||
export type EqualsGreaterThanToken = Token<SyntaxKind.EqualsGreaterThanToken>;
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken>;
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken> & JSDocContainer;
|
||||
export type AtToken = Token<SyntaxKind.AtToken>;
|
||||
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
|
||||
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
|
||||
@@ -636,6 +672,7 @@ namespace ts {
|
||||
|
||||
export interface Decorator extends Node {
|
||||
kind: SyntaxKind.Decorator;
|
||||
parent?: NamedDeclaration;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
|
||||
@@ -650,18 +687,34 @@ namespace ts {
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
export interface SignatureDeclaration extends NamedDeclaration {
|
||||
export interface SignatureDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SignatureDeclaration["kind"];
|
||||
name?: PropertyName;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
parameters: NodeArray<ParameterDeclaration>;
|
||||
type?: TypeNode;
|
||||
type: TypeNode | undefined;
|
||||
}
|
||||
|
||||
export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement {
|
||||
export type SignatureDeclaration =
|
||||
| CallSignatureDeclaration
|
||||
| ConstructSignatureDeclaration
|
||||
| MethodSignature
|
||||
| IndexSignatureDeclaration
|
||||
| FunctionTypeNode
|
||||
| ConstructorTypeNode
|
||||
| JSDocFunctionType
|
||||
| FunctionDeclaration
|
||||
| MethodDeclaration
|
||||
| ConstructorDeclaration
|
||||
| AccessorDeclaration
|
||||
| FunctionExpression
|
||||
| ArrowFunction;
|
||||
|
||||
export interface CallSignatureDeclaration extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.CallSignature;
|
||||
}
|
||||
|
||||
export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement {
|
||||
export interface ConstructSignatureDeclaration extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.ConstructSignature;
|
||||
}
|
||||
|
||||
@@ -681,7 +734,7 @@ namespace ts {
|
||||
declarations: NodeArray<VariableDeclaration>;
|
||||
}
|
||||
|
||||
export interface ParameterDeclaration extends NamedDeclaration {
|
||||
export interface ParameterDeclaration extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.Parameter;
|
||||
parent?: SignatureDeclaration;
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
|
||||
@@ -700,7 +753,7 @@ namespace ts {
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
export interface PropertySignature extends TypeElement {
|
||||
export interface PropertySignature extends TypeElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertySignature;
|
||||
name: PropertyName; // Declared property name
|
||||
questionToken?: QuestionToken; // Present on optional property
|
||||
@@ -708,7 +761,7 @@ namespace ts {
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
export interface PropertyDeclaration extends ClassElement {
|
||||
export interface PropertyDeclaration extends ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertyDeclaration;
|
||||
questionToken?: QuestionToken; // Present for use with reporting a grammar error
|
||||
name: PropertyName;
|
||||
@@ -729,14 +782,16 @@ namespace ts {
|
||||
| AccessorDeclaration
|
||||
;
|
||||
|
||||
export interface PropertyAssignment extends ObjectLiteralElement {
|
||||
export interface PropertyAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.PropertyAssignment;
|
||||
name: PropertyName;
|
||||
questionToken?: QuestionToken;
|
||||
initializer: Expression;
|
||||
}
|
||||
|
||||
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
|
||||
export interface ShorthandPropertyAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
questionToken?: QuestionToken;
|
||||
@@ -746,7 +801,8 @@ namespace ts {
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
|
||||
export interface SpreadAssignment extends ObjectLiteralElement {
|
||||
export interface SpreadAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.SpreadAssignment;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -764,7 +820,7 @@ namespace ts {
|
||||
export interface VariableLikeDeclaration extends NamedDeclaration {
|
||||
propertyName?: PropertyName;
|
||||
dotDotDotToken?: DotDotDotToken;
|
||||
name?: DeclarationName; // May be missing for ParameterDeclaration, see comment there
|
||||
name: DeclarationName;
|
||||
questionToken?: QuestionToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
@@ -798,7 +854,7 @@ namespace ts {
|
||||
* - MethodDeclaration
|
||||
* - AccessorDeclaration
|
||||
*/
|
||||
export interface FunctionLikeDeclarationBase extends SignatureDeclaration {
|
||||
export interface FunctionLikeDeclarationBase extends SignatureDeclarationBase {
|
||||
_functionLikeDeclarationBrand: any;
|
||||
|
||||
asteriskToken?: AsteriskToken;
|
||||
@@ -829,7 +885,7 @@ namespace ts {
|
||||
body?: FunctionBody;
|
||||
}
|
||||
|
||||
export interface MethodSignature extends SignatureDeclaration, TypeElement {
|
||||
export interface MethodSignature extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.MethodSignature;
|
||||
name: PropertyName;
|
||||
}
|
||||
@@ -843,13 +899,13 @@ namespace ts {
|
||||
// Because of this, it may be necessary to determine what sort of MethodDeclaration you have
|
||||
// at later stages of the compiler pipeline. In that case, you can either check the parent kind
|
||||
// of the method, or use helpers like isObjectLiteralMethodDeclaration
|
||||
export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.MethodDeclaration;
|
||||
name: PropertyName;
|
||||
body?: FunctionBody;
|
||||
}
|
||||
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement {
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.Constructor;
|
||||
parent?: ClassDeclaration | ClassExpression;
|
||||
body?: FunctionBody;
|
||||
@@ -863,7 +919,7 @@ namespace ts {
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.GetAccessor;
|
||||
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
@@ -872,7 +928,7 @@ namespace ts {
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind SetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.SetAccessor;
|
||||
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
@@ -881,7 +937,7 @@ namespace ts {
|
||||
|
||||
export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration;
|
||||
|
||||
export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
|
||||
export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement {
|
||||
kind: SyntaxKind.IndexSignature;
|
||||
parent?: ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode;
|
||||
}
|
||||
@@ -910,11 +966,11 @@ namespace ts {
|
||||
|
||||
export type FunctionOrConstructorTypeNode = FunctionTypeNode | ConstructorTypeNode;
|
||||
|
||||
export interface FunctionTypeNode extends TypeNode, SignatureDeclaration {
|
||||
export interface FunctionTypeNode extends TypeNode, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.FunctionType;
|
||||
}
|
||||
|
||||
export interface ConstructorTypeNode extends TypeNode, SignatureDeclaration {
|
||||
export interface ConstructorTypeNode extends TypeNode, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.ConstructorType;
|
||||
}
|
||||
|
||||
@@ -928,6 +984,7 @@ namespace ts {
|
||||
|
||||
export interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent?: SignatureDeclaration;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
}
|
||||
@@ -984,7 +1041,6 @@ namespace ts {
|
||||
|
||||
export interface MappedTypeNode extends TypeNode, Declaration {
|
||||
kind: SyntaxKind.MappedType;
|
||||
parent?: TypeAliasDeclaration;
|
||||
readonlyToken?: ReadonlyToken;
|
||||
typeParameter: TypeParameterDeclaration;
|
||||
questionToken?: QuestionToken;
|
||||
@@ -993,7 +1049,7 @@ namespace ts {
|
||||
|
||||
export interface LiteralTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.LiteralType;
|
||||
literal: Expression;
|
||||
literal: BooleanLiteral | LiteralExpression | PrefixUnaryExpression;
|
||||
}
|
||||
|
||||
export interface StringLiteral extends LiteralExpression {
|
||||
@@ -1337,13 +1393,13 @@ namespace ts {
|
||||
export type FunctionBody = Block;
|
||||
export type ConciseBody = FunctionBody | Expression;
|
||||
|
||||
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase {
|
||||
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer {
|
||||
kind: SyntaxKind.FunctionExpression;
|
||||
name?: Identifier;
|
||||
body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional
|
||||
}
|
||||
|
||||
export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase {
|
||||
export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase, JSDocContainer {
|
||||
kind: SyntaxKind.ArrowFunction;
|
||||
equalsGreaterThanToken: EqualsGreaterThanToken;
|
||||
body: ConciseBody;
|
||||
@@ -1422,7 +1478,7 @@ namespace ts {
|
||||
literal: TemplateMiddle | TemplateTail;
|
||||
}
|
||||
|
||||
export interface ParenthesizedExpression extends PrimaryExpression {
|
||||
export interface ParenthesizedExpression extends PrimaryExpression, JSDocContainer {
|
||||
kind: SyntaxKind.ParenthesizedExpression;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1436,6 +1492,7 @@ namespace ts {
|
||||
|
||||
export interface SpreadElement extends Expression {
|
||||
kind: SyntaxKind.SpreadElement;
|
||||
parent?: ArrayLiteralExpression | CallExpression | NewExpression;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
@@ -1677,12 +1734,12 @@ namespace ts {
|
||||
/*@internal*/ multiLine?: boolean;
|
||||
}
|
||||
|
||||
export interface VariableStatement extends Statement {
|
||||
export interface VariableStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.VariableStatement;
|
||||
declarationList: VariableDeclarationList;
|
||||
}
|
||||
|
||||
export interface ExpressionStatement extends Statement {
|
||||
export interface ExpressionStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.ExpressionStatement;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1788,7 +1845,7 @@ namespace ts {
|
||||
|
||||
export type CaseOrDefaultClause = CaseClause | DefaultClause;
|
||||
|
||||
export interface LabeledStatement extends Statement {
|
||||
export interface LabeledStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.LabeledStatement;
|
||||
label: Identifier;
|
||||
statement: Statement;
|
||||
@@ -1815,22 +1872,25 @@ namespace ts {
|
||||
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
|
||||
export interface ClassLikeDeclaration extends NamedDeclaration {
|
||||
export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression;
|
||||
name?: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
heritageClauses?: NodeArray<HeritageClause>;
|
||||
members: NodeArray<ClassElement>;
|
||||
}
|
||||
|
||||
export interface ClassDeclaration extends ClassLikeDeclaration, DeclarationStatement {
|
||||
export interface ClassDeclaration extends ClassLikeDeclarationBase, DeclarationStatement {
|
||||
kind: SyntaxKind.ClassDeclaration;
|
||||
name?: Identifier;
|
||||
}
|
||||
|
||||
export interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression {
|
||||
export interface ClassExpression extends ClassLikeDeclarationBase, PrimaryExpression {
|
||||
kind: SyntaxKind.ClassExpression;
|
||||
}
|
||||
|
||||
export type ClassLikeDeclaration = ClassDeclaration | ClassExpression;
|
||||
|
||||
export interface ClassElement extends NamedDeclaration {
|
||||
_classElementBrand: any;
|
||||
name?: PropertyName;
|
||||
@@ -1842,7 +1902,7 @@ namespace ts {
|
||||
questionToken?: QuestionToken;
|
||||
}
|
||||
|
||||
export interface InterfaceDeclaration extends DeclarationStatement {
|
||||
export interface InterfaceDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.InterfaceDeclaration;
|
||||
name: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
@@ -1857,14 +1917,14 @@ namespace ts {
|
||||
types: NodeArray<ExpressionWithTypeArguments>;
|
||||
}
|
||||
|
||||
export interface TypeAliasDeclaration extends DeclarationStatement {
|
||||
export interface TypeAliasDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.TypeAliasDeclaration;
|
||||
name: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface EnumMember extends NamedDeclaration {
|
||||
export interface EnumMember extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.EnumMember;
|
||||
parent?: EnumDeclaration;
|
||||
// This does include ComputedPropertyName, but the parser will give an error
|
||||
@@ -1873,7 +1933,7 @@ namespace ts {
|
||||
initializer?: Expression;
|
||||
}
|
||||
|
||||
export interface EnumDeclaration extends DeclarationStatement {
|
||||
export interface EnumDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.EnumDeclaration;
|
||||
name: Identifier;
|
||||
members: NodeArray<EnumMember>;
|
||||
@@ -1883,7 +1943,7 @@ namespace ts {
|
||||
|
||||
export type ModuleBody = NamespaceBody | JSDocNamespaceBody;
|
||||
|
||||
export interface ModuleDeclaration extends DeclarationStatement {
|
||||
export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ModuleDeclaration;
|
||||
parent?: ModuleBody | SourceFile;
|
||||
name: ModuleName;
|
||||
@@ -1917,7 +1977,7 @@ namespace ts {
|
||||
* - import x = require("mod");
|
||||
* - import x = M.x;
|
||||
*/
|
||||
export interface ImportEqualsDeclaration extends DeclarationStatement {
|
||||
export interface ImportEqualsDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ImportEqualsDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
name: Identifier;
|
||||
@@ -2070,7 +2130,7 @@ namespace ts {
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface JSDocFunctionType extends JSDocType, SignatureDeclaration {
|
||||
export interface JSDocFunctionType extends JSDocType, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.JSDocFunctionType;
|
||||
}
|
||||
|
||||
@@ -2083,6 +2143,7 @@ namespace ts {
|
||||
|
||||
export interface JSDoc extends Node {
|
||||
kind: SyntaxKind.JSDocComment;
|
||||
parent?: HasJSDoc;
|
||||
tags: NodeArray<JSDocTag> | undefined;
|
||||
comment: string | undefined;
|
||||
}
|
||||
@@ -2150,7 +2211,6 @@ namespace ts {
|
||||
export interface JSDocTypeLiteral extends JSDocType {
|
||||
kind: SyntaxKind.JSDocTypeLiteral;
|
||||
jsDocPropertyTags?: ReadonlyArray<JSDocPropertyLikeTag>;
|
||||
jsDocTypeTag?: JSDocTypeTag;
|
||||
/** If true, then this type literal represents an *array* of its type. */
|
||||
isArrayType?: boolean;
|
||||
}
|
||||
@@ -2254,7 +2314,7 @@ namespace ts {
|
||||
*/
|
||||
export interface SourceFileLike {
|
||||
readonly text: string;
|
||||
lineMap: number[];
|
||||
lineMap: ReadonlyArray<number>;
|
||||
}
|
||||
|
||||
|
||||
@@ -2286,16 +2346,16 @@ namespace ts {
|
||||
*/
|
||||
/* @internal */ redirectInfo?: RedirectInfo | undefined;
|
||||
|
||||
amdDependencies: AmdDependency[];
|
||||
amdDependencies: ReadonlyArray<AmdDependency>;
|
||||
moduleName: string;
|
||||
referencedFiles: FileReference[];
|
||||
typeReferenceDirectives: FileReference[];
|
||||
referencedFiles: ReadonlyArray<FileReference>;
|
||||
typeReferenceDirectives: ReadonlyArray<FileReference>;
|
||||
languageVariant: LanguageVariant;
|
||||
isDeclarationFile: boolean;
|
||||
|
||||
// this map is used by transpiler to supply alternative names for dependencies (i.e. in case of bundling)
|
||||
/* @internal */
|
||||
renamedDependencies?: Map<string>;
|
||||
renamedDependencies?: ReadonlyMap<string>;
|
||||
|
||||
/**
|
||||
* lib.d.ts should have a reference comment like
|
||||
@@ -2331,19 +2391,20 @@ namespace ts {
|
||||
/* @internal */ jsDocDiagnostics?: Diagnostic[];
|
||||
|
||||
// Stores additional file-level diagnostics reported by the program
|
||||
/* @internal */ additionalSyntacticDiagnostics?: Diagnostic[];
|
||||
/* @internal */ additionalSyntacticDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
|
||||
// Stores a line map for the file.
|
||||
// This field should never be used directly to obtain line map, use getLineMap function instead.
|
||||
/* @internal */ lineMap: number[];
|
||||
/* @internal */ classifiableNames?: UnderscoreEscapedMap<true>;
|
||||
/* @internal */ lineMap: ReadonlyArray<number>;
|
||||
/* @internal */ classifiableNames?: ReadonlyUnderscoreEscapedMap<true>;
|
||||
// Stores a mapping 'external module reference text' -> 'resolved file name' | undefined
|
||||
// It is used to resolve module names in the checker.
|
||||
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
|
||||
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
|
||||
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ imports: ReadonlyArray<StringLiteral>;
|
||||
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral>;
|
||||
// Identifier only if `declare global`
|
||||
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral | Identifier>;
|
||||
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
|
||||
/* @internal */ ambientModuleNames: ReadonlyArray<string>;
|
||||
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
|
||||
@@ -2351,7 +2412,7 @@ namespace ts {
|
||||
|
||||
export interface Bundle extends Node {
|
||||
kind: SyntaxKind.Bundle;
|
||||
sourceFiles: SourceFile[];
|
||||
sourceFiles: ReadonlyArray<SourceFile>;
|
||||
}
|
||||
|
||||
export interface JsonSourceFile extends SourceFile {
|
||||
@@ -2398,19 +2459,19 @@ namespace ts {
|
||||
/**
|
||||
* Get a list of root file names that were passed to a 'createProgram'
|
||||
*/
|
||||
getRootFileNames(): string[];
|
||||
getRootFileNames(): ReadonlyArray<string>;
|
||||
|
||||
/**
|
||||
* Get a list of files in the program
|
||||
*/
|
||||
getSourceFiles(): SourceFile[];
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
|
||||
/**
|
||||
* Get a list of file names that were passed to 'createProgram' or referenced in a
|
||||
* program source file but could not be located.
|
||||
*/
|
||||
/* @internal */
|
||||
getMissingFilePaths(): Path[];
|
||||
getMissingFilePaths(): ReadonlyArray<Path>;
|
||||
|
||||
/**
|
||||
* Emits the JavaScript and declaration files. If targetSourceFile is not specified, then
|
||||
@@ -2424,14 +2485,14 @@ namespace ts {
|
||||
*/
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult;
|
||||
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
|
||||
/**
|
||||
* Gets a type checker that can be used to semantically analyze source fils in the program.
|
||||
* Gets a type checker that can be used to semantically analyze source files in the program.
|
||||
*/
|
||||
getTypeChecker(): TypeChecker;
|
||||
|
||||
@@ -2451,7 +2512,9 @@ namespace ts {
|
||||
|
||||
/* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection;
|
||||
/* @internal */ getResolvedTypeReferenceDirectives(): Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
/* @internal */ isSourceFileDefaultLibrary(file: SourceFile): boolean;
|
||||
|
||||
// For testing purposes only.
|
||||
/* @internal */ structureIsReused?: StructureIsReused;
|
||||
|
||||
@@ -2522,7 +2585,7 @@ namespace ts {
|
||||
export interface EmitResult {
|
||||
emitSkipped: boolean;
|
||||
/** Contains declaration emit diagnostics */
|
||||
diagnostics: Diagnostic[];
|
||||
diagnostics: ReadonlyArray<Diagnostic>;
|
||||
emittedFiles: string[]; // Array of files the compiler wrote to disk
|
||||
/* @internal */ sourceMaps: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps
|
||||
}
|
||||
@@ -2531,9 +2594,9 @@ namespace ts {
|
||||
export interface TypeCheckerHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
|
||||
getSourceFiles(): SourceFile[];
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
getSourceFile(fileName: string): SourceFile;
|
||||
getResolvedTypeReferenceDirectives(): Map<ResolvedTypeReferenceDirective>;
|
||||
getResolvedTypeReferenceDirectives(): ReadonlyMap<ResolvedTypeReferenceDirective>;
|
||||
}
|
||||
|
||||
export interface TypeChecker {
|
||||
@@ -2625,6 +2688,8 @@ namespace ts {
|
||||
|
||||
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol | undefined;
|
||||
|
||||
/* @internal */ getSymbolWalker(accept?: (symbol: Symbol) => boolean): SymbolWalker;
|
||||
|
||||
// Should not be called directly. Should only be accessed through the Program instance.
|
||||
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
/* @internal */ getGlobalDiagnostics(): Diagnostic[];
|
||||
@@ -2640,7 +2705,8 @@ namespace ts {
|
||||
* So for `{ a } | { b }`, this will include both `a` and `b`.
|
||||
* Does not include properties of primitive types.
|
||||
*/
|
||||
/* @internal */ getAllPossiblePropertiesOfType(type: Type): Symbol[];
|
||||
/* @internal */ isArrayLikeType(type: Type): boolean;
|
||||
/* @internal */ getAllPossiblePropertiesOfTypes(type: ReadonlyArray<Type>): Symbol[];
|
||||
/* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags): Symbol | undefined;
|
||||
/* @internal */ getJsxNamespace(): string;
|
||||
}
|
||||
@@ -2669,6 +2735,14 @@ namespace ts {
|
||||
InTypeAlias = 1 << 23, // Writing type in type alias declaration
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface SymbolWalker {
|
||||
/** Note: Return values are not ordered. */
|
||||
walkType(root: Type): { visitedTypes: ReadonlyArray<Type>, visitedSymbols: ReadonlyArray<Symbol> };
|
||||
/** Note: Return values are not ordered. */
|
||||
walkSymbol(root: Symbol): { visitedTypes: ReadonlyArray<Type>, visitedSymbols: ReadonlyArray<Symbol> };
|
||||
}
|
||||
|
||||
export interface SymbolDisplayBuilder {
|
||||
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
|
||||
buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
|
||||
@@ -2931,7 +3005,7 @@ namespace ts {
|
||||
|
||||
export interface Symbol {
|
||||
flags: SymbolFlags; // Symbol flags
|
||||
escapedName: __String; // Name of symbol
|
||||
escapedName: __String; // Name of symbol
|
||||
declarations?: Declaration[]; // Declarations associated with this symbol
|
||||
valueDeclaration?: Declaration; // First value declaration of the symbol
|
||||
members?: SymbolTable; // Class, interface or literal instance members
|
||||
@@ -2962,6 +3036,7 @@ namespace ts {
|
||||
leftSpread?: Symbol; // Left source for synthetic spread property
|
||||
rightSpread?: Symbol; // Right source for synthetic spread property
|
||||
syntheticOrigin?: Symbol; // For a property on a mapped or spread type, points back to the original property
|
||||
syntheticLiteralTypeOrigin?: StringLiteralType; // For a property on a mapped type, indicates the type whose text to use as the declaration name, instead of the symbol name
|
||||
isDiscriminantProperty?: boolean; // True if discriminant synthetic property
|
||||
resolvedExports?: SymbolTable; // Resolved exports of module
|
||||
exportsChecked?: boolean; // True if exports of external module have been checked
|
||||
@@ -3144,6 +3219,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
Nullable = Undefined | Null,
|
||||
Literal = StringLiteral | NumberLiteral | BooleanLiteral,
|
||||
Unit = Literal | Nullable,
|
||||
StringOrNumberLiteral = StringLiteral | NumberLiteral,
|
||||
/* @internal */
|
||||
DefinitelyFalsy = StringLiteral | NumberLiteral | BooleanLiteral | Void | Undefined | Null,
|
||||
@@ -3304,13 +3380,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface MappedType extends ObjectType {
|
||||
export interface MappedType extends AnonymousType {
|
||||
declaration: MappedTypeNode;
|
||||
typeParameter?: TypeParameter;
|
||||
constraintType?: Type;
|
||||
templateType?: Type;
|
||||
modifiersType?: Type;
|
||||
mapper?: TypeMapper; // Instantiation mapper
|
||||
}
|
||||
|
||||
export interface EvolvingArrayType extends ObjectType {
|
||||
@@ -3367,6 +3442,7 @@ namespace ts {
|
||||
|
||||
// Type parameters (TypeFlags.TypeParameter)
|
||||
export interface TypeParameter extends TypeVariable {
|
||||
/** Retrieve using getConstraintFromTypeParameter */
|
||||
constraint: Type; // Constraint
|
||||
default?: Type;
|
||||
/* @internal */
|
||||
@@ -3420,6 +3496,8 @@ namespace ts {
|
||||
/* @internal */
|
||||
erasedSignatureCache?: Signature; // Erased version of signature (deferred)
|
||||
/* @internal */
|
||||
canonicalSignatureCache?: Signature; // Canonical version of signature (deferred)
|
||||
/* @internal */
|
||||
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
|
||||
/* @internal */
|
||||
typePredicate?: TypePredicate;
|
||||
@@ -3441,8 +3519,6 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface TypeMapper {
|
||||
(t: TypeParameter): Type;
|
||||
mappedTypes?: TypeParameter[]; // Types mapped by this mapper
|
||||
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
|
||||
}
|
||||
|
||||
export const enum InferencePriority {
|
||||
@@ -3556,7 +3632,7 @@ namespace ts {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[];
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | null | undefined;
|
||||
|
||||
export interface CompilerOptions {
|
||||
/*@internal*/ all?: boolean;
|
||||
@@ -3953,12 +4029,7 @@ namespace ts {
|
||||
export interface ResolvedModule {
|
||||
/** Path of the file the module was resolved to. */
|
||||
resolvedFileName: string;
|
||||
/**
|
||||
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be a proper external module:
|
||||
* - be a .d.ts file
|
||||
* - use top level imports\exports
|
||||
* - don't use tripleslash references
|
||||
*/
|
||||
/** True if `resolvedFileName` comes from `node_modules`. */
|
||||
isExternalLibraryImport?: boolean;
|
||||
}
|
||||
|
||||
@@ -3987,6 +4058,11 @@ namespace ts {
|
||||
* If accessing a non-index file, this should include its name e.g. "foo/bar".
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Name of a submodule within this package.
|
||||
* May be "".
|
||||
*/
|
||||
subModuleName: string;
|
||||
/** Version of the package, e.g. "1.2.3" */
|
||||
version: string;
|
||||
}
|
||||
@@ -4010,6 +4086,7 @@ namespace ts {
|
||||
primary: boolean;
|
||||
// The location of the .d.ts file we located, or undefined if resolution failed
|
||||
resolvedFileName?: string;
|
||||
packageId?: PackageId;
|
||||
}
|
||||
|
||||
export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
@@ -4131,7 +4208,7 @@ namespace ts {
|
||||
export interface SourceMapSource {
|
||||
fileName: string;
|
||||
text: string;
|
||||
/* @internal */ lineMap: number[];
|
||||
/* @internal */ lineMap: ReadonlyArray<number>;
|
||||
skipTrivia?: (pos: number) => number;
|
||||
}
|
||||
|
||||
@@ -4178,6 +4255,7 @@ namespace ts {
|
||||
HasEndOfDeclarationMarker = 1 << 22, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
|
||||
Iterator = 1 << 23, // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable.
|
||||
NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions.
|
||||
/*@internal*/ TypeScriptClassWrapper = 1 << 25, // The node is an IIFE class wrapper created by the ts transform.
|
||||
}
|
||||
|
||||
export interface EmitHelper {
|
||||
@@ -4230,15 +4308,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
export const enum EmitHint {
|
||||
SourceFile, // Emitting a SourceFile
|
||||
Expression, // Emitting an Expression
|
||||
IdentifierName, // Emitting an IdentifierName
|
||||
Unspecified, // Emitting an otherwise unspecified node
|
||||
SourceFile, // Emitting a SourceFile
|
||||
Expression, // Emitting an Expression
|
||||
IdentifierName, // Emitting an IdentifierName
|
||||
MappedTypeParameter, // Emitting a TypeParameterDeclaration inside of a MappedTypeNode
|
||||
Unspecified, // Emitting an otherwise unspecified node
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface EmitHost extends ScriptReferenceHost {
|
||||
getSourceFiles(): SourceFile[];
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
|
||||
/* @internal */
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
|
||||
+416
-186
@@ -32,7 +32,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
const stringWriter = createSingleLineStringWriter();
|
||||
let stringWriterAcquired = false;
|
||||
|
||||
function createSingleLineStringWriter(): StringSymbolWriter {
|
||||
let str = "";
|
||||
@@ -62,15 +61,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function usingSingleLineStringWriter(action: (writer: StringSymbolWriter) => void): string {
|
||||
const oldString = stringWriter.string();
|
||||
try {
|
||||
Debug.assert(!stringWriterAcquired);
|
||||
stringWriterAcquired = true;
|
||||
action(stringWriter);
|
||||
return stringWriter.string();
|
||||
}
|
||||
finally {
|
||||
stringWriter.clear();
|
||||
stringWriterAcquired = false;
|
||||
stringWriter.writeKeyword(oldString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +104,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function packageIdIsEqual(a: PackageId | undefined, b: PackageId | undefined): boolean {
|
||||
return a === b || a && b && a.name === b.name && a.version === b.version;
|
||||
return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
|
||||
}
|
||||
|
||||
export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirective, newResolution: ResolvedTypeReferenceDirective): boolean {
|
||||
@@ -279,7 +277,7 @@ namespace ts {
|
||||
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
}
|
||||
|
||||
if (includeJsDoc && node.jsDoc && node.jsDoc.length > 0) {
|
||||
if (includeJsDoc && hasJSDocNodes(node)) {
|
||||
return getTokenPosOfNode(node.jsDoc[0]);
|
||||
}
|
||||
|
||||
@@ -359,6 +357,7 @@ namespace ts {
|
||||
case SyntaxKind.TemplateTail:
|
||||
return "}" + escapeText(node.text, CharacterCodes.backtick) + "`";
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
return node.text;
|
||||
}
|
||||
|
||||
@@ -476,6 +475,36 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isDeclarationWithTypeParameters(node: Node): node is DeclarationWithTypeParameters;
|
||||
export function isDeclarationWithTypeParameters(node: DeclarationWithTypeParameters): node is DeclarationWithTypeParameters {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return true;
|
||||
default:
|
||||
assertTypeIsNever(node);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the nearest enclosing block scope container that has the provided node
|
||||
// as a descendant, that is not the provided node.
|
||||
export function getEnclosingBlockScopeContainer(node: Node): Node {
|
||||
@@ -647,7 +676,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: SourceFile) {
|
||||
return getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
|
||||
return node.kind !== SyntaxKind.JsxText ? getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined;
|
||||
}
|
||||
|
||||
export function getJSDocCommentRanges(node: Node, text: string) {
|
||||
@@ -1224,57 +1253,60 @@ namespace ts {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
const parent = node.parent;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.BindingElement:
|
||||
return (<VariableLikeDeclaration>parent).initializer === node;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.ReturnStatement:
|
||||
case SyntaxKind.WithStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.CaseClause:
|
||||
case SyntaxKind.ThrowStatement:
|
||||
return (<ExpressionStatement>parent).expression === node;
|
||||
case SyntaxKind.ForStatement:
|
||||
const forStatement = <ForStatement>parent;
|
||||
return (forStatement.initializer === node && forStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) ||
|
||||
forStatement.condition === node ||
|
||||
forStatement.incrementor === node;
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
const forInStatement = <ForInStatement | ForOfStatement>parent;
|
||||
return (forInStatement.initializer === node && forInStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) ||
|
||||
forInStatement.expression === node;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.AsExpression:
|
||||
return node === (<AssertionExpression>parent).expression;
|
||||
case SyntaxKind.TemplateSpan:
|
||||
return node === (<TemplateSpan>parent).expression;
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return node === (<ComputedPropertyName>parent).expression;
|
||||
case SyntaxKind.Decorator:
|
||||
case SyntaxKind.JsxExpression:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return true;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return (<ExpressionWithTypeArguments>parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
|
||||
default:
|
||||
if (isPartOfExpression(parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return isInExpressionContext(node);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isInExpressionContext(node: Node): boolean {
|
||||
const parent = node.parent;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.BindingElement:
|
||||
return (<VariableLikeDeclaration>parent).initializer === node;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.ReturnStatement:
|
||||
case SyntaxKind.WithStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.CaseClause:
|
||||
case SyntaxKind.ThrowStatement:
|
||||
return (<ExpressionStatement>parent).expression === node;
|
||||
case SyntaxKind.ForStatement:
|
||||
const forStatement = <ForStatement>parent;
|
||||
return (forStatement.initializer === node && forStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) ||
|
||||
forStatement.condition === node ||
|
||||
forStatement.incrementor === node;
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
const forInStatement = <ForInStatement | ForOfStatement>parent;
|
||||
return (forInStatement.initializer === node && forInStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) ||
|
||||
forInStatement.expression === node;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.AsExpression:
|
||||
return node === (<AssertionExpression>parent).expression;
|
||||
case SyntaxKind.TemplateSpan:
|
||||
return node === (<TemplateSpan>parent).expression;
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return node === (<ComputedPropertyName>parent).expression;
|
||||
case SyntaxKind.Decorator:
|
||||
case SyntaxKind.JsxExpression:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return true;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return (<ExpressionWithTypeArguments>parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
|
||||
default:
|
||||
return isPartOfExpression(parent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isExternalModuleImportEqualsDeclaration(node: Node) {
|
||||
@@ -1294,11 +1326,11 @@ namespace ts {
|
||||
return isInJavaScriptFile(file);
|
||||
}
|
||||
|
||||
export function isInJavaScriptFile(node: Node): boolean {
|
||||
export function isInJavaScriptFile(node: Node | undefined): boolean {
|
||||
return node && !!(node.flags & NodeFlags.JavaScriptFile);
|
||||
}
|
||||
|
||||
export function isInJSDoc(node: Node): boolean {
|
||||
export function isInJSDoc(node: Node | undefined): boolean {
|
||||
return node && !!(node.flags & NodeFlags.JSDoc);
|
||||
}
|
||||
|
||||
@@ -1462,15 +1494,6 @@ namespace ts {
|
||||
((node as JSDocFunctionType).parameters[0].name as Identifier).escapedText === "new";
|
||||
}
|
||||
|
||||
export function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration): boolean {
|
||||
return !!getFirstJSDocTag(node, SyntaxKind.JSDocParameterTag);
|
||||
}
|
||||
|
||||
function getFirstJSDocTag(node: Node, kind: SyntaxKind): JSDocTag | undefined {
|
||||
const tags = getJSDocTags(node);
|
||||
return find(tags, doc => doc.kind === kind);
|
||||
}
|
||||
|
||||
export function getAllJSDocs(node: Node): (JSDoc | JSDocTag)[] {
|
||||
if (isJSDocTypedefTag(node)) {
|
||||
return [node.parent];
|
||||
@@ -1478,16 +1501,7 @@ namespace ts {
|
||||
return getJSDocCommentsAndTags(node);
|
||||
}
|
||||
|
||||
export function getJSDocTags(node: Node): ReadonlyArray<JSDocTag> | undefined {
|
||||
let tags = node.jsDocCache;
|
||||
// If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
|
||||
if (tags === undefined) {
|
||||
node.jsDocCache = tags = flatMap(getJSDocCommentsAndTags(node), j => isJSDoc(j) ? j.tags : j);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
function getJSDocCommentsAndTags(node: Node): (JSDoc | JSDocTag)[] {
|
||||
export function getJSDocCommentsAndTags(node: Node): (JSDoc | JSDocTag)[] {
|
||||
let result: Array<JSDoc | JSDocTag> | undefined;
|
||||
getJSDocCommentsAndTagsWorker(node);
|
||||
return result || emptyArray;
|
||||
@@ -1536,23 +1550,16 @@ namespace ts {
|
||||
result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration));
|
||||
}
|
||||
|
||||
if (isVariableLike(node) && node.initializer) {
|
||||
if (isVariableLike(node) && node.initializer && hasJSDocNodes(node.initializer)) {
|
||||
result = addRange(result, node.initializer.jsDoc);
|
||||
}
|
||||
|
||||
result = addRange(result, node.jsDoc);
|
||||
if (hasJSDocNodes(node)) {
|
||||
result = addRange(result, node.jsDoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getJSDocParameterTags(param: ParameterDeclaration): JSDocParameterTag[] | undefined {
|
||||
if (param.name && isIdentifier(param.name)) {
|
||||
const name = param.name.escapedText;
|
||||
return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name) as JSDocParameterTag[];
|
||||
}
|
||||
// a binding pattern doesn't have a name, so it's not possible to match it a jsdoc parameter, which is identified by name
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
|
||||
export function getParameterSymbolFromJSDoc(node: JSDocParameterTag): Symbol | undefined {
|
||||
if (node.symbol) {
|
||||
@@ -1578,39 +1585,6 @@ namespace ts {
|
||||
return find(typeParameters, p => p.name.escapedText === name);
|
||||
}
|
||||
|
||||
export function getJSDocType(node: Node): TypeNode {
|
||||
let tag: JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag;
|
||||
if (!tag && node.kind === SyntaxKind.Parameter) {
|
||||
const paramTags = getJSDocParameterTags(node as ParameterDeclaration);
|
||||
if (paramTags) {
|
||||
tag = find(paramTags, tag => !!tag.typeExpression);
|
||||
}
|
||||
}
|
||||
|
||||
return tag && tag.typeExpression && tag.typeExpression.type;
|
||||
}
|
||||
|
||||
export function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocAugmentsTag) as JSDocAugmentsTag;
|
||||
}
|
||||
|
||||
export function getJSDocClassTag(node: Node): JSDocClassTag {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocClassTag) as JSDocClassTag;
|
||||
}
|
||||
|
||||
export function getJSDocReturnTag(node: Node): JSDocReturnTag {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocReturnTag) as JSDocReturnTag;
|
||||
}
|
||||
|
||||
export function getJSDocReturnType(node: Node): TypeNode {
|
||||
const returnTag = getJSDocReturnTag(node);
|
||||
return returnTag && returnTag.typeExpression && returnTag.typeExpression.type;
|
||||
}
|
||||
|
||||
export function getJSDocTemplateTag(node: Node): JSDocTemplateTag {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocTemplateTag) as JSDocTemplateTag;
|
||||
}
|
||||
|
||||
export function hasRestParameter(s: SignatureDeclaration): boolean {
|
||||
return isRestParameter(lastOrUndefined(s.parameters));
|
||||
}
|
||||
@@ -2068,9 +2042,9 @@ namespace ts {
|
||||
|| kind === SyntaxKind.SourceFile;
|
||||
}
|
||||
|
||||
export function nodeIsSynthesized(node: TextRange): boolean {
|
||||
return positionIsSynthesized(node.pos)
|
||||
|| positionIsSynthesized(node.end);
|
||||
export function nodeIsSynthesized(range: TextRange): boolean {
|
||||
return positionIsSynthesized(range.pos)
|
||||
|| positionIsSynthesized(range.end);
|
||||
}
|
||||
|
||||
export function getOriginalSourceFile(sourceFile: SourceFile) {
|
||||
@@ -2380,6 +2354,7 @@ namespace ts {
|
||||
"\u2029": "\\u2029", // paragraphSeparator
|
||||
"\u0085": "\\u0085" // nextLine
|
||||
});
|
||||
const escapedNullRegExp = /\\0[0-9]/g;
|
||||
|
||||
/**
|
||||
* Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
|
||||
@@ -2391,7 +2366,11 @@ namespace ts {
|
||||
quoteChar === CharacterCodes.backtick ? backtickQuoteEscapedCharsRegExp :
|
||||
quoteChar === CharacterCodes.singleQuote ? singleQuoteEscapedCharsRegExp :
|
||||
doubleQuoteEscapedCharsRegExp;
|
||||
return s.replace(escapedCharsRegExp, getReplacement);
|
||||
return s.replace(escapedCharsRegExp, getReplacement).replace(escapedNullRegExp, nullReplacement);
|
||||
}
|
||||
|
||||
function nullReplacement(c: string) {
|
||||
return "\\x00" + c.charAt(c.length - 1);
|
||||
}
|
||||
|
||||
function getReplacement(c: string) {
|
||||
@@ -2572,7 +2551,7 @@ namespace ts {
|
||||
* @param host An EmitHost.
|
||||
* @param targetSourceFile An optional target source file to emit.
|
||||
*/
|
||||
export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): SourceFile[] {
|
||||
export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): ReadonlyArray<SourceFile> {
|
||||
const options = host.getCompilerOptions();
|
||||
const isSourceFileFromExternalLibrary = (file: SourceFile) => host.isSourceFileFromExternalLibrary(file);
|
||||
if (options.outFile || options.out) {
|
||||
@@ -3466,6 +3445,46 @@ namespace ts {
|
||||
export function getCombinedLocalAndExportSymbolFlags(symbol: Symbol): SymbolFlags {
|
||||
return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
|
||||
}
|
||||
|
||||
export function isWriteOnlyAccess(node: Node) {
|
||||
return accessKind(node) === AccessKind.Write;
|
||||
}
|
||||
|
||||
export function isWriteAccess(node: Node) {
|
||||
return accessKind(node) !== AccessKind.Read;
|
||||
}
|
||||
|
||||
const enum AccessKind {
|
||||
/** Only reads from a variable. */
|
||||
Read,
|
||||
/** Only writes to a variable without using the result. E.g.: `x++;`. */
|
||||
Write,
|
||||
/** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */
|
||||
ReadWrite
|
||||
}
|
||||
function accessKind(node: Node): AccessKind {
|
||||
const { parent } = node;
|
||||
if (!parent) return AccessKind.Read;
|
||||
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
const { operator } = parent as PrefixUnaryExpression | PostfixUnaryExpression;
|
||||
return operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken ? writeOrReadWrite() : AccessKind.Read;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
const { left, operatorToken } = parent as BinaryExpression;
|
||||
return left === node && isAssignmentOperator(operatorToken.kind) ? writeOrReadWrite() : AccessKind.Read;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return (parent as PropertyAccessExpression).name !== node ? AccessKind.Read : accessKind(parent);
|
||||
default:
|
||||
return AccessKind.Read;
|
||||
}
|
||||
|
||||
function writeOrReadWrite(): AccessKind {
|
||||
// If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect.
|
||||
return parent.parent && parent.parent.kind === SyntaxKind.ExpressionStatement ? AccessKind.Write : AccessKind.ReadWrite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
@@ -3922,7 +3941,66 @@ namespace ts {
|
||||
return id;
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration): DeclarationName | undefined {
|
||||
/**
|
||||
* A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should
|
||||
* attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol
|
||||
* will be merged with)
|
||||
*/
|
||||
function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined {
|
||||
const hostNode = declaration.parent.parent;
|
||||
if (!hostNode) {
|
||||
return undefined;
|
||||
}
|
||||
// Covers classes, functions - any named declaration host node
|
||||
if (isDeclaration(hostNode)) {
|
||||
return getDeclarationIdentifier(hostNode);
|
||||
}
|
||||
// Covers remaining cases
|
||||
switch (hostNode.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
if ((hostNode as VariableStatement).declarationList &&
|
||||
(hostNode as VariableStatement).declarationList.declarations[0]) {
|
||||
return getDeclarationIdentifier((hostNode as VariableStatement).declarationList.declarations[0]);
|
||||
}
|
||||
return undefined;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
const expr = (hostNode as ExpressionStatement).expression;
|
||||
switch (expr.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return (expr as PropertyAccessExpression).name;
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
const arg = (expr as ElementAccessExpression).argumentExpression;
|
||||
if (isIdentifier(arg)) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
case SyntaxKind.EndOfFileToken:
|
||||
return undefined;
|
||||
case SyntaxKind.ParenthesizedExpression: {
|
||||
return getDeclarationIdentifier(hostNode.expression);
|
||||
}
|
||||
case SyntaxKind.LabeledStatement: {
|
||||
if (isDeclaration(hostNode.statement) || isExpression(hostNode.statement)) {
|
||||
return getDeclarationIdentifier(hostNode.statement);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
default:
|
||||
Debug.assertNever(hostNode, "Found typedef tag attached to node which it should not be!");
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationIdentifier(node: Declaration | Expression) {
|
||||
const name = getNameOfDeclaration(node);
|
||||
return isIdentifier(name) ? name : undefined;
|
||||
}
|
||||
|
||||
export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined {
|
||||
return declaration.name || nameForNamelessJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined {
|
||||
if (!declaration) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -3941,10 +4019,121 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
return getNameOfJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
}
|
||||
else {
|
||||
return (declaration as NamedDeclaration).name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the JSDoc parameter tags for the node if present.
|
||||
*
|
||||
* @remarks Returns any JSDoc param tag that matches the provided
|
||||
* parameter, whether a param tag on a containing function
|
||||
* expression, or a param tag on a variable declaration whose
|
||||
* initializer is the containing function. The tags closest to the
|
||||
* node are returned first, so in the previous example, the param
|
||||
* tag on the containing function expression would be first.
|
||||
*
|
||||
* Does not return tags for binding patterns, because JSDoc matches
|
||||
* parameters by name and binding patterns do not have a name.
|
||||
*/
|
||||
export function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray<JSDocParameterTag> | undefined {
|
||||
if (param.name && isIdentifier(param.name)) {
|
||||
const name = param.name.escapedText;
|
||||
return getJSDocTags(param.parent).filter((tag): tag is JSDocParameterTag => isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name) as JSDocParameterTag[];
|
||||
}
|
||||
// a binding pattern doesn't have a name, so it's not possible to match it a JSDoc parameter, which is identified by name
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the node has JSDoc parameter tags.
|
||||
*
|
||||
* @remarks Includes parameter tags that are not directly on the node,
|
||||
* for example on a variable declaration whose initializer is a function expression.
|
||||
*/
|
||||
export function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration): boolean {
|
||||
return !!getFirstJSDocTag(node, SyntaxKind.JSDocParameterTag);
|
||||
}
|
||||
|
||||
/** Gets the JSDoc augments tag for the node if present */
|
||||
export function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag | undefined {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocAugmentsTag) as JSDocAugmentsTag;
|
||||
}
|
||||
|
||||
/** Gets the JSDoc class tag for the node if present */
|
||||
export function getJSDocClassTag(node: Node): JSDocClassTag | undefined {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocClassTag) as JSDocClassTag;
|
||||
}
|
||||
|
||||
/** Gets the JSDoc return tag for the node if present */
|
||||
export function getJSDocReturnTag(node: Node): JSDocReturnTag | undefined {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocReturnTag) as JSDocReturnTag;
|
||||
}
|
||||
|
||||
/** Gets the JSDoc template tag for the node if present */
|
||||
export function getJSDocTemplateTag(node: Node): JSDocTemplateTag | undefined {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocTemplateTag) as JSDocTemplateTag;
|
||||
}
|
||||
|
||||
/** Gets the JSDoc type tag for the node if present */
|
||||
export function getJSDocTypeTag(node: Node): JSDocTypeTag | undefined {
|
||||
return getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type node for the node if provided via JSDoc.
|
||||
*
|
||||
* @remarks The search includes any JSDoc param tag that relates
|
||||
* to the provided parameter, for example a type tag on the
|
||||
* parameter itself, or a param tag on a containing function
|
||||
* expression, or a param tag on a variable declaration whose
|
||||
* initializer is the containing function. The tags closest to the
|
||||
* node are examined first, so in the previous example, the type
|
||||
* tag directly on the node would be returned.
|
||||
*/
|
||||
export function getJSDocType(node: Node): TypeNode | undefined {
|
||||
let tag: JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag;
|
||||
if (!tag && node.kind === SyntaxKind.Parameter) {
|
||||
const paramTags = getJSDocParameterTags(node as ParameterDeclaration);
|
||||
if (paramTags) {
|
||||
tag = find(paramTags, tag => !!tag.typeExpression);
|
||||
}
|
||||
}
|
||||
|
||||
return tag && tag.typeExpression && tag.typeExpression.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the return type node for the node if provided via JSDoc's return tag.
|
||||
*
|
||||
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
|
||||
* gets the type from inside the braces.
|
||||
*/
|
||||
export function getJSDocReturnType(node: Node): TypeNode | undefined {
|
||||
const returnTag = getJSDocReturnTag(node);
|
||||
return returnTag && returnTag.typeExpression && returnTag.typeExpression.type;
|
||||
}
|
||||
|
||||
/** Get all JSDoc tags related to a node, including those on parent nodes. */
|
||||
export function getJSDocTags(node: Node): ReadonlyArray<JSDocTag> | undefined {
|
||||
let tags = (node as JSDocContainer).jsDocCache;
|
||||
// If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
|
||||
if (tags === undefined) {
|
||||
(node as JSDocContainer).jsDocCache = tags = flatMap(getJSDocCommentsAndTags(node), j => isJSDoc(j) ? j.tags : j);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
/** Get the first JSDoc tag of a specified kind, or undefined if not present. */
|
||||
function getFirstJSDocTag(node: Node, kind: SyntaxKind): JSDocTag | undefined {
|
||||
const tags = getJSDocTags(node);
|
||||
return find(tags, doc => doc.kind === kind);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Simple node tests of the form `node.kind === SyntaxKind.Foo`.
|
||||
@@ -4628,8 +4817,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function isNodeArray<T extends Node>(array: ReadonlyArray<T>): array is NodeArray<T> {
|
||||
return array.hasOwnProperty("pos")
|
||||
&& array.hasOwnProperty("end");
|
||||
return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
|
||||
}
|
||||
|
||||
// Literals
|
||||
@@ -4730,16 +4918,29 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isFunctionLikeKind(kind: SyntaxKind): boolean {
|
||||
export function isFunctionLikeDeclaration(node: Node): node is FunctionLikeDeclaration {
|
||||
return node && isFunctionLikeDeclarationKind(node.kind);
|
||||
}
|
||||
|
||||
function isFunctionLikeDeclarationKind(kind: SyntaxKind): boolean {
|
||||
switch (kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isFunctionLikeKind(kind: SyntaxKind): boolean {
|
||||
switch (kind) {
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
@@ -4747,9 +4948,14 @@ namespace ts {
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
return true;
|
||||
default:
|
||||
return isFunctionLikeDeclarationKind(kind);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
/* @internal */
|
||||
export function isFunctionOrModuleBlock(node: Node): boolean {
|
||||
return isSourceFile(node) || isModuleBlock(node) || isBlock(node) && isFunctionLike(node.parent);
|
||||
}
|
||||
|
||||
// Classes
|
||||
@@ -4946,49 +5152,43 @@ namespace ts {
|
||||
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
}
|
||||
|
||||
function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.PropertyAccessExpression
|
||||
|| kind === SyntaxKind.ElementAccessExpression
|
||||
|| kind === SyntaxKind.NewExpression
|
||||
|| kind === SyntaxKind.CallExpression
|
||||
|| kind === SyntaxKind.JsxElement
|
||||
|| kind === SyntaxKind.JsxSelfClosingElement
|
||||
|| kind === SyntaxKind.TaggedTemplateExpression
|
||||
|| kind === SyntaxKind.ArrayLiteralExpression
|
||||
|| kind === SyntaxKind.ParenthesizedExpression
|
||||
|| kind === SyntaxKind.ObjectLiteralExpression
|
||||
|| kind === SyntaxKind.ClassExpression
|
||||
|| kind === SyntaxKind.FunctionExpression
|
||||
|| kind === SyntaxKind.Identifier
|
||||
|| kind === SyntaxKind.RegularExpressionLiteral
|
||||
|| kind === SyntaxKind.NumericLiteral
|
||||
|| kind === SyntaxKind.StringLiteral
|
||||
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
|| kind === SyntaxKind.TemplateExpression
|
||||
|| kind === SyntaxKind.FalseKeyword
|
||||
|| kind === SyntaxKind.NullKeyword
|
||||
|| kind === SyntaxKind.ThisKeyword
|
||||
|| kind === SyntaxKind.TrueKeyword
|
||||
|| kind === SyntaxKind.SuperKeyword
|
||||
|| kind === SyntaxKind.ImportKeyword
|
||||
|| kind === SyntaxKind.NonNullExpression
|
||||
|| kind === SyntaxKind.MetaProperty;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression {
|
||||
return isLeftHandSideExpressionKind(skipPartiallyEmittedExpressions(node).kind);
|
||||
}
|
||||
|
||||
function isUnaryExpressionKind(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.PrefixUnaryExpression
|
||||
|| kind === SyntaxKind.PostfixUnaryExpression
|
||||
|| kind === SyntaxKind.DeleteExpression
|
||||
|| kind === SyntaxKind.TypeOfExpression
|
||||
|| kind === SyntaxKind.VoidExpression
|
||||
|| kind === SyntaxKind.AwaitExpression
|
||||
|| kind === SyntaxKind.TypeAssertionExpression
|
||||
|| isLeftHandSideExpressionKind(kind);
|
||||
function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.SuperKeyword:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
case SyntaxKind.MetaProperty:
|
||||
case SyntaxKind.ImportKeyword: // technically this is only an Expression if it's in a CallExpression
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4996,6 +5196,21 @@ namespace ts {
|
||||
return isUnaryExpressionKind(skipPartiallyEmittedExpressions(node).kind);
|
||||
}
|
||||
|
||||
function isUnaryExpressionKind(kind: SyntaxKind): boolean {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.DeleteExpression:
|
||||
case SyntaxKind.TypeOfExpression:
|
||||
case SyntaxKind.VoidExpression:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
return true;
|
||||
default:
|
||||
return isLeftHandSideExpressionKind(kind);
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isUnaryExpressionWithWrite(expr: Node): expr is PrefixUnaryExpression | PostfixUnaryExpression {
|
||||
switch (expr.kind) {
|
||||
@@ -5009,23 +5224,32 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isExpressionKind(kind: SyntaxKind) {
|
||||
return kind === SyntaxKind.ConditionalExpression
|
||||
|| kind === SyntaxKind.YieldExpression
|
||||
|| kind === SyntaxKind.ArrowFunction
|
||||
|| kind === SyntaxKind.BinaryExpression
|
||||
|| kind === SyntaxKind.SpreadElement
|
||||
|| kind === SyntaxKind.AsExpression
|
||||
|| kind === SyntaxKind.OmittedExpression
|
||||
|| kind === SyntaxKind.CommaListExpression
|
||||
|| isUnaryExpressionKind(kind);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
/**
|
||||
* Determines whether a node is an expression based only on its kind.
|
||||
* Use `isPartOfExpression` if not in transforms.
|
||||
*/
|
||||
export function isExpression(node: Node): node is Expression {
|
||||
return isExpressionKind(skipPartiallyEmittedExpressions(node).kind);
|
||||
}
|
||||
|
||||
function isExpressionKind(kind: SyntaxKind): boolean {
|
||||
switch (kind) {
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.AsExpression:
|
||||
case SyntaxKind.OmittedExpression:
|
||||
case SyntaxKind.CommaListExpression:
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
return true;
|
||||
default:
|
||||
return isUnaryExpressionKind(kind);
|
||||
}
|
||||
}
|
||||
|
||||
export function isAssertionExpression(node: Node): node is AssertionExpression {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.TypeAssertionExpression
|
||||
@@ -5311,4 +5535,10 @@ namespace ts {
|
||||
export function isJSDocTag(node: Node): boolean {
|
||||
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
|
||||
}
|
||||
|
||||
/** True if has jsdoc nodes attached to it. */
|
||||
/* @internal */
|
||||
export function hasJSDocNodes(node: Node): node is HasJSDoc {
|
||||
return !!(node as JSDocContainer).jsDoc && (node as JSDocContainer).jsDoc.length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,6 +488,7 @@ namespace ts {
|
||||
nodesVisitor((<ArrowFunction>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
visitParameterList((<ArrowFunction>node).parameters, visitor, context, nodesVisitor),
|
||||
visitNode((<ArrowFunction>node).type, visitor, isTypeNode),
|
||||
visitNode((<ArrowFunction>node).equalsGreaterThanToken, visitor, isToken),
|
||||
visitFunctionBody((<ArrowFunction>node).body, visitor, context));
|
||||
|
||||
case SyntaxKind.DeleteExpression:
|
||||
@@ -523,7 +524,9 @@ namespace ts {
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
return updateConditional(<ConditionalExpression>node,
|
||||
visitNode((<ConditionalExpression>node).condition, visitor, isExpression),
|
||||
visitNode((<ConditionalExpression>node).questionToken, visitor, isToken),
|
||||
visitNode((<ConditionalExpression>node).whenTrue, visitor, isExpression),
|
||||
visitNode((<ConditionalExpression>node).colonToken, visitor, isToken),
|
||||
visitNode((<ConditionalExpression>node).whenFalse, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.TemplateExpression:
|
||||
|
||||
@@ -11,19 +11,13 @@ const enum CompilerTestType {
|
||||
class CompilerBaselineRunner extends RunnerBase {
|
||||
private basePath = "tests/cases";
|
||||
private testSuiteName: TestRunnerKind;
|
||||
private errors: boolean;
|
||||
private emit: boolean;
|
||||
private decl: boolean;
|
||||
private output: boolean;
|
||||
|
||||
public options: string;
|
||||
|
||||
constructor(public testType: CompilerTestType) {
|
||||
super();
|
||||
this.errors = true;
|
||||
this.emit = true;
|
||||
this.decl = true;
|
||||
this.output = true;
|
||||
if (testType === CompilerTestType.Conformance) {
|
||||
this.testSuiteName = "conformance";
|
||||
}
|
||||
@@ -141,7 +135,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
// check errors
|
||||
it("Correct errors for " + fileName, () => {
|
||||
Harness.Compiler.doErrorBaseline(justName, tsConfigFiles.concat(toBeCompiled, otherFiles), result.errors);
|
||||
Harness.Compiler.doErrorBaseline(justName, tsConfigFiles.concat(toBeCompiled, otherFiles), result.errors, !!options.pretty);
|
||||
});
|
||||
|
||||
it (`Correct module resolution tracing for ${fileName}`, () => {
|
||||
@@ -214,26 +208,14 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
private parseOptions() {
|
||||
if (this.options && this.options.length > 0) {
|
||||
this.errors = false;
|
||||
this.emit = false;
|
||||
this.decl = false;
|
||||
this.output = false;
|
||||
|
||||
const opts = this.options.split(",");
|
||||
for (let i = 0; i < opts.length; i++) {
|
||||
switch (opts[i]) {
|
||||
case "error":
|
||||
this.errors = true;
|
||||
break;
|
||||
case "emit":
|
||||
this.emit = true;
|
||||
break;
|
||||
case "decl":
|
||||
this.decl = true;
|
||||
break;
|
||||
case "output":
|
||||
this.output = true;
|
||||
break;
|
||||
default:
|
||||
throw new Error("unsupported flag");
|
||||
}
|
||||
|
||||
+155
-75
@@ -22,10 +22,6 @@
|
||||
namespace FourSlash {
|
||||
ts.disableIncrementalParsing = false;
|
||||
|
||||
function normalizeNewLines(s: string) {
|
||||
return s.replace(/\r\n/g, "\n");
|
||||
}
|
||||
|
||||
// Represents a parsed source file with metadata
|
||||
export interface FourSlashFile {
|
||||
// The contents of the file (with markers, etc stripped out)
|
||||
@@ -364,7 +360,7 @@ namespace FourSlash {
|
||||
baseIndentSize: 0,
|
||||
indentSize: 4,
|
||||
tabSize: 4,
|
||||
newLineCharacter: Harness.IO.newLine(),
|
||||
newLineCharacter: "\n",
|
||||
convertTabsToSpaces: true,
|
||||
indentStyle: ts.IndentStyle.Smart,
|
||||
insertSpaceAfterCommaDelimiter: true,
|
||||
@@ -490,7 +486,8 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private getDiagnostics(fileName: string): ts.Diagnostic[] {
|
||||
return this.languageService.getSyntacticDiagnostics(fileName).concat(this.languageService.getSemanticDiagnostics(fileName));
|
||||
return ts.concatenate(this.languageService.getSyntacticDiagnostics(fileName),
|
||||
this.languageService.getSemanticDiagnostics(fileName));
|
||||
}
|
||||
|
||||
private getAllDiagnostics(): ts.Diagnostic[] {
|
||||
@@ -761,7 +758,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyCompletionsAt(markerName: string, expected: string[]) {
|
||||
public verifyCompletionsAt(markerName: string, expected: string[], options?: FourSlashInterface.CompletionsAtOptions) {
|
||||
this.goToMarker(markerName);
|
||||
|
||||
const actualCompletions = this.getCompletionListAtCaret();
|
||||
@@ -769,6 +766,10 @@ namespace FourSlash {
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}'.`);
|
||||
}
|
||||
|
||||
if (options && options.isNewIdentifierLocation !== undefined && actualCompletions.isNewIdentifierLocation !== options.isNewIdentifierLocation) {
|
||||
this.raiseError(`Expected 'isNewIdentifierLocation' to be ${options.isNewIdentifierLocation}, got ${actualCompletions.isNewIdentifierLocation}`);
|
||||
}
|
||||
|
||||
const actual = actualCompletions.entries;
|
||||
|
||||
if (actual.length !== expected.length) {
|
||||
@@ -1148,7 +1149,7 @@ namespace FourSlash {
|
||||
this.testDiagnostics(expected, diagnostics);
|
||||
}
|
||||
|
||||
private testDiagnostics(expected: string, diagnostics: ts.Diagnostic[]) {
|
||||
private testDiagnostics(expected: string, diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
const realized = ts.realizeDiagnostics(diagnostics, "\r\n");
|
||||
const actual = stringify(realized);
|
||||
assert.equal(actual, expected);
|
||||
@@ -1585,7 +1586,7 @@ namespace FourSlash {
|
||||
public printErrorList() {
|
||||
const syntacticErrors = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName);
|
||||
const semanticErrors = this.languageService.getSemanticDiagnostics(this.activeFile.fileName);
|
||||
const errorList = syntacticErrors.concat(semanticErrors);
|
||||
const errorList = ts.concatenate(syntacticErrors, semanticErrors);
|
||||
Harness.IO.log(`Error list (${errorList.length} errors)`);
|
||||
|
||||
if (errorList.length) {
|
||||
@@ -1598,7 +1599,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public printCurrentFileState(makeWhitespaceVisible: boolean, makeCaretVisible: boolean) {
|
||||
public printCurrentFileState(showWhitespace: boolean, makeCaretVisible: boolean) {
|
||||
for (const file of this.testData.files) {
|
||||
const active = (this.activeFile === file);
|
||||
Harness.IO.log(`=== Script (${file.fileName}) ${(active ? "(active, cursor at |)" : "")} ===`);
|
||||
@@ -1606,8 +1607,8 @@ namespace FourSlash {
|
||||
if (active) {
|
||||
content = content.substr(0, this.currentCaretPosition) + (makeCaretVisible ? "|" : "") + content.substr(this.currentCaretPosition);
|
||||
}
|
||||
if (makeWhitespaceVisible) {
|
||||
content = TestState.makeWhitespaceVisible(content);
|
||||
if (showWhitespace) {
|
||||
content = makeWhitespaceVisible(content);
|
||||
}
|
||||
Harness.IO.log(content);
|
||||
}
|
||||
@@ -2123,10 +2124,8 @@ namespace FourSlash {
|
||||
|
||||
public verifyCurrentFileContent(text: string) {
|
||||
const actual = this.getFileContent(this.activeFile.fileName);
|
||||
if (normalizeNewLines(actual) !== normalizeNewLines(text)) {
|
||||
throw new Error("verifyCurrentFileContent\n" +
|
||||
"\tExpected: \"" + TestState.makeWhitespaceVisible(text) + "\"\n" +
|
||||
"\t Actual: \"" + TestState.makeWhitespaceVisible(actual) + "\"");
|
||||
if (actual !== text) {
|
||||
throw new Error(`verifyCurrentFileContent failed:\n${showTextDiff(text, actual)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2300,11 +2299,11 @@ namespace FourSlash {
|
||||
const actualText = this.rangeText(ranges[0]);
|
||||
|
||||
const result = includeWhiteSpace
|
||||
? normalizeNewLines(actualText) === normalizeNewLines(expectedText)
|
||||
? actualText === expectedText
|
||||
: this.removeWhitespace(actualText) === this.removeWhitespace(expectedText);
|
||||
|
||||
if (!result) {
|
||||
this.raiseError(`Actual text doesn't match expected text. Actual:\n'${actualText}'\nExpected:\n'${expectedText}'`);
|
||||
this.raiseError(`Actual range text doesn't match expected text.\n${showTextDiff(expectedText, actualText)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2398,18 +2397,22 @@ namespace FourSlash {
|
||||
const originalContent = scriptInfo.content;
|
||||
for (const codeFix of codeFixes) {
|
||||
this.applyEdits(codeFix.changes[0].fileName, codeFix.changes[0].textChanges, /*isFormattingEdit*/ false);
|
||||
actualTextArray.push(this.normalizeNewlines(this.rangeText(ranges[0])));
|
||||
let text = this.rangeText(ranges[0]);
|
||||
// TODO:GH#18445 (remove this line to see errors in many `importNameCodeFix` tests)
|
||||
text = text.replace(/\r\n/g, "\n");
|
||||
actualTextArray.push(text);
|
||||
scriptInfo.updateContent(originalContent);
|
||||
}
|
||||
const sortedExpectedArray = ts.map(expectedTextArray, str => this.normalizeNewlines(str)).sort();
|
||||
const sortedExpectedArray = expectedTextArray.sort();
|
||||
const sortedActualArray = actualTextArray.sort();
|
||||
if (!ts.arrayIsEqualTo(sortedExpectedArray, sortedActualArray)) {
|
||||
this.raiseError(
|
||||
`Actual text array doesn't match expected text array. \nActual: \n'${sortedActualArray.join("\n\n")}'\n---\nExpected: \n'${sortedExpectedArray.join("\n\n")}'`);
|
||||
}
|
||||
ts.zipWith(sortedExpectedArray, sortedActualArray, (expected, actual, index) => {
|
||||
if (expected !== actual) {
|
||||
this.raiseError(`Import fix at index ${index} doesn't match.\n${showTextDiff(expected, actual)}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public verifyDocCommentTemplate(expected?: ts.TextInsertion) {
|
||||
public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined) {
|
||||
const name = "verifyDocCommentTemplate";
|
||||
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
|
||||
@@ -2426,7 +2429,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
if (actual.newText !== expected.newText) {
|
||||
this.raiseError(`${name} failed - expected insertion:\n"${this.clarifyNewlines(expected.newText)}"\nactual insertion:\n"${this.clarifyNewlines(actual.newText)}"`);
|
||||
this.raiseError(`${name} failed for expected insertion.\n${showTextDiff(expected.newText, actual.newText)}`);
|
||||
}
|
||||
|
||||
if (actual.caretOffset !== expected.caretOffset) {
|
||||
@@ -2435,17 +2438,6 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private clarifyNewlines(str: string) {
|
||||
return str.replace(/\r?\n/g, lineEnding => {
|
||||
const representation = lineEnding === "\r\n" ? "CRLF" : "LF";
|
||||
return "# - " + representation + lineEnding;
|
||||
});
|
||||
}
|
||||
|
||||
private normalizeNewlines(str: string) {
|
||||
return str.replace(/\r?\n/g, "\n");
|
||||
}
|
||||
|
||||
public verifyBraceCompletionAtPosition(negative: boolean, openingBrace: string) {
|
||||
|
||||
const openBraceMap = ts.createMapFromTemplate<ts.CharacterCodes>({
|
||||
@@ -2508,6 +2500,23 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifySpanOfEnclosingComment(negative: boolean, onlyMultiLineDiverges?: boolean) {
|
||||
const expected = !negative;
|
||||
const position = this.currentCaretPosition;
|
||||
const fileName = this.activeFile.fileName;
|
||||
const actual = !!this.languageService.getSpanOfEnclosingComment(fileName, position, /*onlyMultiLine*/ false);
|
||||
const actualOnlyMultiLine = !!this.languageService.getSpanOfEnclosingComment(fileName, position, /*onlyMultiLine*/ true);
|
||||
if (expected !== actual || onlyMultiLineDiverges === (actual === actualOnlyMultiLine)) {
|
||||
this.raiseError(`verifySpanOfEnclosingComment failed:
|
||||
position: '${position}'
|
||||
fileName: '${fileName}'
|
||||
onlyMultiLineDiverges: '${onlyMultiLineDiverges}'
|
||||
actual: '${actual}'
|
||||
actualOnlyMultiLine: '${actualOnlyMultiLine}'
|
||||
expected: '${expected}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Check number of navigationItems which match both searchValue and matchKind,
|
||||
if a filename is passed in, limit the results to that file.
|
||||
@@ -2736,27 +2745,32 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private getSelection() {
|
||||
return ({
|
||||
private getSelection(): ts.TextRange {
|
||||
return {
|
||||
pos: this.currentCaretPosition,
|
||||
end: this.selectionEnd === -1 ? this.currentCaretPosition : this.selectionEnd
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
public verifyRefactorAvailable(negative: boolean, name?: string, subName?: string) {
|
||||
public verifyRefactorAvailable(negative: boolean, name: string, actionName?: string) {
|
||||
const selection = this.getSelection();
|
||||
|
||||
let refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, selection) || [];
|
||||
if (name) {
|
||||
refactors = refactors.filter(r => r.name === name && (subName === undefined || r.actions.some(a => a.name === subName)));
|
||||
}
|
||||
refactors = refactors.filter(r => r.name === name && (actionName === undefined || r.actions.some(a => a.name === actionName)));
|
||||
const isAvailable = refactors.length > 0;
|
||||
|
||||
if (negative && isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected no refactor but found some: ${refactors.map(r => r.name).join(", ")}`);
|
||||
if (negative) {
|
||||
if (isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected no refactor but found: ${refactors.map(r => r.name).join(", ")}`);
|
||||
}
|
||||
}
|
||||
else if (!negative && !isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected a refactor but found none.`);
|
||||
else {
|
||||
if (!isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected a refactor but found none.`);
|
||||
}
|
||||
if (refactors.length > 1) {
|
||||
this.raiseError(`${refactors.length} available refactors both have name ${name} and action ${actionName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2776,18 +2790,55 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public applyRefactor(refactorName: string, actionName: string) {
|
||||
public applyRefactor({ refactorName, actionName, actionDescription, newContent: newContentWithRenameMarker }: FourSlashInterface.ApplyRefactorOptions) {
|
||||
const range = this.getSelection();
|
||||
const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range);
|
||||
const refactor = ts.find(refactors, r => r.name === refactorName);
|
||||
const refactor = refactors.find(r => r.name === refactorName);
|
||||
if (!refactor) {
|
||||
this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.`);
|
||||
}
|
||||
|
||||
const action = refactor.actions.find(a => a.name === actionName);
|
||||
if (!action) {
|
||||
this.raiseError(`The expected action: ${action} is not included in: ${refactor.actions.map(a => a.name)}`);
|
||||
}
|
||||
if (action.description !== actionDescription) {
|
||||
this.raiseError(`Expected action description to be ${JSON.stringify(actionDescription)}, got: ${JSON.stringify(action.description)}`);
|
||||
}
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactorName, actionName);
|
||||
for (const edit of editInfo.edits) {
|
||||
this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
|
||||
}
|
||||
|
||||
const { renamePosition, newContent } = parseNewContent();
|
||||
|
||||
this.verifyCurrentFileContent(newContent);
|
||||
|
||||
if (renamePosition === undefined) {
|
||||
if (editInfo.renameLocation !== undefined) {
|
||||
this.raiseError(`Did not expect a rename location, got ${editInfo.renameLocation}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO: test editInfo.renameFilename value
|
||||
assert.isDefined(editInfo.renameFilename);
|
||||
if (renamePosition !== editInfo.renameLocation) {
|
||||
this.raiseError(`Expected rename position of ${renamePosition}, but got ${editInfo.renameLocation}`);
|
||||
}
|
||||
}
|
||||
|
||||
function parseNewContent(): { renamePosition: number | undefined, newContent: string } {
|
||||
const renamePosition = newContentWithRenameMarker.indexOf("/*RENAME*/");
|
||||
if (renamePosition === -1) {
|
||||
return { renamePosition: undefined, newContent: newContentWithRenameMarker };
|
||||
}
|
||||
else {
|
||||
const newContent = newContentWithRenameMarker.slice(0, renamePosition) + newContentWithRenameMarker.slice(renamePosition + "/*RENAME*/".length);
|
||||
return { renamePosition, newContent };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public verifyFileAfterApplyingRefactorAtMarker(
|
||||
@@ -2814,8 +2865,8 @@ namespace FourSlash {
|
||||
}
|
||||
const actualContent = this.getFileContent(this.activeFile.fileName);
|
||||
|
||||
if (this.normalizeNewlines(actualContent) !== this.normalizeNewlines(expectedContent)) {
|
||||
this.raiseError(`verifyFileAfterApplyingRefactors failed: expected:\n${expectedContent}\nactual:\n${actualContent}`);
|
||||
if (actualContent !== expectedContent) {
|
||||
this.raiseError(`verifyFileAfterApplyingRefactors failed:\n${showTextDiff(expectedContent, actualContent)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2950,10 +3001,6 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private static makeWhitespaceVisible(text: string) {
|
||||
return text.replace(/ /g, "\u00B7").replace(/\r/g, "\u00B6").replace(/\n/g, "\u2193\n").replace(/\t/g, "\u2192\ ");
|
||||
}
|
||||
|
||||
public setCancelled(numberOfCalls: number): void {
|
||||
this.cancellationToken.setCancelled(numberOfCalls);
|
||||
}
|
||||
@@ -3255,12 +3302,7 @@ ${code}
|
||||
let column = 1;
|
||||
|
||||
const flush = (lastSafeCharIndex: number) => {
|
||||
if (lastSafeCharIndex === undefined) {
|
||||
output = output + content.substr(lastNormalCharPosition);
|
||||
}
|
||||
else {
|
||||
output = output + content.substr(lastNormalCharPosition, lastSafeCharIndex - lastNormalCharPosition);
|
||||
}
|
||||
output = output + content.substr(lastNormalCharPosition, lastSafeCharIndex === undefined ? undefined : lastSafeCharIndex - lastNormalCharPosition);
|
||||
};
|
||||
|
||||
if (content.length > 0) {
|
||||
@@ -3447,6 +3489,27 @@ ${code}
|
||||
function toArray<T>(x: T | T[]): T[] {
|
||||
return ts.isArray(x) ? x : [x];
|
||||
}
|
||||
|
||||
function makeWhitespaceVisible(text: string) {
|
||||
return text.replace(/ /g, "\u00B7").replace(/\r/g, "\u00B6").replace(/\n/g, "\u2193\n").replace(/\t/g, "\u2192\ ");
|
||||
}
|
||||
|
||||
function showTextDiff(expected: string, actual: string): string {
|
||||
// Only show whitespace if the difference is whitespace-only.
|
||||
if (differOnlyByWhitespace(expected, actual)) {
|
||||
expected = makeWhitespaceVisible(expected);
|
||||
actual = makeWhitespaceVisible(actual);
|
||||
}
|
||||
return `Expected:\n${expected}\nActual:\n${actual}`;
|
||||
}
|
||||
|
||||
function differOnlyByWhitespace(a: string, b: string) {
|
||||
return stripWhitespace(a) === stripWhitespace(b);
|
||||
}
|
||||
|
||||
function stripWhitespace(s: string): string {
|
||||
return s.replace(/\s/g, "");
|
||||
}
|
||||
}
|
||||
|
||||
namespace FourSlashInterface {
|
||||
@@ -3648,6 +3711,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifyBraceCompletionAtPosition(this.negative, openingBrace);
|
||||
}
|
||||
|
||||
public isInCommentAtPosition(onlyMultiLineDiverges?: boolean) {
|
||||
this.state.verifySpanOfEnclosingComment(this.negative, onlyMultiLineDiverges);
|
||||
}
|
||||
|
||||
public codeFixAvailable() {
|
||||
this.state.verifyCodeFixAvailable(this.negative);
|
||||
}
|
||||
@@ -3660,8 +3727,8 @@ namespace FourSlashInterface {
|
||||
this.state.verifyApplicableRefactorAvailableForRange(this.negative);
|
||||
}
|
||||
|
||||
public refactorAvailable(name?: string, subName?: string) {
|
||||
this.state.verifyRefactorAvailable(this.negative, name, subName);
|
||||
public refactorAvailable(name: string, actionName?: string) {
|
||||
this.state.verifyRefactorAvailable(this.negative, name, actionName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3670,8 +3737,8 @@ namespace FourSlashInterface {
|
||||
super(state);
|
||||
}
|
||||
|
||||
public completionsAt(markerName: string, completions: string[]) {
|
||||
this.state.verifyCompletionsAt(markerName, completions);
|
||||
public completionsAt(markerName: string, completions: string[], options?: CompletionsAtOptions) {
|
||||
this.state.verifyCompletionsAt(markerName, completions, options);
|
||||
}
|
||||
|
||||
public quickInfoIs(expectedText: string, expectedDocumentation?: string) {
|
||||
@@ -3869,12 +3936,14 @@ namespace FourSlashInterface {
|
||||
this.state.verifyNoMatchingBracePosition(bracePosition);
|
||||
}
|
||||
|
||||
public DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean) {
|
||||
this.state.verifyDocCommentTemplate(empty ? undefined : { newText: expectedText, caretOffset: expectedOffset });
|
||||
public docCommentTemplateAt(marker: string | FourSlash.Marker, expectedOffset: number, expectedText: string) {
|
||||
this.state.goToMarker(marker);
|
||||
this.state.verifyDocCommentTemplate({ newText: expectedText.replace(/\r?\n/g, "\r\n"), caretOffset: expectedOffset });
|
||||
}
|
||||
|
||||
public noDocCommentTemplate() {
|
||||
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
|
||||
public noDocCommentTemplateAt(marker: string | FourSlash.Marker) {
|
||||
this.state.goToMarker(marker);
|
||||
this.state.verifyDocCommentTemplate(/*expected*/ undefined);
|
||||
}
|
||||
|
||||
public rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void {
|
||||
@@ -4059,8 +4128,8 @@ namespace FourSlashInterface {
|
||||
this.state.enableFormatting = false;
|
||||
}
|
||||
|
||||
public applyRefactor(refactorName: string, actionName: string) {
|
||||
this.state.applyRefactor(refactorName, actionName);
|
||||
public applyRefactor(options: ApplyRefactorOptions) {
|
||||
this.state.applyRefactor(options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4073,15 +4142,15 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
public printCurrentFileState() {
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/ false, /*makeCaretVisible*/ true);
|
||||
this.state.printCurrentFileState(/*showWhitespace*/ false, /*makeCaretVisible*/ true);
|
||||
}
|
||||
|
||||
public printCurrentFileStateWithWhitespace() {
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/ true, /*makeCaretVisible*/ true);
|
||||
this.state.printCurrentFileState(/*showWhitespace*/ true, /*makeCaretVisible*/ true);
|
||||
}
|
||||
|
||||
public printCurrentFileStateWithoutCaret() {
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/ false, /*makeCaretVisible*/ false);
|
||||
this.state.printCurrentFileState(/*showWhitespace*/ false, /*makeCaretVisible*/ false);
|
||||
}
|
||||
|
||||
public printCurrentQuickInfo() {
|
||||
@@ -4273,4 +4342,15 @@ namespace FourSlashInterface {
|
||||
return { classificationType, text, textSpan };
|
||||
}
|
||||
}
|
||||
|
||||
export interface ApplyRefactorOptions {
|
||||
refactorName: string;
|
||||
actionName: string;
|
||||
actionDescription: string;
|
||||
newContent: string;
|
||||
}
|
||||
|
||||
export interface CompletionsAtOptions {
|
||||
isNewIdentifierLocation?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
+170
-46
@@ -207,7 +207,7 @@ namespace Utils {
|
||||
return a !== undefined && typeof a.pos === "number";
|
||||
}
|
||||
|
||||
export function convertDiagnostics(diagnostics: ts.Diagnostic[]) {
|
||||
export function convertDiagnostics(diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
return diagnostics.map(convertDiagnostic);
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace Utils {
|
||||
}
|
||||
}
|
||||
|
||||
export function assertDiagnosticsEquals(array1: ts.Diagnostic[], array2: ts.Diagnostic[]) {
|
||||
export function assertDiagnosticsEquals(array1: ReadonlyArray<ts.Diagnostic>, array2: ReadonlyArray<ts.Diagnostic>) {
|
||||
if (array1 === array2) {
|
||||
return;
|
||||
}
|
||||
@@ -500,7 +500,8 @@ namespace Harness {
|
||||
export let IO: IO;
|
||||
|
||||
// harness always uses one kind of new line
|
||||
const harnessNewLine = "\r\n";
|
||||
// But note that `parseTestData` in `fourslash.ts` uses "\n"
|
||||
export const harnessNewLine = "\r\n";
|
||||
|
||||
// Root for file paths that are stored in a virtual file system
|
||||
export const virtualFileSystemRoot = "/";
|
||||
@@ -1284,16 +1285,31 @@ namespace Harness {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function minimalDiagnosticsToString(diagnostics: ts.Diagnostic[]) {
|
||||
return ts.formatDiagnostics(diagnostics, { getCanonicalFileName, getCurrentDirectory: () => "", getNewLine: () => Harness.IO.newLine() });
|
||||
export function minimalDiagnosticsToString(diagnostics: ReadonlyArray<ts.Diagnostic>, pretty?: boolean) {
|
||||
const host = { getCanonicalFileName, getCurrentDirectory: () => "", getNewLine: () => Harness.IO.newLine() };
|
||||
return (pretty ? ts.formatDiagnosticsWithColorAndContext : ts.formatDiagnostics)(diagnostics, host);
|
||||
}
|
||||
|
||||
export function getErrorBaseline(inputFiles: TestFile[], diagnostics: ts.Diagnostic[]) {
|
||||
diagnostics.sort(ts.compareDiagnostics);
|
||||
export function getErrorBaseline(inputFiles: ReadonlyArray<TestFile>, diagnostics: ReadonlyArray<ts.Diagnostic>, pretty?: boolean) {
|
||||
let outputLines = "";
|
||||
const gen = iterateErrorBaseline(inputFiles, diagnostics, pretty);
|
||||
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
|
||||
const [, content] = value;
|
||||
outputLines += content;
|
||||
}
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
export const diagnosticSummaryMarker = "__diagnosticSummary";
|
||||
export const globalErrorsMarker = "__globalErrors";
|
||||
export function *iterateErrorBaseline(inputFiles: ReadonlyArray<TestFile>, diagnostics: ReadonlyArray<ts.Diagnostic>, pretty?: boolean): IterableIterator<[string, string, number]> {
|
||||
diagnostics = diagnostics.slice().sort(ts.compareDiagnostics);
|
||||
let outputLines = "";
|
||||
// Count up all errors that were found in files other than lib.d.ts so we don't miss any
|
||||
let totalErrorsReportedInNonLibraryFiles = 0;
|
||||
|
||||
let errorsReported = 0;
|
||||
|
||||
let firstLine = true;
|
||||
function newLine() {
|
||||
if (firstLine) {
|
||||
@@ -1312,6 +1328,7 @@ namespace Harness {
|
||||
.filter(s => s.length > 0)
|
||||
.map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s);
|
||||
errLines.forEach(e => outputLines += (newLine() + e));
|
||||
errorsReported++;
|
||||
|
||||
// do not count errors from lib.d.ts here, they are computed separately as numLibraryDiagnostics
|
||||
// if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers)
|
||||
@@ -1323,12 +1340,18 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
yield [diagnosticSummaryMarker, minimalDiagnosticsToString(diagnostics, pretty) + Harness.IO.newLine() + Harness.IO.newLine(), diagnostics.length];
|
||||
|
||||
// Report global errors
|
||||
const globalErrors = diagnostics.filter(err => !err.file);
|
||||
globalErrors.forEach(outputErrorText);
|
||||
yield [globalErrorsMarker, outputLines, errorsReported];
|
||||
outputLines = "";
|
||||
errorsReported = 0;
|
||||
|
||||
// 'merge' the lines of each input file with any errors associated with it
|
||||
inputFiles.filter(f => f.content !== undefined).forEach(inputFile => {
|
||||
const dupeCase = ts.createMap<number>();
|
||||
for (const inputFile of inputFiles.filter(f => f.content !== undefined)) {
|
||||
// Filter down to the errors in the file
|
||||
const fileErrors = diagnostics.filter(e => {
|
||||
const errFn = e.file;
|
||||
@@ -1394,7 +1417,10 @@ namespace Harness {
|
||||
|
||||
// Verify we didn't miss any errors in this file
|
||||
assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName);
|
||||
});
|
||||
yield [checkDuplicatedFileName(inputFile.unitName, dupeCase), outputLines, errorsReported];
|
||||
outputLines = "";
|
||||
errorsReported = 0;
|
||||
}
|
||||
|
||||
const numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
return diagnostic.file && (isDefaultLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName));
|
||||
@@ -1407,23 +1433,20 @@ namespace Harness {
|
||||
|
||||
// Verify we didn't miss any errors in total
|
||||
assert.equal(totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors");
|
||||
|
||||
return minimalDiagnosticsToString(diagnostics) +
|
||||
Harness.IO.newLine() + Harness.IO.newLine() + outputLines;
|
||||
}
|
||||
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: TestFile[], errors: ts.Diagnostic[]) {
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: TestFile[], errors: ts.Diagnostic[], pretty?: boolean) {
|
||||
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), (): string => {
|
||||
if (!errors || (errors.length === 0)) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
return getErrorBaseline(inputFiles, errors);
|
||||
return getErrorBaseline(inputFiles, errors, pretty);
|
||||
});
|
||||
}
|
||||
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, result: CompilerResult, allFiles: {unitName: string, content: string}[], opts?: Harness.Baseline.BaselineOptions) {
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, result: CompilerResult, allFiles: {unitName: string, content: string}[], opts?: Harness.Baseline.BaselineOptions, multifile?: boolean) {
|
||||
if (result.errors.length !== 0) {
|
||||
return;
|
||||
}
|
||||
@@ -1484,24 +1507,42 @@ namespace Harness {
|
||||
return;
|
||||
|
||||
function checkBaseLines(isSymbolBaseLine: boolean) {
|
||||
const fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine);
|
||||
|
||||
const fullExtension = isSymbolBaseLine ? ".symbols" : ".types";
|
||||
|
||||
// When calling this function from rwc-runner, the baselinePath will have no extension.
|
||||
// As rwc test- file is stored in json which ".json" will get stripped off.
|
||||
// When calling this function from compiler-runner, the baselinePath will then has either ".ts" or ".tsx" extension
|
||||
const outputFileName = ts.endsWith(baselinePath, ts.Extension.Ts) || ts.endsWith(baselinePath, ts.Extension.Tsx) ?
|
||||
baselinePath.replace(/\.tsx?/, fullExtension) : baselinePath.concat(fullExtension);
|
||||
Harness.Baseline.runBaseline(outputFileName, () => fullBaseLine, opts);
|
||||
baselinePath.replace(/\.tsx?/, "") : baselinePath;
|
||||
|
||||
if (!multifile) {
|
||||
const fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine);
|
||||
Harness.Baseline.runBaseline(outputFileName + fullExtension, () => fullBaseLine, opts);
|
||||
}
|
||||
else {
|
||||
Harness.Baseline.runMultifileBaseline(outputFileName, fullExtension, () => {
|
||||
return iterateBaseLine(fullResults, isSymbolBaseLine);
|
||||
}, opts);
|
||||
}
|
||||
}
|
||||
|
||||
function generateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
||||
const typeLines: string[] = [];
|
||||
const typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||
let result = "";
|
||||
const gen = iterateBaseLine(typeWriterResults, isSymbolBaseline);
|
||||
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
|
||||
const [, content] = value;
|
||||
result += content;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
allFiles.forEach(file => {
|
||||
function *iterateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): IterableIterator<[string, string]> {
|
||||
let typeLines = "";
|
||||
const typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||
const dupeCase = ts.createMap<number>();
|
||||
|
||||
for (const file of allFiles) {
|
||||
const codeLines = file.content.split("\n");
|
||||
const key = file.unitName;
|
||||
typeWriterResults.get(file.unitName).forEach(result => {
|
||||
if (isSymbolBaseline && !result.symbol) {
|
||||
return;
|
||||
@@ -1509,42 +1550,42 @@ namespace Harness {
|
||||
|
||||
const typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type;
|
||||
const formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString;
|
||||
if (!typeMap[file.unitName]) {
|
||||
typeMap[file.unitName] = {};
|
||||
if (!typeMap[key]) {
|
||||
typeMap[key] = {};
|
||||
}
|
||||
|
||||
let typeInfo = [formattedLine];
|
||||
const existingTypeInfo = typeMap[file.unitName][result.line];
|
||||
const existingTypeInfo = typeMap[key][result.line];
|
||||
if (existingTypeInfo) {
|
||||
typeInfo = existingTypeInfo.concat(typeInfo);
|
||||
}
|
||||
typeMap[file.unitName][result.line] = typeInfo;
|
||||
typeMap[key][result.line] = typeInfo;
|
||||
});
|
||||
|
||||
typeLines.push("=== " + file.unitName + " ===\r\n");
|
||||
typeLines += "=== " + file.unitName + " ===\r\n";
|
||||
for (let i = 0; i < codeLines.length; i++) {
|
||||
const currentCodeLine = codeLines[i];
|
||||
typeLines.push(currentCodeLine + "\r\n");
|
||||
if (typeMap[file.unitName]) {
|
||||
const typeInfo = typeMap[file.unitName][i];
|
||||
typeLines += currentCodeLine + "\r\n";
|
||||
if (typeMap[key]) {
|
||||
const typeInfo = typeMap[key][i];
|
||||
if (typeInfo) {
|
||||
typeInfo.forEach(ty => {
|
||||
typeLines.push(">" + ty + "\r\n");
|
||||
typeLines += ">" + ty + "\r\n";
|
||||
});
|
||||
if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === "")) {
|
||||
}
|
||||
else {
|
||||
typeLines.push("\r\n");
|
||||
typeLines += "\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
typeLines.push("No type information for this code.");
|
||||
typeLines += "No type information for this code.";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return typeLines.join("");
|
||||
yield [checkDuplicatedFileName(file.unitName, dupeCase), typeLines];
|
||||
typeLines = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1640,24 +1681,29 @@ namespace Harness {
|
||||
}
|
||||
|
||||
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string {
|
||||
// Collect, test, and sort the fileNames
|
||||
outputFiles.sort((a, b) => ts.compareStrings(cleanName(a.fileName), cleanName(b.fileName)));
|
||||
|
||||
const gen = iterateOutputs(outputFiles);
|
||||
// Emit them
|
||||
let result = "";
|
||||
for (const outputFile of outputFiles) {
|
||||
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
|
||||
// Some extra spacing if this isn't the first file
|
||||
if (result.length) {
|
||||
result += "\r\n\r\n";
|
||||
}
|
||||
|
||||
// FileName header + content
|
||||
result += "/*====== " + outputFile.fileName + " ======*/\r\n";
|
||||
|
||||
result += outputFile.code;
|
||||
const [, content] = value;
|
||||
result += content;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function *iterateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): IterableIterator<[string, string]> {
|
||||
// Collect, test, and sort the fileNames
|
||||
outputFiles.sort((a, b) => ts.compareStrings(cleanName(a.fileName), cleanName(b.fileName)));
|
||||
const dupeCase = ts.createMap<number>();
|
||||
// Yield them
|
||||
for (const outputFile of outputFiles) {
|
||||
yield [checkDuplicatedFileName(outputFile.fileName, dupeCase), "/*====== " + outputFile.fileName + " ======*/\r\n" + outputFile.code];
|
||||
}
|
||||
|
||||
function cleanName(fn: string) {
|
||||
const lastSlash = ts.normalizeSlashes(fn).lastIndexOf("/");
|
||||
@@ -1665,6 +1711,24 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
function checkDuplicatedFileName(resultName: string, dupeCase: ts.Map<number>): string {
|
||||
resultName = sanitizeTestFilePath(resultName);
|
||||
if (dupeCase.has(resultName)) {
|
||||
// A different baseline filename should be manufactured if the names differ only in case, for windows compat
|
||||
const count = 1 + dupeCase.get(resultName);
|
||||
dupeCase.set(resultName, count);
|
||||
resultName = `${resultName}.dupe${count}`;
|
||||
}
|
||||
else {
|
||||
dupeCase.set(resultName, 0);
|
||||
}
|
||||
return resultName;
|
||||
}
|
||||
|
||||
function sanitizeTestFilePath(name: string) {
|
||||
return ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/").toLowerCase();
|
||||
}
|
||||
|
||||
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
|
||||
export function compileString(_code: string, _unitName: string, _callback: (result: CompilerResult) => void) {
|
||||
// NEWTODO: Re-implement 'compileString'
|
||||
@@ -2002,6 +2066,66 @@ namespace Harness {
|
||||
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName);
|
||||
}
|
||||
|
||||
export function runMultifileBaseline(relativeFileBase: string, extension: string, generateContent: () => IterableIterator<[string, string, number]> | IterableIterator<[string, string]>, opts?: BaselineOptions, referencedExtensions?: string[]): void {
|
||||
const gen = generateContent();
|
||||
const writtenFiles = ts.createMap<true>();
|
||||
const canonicalize = ts.createGetCanonicalFileName(/*caseSensitive*/ false); // This is done so tests work on windows _and_ linux
|
||||
/* tslint:disable-next-line:no-null-keyword */
|
||||
const errors: Error[] = [];
|
||||
if (gen !== null) {
|
||||
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
|
||||
const [name, content, count] = value as [string, string, number | undefined];
|
||||
if (count === 0) continue; // Allow error reporter to skip writing files without errors
|
||||
const relativeFileName = ts.combinePaths(relativeFileBase, name) + extension;
|
||||
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
const actual = content;
|
||||
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
try {
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName);
|
||||
}
|
||||
catch (e) {
|
||||
errors.push(e);
|
||||
}
|
||||
const path = ts.toPath(relativeFileName, "", canonicalize);
|
||||
writtenFiles.set(path, true);
|
||||
}
|
||||
}
|
||||
|
||||
const referenceDir = referencePath(relativeFileBase, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
let existing = Harness.IO.readDirectory(referenceDir, referencedExtensions || [extension]);
|
||||
if (extension === ".ts" || referencedExtensions && referencedExtensions.indexOf(".ts") > -1 && referencedExtensions.indexOf(".d.ts") === -1) {
|
||||
// special-case and filter .d.ts out of .ts results
|
||||
existing = existing.filter(f => !ts.endsWith(f, ".d.ts"));
|
||||
}
|
||||
const missing: string[] = [];
|
||||
for (const name of existing) {
|
||||
const localCopy = name.substring(referenceDir.length - relativeFileBase.length);
|
||||
const path = ts.toPath(localCopy, "", canonicalize);
|
||||
if (!writtenFiles.has(path)) {
|
||||
missing.push(localCopy);
|
||||
}
|
||||
}
|
||||
if (missing.length) {
|
||||
for (const file of missing) {
|
||||
IO.writeFile(localPath(file + ".delete", opts && opts.Baselinefolder, opts && opts.Subfolder), "");
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length || missing.length) {
|
||||
let errorMsg = "";
|
||||
if (errors.length) {
|
||||
errorMsg += `The baseline for ${relativeFileBase} has changed:${"\n " + errors.map(e => e.message).join("\n ")}`;
|
||||
}
|
||||
if (errors.length && missing.length) {
|
||||
errorMsg += "\n";
|
||||
}
|
||||
if (missing.length) {
|
||||
errorMsg += `Baseline missing files:${"\n " + missing.join("\n ") + "\n"}Written:${"\n " + ts.arrayFrom(writtenFiles.keys()).join("\n ")}`;
|
||||
}
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function isDefaultLibraryFile(filePath: string): boolean {
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
public getNewLine(): string {
|
||||
return "\r\n";
|
||||
return harnessNewLine;
|
||||
}
|
||||
|
||||
public getFilenames(): string[] {
|
||||
@@ -487,6 +487,9 @@ namespace Harness.LanguageService {
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
|
||||
return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace));
|
||||
}
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan {
|
||||
return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine));
|
||||
}
|
||||
getCodeFixesAtPosition(): ts.CodeAction[] {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
@@ -686,7 +689,7 @@ namespace Harness.LanguageService {
|
||||
this.host.log(message);
|
||||
}
|
||||
|
||||
err(message: string): void {
|
||||
msg(message: string): void {
|
||||
this.host.log(message);
|
||||
}
|
||||
|
||||
@@ -702,7 +705,8 @@ namespace Harness.LanguageService {
|
||||
return false;
|
||||
}
|
||||
|
||||
group() { throw ts.notImplemented(); }
|
||||
startGroup() { throw ts.notImplemented(); }
|
||||
endGroup() { throw ts.notImplemented(); }
|
||||
|
||||
perftrc(message: string): void {
|
||||
return this.host.log(message);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const fs: any = require("fs");
|
||||
const path: any = require("path");
|
||||
import fs = require("fs");
|
||||
import path = require("path");
|
||||
|
||||
function instrumentForRecording(fn: string, tscPath: string) {
|
||||
instrument(tscPath, `
|
||||
@@ -38,7 +38,9 @@ function instrument(tscPath: string, prepareCode: string, cleanupCode = "") {
|
||||
|
||||
const index2 = index1 + invocationLine.length;
|
||||
const newContent = tscContent.substr(0, index1) + loggerContent + prepareCode + invocationLine + cleanupCode + tscContent.substr(index2) + "\r\n";
|
||||
fs.writeFile(tscPath, newContent);
|
||||
fs.writeFile(tscPath, newContent, err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -70,6 +70,7 @@ interface IOLog {
|
||||
depth: number,
|
||||
result: ReadonlyArray<string>,
|
||||
}[];
|
||||
useCaseSensitiveFileNames?: boolean;
|
||||
}
|
||||
|
||||
interface PlaybackControl {
|
||||
@@ -151,7 +152,7 @@ namespace Playback {
|
||||
wrapper.startRecord = (fileNameBase) => {
|
||||
recordLogFileNameBase = fileNameBase;
|
||||
recordLog = createEmptyLog();
|
||||
|
||||
recordLog.useCaseSensitiveFileNames = typeof underlying.useCaseSensitiveFileNames === "function" ? underlying.useCaseSensitiveFileNames() : underlying.useCaseSensitiveFileNames;
|
||||
if (typeof underlying.args !== "function") {
|
||||
recordLog.arguments = underlying.args;
|
||||
}
|
||||
@@ -249,6 +250,13 @@ namespace Playback {
|
||||
}
|
||||
underlying.exit(exitCode);
|
||||
};
|
||||
|
||||
wrapper.useCaseSensitiveFileNames = () => {
|
||||
if (replayLog !== undefined) {
|
||||
return !!replayLog.useCaseSensitiveFileNames;
|
||||
}
|
||||
return typeof underlying.useCaseSensitiveFileNames === "function" ? underlying.useCaseSensitiveFileNames() : underlying.useCaseSensitiveFileNames;
|
||||
};
|
||||
}
|
||||
|
||||
function recordReplay<T extends Function>(original: T, underlying: any) {
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
if (typeof describe === "undefined") {
|
||||
(global as any).describe = undefined; // If launched without mocha for parallel mode, we still need a global describe visible to satisfy the parsing of the unit tests
|
||||
(global as any).it = undefined;
|
||||
}
|
||||
namespace Harness.Parallel.Host {
|
||||
|
||||
interface ChildProcessPartial {
|
||||
send(message: any, callback?: (error: Error) => void): boolean;
|
||||
on(event: "error", listener: (err: Error) => void): this;
|
||||
on(event: "exit", listener: (code: number, signal: string) => void): this;
|
||||
on(event: "message", listener: (message: any) => void): this;
|
||||
disconnect(): void;
|
||||
}
|
||||
|
||||
interface ProgressBarsOptions {
|
||||
open: string;
|
||||
close: string;
|
||||
complete: string;
|
||||
incomplete: string;
|
||||
width: number;
|
||||
noColors: boolean;
|
||||
}
|
||||
interface ProgressBar {
|
||||
lastN?: number;
|
||||
title?: string;
|
||||
progressColor?: string;
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export function start() {
|
||||
initializeProgressBarsDependencies();
|
||||
console.log("Discovering tests...");
|
||||
const discoverStart = +(new Date());
|
||||
const { statSync }: { statSync(path: string): { size: number }; } = require("fs");
|
||||
const tasks: { runner: TestRunnerKind, file: string, size: number }[] = [];
|
||||
let totalSize = 0;
|
||||
for (const runner of runners) {
|
||||
const files = runner.enumerateTestFiles();
|
||||
for (const file of files) {
|
||||
const size = statSync(file).size;
|
||||
tasks.push({ runner: runner.kind(), file, size });
|
||||
totalSize += size;
|
||||
}
|
||||
}
|
||||
tasks.sort((a, b) => a.size - b.size);
|
||||
const batchSize = (totalSize / workerCount) * 0.9;
|
||||
console.log(`Discovered ${tasks.length} test files in ${+(new Date()) - discoverStart}ms.`);
|
||||
console.log(`Starting to run tests using ${workerCount} threads...`);
|
||||
const { fork }: { fork(modulePath: string, args?: string[], options?: {}): ChildProcessPartial; } = require("child_process");
|
||||
|
||||
const totalFiles = tasks.length;
|
||||
let passingFiles = 0;
|
||||
let failingFiles = 0;
|
||||
let errorResults: ErrorInfo[] = [];
|
||||
let totalPassing = 0;
|
||||
const startTime = Date.now();
|
||||
|
||||
const progressBars = new ProgressBars({ noColors });
|
||||
const progressUpdateInterval = 1 / progressBars._options.width;
|
||||
let nextProgress = progressUpdateInterval;
|
||||
|
||||
const workers: ChildProcessPartial[] = [];
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
// TODO: Just send the config over the IPC channel or in the command line arguments
|
||||
const config: TestConfig = { light: Harness.lightMode, listenForWork: true, runUnitTests: runners.length === 1 ? false : i === workerCount - 1 };
|
||||
const configPath = ts.combinePaths(taskConfigsFolder, `task-config${i}.json`);
|
||||
Harness.IO.writeFile(configPath, JSON.stringify(config));
|
||||
const child = fork(__filename, [`--config="${configPath}"`]);
|
||||
child.on("error", err => {
|
||||
child.disconnect();
|
||||
console.error("Unexpected error in child process:");
|
||||
console.error(err);
|
||||
return process.exit(2);
|
||||
});
|
||||
child.on("exit", (code, _signal) => {
|
||||
if (code !== 0) {
|
||||
console.error("Test worker process exited with nonzero exit code!");
|
||||
return process.exit(2);
|
||||
}
|
||||
});
|
||||
child.on("message", (data: ParallelClientMessage) => {
|
||||
switch (data.type) {
|
||||
case "error": {
|
||||
child.disconnect();
|
||||
console.error(`Test worker encounted unexpected error and was forced to close:
|
||||
Message: ${data.payload.error}
|
||||
Stack: ${data.payload.stack}`);
|
||||
return process.exit(2);
|
||||
}
|
||||
case "progress":
|
||||
case "result": {
|
||||
totalPassing += data.payload.passing;
|
||||
if (data.payload.errors.length) {
|
||||
errorResults = errorResults.concat(data.payload.errors);
|
||||
failingFiles++;
|
||||
}
|
||||
else {
|
||||
passingFiles++;
|
||||
}
|
||||
|
||||
const progress = (failingFiles + passingFiles) / totalFiles;
|
||||
if (progress >= nextProgress) {
|
||||
while (nextProgress < progress) {
|
||||
nextProgress += progressUpdateInterval;
|
||||
}
|
||||
updateProgress(progress, errorResults.length ? `${errorResults.length} failing` : `${totalPassing} passing`, errorResults.length ? "fail" : undefined);
|
||||
}
|
||||
|
||||
if (failingFiles + passingFiles === totalFiles) {
|
||||
// Done. Finished every task and collected results.
|
||||
child.send({ type: "close" });
|
||||
child.disconnect();
|
||||
return outputFinalResult();
|
||||
}
|
||||
if (tasks.length === 0) {
|
||||
// No more tasks to distribute
|
||||
child.send({ type: "close" });
|
||||
child.disconnect();
|
||||
return;
|
||||
}
|
||||
if (data.type === "result") {
|
||||
child.send({ type: "test", payload: tasks.pop() });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
workers.push(child);
|
||||
}
|
||||
|
||||
// It's only really worth doing an initial batching if there are a ton of files to go through
|
||||
if (totalFiles > 1000) {
|
||||
console.log("Batching initial test lists...");
|
||||
const batches: { runner: TestRunnerKind, file: string, size: number }[][] = new Array(workerCount);
|
||||
const doneBatching = new Array(workerCount);
|
||||
batcher: while (true) {
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
if (tasks.length === 0) {
|
||||
// TODO: This indicates a particularly suboptimal packing
|
||||
break batcher;
|
||||
}
|
||||
if (doneBatching[i]) {
|
||||
continue;
|
||||
}
|
||||
if (!batches[i]) {
|
||||
batches[i] = [];
|
||||
}
|
||||
const total = batches[i].reduce((p, c) => p + c.size, 0);
|
||||
if (total >= batchSize && !doneBatching[i]) {
|
||||
doneBatching[i] = true;
|
||||
continue;
|
||||
}
|
||||
batches[i].push(tasks.pop());
|
||||
}
|
||||
for (let j = 0; j < workerCount; j++) {
|
||||
if (!doneBatching[j]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
console.log(`Batched into ${workerCount} groups with approximate total file sizes of ${Math.floor(batchSize)} bytes in each group.`);
|
||||
for (const worker of workers) {
|
||||
const action: ParallelBatchMessage = { type: "batch", payload: batches.pop() };
|
||||
if (!action.payload[0]) {
|
||||
throw new Error(`Tried to send invalid message ${action}`);
|
||||
}
|
||||
worker.send(action);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
workers[i].send({ type: "test", payload: tasks.pop() });
|
||||
}
|
||||
}
|
||||
|
||||
progressBars.enable();
|
||||
updateProgress(0);
|
||||
let duration: number;
|
||||
|
||||
const ms = require("mocha/lib/ms");
|
||||
function completeBar() {
|
||||
const isPartitionFail = failingFiles !== 0;
|
||||
const summaryColor = isPartitionFail ? "fail" : "green";
|
||||
const summarySymbol = isPartitionFail ? Base.symbols.err : Base.symbols.ok;
|
||||
|
||||
const summaryTests = (isPartitionFail ? totalPassing + "/" + (errorResults.length + totalPassing) : totalPassing) + " passing";
|
||||
const summaryDuration = "(" + ms(duration) + ")";
|
||||
const savedUseColors = Base.useColors;
|
||||
Base.useColors = !noColors;
|
||||
|
||||
const summary = color(summaryColor, summarySymbol + " " + summaryTests) + " " + color("light", summaryDuration);
|
||||
Base.useColors = savedUseColors;
|
||||
|
||||
updateProgress(1, summary);
|
||||
}
|
||||
|
||||
function updateProgress(percentComplete: number, title?: string, titleColor?: string) {
|
||||
let progressColor = "pending";
|
||||
if (failingFiles) {
|
||||
progressColor = "fail";
|
||||
}
|
||||
|
||||
progressBars.update(
|
||||
0,
|
||||
percentComplete,
|
||||
progressColor,
|
||||
title,
|
||||
titleColor
|
||||
);
|
||||
}
|
||||
|
||||
function outputFinalResult() {
|
||||
duration = Date.now() - startTime;
|
||||
completeBar();
|
||||
progressBars.disable();
|
||||
|
||||
const reporter = new Base();
|
||||
const stats = reporter.stats;
|
||||
const failures = reporter.failures;
|
||||
stats.passes = totalPassing;
|
||||
stats.failures = errorResults.length;
|
||||
stats.tests = totalPassing + errorResults.length;
|
||||
stats.duration = duration;
|
||||
for (let j = 0; j < errorResults.length; j++) {
|
||||
const failure = errorResults[j];
|
||||
failures.push(makeMochaTest(failure));
|
||||
}
|
||||
if (noColors) {
|
||||
const savedUseColors = Base.useColors;
|
||||
Base.useColors = false;
|
||||
reporter.epilogue();
|
||||
Base.useColors = savedUseColors;
|
||||
}
|
||||
else {
|
||||
reporter.epilogue();
|
||||
}
|
||||
|
||||
process.exit(errorResults.length);
|
||||
}
|
||||
|
||||
function makeMochaTest(test: ErrorInfo) {
|
||||
return {
|
||||
fullTitle: () => {
|
||||
return test.name;
|
||||
},
|
||||
err: {
|
||||
message: test.error,
|
||||
stack: test.stack
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describe = ts.noop as any; // Disable unit tests
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let Mocha: any;
|
||||
let Base: any;
|
||||
let color: any;
|
||||
let cursor: any;
|
||||
let readline: any;
|
||||
let os: any;
|
||||
let tty: { isatty(x: number): boolean };
|
||||
let isatty: boolean;
|
||||
|
||||
function initializeProgressBarsDependencies() {
|
||||
Mocha = require("mocha");
|
||||
Base = Mocha.reporters.Base;
|
||||
color = Base.color;
|
||||
cursor = Base.cursor;
|
||||
readline = require("readline");
|
||||
os = require("os");
|
||||
tty = require("tty");
|
||||
isatty = tty.isatty(1) && tty.isatty(2);
|
||||
}
|
||||
|
||||
class ProgressBars {
|
||||
public readonly _options: Readonly<ProgressBarsOptions>;
|
||||
private _enabled: boolean;
|
||||
private _lineCount: number;
|
||||
private _progressBars: ProgressBar[];
|
||||
constructor(options?: Partial<ProgressBarsOptions>) {
|
||||
if (!options) options = {};
|
||||
const open = options.open || "[";
|
||||
const close = options.close || "]";
|
||||
const complete = options.complete || "▬";
|
||||
const incomplete = options.incomplete || Base.symbols.dot;
|
||||
const maxWidth = Base.window.width - open.length - close.length - 30;
|
||||
const width = minMax(options.width || maxWidth, 10, maxWidth);
|
||||
this._options = {
|
||||
open,
|
||||
complete,
|
||||
incomplete,
|
||||
close,
|
||||
width,
|
||||
noColors: options.noColors || false
|
||||
};
|
||||
|
||||
this._progressBars = [];
|
||||
this._lineCount = 0;
|
||||
this._enabled = false;
|
||||
}
|
||||
enable() {
|
||||
if (!this._enabled) {
|
||||
process.stdout.write(os.EOL);
|
||||
this._enabled = true;
|
||||
}
|
||||
}
|
||||
disable() {
|
||||
if (this._enabled) {
|
||||
process.stdout.write(os.EOL);
|
||||
this._enabled = false;
|
||||
}
|
||||
}
|
||||
update(index: number, percentComplete: number, color: string, title: string, titleColor?: string) {
|
||||
percentComplete = minMax(percentComplete, 0, 1);
|
||||
|
||||
const progressBar = this._progressBars[index] || (this._progressBars[index] = { });
|
||||
const width = this._options.width;
|
||||
const n = Math.floor(width * percentComplete);
|
||||
const i = width - n;
|
||||
if (n === progressBar.lastN && title === progressBar.title && color === progressBar.progressColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
progressBar.lastN = n;
|
||||
progressBar.title = title;
|
||||
progressBar.progressColor = color;
|
||||
|
||||
let progress = " ";
|
||||
progress += this._color("progress", this._options.open);
|
||||
progress += this._color(color, fill(this._options.complete, n));
|
||||
progress += this._color("progress", fill(this._options.incomplete, i));
|
||||
progress += this._color("progress", this._options.close);
|
||||
|
||||
if (title) {
|
||||
progress += this._color(titleColor || "progress", " " + title);
|
||||
}
|
||||
|
||||
if (progressBar.text !== progress) {
|
||||
progressBar.text = progress;
|
||||
this._render(index);
|
||||
}
|
||||
}
|
||||
private _render(index: number) {
|
||||
if (!this._enabled || !isatty) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.hide();
|
||||
readline.moveCursor(process.stdout, -process.stdout.columns, -this._lineCount);
|
||||
let lineCount = 0;
|
||||
const numProgressBars = this._progressBars.length;
|
||||
for (let i = 0; i < numProgressBars; i++) {
|
||||
if (i === index) {
|
||||
readline.clearLine(process.stdout, 1);
|
||||
process.stdout.write(this._progressBars[i].text + os.EOL);
|
||||
}
|
||||
else {
|
||||
readline.moveCursor(process.stdout, -process.stdout.columns, +1);
|
||||
}
|
||||
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
this._lineCount = lineCount;
|
||||
cursor.show();
|
||||
}
|
||||
private _color(type: string, text: string) {
|
||||
return type && !this._options.noColors ? color(type, text) : text;
|
||||
}
|
||||
}
|
||||
|
||||
function fill(ch: string, size: number) {
|
||||
let s = "";
|
||||
while (s.length < size) {
|
||||
s += ch;
|
||||
}
|
||||
|
||||
return s.length > size ? s.substr(0, size) : s;
|
||||
}
|
||||
|
||||
function minMax(value: number, min: number, max: number) {
|
||||
if (value < min) return min;
|
||||
if (value > max) return max;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/// <reference path="./host.ts" />
|
||||
/// <reference path="./worker.ts" />
|
||||
namespace Harness.Parallel {
|
||||
export type ParallelTestMessage = { type: "test", payload: { runner: TestRunnerKind, file: string } } | never;
|
||||
export type ParallelBatchMessage = { type: "batch", payload: ParallelTestMessage["payload"][] } | never;
|
||||
export type ParallelCloseMessage = { type: "close" } | never;
|
||||
export type ParallelHostMessage = ParallelTestMessage | ParallelCloseMessage | ParallelBatchMessage;
|
||||
|
||||
export type ParallelErrorMessage = { type: "error", payload: { error: string, stack: string } } | never;
|
||||
export type ErrorInfo = ParallelErrorMessage["payload"] & { name: string };
|
||||
export type ParallelResultMessage = { type: "result", payload: { passing: number, errors: ErrorInfo[] } } | never;
|
||||
export type ParallelBatchProgressMessage = { type: "progress", payload: ParallelResultMessage["payload"] } | never;
|
||||
export type ParallelClientMessage = ParallelErrorMessage | ParallelResultMessage | ParallelBatchProgressMessage;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
namespace Harness.Parallel.Worker {
|
||||
let errors: ErrorInfo[] = [];
|
||||
let passing = 0;
|
||||
function resetShimHarnessAndExecute(runner: RunnerBase) {
|
||||
errors = [];
|
||||
passing = 0;
|
||||
runner.initializeTests();
|
||||
return { errors, passing };
|
||||
}
|
||||
|
||||
function shimMochaHarness() {
|
||||
(global as any).before = undefined;
|
||||
(global as any).after = undefined;
|
||||
(global as any).beforeEach = undefined;
|
||||
let beforeEachFunc: Function;
|
||||
describe = ((_name, callback) => {
|
||||
const fakeContext: Mocha.ISuiteCallbackContext = {
|
||||
retries() { return this; },
|
||||
slow() { return this; },
|
||||
timeout() { return this; },
|
||||
};
|
||||
(before as any) = (cb: Function) => cb();
|
||||
let afterFunc: Function;
|
||||
(after as any) = (cb: Function) => afterFunc = cb;
|
||||
const savedBeforeEach = beforeEachFunc;
|
||||
(beforeEach as any) = (cb: Function) => beforeEachFunc = cb;
|
||||
callback.call(fakeContext);
|
||||
afterFunc && afterFunc();
|
||||
afterFunc = undefined;
|
||||
beforeEachFunc = savedBeforeEach;
|
||||
}) as Mocha.IContextDefinition;
|
||||
it = ((name, callback) => {
|
||||
const fakeContext: Mocha.ITestCallbackContext = {
|
||||
skip() { return this; },
|
||||
timeout() { return this; },
|
||||
retries() { return this; },
|
||||
slow() { return this; },
|
||||
};
|
||||
// TODO: If we ever start using async test completions, polyfill the `done` parameter/promise return handling
|
||||
if (beforeEachFunc) {
|
||||
try {
|
||||
beforeEachFunc();
|
||||
}
|
||||
catch (error) {
|
||||
errors.push({ error: error.message, stack: error.stack, name });
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
callback.call(fakeContext);
|
||||
}
|
||||
catch (error) {
|
||||
errors.push({ error: error.message, stack: error.stack, name });
|
||||
return;
|
||||
}
|
||||
passing++;
|
||||
}) as Mocha.ITestDefinition;
|
||||
}
|
||||
|
||||
export function start() {
|
||||
let initialized = false;
|
||||
const runners = ts.createMap<RunnerBase>();
|
||||
process.on("message", (data: ParallelHostMessage) => {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
shimMochaHarness();
|
||||
}
|
||||
switch (data.type) {
|
||||
case "test":
|
||||
const { runner, file } = data.payload;
|
||||
if (!runner) {
|
||||
console.error(data);
|
||||
}
|
||||
const message: ParallelResultMessage = { type: "result", payload: handleTest(runner, file) };
|
||||
process.send(message);
|
||||
break;
|
||||
case "close":
|
||||
process.exit(0);
|
||||
break;
|
||||
case "batch": {
|
||||
const items = data.payload;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const { runner, file } = items[i];
|
||||
if (!runner) {
|
||||
console.error(data);
|
||||
}
|
||||
let message: ParallelBatchProgressMessage | ParallelResultMessage;
|
||||
const payload = handleTest(runner, file);
|
||||
if (i === (items.length - 1)) {
|
||||
message = { type: "result", payload };
|
||||
}
|
||||
else {
|
||||
message = { type: "progress", payload };
|
||||
}
|
||||
process.send(message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
process.on("uncaughtException", error => {
|
||||
const message: ParallelErrorMessage = { type: "error", payload: { error: error.message, stack: error.stack } };
|
||||
process.send(message);
|
||||
});
|
||||
if (!runUnitTests) {
|
||||
// ensure unit tests do not get run
|
||||
describe = ts.noop as any;
|
||||
}
|
||||
else {
|
||||
initialized = true;
|
||||
shimMochaHarness();
|
||||
}
|
||||
|
||||
function handleTest(runner: TestRunnerKind, file: string) {
|
||||
if (!runners.has(runner)) {
|
||||
runners.set(runner, createRunner(runner));
|
||||
}
|
||||
const instance = runners.get(runner);
|
||||
instance.tests = [file];
|
||||
return resetShimHarnessAndExecute(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
interface ProjectRunnerTestCase {
|
||||
scenario: string;
|
||||
projectRoot: string; // project where it lives - this also is the current directory when compiling
|
||||
inputFiles: string[]; // list of input files to be given to program
|
||||
inputFiles: ReadonlyArray<string>; // list of input files to be given to program
|
||||
resolveMapRoot?: boolean; // should we resolve this map root and give compiler the absolute disk path as map root?
|
||||
resolveSourceRoot?: boolean; // should we resolve this source root and give compiler the absolute disk path as map root?
|
||||
baselineCheck?: boolean; // Verify the baselines of output files, if this is false, we will write to output to the disk but there is no verification of baselines
|
||||
@@ -15,8 +15,8 @@ interface ProjectRunnerTestCase {
|
||||
|
||||
interface ProjectRunnerTestCaseResolutionInfo extends ProjectRunnerTestCase {
|
||||
// Apart from actual test case the results of the resolution
|
||||
resolvedInputFiles: string[]; // List of files that were asked to read by compiler
|
||||
emittedFiles: string[]; // List of files that were emitted by the compiler
|
||||
resolvedInputFiles: ReadonlyArray<string>; // List of files that were asked to read by compiler
|
||||
emittedFiles: ReadonlyArray<string>; // List of files that were emitted by the compiler
|
||||
}
|
||||
|
||||
interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.GeneratedFile {
|
||||
@@ -24,12 +24,12 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
|
||||
}
|
||||
|
||||
interface CompileProjectFilesResult {
|
||||
configFileSourceFiles: ts.SourceFile[];
|
||||
configFileSourceFiles: ReadonlyArray<ts.SourceFile>;
|
||||
moduleKind: ts.ModuleKind;
|
||||
program?: ts.Program;
|
||||
compilerOptions?: ts.CompilerOptions;
|
||||
errors: ts.Diagnostic[];
|
||||
sourceMapData?: ts.SourceMapData[];
|
||||
errors: ReadonlyArray<ts.Diagnostic>;
|
||||
sourceMapData?: ReadonlyArray<ts.SourceMapData>;
|
||||
}
|
||||
|
||||
interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult {
|
||||
@@ -125,17 +125,17 @@ class ProjectRunner extends RunnerBase {
|
||||
return Harness.IO.resolvePath(testCase.projectRoot);
|
||||
}
|
||||
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, configFileSourceFiles: ts.SourceFile[],
|
||||
getInputFiles: () => string[],
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, configFileSourceFiles: ReadonlyArray<ts.SourceFile>,
|
||||
getInputFiles: () => ReadonlyArray<string>,
|
||||
getSourceFileTextImpl: (fileName: string) => string,
|
||||
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void,
|
||||
compilerOptions: ts.CompilerOptions): CompileProjectFilesResult {
|
||||
|
||||
const program = ts.createProgram(getInputFiles(), compilerOptions, createCompilerHost());
|
||||
let errors = ts.getPreEmitDiagnostics(program);
|
||||
const errors = ts.getPreEmitDiagnostics(program);
|
||||
|
||||
const emitResult = program.emit();
|
||||
errors = ts.concatenate(errors, emitResult.diagnostics);
|
||||
ts.addRange(errors, emitResult.diagnostics);
|
||||
const sourceMapData = emitResult.sourceMaps;
|
||||
|
||||
// Clean up source map data that will be used in baselining
|
||||
@@ -235,7 +235,7 @@ class ProjectRunner extends RunnerBase {
|
||||
compilerOptions,
|
||||
sourceMapData: projectCompilerResult.sourceMapData,
|
||||
outputFiles,
|
||||
errors: errors ? errors.concat(projectCompilerResult.errors) : projectCompilerResult.errors,
|
||||
errors: errors ? ts.concatenate(errors, projectCompilerResult.errors) : projectCompilerResult.errors,
|
||||
};
|
||||
|
||||
function createCompilerOptions() {
|
||||
@@ -422,16 +422,21 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function getErrorsBaseline(compilerResult: CompileProjectFilesResult) {
|
||||
const inputFiles = ts.map(compilerResult.configFileSourceFiles.concat(
|
||||
compilerResult.program ?
|
||||
ts.filter(compilerResult.program.getSourceFiles(), sourceFile => !Harness.isDefaultLibraryFile(sourceFile.fileName)) :
|
||||
[]),
|
||||
(sourceFile): Harness.Compiler.TestFile => ({
|
||||
unitName: ts.isRootedDiskPath(sourceFile.fileName) ?
|
||||
RunnerBase.removeFullPaths(sourceFile.fileName) :
|
||||
sourceFile.fileName,
|
||||
content: sourceFile.text
|
||||
}));
|
||||
const inputSourceFiles = compilerResult.configFileSourceFiles.slice();
|
||||
if (compilerResult.program) {
|
||||
for (const sourceFile of compilerResult.program.getSourceFiles()) {
|
||||
if (!Harness.isDefaultLibraryFile(sourceFile.fileName)) {
|
||||
inputSourceFiles.push(sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const inputFiles = inputSourceFiles.map<Harness.Compiler.TestFile>(sourceFile => ({
|
||||
unitName: ts.isRootedDiskPath(sourceFile.fileName) ?
|
||||
RunnerBase.removeFullPaths(sourceFile.fileName) :
|
||||
sourceFile.fileName,
|
||||
content: sourceFile.text
|
||||
}));
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
}
|
||||
|
||||
+106
-118
@@ -19,6 +19,7 @@
|
||||
/// <reference path="projectsRunner.ts" />
|
||||
/// <reference path="rwcRunner.ts" />
|
||||
/// <reference path="harness.ts" />
|
||||
/// <reference path="./parallel/shared.ts" />
|
||||
|
||||
let runners: RunnerBase[] = [];
|
||||
let iterations = 1;
|
||||
@@ -59,6 +60,7 @@ function createRunner(kind: TestRunnerKind): RunnerBase {
|
||||
case "test262":
|
||||
return new Test262BaselineRunner();
|
||||
}
|
||||
ts.Debug.fail(`Unknown runner kind ${kind}`);
|
||||
}
|
||||
|
||||
if (Harness.IO.tryEnableSourceMapsForHost && /^development$/i.test(Harness.IO.getEnvironmentVariable("NODE_ENV"))) {
|
||||
@@ -81,15 +83,17 @@ let testConfigContent =
|
||||
let taskConfigsFolder: string;
|
||||
let workerCount: number;
|
||||
let runUnitTests = true;
|
||||
let noColors = false;
|
||||
|
||||
interface TestConfig {
|
||||
light?: boolean;
|
||||
taskConfigsFolder?: string;
|
||||
listenForWork?: boolean;
|
||||
workerCount?: number;
|
||||
stackTraceLimit?: number | "full";
|
||||
tasks?: TaskSet[];
|
||||
test?: string[];
|
||||
runUnitTests?: boolean;
|
||||
noColors?: boolean;
|
||||
}
|
||||
|
||||
interface TaskSet {
|
||||
@@ -97,138 +101,122 @@ interface TaskSet {
|
||||
files: string[];
|
||||
}
|
||||
|
||||
if (testConfigContent !== "") {
|
||||
const testConfig = <TestConfig>JSON.parse(testConfigContent);
|
||||
if (testConfig.light) {
|
||||
Harness.lightMode = true;
|
||||
}
|
||||
if (testConfig.taskConfigsFolder) {
|
||||
taskConfigsFolder = testConfig.taskConfigsFolder;
|
||||
}
|
||||
if (testConfig.runUnitTests !== undefined) {
|
||||
runUnitTests = testConfig.runUnitTests;
|
||||
}
|
||||
if (testConfig.workerCount) {
|
||||
workerCount = testConfig.workerCount;
|
||||
}
|
||||
if (testConfig.tasks) {
|
||||
for (const taskSet of testConfig.tasks) {
|
||||
const runner = createRunner(taskSet.runner);
|
||||
for (const file of taskSet.files) {
|
||||
runner.addTest(file);
|
||||
}
|
||||
runners.push(runner);
|
||||
function handleTestConfig() {
|
||||
if (testConfigContent !== "") {
|
||||
const testConfig = <TestConfig>JSON.parse(testConfigContent);
|
||||
if (testConfig.light) {
|
||||
Harness.lightMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (testConfig.stackTraceLimit === "full") {
|
||||
(<any>Error).stackTraceLimit = Infinity;
|
||||
}
|
||||
else if ((+testConfig.stackTraceLimit | 0) > 0) {
|
||||
(<any>Error).stackTraceLimit = testConfig.stackTraceLimit;
|
||||
}
|
||||
|
||||
if (testConfig.test && testConfig.test.length > 0) {
|
||||
for (const option of testConfig.test) {
|
||||
if (!option) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (option) {
|
||||
case "compiler":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case "conformance":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
break;
|
||||
case "project":
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case "fourslash":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case "fourslash-shims":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
break;
|
||||
case "fourslash-shims-pp":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
|
||||
break;
|
||||
case "fourslash-server":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
break;
|
||||
case "fourslash-generated":
|
||||
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case "rwc":
|
||||
runners.push(new RWCRunner());
|
||||
break;
|
||||
case "test262":
|
||||
runners.push(new Test262BaselineRunner());
|
||||
break;
|
||||
}
|
||||
if (testConfig.runUnitTests !== undefined) {
|
||||
runUnitTests = testConfig.runUnitTests;
|
||||
}
|
||||
if (testConfig.workerCount) {
|
||||
workerCount = +testConfig.workerCount;
|
||||
}
|
||||
if (testConfig.taskConfigsFolder) {
|
||||
taskConfigsFolder = testConfig.taskConfigsFolder;
|
||||
}
|
||||
if (testConfig.noColors !== undefined) {
|
||||
noColors = testConfig.noColors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (runners.length === 0) {
|
||||
// compiler
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
if (testConfig.stackTraceLimit === "full") {
|
||||
(<any>Error).stackTraceLimit = Infinity;
|
||||
}
|
||||
else if ((+testConfig.stackTraceLimit | 0) > 0) {
|
||||
(<any>Error).stackTraceLimit = testConfig.stackTraceLimit;
|
||||
}
|
||||
if (testConfig.listenForWork) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: project tests don't work in the browser yet
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
|
||||
runners.push(new ProjectRunner());
|
||||
}
|
||||
if (testConfig.test && testConfig.test.length > 0) {
|
||||
for (const option of testConfig.test) {
|
||||
if (!option) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// language services
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
// runners.push(new GeneratedFourslashRunner());
|
||||
}
|
||||
|
||||
if (taskConfigsFolder) {
|
||||
// this instance of mocha should only partition work but not run actual tests
|
||||
runUnitTests = false;
|
||||
const workerConfigs: TestConfig[] = [];
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
// pass light mode settings to workers
|
||||
workerConfigs.push({ light: Harness.lightMode, tasks: [] });
|
||||
}
|
||||
|
||||
for (const runner of runners) {
|
||||
const files = runner.enumerateTestFiles();
|
||||
const chunkSize = Math.floor(files.length / workerCount) + 1; // add extra 1 to prevent missing tests due to rounding
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
const startPos = i * chunkSize;
|
||||
const len = Math.min(chunkSize, files.length - startPos);
|
||||
if (len > 0) {
|
||||
workerConfigs[i].tasks.push({
|
||||
runner: runner.kind(),
|
||||
files: files.slice(startPos, startPos + len)
|
||||
});
|
||||
switch (option) {
|
||||
case "compiler":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case "conformance":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
break;
|
||||
case "project":
|
||||
runners.push(new ProjectRunner());
|
||||
break;
|
||||
case "fourslash":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case "fourslash-shims":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
break;
|
||||
case "fourslash-shims-pp":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
|
||||
break;
|
||||
case "fourslash-server":
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
break;
|
||||
case "fourslash-generated":
|
||||
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
|
||||
break;
|
||||
case "rwc":
|
||||
runners.push(new RWCRunner());
|
||||
break;
|
||||
case "test262":
|
||||
runners.push(new Test262BaselineRunner());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
const config = workerConfigs[i];
|
||||
// use last worker to run unit tests
|
||||
config.runUnitTests = i === workerCount - 1;
|
||||
Harness.IO.writeFile(ts.combinePaths(taskConfigsFolder, `task-config${i}.json`), JSON.stringify(workerConfigs[i]));
|
||||
if (runners.length === 0) {
|
||||
// compiler
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
|
||||
// TODO: project tests don"t work in the browser yet
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
|
||||
runners.push(new ProjectRunner());
|
||||
}
|
||||
|
||||
// language services
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Native));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
// runners.push(new GeneratedFourslashRunner());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
function beginTests() {
|
||||
if (ts.Debug.isDebugging) {
|
||||
ts.Debug.enableDebugInfo();
|
||||
}
|
||||
|
||||
runTests(runners);
|
||||
|
||||
if (!runUnitTests) {
|
||||
// patch `describe` to skip unit tests
|
||||
describe = ts.noop as any;
|
||||
}
|
||||
}
|
||||
if (!runUnitTests) {
|
||||
// patch `describe` to skip unit tests
|
||||
describe = ts.noop as any;
|
||||
|
||||
function startTestEnvironment() {
|
||||
const isWorker = handleTestConfig();
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
|
||||
if (isWorker) {
|
||||
return Harness.Parallel.Worker.start();
|
||||
}
|
||||
else if (taskConfigsFolder && workerCount && workerCount > 1) {
|
||||
return Harness.Parallel.Host.start();
|
||||
}
|
||||
}
|
||||
beginTests();
|
||||
}
|
||||
|
||||
startTestEnvironment();
|
||||
|
||||
+24
-19
@@ -90,9 +90,16 @@ namespace RWC {
|
||||
ts.setConfigFileInOptions(opts.options, configParseResult.options.configFile);
|
||||
}
|
||||
|
||||
// Load the files
|
||||
// Deduplicate files so they are only printed once in baselines (they are deduplicated within the compiler already)
|
||||
const uniqueNames = ts.createMap<true>();
|
||||
for (const fileName of fileNames) {
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
||||
// Must maintain order, build result list while checking map
|
||||
const normalized = ts.normalizeSlashes(fileName);
|
||||
if (!uniqueNames.has(normalized)) {
|
||||
uniqueNames.set(normalized, true);
|
||||
// Load the file
|
||||
inputFiles.push(getHarnessCompilerInputUnit(fileName));
|
||||
}
|
||||
}
|
||||
|
||||
// Add files to compilation
|
||||
@@ -163,29 +170,29 @@ namespace RWC {
|
||||
|
||||
|
||||
it("has the expected emitted code", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.output.js`, () => {
|
||||
return Harness.Compiler.collateOutputs(compilerResult.files);
|
||||
}, baselineOpts);
|
||||
Harness.Baseline.runMultifileBaseline(baseName, "", () => {
|
||||
return Harness.Compiler.iterateOutputs(compilerResult.files);
|
||||
}, baselineOpts, [".js", ".jsx"]);
|
||||
});
|
||||
|
||||
it("has the expected declaration file content", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.d.ts`, () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, "", () => {
|
||||
if (!compilerResult.declFilesCode.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.collateOutputs(compilerResult.declFilesCode);
|
||||
}, baselineOpts);
|
||||
return Harness.Compiler.iterateOutputs(compilerResult.declFilesCode);
|
||||
}, baselineOpts, [".d.ts"]);
|
||||
});
|
||||
|
||||
it("has the expected source maps", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.map`, () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, "", () => {
|
||||
if (!compilerResult.sourceMaps.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.collateOutputs(compilerResult.sourceMaps);
|
||||
}, baselineOpts);
|
||||
return Harness.Compiler.iterateOutputs(compilerResult.sourceMaps);
|
||||
}, baselineOpts, [".map"]);
|
||||
});
|
||||
|
||||
/*it("has correct source map record", () => {
|
||||
@@ -197,14 +204,14 @@ namespace RWC {
|
||||
});*/
|
||||
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.errors.txt`, () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, ".errors.txt", () => {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
// Do not include the library in the baselines to avoid noise
|
||||
const baselineFiles = tsconfigFiles.concat(inputFiles, otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
|
||||
const errors = compilerResult.errors.filter(e => !e.file || !Harness.isDefaultLibraryFile(e.file.fileName));
|
||||
return Harness.Compiler.getErrorBaseline(baselineFiles, errors);
|
||||
return Harness.Compiler.iterateErrorBaseline(baselineFiles, errors);
|
||||
}, baselineOpts);
|
||||
});
|
||||
|
||||
@@ -213,14 +220,14 @@ namespace RWC {
|
||||
Harness.Compiler.doTypeAndSymbolBaseline(baseName, compilerResult, inputFiles
|
||||
.concat(otherFiles)
|
||||
.filter(file => !!compilerResult.program.getSourceFile(file.unitName))
|
||||
.filter(e => !Harness.isDefaultLibraryFile(e.unitName)), baselineOpts);
|
||||
.filter(e => !Harness.isDefaultLibraryFile(e.unitName)), baselineOpts, /*multifile*/ true);
|
||||
});
|
||||
|
||||
// Ideally, a generated declaration file will have no errors. But we allow generated
|
||||
// declaration file errors as part of the baseline.
|
||||
it("has the expected errors in generated declaration files", () => {
|
||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline(`${baseName}.dts.errors.txt`, () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, ".dts.errors.txt", () => {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -232,9 +239,7 @@ namespace RWC {
|
||||
compilerResult = undefined;
|
||||
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(declContext);
|
||||
|
||||
return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) +
|
||||
Harness.IO.newLine() + Harness.IO.newLine() +
|
||||
Harness.Compiler.getErrorBaseline(tsconfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
return Harness.Compiler.iterateErrorBaseline(tsconfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
}, baselineOpts);
|
||||
}
|
||||
});
|
||||
@@ -256,7 +261,7 @@ class RWCRunner extends RunnerBase {
|
||||
*/
|
||||
public initializeTests(): void {
|
||||
// Read in and evaluate the test list
|
||||
const testList = this.enumerateTestFiles();
|
||||
const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
|
||||
for (let i = 0; i < testList.length; i++) {
|
||||
this.runTest(testList[i]);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"../compiler/parser.ts",
|
||||
"../compiler/utilities.ts",
|
||||
"../compiler/binder.ts",
|
||||
"../compiler/symbolWalker.ts",
|
||||
"../compiler/checker.ts",
|
||||
"../compiler/factory.ts",
|
||||
"../compiler/visitor.ts",
|
||||
@@ -91,6 +92,9 @@
|
||||
"loggedIO.ts",
|
||||
"rwcRunner.ts",
|
||||
"test262Runner.ts",
|
||||
"./parallel/shared.ts",
|
||||
"./parallel/host.ts",
|
||||
"./parallel/worker.ts",
|
||||
"runner.ts",
|
||||
"../server/protocol.ts",
|
||||
"../server/session.ts",
|
||||
@@ -103,6 +107,7 @@
|
||||
"./unittests/services/preProcessFile.ts",
|
||||
"./unittests/services/patternMatcher.ts",
|
||||
"./unittests/session.ts",
|
||||
"./unittests/symbolWalker.ts",
|
||||
"./unittests/versionCache.ts",
|
||||
"./unittests/convertToBase64.ts",
|
||||
"./unittests/transpile.ts",
|
||||
@@ -123,8 +128,10 @@
|
||||
"./unittests/printer.ts",
|
||||
"./unittests/transform.ts",
|
||||
"./unittests/customTransforms.ts",
|
||||
"./unittests/extractMethods.ts",
|
||||
"./unittests/textChanges.ts",
|
||||
"./unittests/telemetry.ts",
|
||||
"./unittests/languageService.ts",
|
||||
"./unittests/programMissingFiles.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -55,7 +55,6 @@ namespace ts.projectSystem {
|
||||
let configFile: FileOrFolder;
|
||||
let changeModuleFile1ShapeRequest1: server.protocol.Request;
|
||||
let changeModuleFile1InternalRequest1: server.protocol.Request;
|
||||
let changeModuleFile1ShapeRequest2: server.protocol.Request;
|
||||
// A compile on save affected file request using file1
|
||||
let moduleFile1FileListRequest: server.protocol.Request;
|
||||
|
||||
@@ -112,16 +111,6 @@ namespace ts.projectSystem {
|
||||
insertString: `var T1: number;`
|
||||
});
|
||||
|
||||
// Change the content of file1 to `export var T: number;export function Foo() { };`
|
||||
changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
|
||||
file: moduleFile1.path,
|
||||
line: 1,
|
||||
offset: 1,
|
||||
endLine: 1,
|
||||
endOffset: 1,
|
||||
insertString: `export var T2: number;`
|
||||
});
|
||||
|
||||
moduleFile1FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
|
||||
});
|
||||
|
||||
|
||||
@@ -78,6 +78,23 @@ namespace ts {
|
||||
},
|
||||
include: ["../supplemental.*"]
|
||||
},
|
||||
"/dev/configs/third.json": {
|
||||
extends: "./second",
|
||||
compilerOptions: {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
module: null
|
||||
},
|
||||
include: ["../supplemental.*"]
|
||||
},
|
||||
"/dev/configs/fourth.json": {
|
||||
extends: "./third",
|
||||
compilerOptions: {
|
||||
module: "system"
|
||||
},
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
include: null,
|
||||
files: ["../main.ts"]
|
||||
},
|
||||
"/dev/extends.json": { extends: 42 },
|
||||
"/dev/extends2.json": { extends: "configs/base" },
|
||||
"/dev/main.ts": "",
|
||||
@@ -106,7 +123,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
describe("Configuration Extension", () => {
|
||||
describe("configurationExtension", () => {
|
||||
forEach<[string, string, Utils.MockParseConfigHost], void>([
|
||||
["under a case insensitive host", caseInsensitiveBasePath, caseInsensitiveHost],
|
||||
["under a case sensitive host", caseSensitiveBasePath, caseSensitiveHost]
|
||||
@@ -206,6 +223,24 @@ namespace ts {
|
||||
category: DiagnosticCategory.Error,
|
||||
messageText: `A path in an 'extends' option must be relative or rooted, but 'configs/base' is not.`
|
||||
}]);
|
||||
|
||||
testSuccess("can overwrite compiler options using extended 'null'", "configs/third.json", {
|
||||
allowJs: true,
|
||||
noImplicitAny: true,
|
||||
strictNullChecks: true,
|
||||
module: undefined // Technically, this is distinct from the key never being set; but within the compiler we don't make the distinction
|
||||
}, [
|
||||
combinePaths(basePath, "supplemental.ts")
|
||||
]);
|
||||
|
||||
testSuccess("can overwrite top-level options using extended 'null'", "configs/fourth.json", {
|
||||
allowJs: true,
|
||||
noImplicitAny: true,
|
||||
strictNullChecks: true,
|
||||
module: ModuleKind.System
|
||||
}, [
|
||||
combinePaths(basePath, "main.ts")
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/// <reference path="..\..\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
type ExpectedResult = { typeAcquisition: TypeAcquisition, errors: Diagnostic[] };
|
||||
interface ExpectedResult { typeAcquisition: TypeAcquisition; errors: Diagnostic[]; }
|
||||
describe("convertTypeAcquisitionFromJson", () => {
|
||||
function assertTypeAcquisition(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
assertTypeAcquisitionWithJson(json, configFileName, expectedResult);
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
namespace ts {
|
||||
describe("customTransforms", () => {
|
||||
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) {
|
||||
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers, options: CompilerOptions = {}) {
|
||||
it(name, () => {
|
||||
const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015));
|
||||
const fileMap = arrayToMap(roots, file => file.fileName);
|
||||
const outputs = createMap<string>();
|
||||
const options: CompilerOptions = {};
|
||||
const host: CompilerHost = {
|
||||
getSourceFile: (fileName) => fileMap.get(fileName),
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
@@ -82,5 +81,25 @@ namespace ts {
|
||||
emitsCorrectly("before", sources, { before: [before] });
|
||||
emitsCorrectly("after", sources, { after: [after] });
|
||||
emitsCorrectly("both", sources, { before: [before], after: [after] });
|
||||
|
||||
emitsCorrectly("before+decorators", [{
|
||||
file: "source.ts",
|
||||
text: `
|
||||
declare const dec: any;
|
||||
class B {}
|
||||
@dec export class C { constructor(b: B) { } }
|
||||
'change'
|
||||
`
|
||||
}], {before: [
|
||||
context => node => visitNode(node, function visitor(node: Node): Node {
|
||||
if (isStringLiteral(node) && node.text === "change") return createLiteral("changed");
|
||||
return visitEachChild(node, visitor, context);
|
||||
})
|
||||
]}, {
|
||||
target: ScriptTarget.ES5,
|
||||
module: ModuleKind.ES2015,
|
||||
emitDecoratorMetadata: true,
|
||||
experimentalDecorators: true
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -224,7 +224,7 @@ namespace ts {
|
||||
testExtractRange(`
|
||||
function f() {
|
||||
while (true) {
|
||||
[#|
|
||||
[#|
|
||||
if (x) {
|
||||
return;
|
||||
} |]
|
||||
@@ -234,7 +234,7 @@ namespace ts {
|
||||
testExtractRange(`
|
||||
function f() {
|
||||
while (true) {
|
||||
[#|
|
||||
[#|
|
||||
[$|if (x) {
|
||||
}
|
||||
return;|]
|
||||
@@ -378,6 +378,40 @@ namespace A {
|
||||
"Cannot extract range containing conditional return statement."
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed7",
|
||||
`
|
||||
function test(x: number) {
|
||||
while (x) {
|
||||
x--;
|
||||
[#|break;|]
|
||||
}
|
||||
}
|
||||
`,
|
||||
[
|
||||
"Cannot extract range containing conditional break or continue statements."
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed8",
|
||||
`
|
||||
function test(x: number) {
|
||||
switch (x) {
|
||||
case 1:
|
||||
[#|break;|]
|
||||
}
|
||||
}
|
||||
`,
|
||||
[
|
||||
"Cannot extract range containing conditional break or continue statements."
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed9",
|
||||
`var x = ([#||]1 + 2);`,
|
||||
[
|
||||
"Statement or expression expected."
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, ["Select more than a single identifier."]);
|
||||
|
||||
testExtractMethod("extractMethod1",
|
||||
`namespace A {
|
||||
let x = 1;
|
||||
@@ -544,13 +578,208 @@ namespace A {
|
||||
return a1.x + 10;|]
|
||||
}
|
||||
}
|
||||
}`);
|
||||
// The "b" type parameters aren't used and shouldn't be passed to the extracted function.
|
||||
// Type parameters should be in syntactic order (i.e. in order or character offset from BOF).
|
||||
// In all cases, we could use type inference, rather than passing explicit type arguments.
|
||||
// Note the inclusion of arrow functions to ensure that some type parameters are not from
|
||||
// targetable scopes.
|
||||
testExtractMethod("extractMethod13",
|
||||
`<U1a, U1b>(u1a: U1a, u1b: U1b) => {
|
||||
function F1<T1a, T1b>(t1a: T1a, t1b: T1b) {
|
||||
<U2a, U2b>(u2a: U2a, u2b: U2b) => {
|
||||
function F2<T2a, T2b>(t2a: T2a, t2b: T2b) {
|
||||
<U3a, U3b>(u3a: U3a, u3b: U3b) => {
|
||||
[#|t1a.toString();
|
||||
t2a.toString();
|
||||
u1a.toString();
|
||||
u2a.toString();
|
||||
u3a.toString();|]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`);
|
||||
// This test is descriptive, rather than normative. The current implementation
|
||||
// doesn't handle type parameter shadowing.
|
||||
testExtractMethod("extractMethod14",
|
||||
`function F<T>(t1: T) {
|
||||
function F<T>(t2: T) {
|
||||
[#|t1.toString();
|
||||
t2.toString();|]
|
||||
}
|
||||
}`);
|
||||
// Confirm that the constraint is preserved.
|
||||
testExtractMethod("extractMethod15",
|
||||
`function F<T>(t1: T) {
|
||||
function F<U extends T[]>(t2: U) {
|
||||
[#|t2.toString();|]
|
||||
}
|
||||
}`);
|
||||
// Confirm that the contextual type of an extracted expression counts as a use.
|
||||
testExtractMethod("extractMethod16",
|
||||
`function F<T>() {
|
||||
const array: T[] = [#|[]|];
|
||||
}`);
|
||||
// Class type parameter
|
||||
testExtractMethod("extractMethod17",
|
||||
`class C<T1, T2> {
|
||||
M(t1: T1, t2: T2) {
|
||||
[#|t1.toString()|];
|
||||
}
|
||||
}`);
|
||||
// Method type parameter
|
||||
testExtractMethod("extractMethod18",
|
||||
`class C {
|
||||
M<T1, T2>(t1: T1, t2: T2) {
|
||||
[#|t1.toString()|];
|
||||
}
|
||||
}`);
|
||||
// Coupled constraints
|
||||
testExtractMethod("extractMethod19",
|
||||
`function F<T, U extends T[], V extends U[]>(v: V) {
|
||||
[#|v.toString()|];
|
||||
}`);
|
||||
|
||||
testExtractMethod("extractMethod20",
|
||||
`const _ = class {
|
||||
a() {
|
||||
[#|let a1 = { x: 1 };
|
||||
return a1.x + 10;|]
|
||||
}
|
||||
}`);
|
||||
// Write + void return
|
||||
testExtractMethod("extractMethod21",
|
||||
`function foo() {
|
||||
let x = 10;
|
||||
[#|x++;
|
||||
return;|]
|
||||
}`);
|
||||
// Return in finally block
|
||||
testExtractMethod("extractMethod22",
|
||||
`function test() {
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
[#|return 1;|]
|
||||
}
|
||||
}`);
|
||||
// Extraction position - namespace
|
||||
testExtractMethod("extractMethod23",
|
||||
`namespace NS {
|
||||
function M1() { }
|
||||
function M2() {
|
||||
[#|return 1;|]
|
||||
}
|
||||
function M3() { }
|
||||
}`);
|
||||
// Extraction position - function
|
||||
testExtractMethod("extractMethod24",
|
||||
`function Outer() {
|
||||
function M1() { }
|
||||
function M2() {
|
||||
[#|return 1;|]
|
||||
}
|
||||
function M3() { }
|
||||
}`);
|
||||
// Extraction position - file
|
||||
testExtractMethod("extractMethod25",
|
||||
`function M1() { }
|
||||
function M2() {
|
||||
[#|return 1;|]
|
||||
}
|
||||
function M3() { }`);
|
||||
// Extraction position - class without ctor
|
||||
testExtractMethod("extractMethod26",
|
||||
`class C {
|
||||
M1() { }
|
||||
M2() {
|
||||
[#|return 1;|]
|
||||
}
|
||||
M3() { }
|
||||
}`);
|
||||
// Extraction position - class with ctor in middle
|
||||
testExtractMethod("extractMethod27",
|
||||
`class C {
|
||||
M1() { }
|
||||
M2() {
|
||||
[#|return 1;|]
|
||||
}
|
||||
constructor() { }
|
||||
M3() { }
|
||||
}`);
|
||||
// Extraction position - class with ctor at end
|
||||
testExtractMethod("extractMethod28",
|
||||
`class C {
|
||||
M1() { }
|
||||
M2() {
|
||||
[#|return 1;|]
|
||||
}
|
||||
M3() { }
|
||||
constructor() { }
|
||||
}`);
|
||||
// Shorthand property names
|
||||
testExtractMethod("extractMethod29",
|
||||
`interface UnaryExpression {
|
||||
kind: "Unary";
|
||||
operator: string;
|
||||
operand: any;
|
||||
}
|
||||
|
||||
function parseUnaryExpression(operator: string): UnaryExpression {
|
||||
[#|return {
|
||||
kind: "Unary",
|
||||
operator,
|
||||
operand: parsePrimaryExpression(),
|
||||
};|]
|
||||
}
|
||||
|
||||
function parsePrimaryExpression(): any {
|
||||
throw "Not implemented";
|
||||
}`);
|
||||
// Type parameter as declared type
|
||||
testExtractMethod("extractMethod30",
|
||||
`function F<T>() {
|
||||
[#|let t: T;|]
|
||||
}`);
|
||||
// Return in nested function
|
||||
testExtractMethod("extractMethod31",
|
||||
`namespace N {
|
||||
|
||||
export const value = 1;
|
||||
|
||||
() => {
|
||||
var f: () => number;
|
||||
[#|f = function (): number {
|
||||
return value;
|
||||
}|]
|
||||
}
|
||||
}`);
|
||||
// Return in nested class
|
||||
testExtractMethod("extractMethod32",
|
||||
`namespace N {
|
||||
|
||||
export const value = 1;
|
||||
|
||||
() => {
|
||||
[#|var c = class {
|
||||
M() {
|
||||
return value;
|
||||
}
|
||||
}|]
|
||||
}
|
||||
}`);
|
||||
// Selection excludes leading trivia of declaration
|
||||
testExtractMethod("extractMethod33",
|
||||
`function F() {
|
||||
[#|function G() { }|]
|
||||
}`);
|
||||
});
|
||||
|
||||
|
||||
function testExtractMethod(caption: string, text: string) {
|
||||
it(caption, () => {
|
||||
Harness.Baseline.runBaseline(`extractMethod/${caption}.js`, () => {
|
||||
Harness.Baseline.runBaseline(`extractMethod/${caption}.ts`, () => {
|
||||
const t = extractTest(text);
|
||||
const selectionRange = t.ranges.get("selection");
|
||||
if (!selectionRange) {
|
||||
@@ -560,7 +789,7 @@ namespace A {
|
||||
path: "/a.ts",
|
||||
content: t.source
|
||||
};
|
||||
const host = projectSystem.createServerHost([f]);
|
||||
const host = projectSystem.createServerHost([f, projectSystem.libFile]);
|
||||
const projectService = projectSystem.createProjectService(host);
|
||||
projectService.openClientFile(f.path);
|
||||
const program = projectService.inferredProjects[0].getLanguageService().getProgram();
|
||||
@@ -577,12 +806,15 @@ namespace A {
|
||||
assert.equal(result.errors, undefined, "expect no errors");
|
||||
const results = refactor.extractMethod.getPossibleExtractions(result.targetRange, context);
|
||||
const data: string[] = [];
|
||||
data.push(`==ORIGINAL==`);
|
||||
data.push(`// ==ORIGINAL==`);
|
||||
data.push(sourceFile.text);
|
||||
for (const r of results) {
|
||||
const changes = refactor.extractMethod.getPossibleExtractions(result.targetRange, context, results.indexOf(r))[0].changes;
|
||||
data.push(`==SCOPE::${r.scopeDescription}==`);
|
||||
data.push(textChanges.applyChanges(sourceFile.text, changes[0].textChanges));
|
||||
const { renameLocation, edits } = refactor.extractMethod.getExtractionAtIndex(result.targetRange, context, results.indexOf(r));
|
||||
assert.lengthOf(edits, 1);
|
||||
data.push(`// ==SCOPE::${r.scopeDescription}==`);
|
||||
const newText = textChanges.applyChanges(sourceFile.text, edits[0].textChanges);
|
||||
const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation);
|
||||
data.push(newTextWithRename);
|
||||
}
|
||||
return data.join(newLineCharacter);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("languageService", () => {
|
||||
const files: {[index: string]: string} = {
|
||||
"foo.ts": `import Vue from "./vue";
|
||||
import Component from "./vue-class-component";
|
||||
import { vueTemplateHtml } from "./variables";
|
||||
|
||||
@Component({
|
||||
template: vueTemplateHtml,
|
||||
})
|
||||
class Carousel<T> extends Vue {
|
||||
}`,
|
||||
"variables.ts": `export const vueTemplateHtml = \`<div></div>\`;`,
|
||||
"vue.d.ts": `export namespace Vue { export type Config = { template: string }; }`,
|
||||
"vue-class-component.d.ts": `import Vue from "./vue";
|
||||
export function Component(x: Config): any;`
|
||||
};
|
||||
// Regression test for GH #18245 - bug in single line comment writer caused a debug assertion when attempting
|
||||
// to write an alias to a module's default export was referrenced across files and had no default export
|
||||
it("should be able to create a language service which can respond to deinition requests without throwing", () => {
|
||||
const languageService = ts.createLanguageService({
|
||||
getCompilationSettings() {
|
||||
return {};
|
||||
},
|
||||
getScriptFileNames() {
|
||||
return ["foo.ts", "variables.ts", "vue.d.ts", "vue-class-component.d.ts"];
|
||||
},
|
||||
getScriptVersion(_fileName) {
|
||||
return "";
|
||||
},
|
||||
getScriptSnapshot(fileName) {
|
||||
if (fileName === ".ts") {
|
||||
return ts.ScriptSnapshot.fromString("");
|
||||
}
|
||||
return ts.ScriptSnapshot.fromString(files[fileName] || "");
|
||||
},
|
||||
getCurrentDirectory: () => ".",
|
||||
getDefaultLibFileName(options) {
|
||||
return ts.getDefaultLibFilePath(options);
|
||||
},
|
||||
fileExists: noop as any,
|
||||
readFile: noop as any,
|
||||
readDirectory: noop as any,
|
||||
});
|
||||
const definitions = languageService.getDefinitionAtPosition("foo.ts", 160); // 160 is the latter `vueTemplateHtml` position
|
||||
expect(definitions).to.exist;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -198,33 +198,34 @@ namespace ts {
|
||||
const moduleFile = { name: "/a/b/node_modules/foo.ts" };
|
||||
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
|
||||
"/a/b/c/d/node_modules/foo/package.json",
|
||||
"/a/b/c/d/node_modules/foo.ts",
|
||||
"/a/b/c/d/node_modules/foo.tsx",
|
||||
"/a/b/c/d/node_modules/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/foo/package.json",
|
||||
|
||||
"/a/b/c/d/node_modules/foo/index.ts",
|
||||
"/a/b/c/d/node_modules/foo/index.tsx",
|
||||
"/a/b/c/d/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/d/node_modules/@types/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/@types/foo/package.json",
|
||||
"/a/b/c/d/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/b/c/d/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/node_modules/foo/package.json",
|
||||
"/a/b/c/node_modules/foo.ts",
|
||||
"/a/b/c/node_modules/foo.tsx",
|
||||
"/a/b/c/node_modules/foo.d.ts",
|
||||
"/a/b/c/node_modules/foo/package.json",
|
||||
|
||||
"/a/b/c/node_modules/foo/index.ts",
|
||||
"/a/b/c/node_modules/foo/index.tsx",
|
||||
"/a/b/c/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/node_modules/@types/foo.d.ts",
|
||||
"/a/b/c/node_modules/@types/foo/package.json",
|
||||
"/a/b/c/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/b/c/node_modules/@types/foo/index.d.ts",
|
||||
"/a/b/node_modules/foo/package.json",
|
||||
]);
|
||||
}
|
||||
});
|
||||
@@ -250,52 +251,52 @@ namespace ts {
|
||||
const moduleFile: File = { name: "/a/node_modules/foo/index.d.ts" };
|
||||
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo/package.json",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/node_modules/foo/package.json",
|
||||
"/a/node_modules/b/node_modules/foo.ts",
|
||||
"/a/node_modules/b/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/node_modules/@types/foo/package.json",
|
||||
"/a/node_modules/b/node_modules/@types/foo.d.ts",
|
||||
|
||||
"/a/node_modules/b/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/foo/package.json",
|
||||
"/a/node_modules/foo.ts",
|
||||
"/a/node_modules/foo.tsx",
|
||||
"/a/node_modules/foo.d.ts",
|
||||
"/a/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/foo/index.ts",
|
||||
"/a/node_modules/foo/index.tsx"
|
||||
@@ -425,7 +426,7 @@ export = C;
|
||||
readFile: notImplemented
|
||||
};
|
||||
const program = createProgram(rootFiles, options, host);
|
||||
const diagnostics = sortAndDeduplicateDiagnostics(program.getSemanticDiagnostics().concat(program.getOptionsDiagnostics()));
|
||||
const diagnostics = sortAndDeduplicateDiagnostics([...program.getSemanticDiagnostics(), ...program.getOptionsDiagnostics()]);
|
||||
assert.equal(diagnostics.length, diagnosticCodes.length, `Incorrect number of expected diagnostics, expected ${diagnosticCodes.length}, got '${Harness.Compiler.minimalDiagnosticsToString(diagnostics)}'`);
|
||||
for (let i = 0; i < diagnosticCodes.length; i++) {
|
||||
assert.equal(diagnostics[i].code, diagnosticCodes[i], `Expected diagnostic code ${diagnosticCodes[i]}, got '${diagnostics[i].code}': '${diagnostics[i].messageText}'`);
|
||||
@@ -707,21 +708,23 @@ import b = require("./moduleB");
|
||||
"/root/generated/file6/index.d.ts",
|
||||
|
||||
// fallback to standard node behavior
|
||||
"/root/folder1/node_modules/file6/package.json",
|
||||
|
||||
// load from file
|
||||
"/root/folder1/node_modules/file6.ts",
|
||||
"/root/folder1/node_modules/file6.tsx",
|
||||
"/root/folder1/node_modules/file6.d.ts",
|
||||
|
||||
// load from folder
|
||||
"/root/folder1/node_modules/file6/package.json",
|
||||
"/root/folder1/node_modules/file6/index.ts",
|
||||
"/root/folder1/node_modules/file6/index.tsx",
|
||||
"/root/folder1/node_modules/file6/index.d.ts",
|
||||
|
||||
"/root/folder1/node_modules/@types/file6.d.ts",
|
||||
|
||||
"/root/folder1/node_modules/@types/file6/package.json",
|
||||
"/root/folder1/node_modules/@types/file6.d.ts",
|
||||
"/root/folder1/node_modules/@types/file6/index.d.ts",
|
||||
|
||||
"/root/node_modules/file6/package.json",
|
||||
// success on /root/node_modules/file6.ts
|
||||
], /*isExternalLibraryImport*/ true);
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ namespace ts {
|
||||
|
||||
// github #14948
|
||||
printsCorrectly("templateLiteral", {}, printer => printer.printFile(createSourceFile("source.ts", "let greeting = `Hi ${name}, how are you?`;", ScriptTarget.ES2017)));
|
||||
|
||||
// github #18071
|
||||
printsCorrectly("regularExpressionLiteral", {}, printer => printer.printFile(createSourceFile("source.ts", "let regex = /abc/;", ScriptTarget.ES2017)));
|
||||
});
|
||||
|
||||
describe("printBundle", () => {
|
||||
|
||||
@@ -48,18 +48,18 @@ namespace ts {
|
||||
const program = createProgram(["./nonexistent.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts"]); // Absolute path
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts" as Path]); // Absolute path
|
||||
});
|
||||
|
||||
it("handles multiple missing root files", () => {
|
||||
const program = createProgram(["./nonexistent0.ts", "./nonexistent1.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths().sort();
|
||||
const missing = program.getMissingFilePaths().slice().sort();
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent0.ts", "d:/pretend/nonexistent1.ts"]);
|
||||
});
|
||||
|
||||
it("handles a mix of present and missing root files", () => {
|
||||
const program = createProgram(["./nonexistent0.ts", emptyFileRelativePath, "./nonexistent1.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths().sort();
|
||||
const missing = program.getMissingFilePaths().slice().sort();
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent0.ts", "d:/pretend/nonexistent1.ts"]);
|
||||
});
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace ts {
|
||||
const program = createProgram(["./nonexistent.ts", "./nonexistent.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts"]);
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts" as Path]);
|
||||
});
|
||||
|
||||
it("normalizes file paths", () => {
|
||||
@@ -81,7 +81,7 @@ namespace ts {
|
||||
|
||||
it("handles missing triple slash references", () => {
|
||||
const program = createProgram([referenceFileRelativePath], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths().sort();
|
||||
const missing = program.getMissingFilePaths().slice().sort();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, [
|
||||
// From absolute reference
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
interface ProgramWithSourceTexts extends Program {
|
||||
sourceTexts?: NamedSourceText[];
|
||||
sourceTexts?: ReadonlyArray<NamedSourceText>;
|
||||
host: TestCompilerHost;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace ts {
|
||||
return file;
|
||||
}
|
||||
|
||||
function createTestCompilerHost(texts: NamedSourceText[], target: ScriptTarget, oldProgram?: ProgramWithSourceTexts): TestCompilerHost {
|
||||
function createTestCompilerHost(texts: ReadonlyArray<NamedSourceText>, target: ScriptTarget, oldProgram?: ProgramWithSourceTexts): TestCompilerHost {
|
||||
const files = arrayToMap(texts, t => t.name, t => {
|
||||
if (oldProgram) {
|
||||
let oldFile = <SourceFileWithText>oldProgram.getSourceFile(t.name);
|
||||
@@ -162,7 +162,7 @@ namespace ts {
|
||||
return program;
|
||||
}
|
||||
|
||||
function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: string[], options: CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[]) {
|
||||
function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: ReadonlyArray<string>, options: CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[]) {
|
||||
if (!newTexts) {
|
||||
newTexts = (<ProgramWithSourceTexts>oldProgram).sourceTexts.slice(0);
|
||||
}
|
||||
@@ -441,20 +441,20 @@ namespace ts {
|
||||
"======== Resolving module 'a' from 'file1.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'NodeJs'.",
|
||||
"Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a.ts' does not exist.",
|
||||
"File 'node_modules/a.tsx' does not exist.",
|
||||
"File 'node_modules/a.d.ts' does not exist.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a/index.ts' does not exist.",
|
||||
"File 'node_modules/a/index.tsx' does not exist.",
|
||||
"File 'node_modules/a/index.d.ts' does not exist.",
|
||||
"File 'node_modules/@types/a.d.ts' does not exist.",
|
||||
"File 'node_modules/@types/a/package.json' does not exist.",
|
||||
"File 'node_modules/@types/a.d.ts' does not exist.",
|
||||
"File 'node_modules/@types/a/index.d.ts' does not exist.",
|
||||
"Loading module 'a' from 'node_modules' folder, target file type 'JavaScript'.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a.js' does not exist.",
|
||||
"File 'node_modules/a.jsx' does not exist.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a/index.js' does not exist.",
|
||||
"File 'node_modules/a/index.jsx' does not exist.",
|
||||
"======== Module name 'a' was not resolved. ========"
|
||||
@@ -474,10 +474,10 @@ namespace ts {
|
||||
"======== Resolving module 'a' from 'file1.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'NodeJs'.",
|
||||
"Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a.ts' does not exist.",
|
||||
"File 'node_modules/a.tsx' does not exist.",
|
||||
"File 'node_modules/a.d.ts' does not exist.",
|
||||
"File 'node_modules/a/package.json' does not exist.",
|
||||
"File 'node_modules/a/index.ts' does not exist.",
|
||||
"File 'node_modules/a/index.tsx' does not exist.",
|
||||
"File 'node_modules/a/index.d.ts' exist - use it as a name resolution result.",
|
||||
@@ -510,14 +510,14 @@ namespace ts {
|
||||
"File '/fs.ts' does not exist.",
|
||||
"File '/fs.tsx' does not exist.",
|
||||
"File '/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/b/fs.js' does not exist.",
|
||||
"File '/a/b/fs.jsx' does not exist.",
|
||||
@@ -552,14 +552,14 @@ namespace ts {
|
||||
"File '/fs.ts' does not exist.",
|
||||
"File '/fs.tsx' does not exist.",
|
||||
"File '/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/b/fs.js' does not exist.",
|
||||
"File '/a/b/fs.jsx' does not exist.",
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("Symbol Walker", () => {
|
||||
function test(description: string, source: string, verifier: (file: SourceFile, checker: TypeChecker) => void) {
|
||||
it(description, () => {
|
||||
let {result} = Harness.Compiler.compileFiles([{
|
||||
unitName: "main.ts",
|
||||
content: source
|
||||
}], [], {}, {}, "/");
|
||||
let file = result.program.getSourceFile("main.ts");
|
||||
let checker = result.program.getTypeChecker();
|
||||
verifier(file, checker);
|
||||
|
||||
result = undefined;
|
||||
file = undefined;
|
||||
checker = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
test("can be created", `
|
||||
interface Bar {
|
||||
x: number;
|
||||
y: number;
|
||||
history: Bar[];
|
||||
}
|
||||
export default function foo(a: number, b: Bar): void {}`, (file, checker) => {
|
||||
let foundCount = 0;
|
||||
let stdLibRefSymbols = 0;
|
||||
const expectedSymbols = ["default", "a", "b", "Bar", "x", "y", "history"];
|
||||
const walker = checker.getSymbolWalker(symbol => {
|
||||
const isStdLibSymbol = forEach(symbol.declarations, d => {
|
||||
return getSourceFileOfNode(d).hasNoDefaultLib;
|
||||
});
|
||||
if (isStdLibSymbol) {
|
||||
stdLibRefSymbols++;
|
||||
return false; // Don't traverse into the stdlib. That's unnecessary for this test.
|
||||
}
|
||||
assert.equal(symbol.name, expectedSymbols[foundCount]);
|
||||
foundCount++;
|
||||
return true;
|
||||
});
|
||||
const symbols = checker.getExportsOfModule(file.symbol);
|
||||
for (const symbol of symbols) {
|
||||
walker.walkSymbol(symbol);
|
||||
}
|
||||
assert.equal(foundCount, expectedSymbols.length);
|
||||
assert.equal(stdLibRefSymbols, 1); // Expect 1 stdlib entry symbol - the implicit Array referenced by Bar.history
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -57,7 +57,7 @@ namespace ts {
|
||||
|
||||
testBaseline("types", () => {
|
||||
return transformSourceFile(`let a: () => void`, [
|
||||
context => file => visitNode(file, function visitor(node: Node): VisitResult<Node> {
|
||||
context => file => visitNode(file, function visitor(node: Node): VisitResult<Node> {
|
||||
return visitEachChild(node, visitor, context);
|
||||
})
|
||||
]);
|
||||
@@ -74,6 +74,101 @@ namespace ts {
|
||||
}
|
||||
}).outputText;
|
||||
});
|
||||
|
||||
testBaseline("rewrittenNamespace", () => {
|
||||
return ts.transpileModule(`namespace Reflect { const x = 1; }`, {
|
||||
transformers: {
|
||||
before: [forceNamespaceRewrite],
|
||||
},
|
||||
compilerOptions: {
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
});
|
||||
|
||||
testBaseline("rewrittenNamespaceFollowingClass", () => {
|
||||
return ts.transpileModule(`
|
||||
class C { foo = 10; static bar = 20 }
|
||||
namespace C { export let x = 10; }
|
||||
`, {
|
||||
transformers: {
|
||||
before: [forceNamespaceRewrite],
|
||||
},
|
||||
compilerOptions: {
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
});
|
||||
|
||||
testBaseline("synthesizedClassAndNamespaceCombination", () => {
|
||||
return ts.transpileModule("", {
|
||||
transformers: {
|
||||
before: [replaceWithClassAndNamespace],
|
||||
},
|
||||
compilerOptions: {
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
|
||||
function replaceWithClassAndNamespace() {
|
||||
return (sourceFile: ts.SourceFile) => {
|
||||
const result = getMutableClone(sourceFile);
|
||||
result.statements = ts.createNodeArray([
|
||||
ts.createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined),
|
||||
ts.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createIdentifier("Foo"), createModuleBlock([createEmptyStatement()]))
|
||||
]);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
function forceNamespaceRewrite(context: ts.TransformationContext) {
|
||||
return (sourceFile: ts.SourceFile): ts.SourceFile => {
|
||||
return visitNode(sourceFile);
|
||||
|
||||
function visitNode<T extends ts.Node>(node: T): T {
|
||||
if (node.kind === ts.SyntaxKind.ModuleBlock) {
|
||||
const block = node as T & ts.ModuleBlock;
|
||||
const statements = ts.createNodeArray([...block.statements]);
|
||||
return ts.updateModuleBlock(block, statements) as typeof block;
|
||||
}
|
||||
return ts.visitEachChild(node, visitNode, context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
testBaseline("transformAwayExportStar", () => {
|
||||
return ts.transpileModule("export * from './helper';", {
|
||||
transformers: {
|
||||
before: [expandExportStar],
|
||||
},
|
||||
compilerOptions: {
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
|
||||
function expandExportStar(context: ts.TransformationContext) {
|
||||
return (sourceFile: ts.SourceFile): ts.SourceFile => {
|
||||
return visitNode(sourceFile);
|
||||
|
||||
function visitNode<T extends ts.Node>(node: T): T {
|
||||
if (node.kind === ts.SyntaxKind.ExportDeclaration) {
|
||||
const ed = node as ts.Node as ts.ExportDeclaration;
|
||||
const exports = [{ name: "x" }];
|
||||
const exportSpecifiers = exports.map(e => ts.createExportSpecifier(e.name, e.name));
|
||||
const exportClause = ts.createNamedExports(exportSpecifiers);
|
||||
const newEd = ts.updateExportDeclaration(ed, ed.decorators, ed.modifiers, exportClause, ed.moduleSpecifier);
|
||||
|
||||
return newEd as ts.Node as T;
|
||||
}
|
||||
return ts.visitEachChild(node, visitNode, context);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,28 @@ namespace ts.projectSystem {
|
||||
})
|
||||
};
|
||||
|
||||
const customSafeList = {
|
||||
path: <Path>"/typeMapList.json",
|
||||
content: JSON.stringify({
|
||||
"quack": {
|
||||
"match": "/duckquack-(\\d+)\\.min\\.js",
|
||||
"types": ["duck-types"]
|
||||
export const customTypesMap = {
|
||||
path: <Path>"/typesMap.json",
|
||||
content: `{
|
||||
"typesMap": {
|
||||
"jquery": {
|
||||
"match": "jquery(-(\\\\.?\\\\d+)+)?(\\\\.intellisense)?(\\\\.min)?\\\\.js$",
|
||||
"types": ["jquery"]
|
||||
},
|
||||
"quack": {
|
||||
"match": "/duckquack-(\\\\d+)\\\\.min\\\\.js",
|
||||
"types": ["duck-types"]
|
||||
}
|
||||
},
|
||||
})
|
||||
"simpleMap": {
|
||||
"Bacon": "baconjs",
|
||||
"bliss": "blissfuljs",
|
||||
"commander": "commander",
|
||||
"cordova": "cordova",
|
||||
"react": "react",
|
||||
"lodash": "lodash"
|
||||
}
|
||||
}`
|
||||
};
|
||||
|
||||
export interface PostExecAction {
|
||||
@@ -39,8 +53,9 @@ namespace ts.projectSystem {
|
||||
loggingEnabled: () => false,
|
||||
perftrc: noop,
|
||||
info: noop,
|
||||
err: noop,
|
||||
group: noop,
|
||||
msg: noop,
|
||||
startGroup: noop,
|
||||
endGroup: noop,
|
||||
getLogFileName: (): string => undefined
|
||||
};
|
||||
|
||||
@@ -58,7 +73,7 @@ namespace ts.projectSystem {
|
||||
installTypingHost: server.ServerHost,
|
||||
readonly typesRegistry = createMap<void>(),
|
||||
log?: TI.Log) {
|
||||
super(installTypingHost, globalTypingsCacheLocation, safeList.path, throttleLimit, log);
|
||||
super(installTypingHost, globalTypingsCacheLocation, safeList.path, customTypesMap.path, throttleLimit, log);
|
||||
}
|
||||
|
||||
protected postExecActions: PostExecAction[] = [];
|
||||
@@ -228,6 +243,7 @@ namespace ts.projectSystem {
|
||||
useSingleInferredProject,
|
||||
useInferredProjectPerProjectRoot: false,
|
||||
typingsInstaller,
|
||||
typesMapLocation: customTypesMap.path,
|
||||
eventHandler,
|
||||
...opts
|
||||
});
|
||||
@@ -1490,9 +1506,8 @@ namespace ts.projectSystem {
|
||||
path: "/lib/duckquack-3.min.js",
|
||||
content: "whoa do @@ not parse me ok thanks!!!"
|
||||
};
|
||||
const host = createServerHost([customSafeList, file1, office]);
|
||||
const host = createServerHost([file1, office, customTypesMap]);
|
||||
const projectService = createProjectService(host);
|
||||
projectService.loadSafeList(customSafeList.path);
|
||||
try {
|
||||
projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) });
|
||||
const proj = projectService.externalProjects[0];
|
||||
@@ -1759,6 +1774,28 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path, file3.path]);
|
||||
});
|
||||
|
||||
it("regression test for crash in acquireOrUpdateDocument", () => {
|
||||
const tsFile = {
|
||||
fileName: "/a/b/file1.ts",
|
||||
path: "/a/b/file1.ts",
|
||||
content: ""
|
||||
};
|
||||
const jsFile = {
|
||||
path: "/a/b/file1.js",
|
||||
content: "var x = 10;",
|
||||
fileName: "/a/b/file1.js",
|
||||
scriptKind: "JS" as "JS"
|
||||
};
|
||||
|
||||
const host = createServerHost([]);
|
||||
const projectService = createProjectService(host);
|
||||
projectService.applyChangesInOpenFiles([tsFile], [], []);
|
||||
const projs = projectService.synchronizeProjectList([]);
|
||||
projectService.findProject(projs[0].info.projectName).getLanguageService().getNavigationBarItems(tsFile.fileName);
|
||||
projectService.synchronizeProjectList([projs[0].info]);
|
||||
projectService.applyChangesInOpenFiles([jsFile], [], []);
|
||||
});
|
||||
|
||||
it("config file is deleted", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/f1.ts",
|
||||
@@ -1859,7 +1896,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// Open HTML file
|
||||
projectService.applyChangesInOpenFiles(
|
||||
/*openFiles*/ [{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
|
||||
/*openFiles*/[{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
|
||||
/*changedFiles*/ undefined,
|
||||
/*closedFiles*/ undefined);
|
||||
|
||||
@@ -1876,7 +1913,7 @@ namespace ts.projectSystem {
|
||||
projectService.applyChangesInOpenFiles(
|
||||
/*openFiles*/ undefined,
|
||||
/*changedFiles*/ undefined,
|
||||
/*closedFiles*/ [file2.path]);
|
||||
/*closedFiles*/[file2.path]);
|
||||
|
||||
// HTML file is still included in project
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
@@ -2473,8 +2510,8 @@ namespace ts.projectSystem {
|
||||
"======== Module name 'lib' was not resolved. ========",
|
||||
`Auto discovery for typings is enabled in project '${proj.getProjectName()}'. Running extra resolution pass for module 'lib' using cache location '/a/cache'.`,
|
||||
"File '/a/cache/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/index.d.ts' exist - use it as a name resolution result.",
|
||||
]);
|
||||
checkProjectActualFiles(proj, [file1.path, lib.path]);
|
||||
@@ -3307,7 +3344,7 @@ namespace ts.projectSystem {
|
||||
const error1Result = <protocol.Diagnostic[]>session.executeCommand(dTsFile1GetErrRequest).response;
|
||||
assert.isTrue(error1Result.length === 0);
|
||||
|
||||
const dTsFile2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
|
||||
const dTsFile2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
|
||||
CommandNames.SemanticDiagnosticsSync,
|
||||
{ file: dTsFile2.path }
|
||||
);
|
||||
|
||||
@@ -322,7 +322,7 @@ namespace ts.projectSystem {
|
||||
content: "declare const lodash: { x: number }"
|
||||
};
|
||||
|
||||
const host = createServerHost([file1, file2, file3]);
|
||||
const host = createServerHost([file1, file2, file3, customTypesMap]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { typesRegistry: createTypesRegistry("lodash", "react") });
|
||||
@@ -366,13 +366,11 @@ namespace ts.projectSystem {
|
||||
};
|
||||
|
||||
const host = createServerHost([file1, file2]);
|
||||
let enqueueIsCalled = false;
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
|
||||
enqueueIsCalled = true;
|
||||
super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
|
||||
}
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
@@ -445,7 +443,7 @@ namespace ts.projectSystem {
|
||||
content: "declare const moment: { x: number }"
|
||||
};
|
||||
|
||||
const host = createServerHost([file1, file2, file3, packageJson]);
|
||||
const host = createServerHost([file1, file2, file3, packageJson, customTypesMap]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery", "commander", "moment", "express") });
|
||||
@@ -521,7 +519,7 @@ namespace ts.projectSystem {
|
||||
};
|
||||
|
||||
const typingFiles = [commander, express, jquery, moment, lodash];
|
||||
const host = createServerHost([lodashJs, commanderJs, file3, packageJson]);
|
||||
const host = createServerHost([lodashJs, commanderJs, file3, packageJson, customTypesMap]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { throttleLimit: 3, typesRegistry: createTypesRegistry("commander", "express", "jquery", "moment", "lodash") });
|
||||
@@ -600,7 +598,7 @@ namespace ts.projectSystem {
|
||||
typings: typingsName("gulp")
|
||||
};
|
||||
|
||||
const host = createServerHost([lodashJs, commanderJs, file3]);
|
||||
const host = createServerHost([lodashJs, commanderJs, file3, customTypesMap]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { throttleLimit: 1, typesRegistry: createTypesRegistry("commander", "jquery", "lodash", "cordova", "gulp", "grunt") });
|
||||
|
||||
Vendored
+171
-110
@@ -4,11 +4,11 @@
|
||||
/////////////////////////////
|
||||
|
||||
interface Account {
|
||||
displayName?: string;
|
||||
id?: string;
|
||||
displayName: string;
|
||||
id: string;
|
||||
imageURL?: string;
|
||||
name?: string;
|
||||
rpDisplayName?: string;
|
||||
rpDisplayName: string;
|
||||
}
|
||||
|
||||
interface Algorithm {
|
||||
@@ -35,11 +35,11 @@ interface CacheQueryOptions {
|
||||
}
|
||||
|
||||
interface ClientData {
|
||||
challenge?: string;
|
||||
challenge: string;
|
||||
extensions?: WebAuthnExtensions;
|
||||
hashAlg?: string | Algorithm;
|
||||
origin?: string;
|
||||
rpId?: string;
|
||||
hashAlg: string | Algorithm;
|
||||
origin: string;
|
||||
rpId: string;
|
||||
tokenBinding?: string;
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ interface CustomEventInit extends EventInit {
|
||||
}
|
||||
|
||||
interface DeviceAccelerationDict {
|
||||
x?: number;
|
||||
y?: number;
|
||||
z?: number;
|
||||
x?: number | null;
|
||||
y?: number | null;
|
||||
z?: number | null;
|
||||
}
|
||||
|
||||
interface DeviceLightEventInit extends EventInit {
|
||||
@@ -97,30 +97,30 @@ interface DeviceLightEventInit extends EventInit {
|
||||
}
|
||||
|
||||
interface DeviceMotionEventInit extends EventInit {
|
||||
acceleration?: DeviceAccelerationDict;
|
||||
accelerationIncludingGravity?: DeviceAccelerationDict;
|
||||
interval?: number;
|
||||
rotationRate?: DeviceRotationRateDict;
|
||||
acceleration?: DeviceAccelerationDict | null;
|
||||
accelerationIncludingGravity?: DeviceAccelerationDict | null;
|
||||
interval?: number | null;
|
||||
rotationRate?: DeviceRotationRateDict | null;
|
||||
}
|
||||
|
||||
interface DeviceOrientationEventInit extends EventInit {
|
||||
absolute?: boolean;
|
||||
alpha?: number;
|
||||
beta?: number;
|
||||
gamma?: number;
|
||||
alpha?: number | null;
|
||||
beta?: number | null;
|
||||
gamma?: number | null;
|
||||
}
|
||||
|
||||
interface DeviceRotationRateDict {
|
||||
alpha?: number;
|
||||
beta?: number;
|
||||
gamma?: number;
|
||||
alpha?: number | null;
|
||||
beta?: number | null;
|
||||
gamma?: number | null;
|
||||
}
|
||||
|
||||
interface DOMRectInit {
|
||||
height?: any;
|
||||
width?: any;
|
||||
x?: any;
|
||||
y?: any;
|
||||
height?: number;
|
||||
width?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
}
|
||||
|
||||
interface DoubleRange {
|
||||
@@ -161,15 +161,15 @@ interface EventModifierInit extends UIEventInit {
|
||||
}
|
||||
|
||||
interface ExceptionInformation {
|
||||
domain?: string;
|
||||
domain?: string | null;
|
||||
}
|
||||
|
||||
interface FocusEventInit extends UIEventInit {
|
||||
relatedTarget?: EventTarget;
|
||||
relatedTarget?: EventTarget | null;
|
||||
}
|
||||
|
||||
interface FocusNavigationEventInit extends EventInit {
|
||||
navigationReason?: string;
|
||||
navigationReason?: string | null;
|
||||
originHeight?: number;
|
||||
originLeft?: number;
|
||||
originTop?: number;
|
||||
@@ -184,7 +184,7 @@ interface FocusNavigationOrigin {
|
||||
}
|
||||
|
||||
interface GamepadEventInit extends EventInit {
|
||||
gamepad?: Gamepad;
|
||||
gamepad?: Gamepad | null;
|
||||
}
|
||||
|
||||
interface GetNotificationOptions {
|
||||
@@ -192,8 +192,8 @@ interface GetNotificationOptions {
|
||||
}
|
||||
|
||||
interface HashChangeEventInit extends EventInit {
|
||||
newURL?: string;
|
||||
oldURL?: string;
|
||||
newURL?: string | null;
|
||||
oldURL?: string | null;
|
||||
}
|
||||
|
||||
interface IDBIndexParameters {
|
||||
@@ -203,19 +203,20 @@ interface IDBIndexParameters {
|
||||
|
||||
interface IDBObjectStoreParameters {
|
||||
autoIncrement?: boolean;
|
||||
keyPath?: IDBKeyPath;
|
||||
keyPath?: IDBKeyPath | null;
|
||||
}
|
||||
|
||||
interface IntersectionObserverEntryInit {
|
||||
boundingClientRect?: DOMRectInit;
|
||||
intersectionRect?: DOMRectInit;
|
||||
rootBounds?: DOMRectInit;
|
||||
target?: Element;
|
||||
time?: number;
|
||||
isIntersecting: boolean;
|
||||
boundingClientRect: DOMRectInit;
|
||||
intersectionRect: DOMRectInit;
|
||||
rootBounds: DOMRectInit;
|
||||
target: Element;
|
||||
time: number;
|
||||
}
|
||||
|
||||
interface IntersectionObserverInit {
|
||||
root?: Element;
|
||||
root?: Element | null;
|
||||
rootMargin?: string;
|
||||
threshold?: number | number[];
|
||||
}
|
||||
@@ -237,12 +238,12 @@ interface LongRange {
|
||||
}
|
||||
|
||||
interface MediaEncryptedEventInit extends EventInit {
|
||||
initData?: ArrayBuffer;
|
||||
initData?: ArrayBuffer | null;
|
||||
initDataType?: string;
|
||||
}
|
||||
|
||||
interface MediaKeyMessageEventInit extends EventInit {
|
||||
message?: ArrayBuffer;
|
||||
message?: ArrayBuffer | null;
|
||||
messageType?: MediaKeyMessageType;
|
||||
}
|
||||
|
||||
@@ -265,7 +266,7 @@ interface MediaStreamConstraints {
|
||||
}
|
||||
|
||||
interface MediaStreamErrorEventInit extends EventInit {
|
||||
error?: MediaStreamError;
|
||||
error?: MediaStreamError | null;
|
||||
}
|
||||
|
||||
interface MediaStreamEventInit extends EventInit {
|
||||
@@ -273,7 +274,7 @@ interface MediaStreamEventInit extends EventInit {
|
||||
}
|
||||
|
||||
interface MediaStreamTrackEventInit extends EventInit {
|
||||
track?: MediaStreamTrack;
|
||||
track?: MediaStreamTrack | null;
|
||||
}
|
||||
|
||||
interface MediaTrackCapabilities {
|
||||
@@ -350,7 +351,7 @@ interface MouseEventInit extends EventModifierInit {
|
||||
buttons?: number;
|
||||
clientX?: number;
|
||||
clientY?: number;
|
||||
relatedTarget?: EventTarget;
|
||||
relatedTarget?: EventTarget | null;
|
||||
screenX?: number;
|
||||
screenY?: number;
|
||||
}
|
||||
@@ -358,8 +359,8 @@ interface MouseEventInit extends EventModifierInit {
|
||||
interface MSAccountInfo {
|
||||
accountImageUri?: string;
|
||||
accountName?: string;
|
||||
rpDisplayName?: string;
|
||||
userDisplayName?: string;
|
||||
rpDisplayName: string;
|
||||
userDisplayName: string;
|
||||
userId?: string;
|
||||
}
|
||||
|
||||
@@ -442,7 +443,7 @@ interface MSCredentialParameters {
|
||||
|
||||
interface MSCredentialSpec {
|
||||
id?: string;
|
||||
type?: MSCredentialType;
|
||||
type: MSCredentialType;
|
||||
}
|
||||
|
||||
interface MSDelay {
|
||||
@@ -652,8 +653,8 @@ interface MsZoomToOptions {
|
||||
contentX?: number;
|
||||
contentY?: number;
|
||||
scaleFactor?: number;
|
||||
viewportX?: string;
|
||||
viewportY?: string;
|
||||
viewportX?: string | null;
|
||||
viewportY?: string | null;
|
||||
}
|
||||
|
||||
interface MutationObserverInit {
|
||||
@@ -679,9 +680,9 @@ interface ObjectURLOptions {
|
||||
}
|
||||
|
||||
interface PaymentCurrencyAmount {
|
||||
currency?: string;
|
||||
currency: string;
|
||||
currencySystem?: string;
|
||||
value?: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface PaymentDetails {
|
||||
@@ -695,19 +696,19 @@ interface PaymentDetails {
|
||||
interface PaymentDetailsModifier {
|
||||
additionalDisplayItems?: PaymentItem[];
|
||||
data?: any;
|
||||
supportedMethods?: string[];
|
||||
supportedMethods: string[];
|
||||
total?: PaymentItem;
|
||||
}
|
||||
|
||||
interface PaymentItem {
|
||||
amount?: PaymentCurrencyAmount;
|
||||
label?: string;
|
||||
amount: PaymentCurrencyAmount;
|
||||
label: string;
|
||||
pending?: boolean;
|
||||
}
|
||||
|
||||
interface PaymentMethodData {
|
||||
data?: any;
|
||||
supportedMethods?: string[];
|
||||
supportedMethods: string[];
|
||||
}
|
||||
|
||||
interface PaymentOptions {
|
||||
@@ -722,9 +723,9 @@ interface PaymentRequestUpdateEventInit extends EventInit {
|
||||
}
|
||||
|
||||
interface PaymentShippingOption {
|
||||
amount?: PaymentCurrencyAmount;
|
||||
id?: string;
|
||||
label?: string;
|
||||
amount: PaymentCurrencyAmount;
|
||||
id: string;
|
||||
label: string;
|
||||
selected?: boolean;
|
||||
}
|
||||
|
||||
@@ -772,7 +773,7 @@ interface RequestInit {
|
||||
body?: any;
|
||||
cache?: RequestCache;
|
||||
credentials?: RequestCredentials;
|
||||
headers?: any;
|
||||
headers?: Headers | string[][];
|
||||
integrity?: string;
|
||||
keepalive?: boolean;
|
||||
method?: string;
|
||||
@@ -784,7 +785,7 @@ interface RequestInit {
|
||||
}
|
||||
|
||||
interface ResponseInit {
|
||||
headers?: any;
|
||||
headers?: Headers | string[][];
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
}
|
||||
@@ -869,15 +870,15 @@ interface RTCIceGatherOptions {
|
||||
}
|
||||
|
||||
interface RTCIceParameters {
|
||||
iceLite?: boolean;
|
||||
iceLite?: boolean | null;
|
||||
password?: string;
|
||||
usernameFragment?: string;
|
||||
}
|
||||
|
||||
interface RTCIceServer {
|
||||
credential?: string;
|
||||
credential?: string | null;
|
||||
urls?: any;
|
||||
username?: string;
|
||||
username?: string | null;
|
||||
}
|
||||
|
||||
interface RTCInboundRTPStreamStats extends RTCRTPStreamStats {
|
||||
@@ -1087,9 +1088,9 @@ interface RTCTransportStats extends RTCStats {
|
||||
}
|
||||
|
||||
interface ScopedCredentialDescriptor {
|
||||
id?: any;
|
||||
id: any;
|
||||
transports?: Transport[];
|
||||
type?: ScopedCredentialType;
|
||||
type: ScopedCredentialType;
|
||||
}
|
||||
|
||||
interface ScopedCredentialOptions {
|
||||
@@ -1100,29 +1101,29 @@ interface ScopedCredentialOptions {
|
||||
}
|
||||
|
||||
interface ScopedCredentialParameters {
|
||||
algorithm?: string | Algorithm;
|
||||
type?: ScopedCredentialType;
|
||||
algorithm: string | Algorithm;
|
||||
type: ScopedCredentialType;
|
||||
}
|
||||
|
||||
interface ServiceWorkerMessageEventInit extends EventInit {
|
||||
data?: any;
|
||||
lastEventId?: string;
|
||||
origin?: string;
|
||||
ports?: MessagePort[];
|
||||
source?: ServiceWorker | MessagePort;
|
||||
ports?: MessagePort[] | null;
|
||||
source?: ServiceWorker | MessagePort | null;
|
||||
}
|
||||
|
||||
interface SpeechSynthesisEventInit extends EventInit {
|
||||
charIndex?: number;
|
||||
elapsedTime?: number;
|
||||
name?: string;
|
||||
utterance?: SpeechSynthesisUtterance;
|
||||
utterance?: SpeechSynthesisUtterance | null;
|
||||
}
|
||||
|
||||
interface StoreExceptionsInformation extends ExceptionInformation {
|
||||
detailURI?: string;
|
||||
explanationString?: string;
|
||||
siteName?: string;
|
||||
detailURI?: string | null;
|
||||
explanationString?: string | null;
|
||||
siteName?: string | null;
|
||||
}
|
||||
|
||||
interface StoreSiteSpecificExceptionsInformation extends StoreExceptionsInformation {
|
||||
@@ -1130,7 +1131,7 @@ interface StoreSiteSpecificExceptionsInformation extends StoreExceptionsInformat
|
||||
}
|
||||
|
||||
interface TrackEventInit extends EventInit {
|
||||
track?: VideoTrack | AudioTrack | TextTrack;
|
||||
track?: VideoTrack | AudioTrack | TextTrack | null;
|
||||
}
|
||||
|
||||
interface TransitionEventInit extends EventInit {
|
||||
@@ -1140,7 +1141,7 @@ interface TransitionEventInit extends EventInit {
|
||||
|
||||
interface UIEventInit extends EventInit {
|
||||
detail?: number;
|
||||
view?: Window;
|
||||
view?: Window | null;
|
||||
}
|
||||
|
||||
interface WebAuthnExtensions {
|
||||
@@ -1520,9 +1521,9 @@ interface Cache {
|
||||
add(request: RequestInfo): Promise<void>;
|
||||
addAll(requests: RequestInfo[]): Promise<void>;
|
||||
delete(request: RequestInfo, options?: CacheQueryOptions): Promise<boolean>;
|
||||
keys(request?: RequestInfo, options?: CacheQueryOptions): any;
|
||||
keys(request?: RequestInfo, options?: CacheQueryOptions): Promise<Request[]>;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): Promise<Response>;
|
||||
matchAll(request?: RequestInfo, options?: CacheQueryOptions): any;
|
||||
matchAll(request?: RequestInfo, options?: CacheQueryOptions): Promise<Response[]>;
|
||||
put(request: RequestInfo, response: Response): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1534,7 +1535,7 @@ declare var Cache: {
|
||||
interface CacheStorage {
|
||||
delete(cacheName: string): Promise<boolean>;
|
||||
has(cacheName: string): Promise<boolean>;
|
||||
keys(): any;
|
||||
keys(): Promise<string[]>;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): Promise<any>;
|
||||
open(cacheName: string): Promise<Cache>;
|
||||
}
|
||||
@@ -2639,7 +2640,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven
|
||||
*/
|
||||
readonly compatMode: string;
|
||||
cookie: string;
|
||||
readonly currentScript: HTMLScriptElement | SVGScriptElement;
|
||||
readonly currentScript: HTMLScriptElement | SVGScriptElement | null;
|
||||
readonly defaultView: Window;
|
||||
/**
|
||||
* Sets or gets a value that indicates whether the document can be edited.
|
||||
@@ -3378,7 +3379,7 @@ interface DOMException {
|
||||
|
||||
declare var DOMException: {
|
||||
prototype: DOMException;
|
||||
new(): DOMException;
|
||||
new(message?: string, name?: string): DOMException;
|
||||
readonly ABORT_ERR: number;
|
||||
readonly DATA_CLONE_ERR: number;
|
||||
readonly DOMSTRING_SIZE_ERR: number;
|
||||
@@ -3884,7 +3885,7 @@ interface Headers {
|
||||
|
||||
declare var Headers: {
|
||||
prototype: Headers;
|
||||
new(init?: any): Headers;
|
||||
new(init?: Headers | string[][] | object): Headers;
|
||||
};
|
||||
|
||||
interface History {
|
||||
@@ -4044,7 +4045,7 @@ interface HTMLAppletElement extends HTMLElement {
|
||||
* Sets or retrieves a character string that can be used to implement your own declare functionality for the object.
|
||||
*/
|
||||
declare: boolean;
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Sets or retrieves the height of the object.
|
||||
*/
|
||||
@@ -4282,7 +4283,7 @@ interface HTMLButtonElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Overrides the action attribute (where the data on a form is sent) on the parent form element.
|
||||
*/
|
||||
@@ -4715,7 +4716,7 @@ interface HTMLFieldSetElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
name: string;
|
||||
/**
|
||||
* Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting.
|
||||
@@ -5294,7 +5295,7 @@ interface HTMLInputElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Overrides the action attribute (where the data on a form is sent) on the parent form element.
|
||||
*/
|
||||
@@ -5461,7 +5462,7 @@ interface HTMLLabelElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Sets or retrieves the object to which the given label object is assigned.
|
||||
*/
|
||||
@@ -5483,7 +5484,7 @@ interface HTMLLegendElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -5917,7 +5918,7 @@ interface HTMLObjectElement extends HTMLElement, GetSVGDocument {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Sets or retrieves the height of the object.
|
||||
*/
|
||||
@@ -6016,7 +6017,7 @@ interface HTMLOptGroupElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Sets or retrieves the ordinal position of an option in a list box.
|
||||
*/
|
||||
@@ -6055,7 +6056,7 @@ interface HTMLOptionElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Sets or retrieves the ordinal position of an option in a list box.
|
||||
*/
|
||||
@@ -6099,7 +6100,7 @@ declare var HTMLOptionsCollection: {
|
||||
|
||||
interface HTMLOutputElement extends HTMLElement {
|
||||
defaultValue: string;
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
readonly htmlFor: DOMSettableTokenList;
|
||||
name: string;
|
||||
readonly type: string;
|
||||
@@ -6188,7 +6189,7 @@ interface HTMLProgressElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Defines the maximum, or "done" value for a progress element.
|
||||
*/
|
||||
@@ -6274,7 +6275,7 @@ interface HTMLSelectElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Sets or retrieves the number of objects in a collection.
|
||||
*/
|
||||
@@ -6745,7 +6746,7 @@ interface HTMLTextAreaElement extends HTMLElement {
|
||||
/**
|
||||
* Retrieves a reference to the form that the object is embedded in.
|
||||
*/
|
||||
readonly form: HTMLFormElement;
|
||||
readonly form: HTMLFormElement | null;
|
||||
/**
|
||||
* Sets or retrieves the maximum number of characters that the user can enter in a text control.
|
||||
*/
|
||||
@@ -7211,6 +7212,7 @@ interface IntersectionObserverEntry {
|
||||
readonly rootBounds: ClientRect;
|
||||
readonly target: Element;
|
||||
readonly time: number;
|
||||
readonly isIntersecting: boolean;
|
||||
}
|
||||
|
||||
declare var IntersectionObserverEntry: {
|
||||
@@ -7312,7 +7314,7 @@ interface MediaDevicesEventMap {
|
||||
|
||||
interface MediaDevices extends EventTarget {
|
||||
ondevicechange: (this: MediaDevices, ev: Event) => any;
|
||||
enumerateDevices(): any;
|
||||
enumerateDevices(): Promise<MediaDeviceInfo[]>;
|
||||
getSupportedConstraints(): MediaTrackSupportedConstraints;
|
||||
getUserMedia(constraints: MediaStreamConstraints): Promise<MediaStream>;
|
||||
addEventListener<K extends keyof MediaDevicesEventMap>(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, useCapture?: boolean): void;
|
||||
@@ -9058,6 +9060,7 @@ interface Response extends Object, Body {
|
||||
readonly statusText: string;
|
||||
readonly type: ResponseType;
|
||||
readonly url: string;
|
||||
readonly redirected: boolean;
|
||||
clone(): Response;
|
||||
}
|
||||
|
||||
@@ -9511,8 +9514,8 @@ interface ServiceWorkerContainer extends EventTarget {
|
||||
oncontrollerchange: (this: ServiceWorkerContainer, ev: Event) => any;
|
||||
onmessage: (this: ServiceWorkerContainer, ev: ServiceWorkerMessageEvent) => any;
|
||||
readonly ready: Promise<ServiceWorkerRegistration>;
|
||||
getRegistration(clientURL?: USVString): Promise<any>;
|
||||
getRegistrations(): any;
|
||||
getRegistration(): Promise<ServiceWorkerRegistration | undefined>;
|
||||
getRegistrations(): Promise<ServiceWorkerRegistration[]>;
|
||||
register(scriptURL: USVString, options?: RegistrationOptions): Promise<ServiceWorkerRegistration>;
|
||||
addEventListener<K extends keyof ServiceWorkerContainerEventMap>(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
@@ -9548,7 +9551,7 @@ interface ServiceWorkerRegistration extends EventTarget {
|
||||
readonly scope: USVString;
|
||||
readonly sync: SyncManager;
|
||||
readonly waiting: ServiceWorker | null;
|
||||
getNotifications(filter?: GetNotificationOptions): any;
|
||||
getNotifications(filter?: GetNotificationOptions): Promise<Notification[]>;
|
||||
showNotification(title: string, options?: NotificationOptions): Promise<void>;
|
||||
unregister(): Promise<boolean>;
|
||||
update(): Promise<void>;
|
||||
@@ -11573,7 +11576,7 @@ declare var SVGZoomEvent: {
|
||||
};
|
||||
|
||||
interface SyncManager {
|
||||
getTags(): any;
|
||||
getTags(): Promise<string[]>;
|
||||
register(tag: string): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -11881,6 +11884,7 @@ interface ValidityState {
|
||||
readonly typeMismatch: boolean;
|
||||
readonly valid: boolean;
|
||||
readonly valueMissing: boolean;
|
||||
readonly tooShort: boolean;
|
||||
}
|
||||
|
||||
declare var ValidityState: {
|
||||
@@ -13742,13 +13746,13 @@ interface NavigatorUserMedia {
|
||||
|
||||
interface NodeSelector {
|
||||
querySelector<K extends keyof ElementTagNameMap>(selectors: K): ElementTagNameMap[K] | null;
|
||||
querySelector(selectors: string): Element | null;
|
||||
querySelector<E extends Element = Element>(selectors: string): E | null;
|
||||
querySelectorAll<K extends keyof ElementListTagNameMap>(selectors: K): ElementListTagNameMap[K];
|
||||
querySelectorAll(selectors: string): NodeListOf<Element>;
|
||||
querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;
|
||||
}
|
||||
|
||||
interface RandomSource {
|
||||
getRandomValues(array: ArrayBufferView): ArrayBufferView;
|
||||
getRandomValues<T extends Int8Array | Uint8ClampedArray | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array>(array: T): T;
|
||||
}
|
||||
|
||||
interface SVGAnimatedPoints {
|
||||
@@ -13823,17 +13827,37 @@ interface XMLHttpRequestEventTargetEventMap {
|
||||
}
|
||||
|
||||
interface XMLHttpRequestEventTarget {
|
||||
onabort: (this: XMLHttpRequestEventTarget, ev: Event) => any;
|
||||
onerror: (this: XMLHttpRequestEventTarget, ev: ErrorEvent) => any;
|
||||
onload: (this: XMLHttpRequestEventTarget, ev: Event) => any;
|
||||
onloadend: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
|
||||
onloadstart: (this: XMLHttpRequestEventTarget, ev: Event) => any;
|
||||
onprogress: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
|
||||
ontimeout: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
|
||||
onabort: (this: XMLHttpRequest, ev: Event) => any;
|
||||
onerror: (this: XMLHttpRequest, ev: ErrorEvent) => any;
|
||||
onload: (this: XMLHttpRequest, ev: Event) => any;
|
||||
onloadend: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
onloadstart: (this: XMLHttpRequest, ev: Event) => any;
|
||||
onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
interface BroadcastChannel extends EventTarget {
|
||||
readonly name: string;
|
||||
onmessage: (ev: MessageEvent) => any;
|
||||
onmessageerror: (ev: MessageEvent) => any;
|
||||
close(): void;
|
||||
postMessage(message: any): void;
|
||||
addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var BroadcastChannel: {
|
||||
prototype: BroadcastChannel;
|
||||
new(name: string): BroadcastChannel;
|
||||
};
|
||||
|
||||
interface BroadcastChannelEventMap {
|
||||
message: MessageEvent;
|
||||
messageerror: MessageEvent;
|
||||
}
|
||||
|
||||
interface ErrorEventInit {
|
||||
message?: string;
|
||||
filename?: string;
|
||||
@@ -13924,8 +13948,7 @@ interface BlobPropertyBag {
|
||||
endings?: string;
|
||||
}
|
||||
|
||||
interface FilePropertyBag {
|
||||
type?: string;
|
||||
interface FilePropertyBag extends BlobPropertyBag {
|
||||
lastModified?: number;
|
||||
}
|
||||
|
||||
@@ -14201,6 +14224,44 @@ interface TouchEventInit extends EventModifierInit {
|
||||
changedTouches?: Touch[];
|
||||
}
|
||||
|
||||
interface HTMLDialogElement extends HTMLElement {
|
||||
open: boolean;
|
||||
returnValue: string;
|
||||
close(returnValue?: string): void;
|
||||
show(): void;
|
||||
showModal(): void;
|
||||
}
|
||||
|
||||
declare var HTMLDialogElement: {
|
||||
prototype: HTMLDialogElement;
|
||||
new(): HTMLDialogElement;
|
||||
};
|
||||
|
||||
interface HTMLMainElement extends HTMLElement {
|
||||
}
|
||||
|
||||
declare var HTMLMainElement: {
|
||||
prototype: HTMLMainElement;
|
||||
new(): HTMLMainElement;
|
||||
};
|
||||
|
||||
interface HTMLDetailsElement extends HTMLElement {
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
declare var HTMLDetailsElement: {
|
||||
prototype: HTMLDetailsElement;
|
||||
new(): HTMLDetailsElement;
|
||||
};
|
||||
|
||||
interface HTMLSummaryElement extends HTMLElement {
|
||||
}
|
||||
|
||||
declare var HTMLSummaryElement: {
|
||||
prototype: HTMLSummaryElement;
|
||||
new(): HTMLSummaryElement;
|
||||
};
|
||||
|
||||
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
|
||||
|
||||
interface DecodeErrorCallback {
|
||||
@@ -14690,7 +14751,7 @@ type GLsizeiptr = number;
|
||||
type GLubyte = number;
|
||||
type GLuint = number;
|
||||
type GLushort = number;
|
||||
type HeadersInit = any;
|
||||
type HeadersInit = Headers | string[][];
|
||||
type IDBKeyPath = string;
|
||||
type KeyFormat = string;
|
||||
type KeyType = string;
|
||||
|
||||
Vendored
+6
-23
@@ -10,9 +10,7 @@ interface Array<T> {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (this: void, value: T, index: number, obj: Array<T>) => boolean): T | undefined;
|
||||
find(predicate: (this: void, value: T, index: number, obj: Array<T>) => boolean, thisArg: undefined): T | undefined;
|
||||
find<Z>(predicate: (this: Z, value: T, index: number, obj: Array<T>) => boolean, thisArg: Z): T | undefined;
|
||||
find(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): T | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -23,9 +21,7 @@ interface Array<T> {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (this: void, value: T, index: number, obj: Array<T>) => boolean): number;
|
||||
findIndex(predicate: (this: void, value: T, index: number, obj: Array<T>) => boolean, thisArg: undefined): number;
|
||||
findIndex<Z>(predicate: (this: Z, value: T, index: number, obj: Array<T>) => boolean, thisArg: Z): number;
|
||||
findIndex(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Returns the this object after filling the section identified by start and end with value
|
||||
@@ -56,16 +52,7 @@ interface ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from<T, U>(arrayLike: ArrayLike<T>, mapfn: (this: void, v: T, k: number) => U): Array<U>;
|
||||
from<T, U>(arrayLike: ArrayLike<T>, mapfn: (this: void, v: T, k: number) => U, thisArg: undefined): Array<U>;
|
||||
from<Z, T, U>(arrayLike: ArrayLike<T>, mapfn: (this: Z, v: T, k: number) => U, thisArg: Z): Array<U>;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an array from an array-like object.
|
||||
* @param arrayLike An array-like object to convert to an array.
|
||||
*/
|
||||
from<T>(arrayLike: ArrayLike<T>): Array<T>;
|
||||
from<T, U = T>(arrayLike: ArrayLike<T>, mapfn?: (v: T, k: number) => U, thisArg?: any): Array<U>;
|
||||
|
||||
/**
|
||||
* Returns a new array from a set of elements.
|
||||
@@ -340,7 +327,7 @@ interface ObjectConstructor {
|
||||
* @param o Object that contains the property.
|
||||
* @param p Name of the property.
|
||||
*/
|
||||
getOwnPropertyDescriptor(o: any, propertyKey: PropertyKey): PropertyDescriptor;
|
||||
getOwnPropertyDescriptor(o: any, propertyKey: PropertyKey): PropertyDescriptor | undefined;
|
||||
|
||||
/**
|
||||
* Adds a property to an object, or modifies attributes of an existing property.
|
||||
@@ -363,9 +350,7 @@ interface ReadonlyArray<T> {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (this: void, value: T, index: number, obj: ReadonlyArray<T>) => boolean): T | undefined;
|
||||
find(predicate: (this: void, value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg: undefined): T | undefined;
|
||||
find<Z>(predicate: (this: Z, value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg: Z): T | undefined;
|
||||
find(predicate: (value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg?: any): T | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -376,9 +361,7 @@ interface ReadonlyArray<T> {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (this: void, value: T, index: number, obj: Array<T>) => boolean): number;
|
||||
findIndex(predicate: (this: void, value: T, index: number, obj: Array<T>) => boolean, thisArg: undefined): number;
|
||||
findIndex<Z>(predicate: (this: Z, value: T, index: number, obj: Array<T>) => boolean, thisArg: Z): number;
|
||||
findIndex(predicate: (value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg?: any): number;
|
||||
}
|
||||
|
||||
interface RegExp {
|
||||
|
||||
Vendored
+10
-90
@@ -54,15 +54,7 @@ interface ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from<T, U>(iterable: Iterable<T>, mapfn: (this: void, v: T, k: number) => U): Array<U>;
|
||||
from<T, U>(iterable: Iterable<T>, mapfn: (this: void, v: T, k: number) => U, thisArg: undefined): Array<U>;
|
||||
from<Z, T, U>(iterable: Iterable<T>, mapfn: (this: Z, v: T, k: number) => U, thisArg: Z): Array<U>;
|
||||
|
||||
/**
|
||||
* Creates an array from an iterable object.
|
||||
* @param iterable An iterable object to convert to an array.
|
||||
*/
|
||||
from<T>(iterable: Iterable<T>): Array<T>;
|
||||
from<T, U = T>(iterable: Iterable<T>, mapfn?: (v: T, k: number) => U, thisArg?: any): Array<U>;
|
||||
}
|
||||
|
||||
interface ReadonlyArray<T> {
|
||||
@@ -217,10 +209,6 @@ interface String {
|
||||
[Symbol.iterator](): IterableIterator<string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
|
||||
* number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int8Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -246,17 +234,9 @@ interface Int8ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Int8Array;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Int8Array;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Int8Array;
|
||||
|
||||
from(arrayLike: Iterable<number>): Int8Array;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int8Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint8Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -282,17 +262,9 @@ interface Uint8ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Uint8Array;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Uint8Array;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Uint8Array;
|
||||
|
||||
from(arrayLike: Iterable<number>): Uint8Array;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Uint8Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
|
||||
* If the requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint8ClampedArray {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -321,17 +293,9 @@ interface Uint8ClampedArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Uint8ClampedArray;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Uint8ClampedArray;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Uint8ClampedArray;
|
||||
|
||||
from(arrayLike: Iterable<number>): Uint8ClampedArray;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Uint8ClampedArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int16Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -359,17 +323,9 @@ interface Int16ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Int16Array;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Int16Array;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Int16Array;
|
||||
|
||||
from(arrayLike: Iterable<number>): Int16Array;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int16Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint16Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -395,17 +351,9 @@ interface Uint16ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Uint16Array;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Uint16Array;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Uint16Array;
|
||||
|
||||
from(arrayLike: Iterable<number>): Uint16Array;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Uint16Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int32Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -431,17 +379,9 @@ interface Int32ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Int32Array;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Int32Array;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Int32Array;
|
||||
|
||||
from(arrayLike: Iterable<number>): Int32Array;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int32Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint32Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -467,17 +407,9 @@ interface Uint32ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Uint32Array;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Uint32Array;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Uint32Array;
|
||||
|
||||
from(arrayLike: Iterable<number>): Uint32Array;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Uint32Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
|
||||
* of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Float32Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -503,17 +435,9 @@ interface Float32ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Float32Array;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Float32Array;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Float32Array;
|
||||
|
||||
from(arrayLike: Iterable<number>): Float32Array;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Float32Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
|
||||
* number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Float64Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
@@ -539,9 +463,5 @@ interface Float64ArrayConstructor {
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number): Float64Array;
|
||||
from(arrayLike: Iterable<number>, mapfn: (this: void, v: number, k: number) => number, thisArg: undefined): Float64Array;
|
||||
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Float64Array;
|
||||
|
||||
from(arrayLike: Iterable<number>): Float64Array;
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Float64Array;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -4,7 +4,7 @@ declare namespace Reflect {
|
||||
function defineProperty(target: object, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
|
||||
function deleteProperty(target: object, propertyKey: PropertyKey): boolean;
|
||||
function get(target: object, propertyKey: PropertyKey, receiver?: any): any;
|
||||
function getOwnPropertyDescriptor(target: object, propertyKey: PropertyKey): PropertyDescriptor;
|
||||
function getOwnPropertyDescriptor(target: object, propertyKey: PropertyKey): PropertyDescriptor | undefined;
|
||||
function getPrototypeOf(target: object): object;
|
||||
function has(target: object, propertyKey: PropertyKey): boolean;
|
||||
function isExtensible(target: object): boolean;
|
||||
|
||||
Vendored
-42
@@ -240,12 +240,6 @@ interface String {
|
||||
split(splitter: { [Symbol.split](string: string, limit?: number): string[]; }, limit?: number): string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a raw buffer of binary data, which is used to store data for the
|
||||
* different typed arrays. ArrayBuffers cannot be read from or written to directly,
|
||||
* but can be passed to a typed array or DataView Object to interpret the raw
|
||||
* buffer as needed.
|
||||
*/
|
||||
interface ArrayBuffer {
|
||||
readonly [Symbol.toStringTag]: "ArrayBuffer";
|
||||
}
|
||||
@@ -254,74 +248,38 @@ interface DataView {
|
||||
readonly [Symbol.toStringTag]: "DataView";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
|
||||
* number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int8Array {
|
||||
readonly [Symbol.toStringTag]: "Int8Array";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint8Array {
|
||||
readonly [Symbol.toStringTag]: "UInt8Array";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
|
||||
* If the requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint8ClampedArray {
|
||||
readonly [Symbol.toStringTag]: "Uint8ClampedArray";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int16Array {
|
||||
readonly [Symbol.toStringTag]: "Int16Array";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint16Array {
|
||||
readonly [Symbol.toStringTag]: "Uint16Array";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int32Array {
|
||||
readonly [Symbol.toStringTag]: "Int32Array";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint32Array {
|
||||
readonly [Symbol.toStringTag]: "Uint32Array";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
|
||||
* of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Float32Array {
|
||||
readonly [Symbol.toStringTag]: "Float32Array";
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
|
||||
* number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Float64Array {
|
||||
readonly [Symbol.toStringTag]: "Float64Array";
|
||||
}
|
||||
|
||||
Vendored
+6
@@ -22,4 +22,10 @@ interface ObjectConstructor {
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
entries(o: any): [string, any][];
|
||||
|
||||
/**
|
||||
* Returns an object containing all own property descriptors of an object
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
getOwnPropertyDescriptors<T>(o: T): {[P in keyof T]: TypedPropertyDescriptor<T[P]>} & { [x: string]: PropertyDescriptor };
|
||||
}
|
||||
|
||||
Vendored
+46
-46
@@ -127,7 +127,7 @@ interface ObjectConstructor {
|
||||
* @param o Object that contains the property.
|
||||
* @param p Name of the property.
|
||||
*/
|
||||
getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor;
|
||||
getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor | undefined;
|
||||
|
||||
/**
|
||||
* Returns the names of the own properties of an object. The own properties of an object are those that are defined directly
|
||||
@@ -1577,7 +1577,7 @@ interface Int8Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -1588,7 +1588,7 @@ interface Int8Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -1635,7 +1635,7 @@ interface Int8Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (this: void, value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array;
|
||||
map(callbackfn: (value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
@@ -1744,8 +1744,8 @@ interface Int8Array {
|
||||
interface Int8ArrayConstructor {
|
||||
readonly prototype: Int8Array;
|
||||
new(length: number): Int8Array;
|
||||
new(array: ArrayLike<number>): Int8Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int8Array;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int8Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int8Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -1844,7 +1844,7 @@ interface Uint8Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -1855,7 +1855,7 @@ interface Uint8Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -1902,7 +1902,7 @@ interface Uint8Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (this: void, value: number, index: number, array: Uint8Array) => number, thisArg?: any): Uint8Array;
|
||||
map(callbackfn: (value: number, index: number, array: Uint8Array) => number, thisArg?: any): Uint8Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
@@ -2012,8 +2012,8 @@ interface Uint8Array {
|
||||
interface Uint8ArrayConstructor {
|
||||
readonly prototype: Uint8Array;
|
||||
new(length: number): Uint8Array;
|
||||
new(array: ArrayLike<number>): Uint8Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint8Array;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint8Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint8Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -2111,7 +2111,7 @@ interface Uint8ClampedArray {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Uint8ClampedArray) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -2122,7 +2122,7 @@ interface Uint8ClampedArray {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Uint8ClampedArray) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -2169,7 +2169,7 @@ interface Uint8ClampedArray {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (this: void, value: number, index: number, array: Uint8ClampedArray) => number, thisArg?: any): Uint8ClampedArray;
|
||||
map(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => number, thisArg?: any): Uint8ClampedArray;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
@@ -2279,8 +2279,8 @@ interface Uint8ClampedArray {
|
||||
interface Uint8ClampedArrayConstructor {
|
||||
readonly prototype: Uint8ClampedArray;
|
||||
new(length: number): Uint8ClampedArray;
|
||||
new(array: ArrayLike<number>): Uint8ClampedArray;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint8ClampedArray;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint8ClampedArray;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint8ClampedArray;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -2366,7 +2366,7 @@ interface Int16Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
filter(callbackfn: (this: void, value: number, index: number, array: Int16Array) => any, thisArg?: any): Int16Array;
|
||||
filter(callbackfn: (value: number, index: number, array: Int16Array) => any, thisArg?: any): Int16Array;
|
||||
|
||||
/**
|
||||
* Returns the value of the first element in the array where predicate is true, and undefined
|
||||
@@ -2377,7 +2377,7 @@ interface Int16Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Int16Array) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -2388,7 +2388,7 @@ interface Int16Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Int16Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -2434,7 +2434,7 @@ interface Int16Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (this: void, value: number, index: number, array: Int16Array) => number, thisArg?: any): Int16Array;
|
||||
map(callbackfn: (value: number, index: number, array: Int16Array) => number, thisArg?: any): Int16Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
@@ -2544,8 +2544,8 @@ interface Int16Array {
|
||||
interface Int16ArrayConstructor {
|
||||
readonly prototype: Int16Array;
|
||||
new(length: number): Int16Array;
|
||||
new(array: ArrayLike<number>): Int16Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int16Array;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int16Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int16Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -2644,7 +2644,7 @@ interface Uint16Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Uint16Array) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -2655,7 +2655,7 @@ interface Uint16Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Uint16Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -2702,7 +2702,7 @@ interface Uint16Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (this: void, value: number, index: number, array: Uint16Array) => number, thisArg?: any): Uint16Array;
|
||||
map(callbackfn: (value: number, index: number, array: Uint16Array) => number, thisArg?: any): Uint16Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
@@ -2812,8 +2812,8 @@ interface Uint16Array {
|
||||
interface Uint16ArrayConstructor {
|
||||
readonly prototype: Uint16Array;
|
||||
new(length: number): Uint16Array;
|
||||
new(array: ArrayLike<number>): Uint16Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint16Array;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint16Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint16Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -2911,7 +2911,7 @@ interface Int32Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Int32Array) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -2922,7 +2922,7 @@ interface Int32Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Int32Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -3079,8 +3079,8 @@ interface Int32Array {
|
||||
interface Int32ArrayConstructor {
|
||||
readonly prototype: Int32Array;
|
||||
new(length: number): Int32Array;
|
||||
new(array: ArrayLike<number>): Int32Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int32Array;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Int32Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Int32Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -3178,7 +3178,7 @@ interface Uint32Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Uint32Array) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -3189,7 +3189,7 @@ interface Uint32Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Uint32Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -3235,7 +3235,7 @@ interface Uint32Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (this: void, value: number, index: number, array: Uint32Array) => number, thisArg?: any): Uint32Array;
|
||||
map(callbackfn: (value: number, index: number, array: Uint32Array) => number, thisArg?: any): Uint32Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
@@ -3345,8 +3345,8 @@ interface Uint32Array {
|
||||
interface Uint32ArrayConstructor {
|
||||
readonly prototype: Uint32Array;
|
||||
new(length: number): Uint32Array;
|
||||
new(array: ArrayLike<number>): Uint32Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint32Array;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Uint32Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Uint32Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -3444,7 +3444,7 @@ interface Float32Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Float32Array) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -3455,7 +3455,7 @@ interface Float32Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Float32Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -3502,7 +3502,7 @@ interface Float32Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (this: void, value: number, index: number, array: Float32Array) => number, thisArg?: any): Float32Array;
|
||||
map(callbackfn: (value: number, index: number, array: Float32Array) => number, thisArg?: any): Float32Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
@@ -3612,8 +3612,8 @@ interface Float32Array {
|
||||
interface Float32ArrayConstructor {
|
||||
readonly prototype: Float32Array;
|
||||
new(length: number): Float32Array;
|
||||
new(array: ArrayLike<number>): Float32Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Float32Array;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Float32Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Float32Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
@@ -3712,7 +3712,7 @@ interface Float64Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
find(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number | undefined;
|
||||
find(predicate: (value: number, index: number, obj: Float64Array) => boolean, thisArg?: any): number | undefined;
|
||||
|
||||
/**
|
||||
* Returns the index of the first element in the array where predicate is true, and -1
|
||||
@@ -3723,7 +3723,7 @@ interface Float64Array {
|
||||
* @param thisArg If provided, it will be used as the this value for each invocation of
|
||||
* predicate. If it is not provided, undefined is used instead.
|
||||
*/
|
||||
findIndex(predicate: (value: number, index: number, obj: Array<number>) => boolean, thisArg?: any): number;
|
||||
findIndex(predicate: (value: number, index: number, obj: Float64Array) => boolean, thisArg?: any): number;
|
||||
|
||||
/**
|
||||
* Performs the specified action for each element in an array.
|
||||
@@ -3770,7 +3770,7 @@ interface Float64Array {
|
||||
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
||||
* If thisArg is omitted, undefined is used as the this value.
|
||||
*/
|
||||
map(callbackfn: (this: void, value: number, index: number, array: Float64Array) => number, thisArg?: any): Float64Array;
|
||||
map(callbackfn: (value: number, index: number, array: Float64Array) => number, thisArg?: any): Float64Array;
|
||||
|
||||
/**
|
||||
* Calls the specified callback function for all the elements in an array. The return value of
|
||||
@@ -3880,8 +3880,8 @@ interface Float64Array {
|
||||
interface Float64ArrayConstructor {
|
||||
readonly prototype: Float64Array;
|
||||
new(length: number): Float64Array;
|
||||
new(array: ArrayLike<number>): Float64Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Float64Array;
|
||||
new(arrayOrArrayBuffer: ArrayLike<number> | ArrayBufferLike): Float64Array;
|
||||
new(buffer: ArrayBufferLike, byteOffset: number, length?: number): Float64Array;
|
||||
|
||||
/**
|
||||
* The size in bytes of each element in the array.
|
||||
|
||||
Vendored
+46
-26
@@ -37,7 +37,7 @@ interface IDBIndexParameters {
|
||||
|
||||
interface IDBObjectStoreParameters {
|
||||
autoIncrement?: boolean;
|
||||
keyPath?: IDBKeyPath;
|
||||
keyPath?: IDBKeyPath | null;
|
||||
}
|
||||
|
||||
interface KeyAlgorithm {
|
||||
@@ -74,7 +74,7 @@ interface RequestInit {
|
||||
body?: any;
|
||||
cache?: RequestCache;
|
||||
credentials?: RequestCredentials;
|
||||
headers?: any;
|
||||
headers?: Headers | string[][];
|
||||
integrity?: string;
|
||||
keepalive?: boolean;
|
||||
method?: string;
|
||||
@@ -86,7 +86,7 @@ interface RequestInit {
|
||||
}
|
||||
|
||||
interface ResponseInit {
|
||||
headers?: any;
|
||||
headers?: Headers | string[][];
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
}
|
||||
@@ -103,18 +103,18 @@ interface ExtendableMessageEventInit extends ExtendableEventInit {
|
||||
data?: any;
|
||||
origin?: string;
|
||||
lastEventId?: string;
|
||||
source?: Client | ServiceWorker | MessagePort;
|
||||
ports?: MessagePort[];
|
||||
source?: Client | ServiceWorker | MessagePort | null;
|
||||
ports?: MessagePort[] | null;
|
||||
}
|
||||
|
||||
interface FetchEventInit extends ExtendableEventInit {
|
||||
request?: Request;
|
||||
clientId?: string;
|
||||
request: Request;
|
||||
clientId?: string | null;
|
||||
isReload?: boolean;
|
||||
}
|
||||
|
||||
interface NotificationEventInit extends ExtendableEventInit {
|
||||
notification?: Notification;
|
||||
notification: Notification;
|
||||
action?: string;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ interface PushEventInit extends ExtendableEventInit {
|
||||
}
|
||||
|
||||
interface SyncEventInit extends ExtendableEventInit {
|
||||
tag?: string;
|
||||
tag: string;
|
||||
lastChance?: boolean;
|
||||
}
|
||||
|
||||
@@ -175,9 +175,9 @@ interface Cache {
|
||||
add(request: RequestInfo): Promise<void>;
|
||||
addAll(requests: RequestInfo[]): Promise<void>;
|
||||
delete(request: RequestInfo, options?: CacheQueryOptions): Promise<boolean>;
|
||||
keys(request?: RequestInfo, options?: CacheQueryOptions): any;
|
||||
keys(request?: RequestInfo, options?: CacheQueryOptions): Promise<Request[]>;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): Promise<Response>;
|
||||
matchAll(request?: RequestInfo, options?: CacheQueryOptions): any;
|
||||
matchAll(request?: RequestInfo, options?: CacheQueryOptions): Promise<Response[]>;
|
||||
put(request: RequestInfo, response: Response): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ declare var Cache: {
|
||||
interface CacheStorage {
|
||||
delete(cacheName: string): Promise<boolean>;
|
||||
has(cacheName: string): Promise<boolean>;
|
||||
keys(): any;
|
||||
keys(): Promise<string[]>;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): Promise<any>;
|
||||
open(cacheName: string): Promise<Cache>;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ interface DOMException {
|
||||
|
||||
declare var DOMException: {
|
||||
prototype: DOMException;
|
||||
new(): DOMException;
|
||||
new(message?: string, name?: string): DOMException;
|
||||
readonly ABORT_ERR: number;
|
||||
readonly DATA_CLONE_ERR: number;
|
||||
readonly DOMSTRING_SIZE_ERR: number;
|
||||
@@ -470,7 +470,7 @@ interface Headers {
|
||||
|
||||
declare var Headers: {
|
||||
prototype: Headers;
|
||||
new(init?: any): Headers;
|
||||
new(init?: Headers | string[][] | object): Headers;
|
||||
};
|
||||
|
||||
interface IDBCursor {
|
||||
@@ -960,6 +960,7 @@ interface Response extends Object, Body {
|
||||
readonly statusText: string;
|
||||
readonly type: ResponseType;
|
||||
readonly url: string;
|
||||
readonly redirected: boolean;
|
||||
clone(): Response;
|
||||
}
|
||||
|
||||
@@ -1000,7 +1001,7 @@ interface ServiceWorkerRegistration extends EventTarget {
|
||||
readonly scope: USVString;
|
||||
readonly sync: SyncManager;
|
||||
readonly waiting: ServiceWorker | null;
|
||||
getNotifications(filter?: GetNotificationOptions): any;
|
||||
getNotifications(filter?: GetNotificationOptions): Promise<Notification[]>;
|
||||
showNotification(title: string, options?: NotificationOptions): Promise<void>;
|
||||
unregister(): Promise<boolean>;
|
||||
update(): Promise<void>;
|
||||
@@ -1014,7 +1015,7 @@ declare var ServiceWorkerRegistration: {
|
||||
};
|
||||
|
||||
interface SyncManager {
|
||||
getTags(): any;
|
||||
getTags(): Promise<string[]>;
|
||||
register(tag: string): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -1248,13 +1249,13 @@ interface XMLHttpRequestEventTargetEventMap {
|
||||
}
|
||||
|
||||
interface XMLHttpRequestEventTarget {
|
||||
onabort: (this: XMLHttpRequestEventTarget, ev: Event) => any;
|
||||
onerror: (this: XMLHttpRequestEventTarget, ev: ErrorEvent) => any;
|
||||
onload: (this: XMLHttpRequestEventTarget, ev: Event) => any;
|
||||
onloadend: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
|
||||
onloadstart: (this: XMLHttpRequestEventTarget, ev: Event) => any;
|
||||
onprogress: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
|
||||
ontimeout: (this: XMLHttpRequestEventTarget, ev: ProgressEvent) => any;
|
||||
onabort: (this: XMLHttpRequest, ev: Event) => any;
|
||||
onerror: (this: XMLHttpRequest, ev: ErrorEvent) => any;
|
||||
onload: (this: XMLHttpRequest, ev: Event) => any;
|
||||
onloadend: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
onloadstart: (this: XMLHttpRequest, ev: Event) => any;
|
||||
onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -1274,7 +1275,7 @@ declare var Client: {
|
||||
interface Clients {
|
||||
claim(): Promise<void>;
|
||||
get(id: string): Promise<any>;
|
||||
matchAll(options?: ClientQueryOptions): any;
|
||||
matchAll(options?: ClientQueryOptions): Promise<Client[]>;
|
||||
openWindow(url: USVString): Promise<WindowClient>;
|
||||
}
|
||||
|
||||
@@ -1499,6 +1500,26 @@ interface WorkerUtils extends Object, WindowBase64 {
|
||||
setTimeout(handler: any, timeout?: any, ...args: any[]): number;
|
||||
}
|
||||
|
||||
interface BroadcastChannel extends EventTarget {
|
||||
readonly name: string;
|
||||
onmessage: (ev: MessageEvent) => any;
|
||||
onmessageerror: (ev: MessageEvent) => any;
|
||||
close(): void;
|
||||
postMessage(message: any): void;
|
||||
addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var BroadcastChannel: {
|
||||
prototype: BroadcastChannel;
|
||||
new(name: string): BroadcastChannel;
|
||||
};
|
||||
|
||||
interface BroadcastChannelEventMap {
|
||||
message: MessageEvent;
|
||||
messageerror: MessageEvent;
|
||||
}
|
||||
|
||||
interface ErrorEventInit {
|
||||
message?: string;
|
||||
filename?: string;
|
||||
@@ -1562,8 +1583,7 @@ interface BlobPropertyBag {
|
||||
endings?: string;
|
||||
}
|
||||
|
||||
interface FilePropertyBag {
|
||||
type?: string;
|
||||
interface FilePropertyBag extends BlobPropertyBag {
|
||||
lastModified?: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace ts.server {
|
||||
|
||||
export function shouldEmitFile(scriptInfo: ScriptInfo) {
|
||||
return !scriptInfo.hasMixedContent;
|
||||
return !scriptInfo.hasMixedContent && !scriptInfo.isDynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,7 +188,7 @@ namespace ts.server {
|
||||
*/
|
||||
getFilesAffectedBy(scriptInfo: ScriptInfo): string[] {
|
||||
const info = this.getOrCreateFileInfo(scriptInfo.path);
|
||||
const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName];
|
||||
const singleFileResult = scriptInfo.hasMixedContent || scriptInfo.isDynamic ? [] : [scriptInfo.fileName];
|
||||
if (info.updateShapeSignature()) {
|
||||
const options = this.project.getCompilerOptions();
|
||||
// If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
|
||||
@@ -303,7 +303,7 @@ namespace ts.server {
|
||||
getFilesAffectedBy(scriptInfo: ScriptInfo): string[] {
|
||||
this.ensureProjectDependencyGraphUpToDate();
|
||||
|
||||
const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName];
|
||||
const singleFileResult = scriptInfo.hasMixedContent || scriptInfo.isDynamic ? [] : [scriptInfo.fileName];
|
||||
const fileInfo = this.getFileInfo(scriptInfo.path);
|
||||
if (!fileInfo || !fileInfo.updateShapeSignature()) {
|
||||
return singleFileResult;
|
||||
|
||||
@@ -527,6 +527,10 @@ namespace ts.server {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getSpanOfEnclosingComment(_fileName: string, _position: number, _onlyMultiLine: boolean): TextSpan {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getCodeFixesAtPosition(file: string, start: number, end: number, errorCodes: number[]): CodeAction[] {
|
||||
const args: protocol.CodeFixRequestArgs = { ...this.createFileRangeRequestArgs(file, start, end), errorCodes };
|
||||
|
||||
@@ -569,7 +573,7 @@ namespace ts.server {
|
||||
|
||||
getEditsForRefactor(
|
||||
fileName: string,
|
||||
_formatOptions: FormatCodeSettings,
|
||||
formatOptions: FormatCodeSettings,
|
||||
positionOrRange: number | TextRange,
|
||||
refactorName: string,
|
||||
actionName: string): RefactorEditInfo {
|
||||
@@ -577,14 +581,13 @@ namespace ts.server {
|
||||
const args = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName) as protocol.GetEditsForRefactorRequestArgs;
|
||||
args.refactor = refactorName;
|
||||
args.action = actionName;
|
||||
args.formatOptions = formatOptions;
|
||||
|
||||
const request = this.processRequest<protocol.GetEditsForRefactorRequest>(CommandNames.GetEditsForRefactor, args);
|
||||
const response = this.processResponse<protocol.GetEditsForRefactorResponse>(request);
|
||||
|
||||
if (!response.body) {
|
||||
return {
|
||||
edits: []
|
||||
};
|
||||
return { edits: [], renameFilename: undefined, renameLocation: undefined };
|
||||
}
|
||||
|
||||
const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits);
|
||||
|
||||
@@ -109,6 +109,11 @@ namespace ts.server {
|
||||
"smart": IndentStyle.Smart
|
||||
});
|
||||
|
||||
export interface TypesMapFile {
|
||||
typesMap: SafeList;
|
||||
simpleMap: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* How to understand this block:
|
||||
* * The 'match' property is a regexp that matches a filename.
|
||||
@@ -234,18 +239,21 @@ namespace ts.server {
|
||||
getFileName(f: T): string;
|
||||
getScriptKind(f: T): ScriptKind;
|
||||
hasMixedContent(f: T, extraFileExtensions: JsFileExtensionInfo[]): boolean;
|
||||
isDynamicFile(f: T): boolean;
|
||||
}
|
||||
|
||||
const fileNamePropertyReader: FilePropertyReader<string> = {
|
||||
getFileName: x => x,
|
||||
getScriptKind: _ => undefined,
|
||||
hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, ext => ext.isMixedContent && fileExtensionIs(fileName, ext.extension)),
|
||||
isDynamicFile: x => x[0] === "^",
|
||||
};
|
||||
|
||||
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
|
||||
getFileName: x => x.fileName,
|
||||
getScriptKind: x => tryConvertScriptKindName(x.scriptKind),
|
||||
hasMixedContent: x => x.hasMixedContent
|
||||
hasMixedContent: x => x.hasMixedContent,
|
||||
isDynamicFile: x => x.fileName[0] === "^",
|
||||
};
|
||||
|
||||
function findProjectByName<T extends Project>(projectName: string, projects: T[]): T {
|
||||
@@ -330,6 +338,7 @@ namespace ts.server {
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
allowLocalPluginLoads?: boolean;
|
||||
typesMapLocation?: string;
|
||||
}
|
||||
|
||||
export class ProjectService {
|
||||
@@ -391,6 +400,7 @@ namespace ts.server {
|
||||
public readonly globalPlugins: ReadonlyArray<string>;
|
||||
public readonly pluginProbeLocations: ReadonlyArray<string>;
|
||||
public readonly allowLocalPluginLoads: boolean;
|
||||
public readonly typesMapLocation: string | undefined;
|
||||
|
||||
/** Tracks projects that we have already sent telemetry for. */
|
||||
private readonly seenProjects = createMap<true>();
|
||||
@@ -407,6 +417,7 @@ namespace ts.server {
|
||||
this.globalPlugins = opts.globalPlugins || emptyArray;
|
||||
this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray;
|
||||
this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads;
|
||||
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.host.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
|
||||
|
||||
Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService");
|
||||
|
||||
@@ -414,6 +425,10 @@ namespace ts.server {
|
||||
this.directoryWatchers = new DirectoryWatchers(this);
|
||||
this.throttledOperations = new ThrottledOperations(this.host);
|
||||
|
||||
if (opts.typesMapLocation) {
|
||||
this.loadTypesMap();
|
||||
}
|
||||
|
||||
this.typingsInstaller.attach(this);
|
||||
|
||||
this.typingsCache = new TypingsCache(this.typingsInstaller);
|
||||
@@ -451,6 +466,27 @@ namespace ts.server {
|
||||
this.eventHandler(event);
|
||||
}
|
||||
|
||||
private loadTypesMap() {
|
||||
try {
|
||||
const fileContent = this.host.readFile(this.typesMapLocation);
|
||||
if (fileContent === undefined) {
|
||||
this.logger.info(`Provided types map file "${this.typesMapLocation}" doesn't exist`);
|
||||
return;
|
||||
}
|
||||
const raw: TypesMapFile = JSON.parse(fileContent);
|
||||
// Parse the regexps
|
||||
for (const k of Object.keys(raw.typesMap)) {
|
||||
raw.typesMap[k].match = new RegExp(raw.typesMap[k].match as {} as string, "i");
|
||||
}
|
||||
// raw is now fixed and ready
|
||||
this.safelist = raw.typesMap;
|
||||
}
|
||||
catch (e) {
|
||||
this.logger.info(`Error loading types map: ${e}`);
|
||||
this.safelist = defaultTypeSafeList;
|
||||
}
|
||||
}
|
||||
|
||||
updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void {
|
||||
const project = this.findProject(response.projectName);
|
||||
if (!project) {
|
||||
@@ -958,28 +994,28 @@ namespace ts.server {
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.group(info => {
|
||||
let counter = 0;
|
||||
counter = printProjects(this.externalProjects, info, counter);
|
||||
counter = printProjects(this.configuredProjects, info, counter);
|
||||
printProjects(this.inferredProjects, info, counter);
|
||||
|
||||
info("Open files: ");
|
||||
for (const rootFile of this.openFiles) {
|
||||
info(`\t${rootFile.fileName}`);
|
||||
}
|
||||
});
|
||||
|
||||
function printProjects(projects: Project[], info: (msg: string) => void, counter: number): number {
|
||||
this.logger.startGroup();
|
||||
let counter = 0;
|
||||
const printProjects = (projects: Project[], counter: number): number => {
|
||||
for (const project of projects) {
|
||||
project.updateGraph();
|
||||
info(`Project '${project.getProjectName()}' (${ProjectKind[project.projectKind]}) ${counter}`);
|
||||
info(project.filesToString());
|
||||
info("-----------------------------------------------");
|
||||
this.logger.info(`Project '${project.getProjectName()}' (${ProjectKind[project.projectKind]}) ${counter}`);
|
||||
this.logger.info(project.filesToString());
|
||||
this.logger.info("-----------------------------------------------");
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
};
|
||||
counter = printProjects(this.externalProjects, counter);
|
||||
counter = printProjects(this.configuredProjects, counter);
|
||||
printProjects(this.inferredProjects, counter);
|
||||
|
||||
this.logger.info("Open files: ");
|
||||
for (const rootFile of this.openFiles) {
|
||||
this.logger.info(`\t${rootFile.fileName}`);
|
||||
}
|
||||
|
||||
this.logger.endGroup();
|
||||
}
|
||||
|
||||
private findConfiguredProjectByProjectName(configFileName: NormalizedPath) {
|
||||
@@ -1177,15 +1213,16 @@ namespace ts.server {
|
||||
private addFilesToProjectAndUpdateGraph<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, clientFileName: string, typeAcquisition: TypeAcquisition, configFileErrors: ReadonlyArray<Diagnostic>): void {
|
||||
let errors: Diagnostic[];
|
||||
for (const f of files) {
|
||||
const rootFilename = propertyReader.getFileName(f);
|
||||
const rootFileName = propertyReader.getFileName(f);
|
||||
const scriptKind = propertyReader.getScriptKind(f);
|
||||
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
|
||||
if (this.host.fileExists(rootFilename)) {
|
||||
const info = this.getOrCreateScriptInfoForNormalizedPath(toNormalizedPath(rootFilename), /*openedByClient*/ clientFileName === rootFilename, /*fileContent*/ undefined, scriptKind, hasMixedContent);
|
||||
const isDynamicFile = propertyReader.isDynamicFile(f);
|
||||
if (isDynamicFile || this.host.fileExists(rootFileName)) {
|
||||
const info = this.getOrCreateScriptInfoForNormalizedPath(toNormalizedPath(rootFileName), /*openedByClient*/ clientFileName === rootFileName, /*fileContent*/ undefined, scriptKind, hasMixedContent, isDynamicFile);
|
||||
project.addRoot(info);
|
||||
}
|
||||
else {
|
||||
(errors || (errors = [])).push(createFileNotFoundDiagnostic(rootFilename));
|
||||
(errors || (errors = [])).push(createFileNotFoundDiagnostic(rootFileName));
|
||||
}
|
||||
}
|
||||
project.setProjectErrors(concatenate(configFileErrors, errors));
|
||||
@@ -1215,7 +1252,8 @@ namespace ts.server {
|
||||
let rootFilesChanged = false;
|
||||
for (const f of newUncheckedFiles) {
|
||||
const newRootFile = propertyReader.getFileName(f);
|
||||
if (!this.host.fileExists(newRootFile)) {
|
||||
const isDynamic = propertyReader.isDynamicFile(f);
|
||||
if (!isDynamic && !this.host.fileExists(newRootFile)) {
|
||||
(projectErrors || (projectErrors = [])).push(createFileNotFoundDiagnostic(newRootFile));
|
||||
continue;
|
||||
}
|
||||
@@ -1226,7 +1264,7 @@ namespace ts.server {
|
||||
if (!scriptInfo) {
|
||||
const scriptKind = propertyReader.getScriptKind(f);
|
||||
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
|
||||
scriptInfo = this.getOrCreateScriptInfoForNormalizedPath(normalizedPath, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent);
|
||||
scriptInfo = this.getOrCreateScriptInfoForNormalizedPath(normalizedPath, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, isDynamic);
|
||||
}
|
||||
}
|
||||
newRootScriptInfos.push(scriptInfo);
|
||||
@@ -1410,17 +1448,17 @@ namespace ts.server {
|
||||
|
||||
watchClosedScriptInfo(info: ScriptInfo) {
|
||||
// do not watch files with mixed content - server doesn't know how to interpret it
|
||||
if (!info.hasMixedContent) {
|
||||
if (!info.hasMixedContent && !info.isDynamic) {
|
||||
const { fileName } = info;
|
||||
info.setWatcher(this.host.watchFile(fileName, _ => this.onSourceFileChanged(fileName)));
|
||||
}
|
||||
}
|
||||
|
||||
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean) {
|
||||
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, isDynamic?: boolean) {
|
||||
let info = this.getScriptInfoForNormalizedPath(fileName);
|
||||
if (!info) {
|
||||
if (openedByClient || this.host.fileExists(fileName)) {
|
||||
info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent);
|
||||
if (openedByClient || isDynamic || this.host.fileExists(fileName)) {
|
||||
info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent, isDynamic);
|
||||
|
||||
this.filenameToScriptInfo.set(info.path, info);
|
||||
|
||||
@@ -1430,6 +1468,7 @@ namespace ts.server {
|
||||
fileContent = this.host.readFile(fileName) || "";
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
this.watchClosedScriptInfo(info);
|
||||
}
|
||||
@@ -1609,7 +1648,7 @@ namespace ts.server {
|
||||
if (openFiles) {
|
||||
for (const file of openFiles) {
|
||||
const scriptInfo = this.getScriptInfo(file.fileName);
|
||||
Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen());
|
||||
Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
|
||||
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
|
||||
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
|
||||
}
|
||||
@@ -1647,11 +1686,13 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private closeConfiguredProject(configFile: NormalizedPath): void {
|
||||
private closeConfiguredProject(configFile: NormalizedPath): boolean {
|
||||
const configuredProject = this.findConfiguredProjectByProjectName(configFile);
|
||||
if (configuredProject && configuredProject.deleteOpenRef() === 0) {
|
||||
this.removeProject(configuredProject);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
closeExternalProject(uncheckedFileName: string, suppressRefresh = false): void {
|
||||
@@ -1712,23 +1753,14 @@ namespace ts.server {
|
||||
this.safelist = defaultTypeSafeList;
|
||||
}
|
||||
|
||||
loadSafeList(fileName: string): void {
|
||||
const raw: SafeList = JSON.parse(this.host.readFile(fileName, "utf-8"));
|
||||
// Parse the regexps
|
||||
for (const k of Object.keys(raw)) {
|
||||
raw[k].match = new RegExp(raw[k].match as {} as string, "i");
|
||||
}
|
||||
// raw is now fixed and ready
|
||||
this.safelist = raw;
|
||||
}
|
||||
|
||||
applySafeList(proj: protocol.ExternalProject): void {
|
||||
applySafeList(proj: protocol.ExternalProject): NormalizedPath[] {
|
||||
const { rootFiles, typeAcquisition } = proj;
|
||||
const types = (typeAcquisition && typeAcquisition.include) || [];
|
||||
|
||||
const excludeRules: string[] = [];
|
||||
|
||||
const normalizedNames = rootFiles.map(f => normalizeSlashes(f.fileName));
|
||||
const normalizedNames = rootFiles.map(f => normalizeSlashes(f.fileName)) as NormalizedPath[];
|
||||
const excludedFiles: NormalizedPath[] = [];
|
||||
|
||||
for (const name of Object.keys(this.safelist)) {
|
||||
const rule = this.safelist[name];
|
||||
@@ -1787,7 +1819,17 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
const excludeRegexes = excludeRules.map(e => new RegExp(e, "i"));
|
||||
proj.rootFiles = proj.rootFiles.filter((_file, index) => !excludeRegexes.some(re => re.test(normalizedNames[index])));
|
||||
const filesToKeep: ts.server.protocol.ExternalFile[] = [];
|
||||
for (let i = 0; i < proj.rootFiles.length; i++) {
|
||||
if (excludeRegexes.some(re => re.test(normalizedNames[i]))) {
|
||||
excludedFiles.push(normalizedNames[i]);
|
||||
}
|
||||
else {
|
||||
filesToKeep.push(proj.rootFiles[i]);
|
||||
}
|
||||
}
|
||||
proj.rootFiles = filesToKeep;
|
||||
return excludedFiles;
|
||||
}
|
||||
|
||||
openExternalProject(proj: protocol.ExternalProject, suppressRefreshOfInferredProjects = false): void {
|
||||
@@ -1798,7 +1840,7 @@ namespace ts.server {
|
||||
proj.typeAcquisition = typeAcquisition;
|
||||
}
|
||||
|
||||
this.applySafeList(proj);
|
||||
const excludedFiles = this.applySafeList(proj);
|
||||
|
||||
let tsConfigFiles: NormalizedPath[];
|
||||
const rootFiles: protocol.ExternalFile[] = [];
|
||||
@@ -1822,6 +1864,7 @@ namespace ts.server {
|
||||
const externalProject = this.findExternalProjectByProjectName(proj.projectFileName);
|
||||
let exisingConfigFiles: string[];
|
||||
if (externalProject) {
|
||||
externalProject.excludedFiles = excludedFiles;
|
||||
if (!tsConfigFiles) {
|
||||
const compilerOptions = convertCompilerOptions(proj.options);
|
||||
if (this.exceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
|
||||
@@ -1891,7 +1934,8 @@ namespace ts.server {
|
||||
else {
|
||||
// no config files - remove the item from the collection
|
||||
this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName);
|
||||
this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition);
|
||||
const newProj = this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition);
|
||||
newProj.excludedFiles = excludedFiles;
|
||||
}
|
||||
if (!suppressRefreshOfInferredProjects) {
|
||||
this.refreshInferredProjects();
|
||||
|
||||
+46
-23
@@ -376,6 +376,10 @@ namespace ts.server {
|
||||
return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles);
|
||||
}
|
||||
|
||||
getExcludedFiles(): ReadonlyArray<NormalizedPath> {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean) {
|
||||
if (!this.program) {
|
||||
return [];
|
||||
@@ -543,33 +547,32 @@ namespace ts.server {
|
||||
this.cachedUnresolvedImportsPerFile.remove(file);
|
||||
}
|
||||
|
||||
// 1. no changes in structure, no changes in unresolved imports - do nothing
|
||||
// 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
|
||||
let unresolvedImports: SortedReadonlyArray<string>;
|
||||
if (hasChanges || changedFiles.length) {
|
||||
const result: string[] = [];
|
||||
for (const sourceFile of this.program.getSourceFiles()) {
|
||||
this.extractUnresolvedImportsFromSourceFile(sourceFile, result);
|
||||
}
|
||||
this.lastCachedUnresolvedImportsList = toDeduplicatedSortedArray(result);
|
||||
}
|
||||
unresolvedImports = this.lastCachedUnresolvedImportsList;
|
||||
|
||||
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, unresolvedImports, hasChanges);
|
||||
if (this.setTypings(cachedTypings)) {
|
||||
hasChanges = this.updateGraphWorker() || hasChanges;
|
||||
}
|
||||
|
||||
// update builder only if language service is enabled
|
||||
// otherwise tell it to drop its internal state
|
||||
if (this.languageServiceEnabled) {
|
||||
// 1. no changes in structure, no changes in unresolved imports - do nothing
|
||||
// 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
|
||||
if (hasChanges || changedFiles.length) {
|
||||
const result: string[] = [];
|
||||
for (const sourceFile of this.program.getSourceFiles()) {
|
||||
this.extractUnresolvedImportsFromSourceFile(sourceFile, result);
|
||||
}
|
||||
this.lastCachedUnresolvedImportsList = toDeduplicatedSortedArray(result);
|
||||
}
|
||||
|
||||
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasChanges);
|
||||
if (this.setTypings(cachedTypings)) {
|
||||
hasChanges = this.updateGraphWorker() || hasChanges;
|
||||
}
|
||||
|
||||
this.builder.onProjectUpdateGraph();
|
||||
}
|
||||
else {
|
||||
this.lastCachedUnresolvedImportsList = undefined;
|
||||
this.builder.clear();
|
||||
}
|
||||
|
||||
@@ -995,16 +998,22 @@ namespace ts.server {
|
||||
if (this.projectService.globalPlugins) {
|
||||
// Enable global plugins with synthetic configuration entries
|
||||
for (const globalPluginName of this.projectService.globalPlugins) {
|
||||
// Skip empty names from odd commandline parses
|
||||
if (!globalPluginName) continue;
|
||||
|
||||
// Skip already-locally-loaded plugins
|
||||
if (options.plugins && options.plugins.some(p => p.name === globalPluginName)) continue;
|
||||
|
||||
// Provide global: true so plugins can detect why they can't find their config
|
||||
this.projectService.logger.info(`Loading global plugin ${globalPluginName}`);
|
||||
this.enablePlugin({ name: globalPluginName, global: true } as PluginImport, searchPaths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]) {
|
||||
this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`);
|
||||
|
||||
const log = (message: string) => {
|
||||
this.projectService.logger.info(message);
|
||||
};
|
||||
@@ -1016,7 +1025,7 @@ namespace ts.server {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name} anywhere in paths: ${searchPaths.join(",")}`);
|
||||
this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name}`);
|
||||
}
|
||||
|
||||
private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) {
|
||||
@@ -1035,7 +1044,15 @@ namespace ts.server {
|
||||
};
|
||||
|
||||
const pluginModule = pluginModuleFactory({ typescript: ts });
|
||||
this.languageService = pluginModule.create(info);
|
||||
const newLS = pluginModule.create(info);
|
||||
for (const k of Object.keys(this.languageService)) {
|
||||
if (!(k in newLS)) {
|
||||
this.projectService.logger.info(`Plugin activation warning: Missing proxied method ${k} in created LS. Patching.`);
|
||||
(newLS as any)[k] = (this.languageService as any)[k];
|
||||
}
|
||||
}
|
||||
this.projectService.logger.info(`Plugin validation succeded`);
|
||||
this.languageService = newLS;
|
||||
this.plugins.push(pluginModule);
|
||||
}
|
||||
catch (e) {
|
||||
@@ -1166,6 +1183,7 @@ namespace ts.server {
|
||||
* These are created only if a host explicitly calls `openExternalProject`.
|
||||
*/
|
||||
export class ExternalProject extends Project {
|
||||
excludedFiles: ReadonlyArray<NormalizedPath> = [];
|
||||
private typeAcquisition: TypeAcquisition;
|
||||
constructor(public externalProjectName: string,
|
||||
projectService: ProjectService,
|
||||
@@ -1175,6 +1193,11 @@ namespace ts.server {
|
||||
public compileOnSaveEnabled: boolean,
|
||||
private readonly projectFilePath?: string) {
|
||||
super(externalProjectName, ProjectKind.External, projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, languageServiceEnabled, compilerOptions, compileOnSaveEnabled);
|
||||
|
||||
}
|
||||
|
||||
getExcludedFiles() {
|
||||
return this.excludedFiles;
|
||||
}
|
||||
|
||||
getProjectRootPath() {
|
||||
|
||||
+25
-4
@@ -8,6 +8,7 @@ namespace ts.server.protocol {
|
||||
/* @internal */
|
||||
BraceFull = "brace-full",
|
||||
BraceCompletion = "braceCompletion",
|
||||
GetSpanOfEnclosingComment = "getSpanOfEnclosingComment",
|
||||
Change = "change",
|
||||
Close = "close",
|
||||
Completions = "completions",
|
||||
@@ -241,6 +242,21 @@ namespace ts.server.protocol {
|
||||
body?: TodoComment[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A request to determine if the caret is inside a comment.
|
||||
*/
|
||||
export interface SpanOfEnclosingCommentRequest extends FileLocationRequest {
|
||||
command: CommandTypes.GetSpanOfEnclosingComment;
|
||||
arguments: SpanOfEnclosingCommentRequestArgs;
|
||||
}
|
||||
|
||||
export interface SpanOfEnclosingCommentRequestArgs extends FileLocationRequestArgs {
|
||||
/**
|
||||
* Requires that the enclosing span be a multi-line comment, or else the request returns undefined.
|
||||
*/
|
||||
onlyMultiLine: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to obtain outlining spans in file.
|
||||
*/
|
||||
@@ -450,7 +466,7 @@ namespace ts.server.protocol {
|
||||
* Represents a single refactoring action - for example, the "Extract Method..." refactor might
|
||||
* offer several actions, each corresponding to a surround class or closure to extract into.
|
||||
*/
|
||||
export type RefactorActionInfo = {
|
||||
export interface RefactorActionInfo {
|
||||
/**
|
||||
* The programmatic name of the refactoring action
|
||||
*/
|
||||
@@ -462,7 +478,7 @@ namespace ts.server.protocol {
|
||||
* so this description should make sense by itself if the parent is inlineable=true
|
||||
*/
|
||||
description: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface GetEditsForRefactorRequest extends Request {
|
||||
command: CommandTypes.GetEditsForRefactor;
|
||||
@@ -478,6 +494,7 @@ namespace ts.server.protocol {
|
||||
refactor: string;
|
||||
/* The 'name' property from the refactoring action */
|
||||
action: string;
|
||||
formatOptions?: FormatCodeSettings,
|
||||
};
|
||||
|
||||
|
||||
@@ -485,7 +502,7 @@ namespace ts.server.protocol {
|
||||
body?: RefactorEditInfo;
|
||||
}
|
||||
|
||||
export type RefactorEditInfo = {
|
||||
export interface RefactorEditInfo {
|
||||
edits: FileCodeEdits[];
|
||||
|
||||
/**
|
||||
@@ -494,7 +511,7 @@ namespace ts.server.protocol {
|
||||
*/
|
||||
renameLocation?: Location;
|
||||
renameFilename?: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Request for the available codefixes at a specific position.
|
||||
@@ -2473,6 +2490,7 @@ namespace ts.server.protocol {
|
||||
System = "System",
|
||||
ES6 = "ES6",
|
||||
ES2015 = "ES2015",
|
||||
ESNext = "ESNext"
|
||||
}
|
||||
|
||||
export const enum ModuleResolutionKind {
|
||||
@@ -2490,5 +2508,8 @@ namespace ts.server.protocol {
|
||||
ES5 = "ES5",
|
||||
ES6 = "ES6",
|
||||
ES2015 = "ES2015",
|
||||
ES2016 = "ES2016",
|
||||
ES2017 = "ES2017",
|
||||
ESNext = "ESNext"
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user